diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 64f8f91ed..7f312baae 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -72,6 +72,7 @@ AppDir: - libxkbcommon-x11-0 # if QT:BOOL=ON - qtwayland5 # if QT:BOOL=ON - zlib1g + - libserialport0 files: exclude: - etc diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index a57d3c715..04b0bc350 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -20,11 +20,12 @@ def repository = ['https://github.com/86Box/86Box.git', scm.userRemoteConfigs[0] def commitBrowser = ['https://github.com/86Box/86Box/commit/%s', null] def branch = ['master', scm.branches[0].name] def buildType = ['beta', 'alpha'] +def tarballFlags = ['', '-s'] def buildBranch = env.JOB_BASE_NAME.contains('-') ? 1 : 0 def osArchs = [ - 'Windows': ['32', '64'], - 'Linux': ['x86', 'x86_64', 'arm32', 'arm64'], + 'Windows': ['64'], + 'Linux': ['x86_64', 'arm64'], 'macOS': ['x86_64+x86_64h+arm64'] ] @@ -238,7 +239,7 @@ pipeline { dir("${env.WORKSPACE_TMP}/output") { /* Run source tarball creation process. */ def packageName = "${env.JOB_BASE_NAME}-Source$buildSuffix" - if (runBuild("-s \"$packageName\"") == 0) { + if (runBuild("-s \"$packageName\" ${tarballFlags[buildBranch]}") == 0) { /* Archive resulting artifacts. */ archiveArtifacts artifacts: "$packageName*" } else { diff --git a/.ci/build.sh b/.ci/build.sh index a53ea0671..0af94132a 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -208,7 +208,7 @@ cmake_flags_extra= if [ -z "$package_name" -a -z "$tarball_name" ] || [ -n "$package_name" -a -z "$arch" ] then echo '[!] Usage: build.sh -b {package_name} {architecture} [-t] [cmake_flags...]' - echo ' build.sh -s {source_tarball_name}' + echo ' build.sh -s {source_tarball_name} [-t]' echo 'Dep. tree: build.sh -p [archive_tmp/path/to/binary]' exit 100 fi @@ -228,7 +228,10 @@ then [ ! -d "$cwd" ] && mkdir -p "$cwd" # Save current HEAD commit to VERSION. - git log --stat -1 > VERSION || rm -f VERSION + if [ $strip -eq 0 ] + then + git log --stat -1 > VERSION || rm -f VERSION + fi # Archive source. make_tar "$cwd/$tarball_name.tar" @@ -522,6 +525,9 @@ then cmake_flags_extra="$cmake_flags_extra -D MOLTENVK=ON -D \"MOLTENVK_INCLUDE_DIR=$macports\"" fi + # Enable Libserialport + cmake_flags_extra="$cmake_flags_extra -D \"LIBSERIALPORT_ROOT=$macports\"" + # Install dependencies only if we're in a new build and/or MacPorts prefix. if check_buildtag "$(basename "$macports")" then @@ -535,6 +541,21 @@ then sudo sed -i -e 's/-no-feature-vulkan/-feature-vulkan/g' "$qt5_portfile" sudo sed -i -e 's/configure.env-append MAKE=/configure.env-append VULKAN_SDK=${prefix} MAKE=/g' "$qt5_portfile" fi + + # Patch openal-soft to use 1.23.1 on all targets instead of 1.24.2 on >=10.13 only, + # to prevent a symlink mismatch from having different versions on x86_64 and arm64. + # See: https://github.com/macports/macports-ports/commit/9b4903fc9c76769d476079e404c9a3b8a225f8aa + # https://github.com/macports/macports-ports/commit/788deb64dc0695e8d04afb32ed904947f2a7591b + openal_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/audio/openal-soft/Portfile" + sudo sed -i -e 's/if {${os.platform} ne "darwin" ||/if {0 \&\&/g' "$openal_portfile" + + # Patch wget to remove libproxy support, as it depends on shared-mime-info which + # fails to build for a 10.13 target, which we have to do despite wget only being + # a host dependency. MacPorts issue 69406 strongly implies this will not be fixed. + wget_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/net/wget/Portfile" + sudo sed -i -e 's/--enable-libproxy/--disable-libproxy/g' "$wget_portfile" + sudo sed -i -e 's/port:libproxy//g' "$wget_portfile" + while : do # Attempt to install dependencies. @@ -582,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" + pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream qttranslations5-l10n" if [ "$(dpkg --print-architecture)" = "$arch_deb" ] then pkgs="$pkgs build-essential" @@ -605,7 +626,7 @@ else # ...and the ones we do want listed. Non-dev packages fill missing spots on the list. libpkgs="" longest_libpkg=0 - for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev + for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev libserialport-dev do libpkgs="$libpkgs $pkg:$arch_deb" length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c) diff --git a/.ci/dependencies_macports.txt b/.ci/dependencies_macports.txt index b23ac441d..e530871ae 100644 --- a/.ci/dependencies_macports.txt +++ b/.ci/dependencies_macports.txt @@ -16,3 +16,4 @@ ghostscript libslirp vde2 libsndfile +libserialport diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index eacdb8b36..b6c0979e2 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -14,3 +14,4 @@ qt5-static qt5-translations vulkan-headers libsndfile +libserialport diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index cdbc0a56f..d805d84a2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -6,7 +6,15 @@ body: - type: markdown attributes: value: | - Thanks for taking the time to fill out this bug report! + ## Thanks for taking the time to fill out this bug report! + - type: checkboxes + attributes: + label: Checklist + options: + - label: I **have searched** the issue tracker and **was unable** to find an [open](../issues?q=is%3Aissue+is%3Aopen) or [closed](../issues?q=is%3Aissue+is%3Aclosed) issue matching what I'm seeing. + required: true + - label: I **have verified** that the issue is happening in the **[latest nightly build](https://ci.86box.net/job/86Box/lastSuccessfulBuild/artifact/)**, or the latest commit, if building from source. + required: true - type: textarea attributes: label: What happened? @@ -25,20 +33,13 @@ body: attributes: label: Operating system description: What is your host operating system? - placeholder: e.g. Windows 10 - validations: - required: true - - type: input - attributes: - label: CPU - description: What is your host CPU? - placeholder: e.g. AMD Ryzen 5 5600G + placeholder: e.g. Windows 11 24H2 validations: required: true - type: input attributes: label: 86Box version - description: What version of 86Box are you running? (Saying "Latest from Jenkins" is not helpful.) + description: What version of 86Box are you running? (Please ensure you have updated to the [latest build](https://ci.86box.net/job/86Box/lastSuccessfulBuild/artifact/) before reporting. Merely saying "Latest from Jenkins" is not helpful.) placeholder: e.g. v4.0 build 5000 validations: required: true @@ -47,13 +48,13 @@ body: label: Build architecture description: 86Box for what architecture are you using? options: - - Linux - ARM (32-bit) - - Linux - ARM (64-bit) - - Linux - x64 (64-bit) - - Linux - x86 (32-bit) - - macOS - Universal (Intel and Apple Silicon) - Windows - x64 (64-bit) + - macOS - Universal (Intel and Apple Silicon) + - Linux - x64 (64-bit) + - Linux - ARM (64-bit) - Windows - x86 (32-bit) + - Linux - ARM (32-bit) + - Linux - x86 (32-bit) validations: required: true - type: checkboxes @@ -63,18 +64,7 @@ body: options: - label: New recompiler - label: Debug build - - type: dropdown - attributes: - label: Download source - description: Where did you download 86Box from? - options: - - Official website (Jenkins, GitHub) - - Manager auto-update - - I built 86Box myself (please tell us more about your build configuration) - - I got 86Box from a third party repository (please tell us where) - validations: - required: true - type: textarea attributes: label: Additional context - description: Is there anything else you want to tell us? + description: Is there anything else you want to tell us? If you build 86Box from source, please post your build configuration here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c03c50764..4ca9bac59 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - name: Machine Request - url: https://github.com/86Box/86Box/issues/3577#issue-comment-box - about: Please submit machine addition requests under this tracking issue. + url: https://github.com/86Box/86Box/discussions/4823#issue-comment-box + about: Please submit machine addition requests in this discussion thread. - name: Feature Request or Question url: https://github.com/86Box/86Box/discussions about: Please submit feature requests and ask questions here. diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index ed0f055a2..83672974f 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -63,6 +63,7 @@ jobs: qtbase5-dev qtbase5-private-dev qttools5-dev + qttranslations5-l10n libevdev-dev libxkbcommon-x11-dev @@ -80,6 +81,8 @@ jobs: libopenal-dev libslirp-dev libfluidsynth-dev + libvdeplug-dev + libserialport-dev ${{ matrix.ui.packages }} - name: Checkout repository @@ -88,7 +91,7 @@ jobs: 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@5c3c39143e381909307f6903f13774b275ed956d + uses: SonarSource/sonarcloud-github-c-cpp@v3 - name: Configure CMake run: >- @@ -103,7 +106,7 @@ jobs: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - name: Run sonar-scanner -# if: 0 + if: 0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index dc45312f5..5a0454385 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -25,10 +25,10 @@ on: jobs: - macos12: + macos13-x86_64: name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" - runs-on: macos-12 + runs-on: macos-13 env: BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed @@ -80,6 +80,9 @@ jobs: rtmidi openal-soft fluidsynth + libslirp + vde + libserialport ${{ matrix.ui.packages }} - name: Checkout repository @@ -88,7 +91,7 @@ jobs: 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@5c3c39143e381909307f6903f13774b275ed956d + uses: SonarSource/sonarcloud-github-c-cpp@v3 - name: Configure CMake run: >- @@ -100,6 +103,7 @@ jobs: -D Qt5_ROOT=$(brew --prefix qt@5) -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) -D OpenAL_ROOT=$(brew --prefix openal-soft) + -D LIBSERIALPORT_ROOT=$(brew --prefix libserialport) - name: Build run: | @@ -179,6 +183,7 @@ jobs: openal-soft fluidsynth libslirp + libserialport ${{ matrix.ui.packages }} - name: Checkout repository @@ -187,7 +192,7 @@ jobs: 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@5c3c39143e381909307f6903f13774b275ed956d +# uses: SonarSource/sonarcloud-github-c-cpp@v3 - name: Configure CMake run: >- @@ -199,6 +204,7 @@ jobs: -D Qt5_ROOT=$(brew --prefix qt@5) -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) -D OpenAL_ROOT=$(brew --prefix openal-soft) + -D LIBSERIALPORT_ROOT=$(brew --prefix libserialport) - name: Build run: | diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 91442eafd..abe25b949 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -67,15 +67,9 @@ jobs: environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: MINGW32 -# prefix: mingw-w64-i686 -# toolchain: ./cmake/flags-gcc-i686.cmake - msystem: MINGW64 prefix: mingw-w64-x86_64 toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake # - msystem: CLANG64 # prefix: mingw-w64-clang-x86_64 # toolchain: ./cmake/llvm-win32-x86_64.cmake @@ -103,6 +97,7 @@ jobs: rtmidi:p libslirp:p fluidsynth:p + libserialport:p ${{ matrix.ui.packages }} - name: Checkout repository @@ -111,7 +106,7 @@ jobs: 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@5c3c39143e381909307f6903f13774b275ed956d + uses: SonarSource/sonarcloud-github-c-cpp@v3 - name: Configure CMake run: >- diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index fee26a0a6..fc0397703 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -66,6 +66,7 @@ jobs: qtbase5-dev qtbase5-private-dev qttools5-dev + qttranslations5-l10n libevdev-dev libxkbcommon-x11-dev @@ -83,6 +84,8 @@ jobs: libopenal-dev libslirp-dev libfluidsynth-dev + libvdeplug-dev + libserialport-dev ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 266a1f051..841ca98f5 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -25,11 +25,11 @@ on: jobs: - analyze-macos12: + analyze-macos13-x86_64: name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64" - runs-on: macos-12 + runs-on: macos-13 permissions: actions: read @@ -74,6 +74,9 @@ jobs: rtmidi openal-soft fluidsynth + libslirp + vde + libserialport ${{ matrix.ui.packages }} - name: Checkout repository @@ -95,6 +98,7 @@ jobs: -D Qt5_ROOT=$(brew --prefix qt@5) -D Qt5LinguistTools_ROOT=$(brew --prefix qt@5) -D OpenAL_ROOT=$(brew --prefix openal-soft) + -D LIBSERIALPORT_ROOT=$(brew --prefix libserialport) - name: Build run: cmake --build build diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 652a1986a..7a0055910 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -72,15 +72,9 @@ jobs: environment: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake - - msystem: MINGW32 - prefix: mingw-w64-i686 - toolchain: ./cmake/flags-gcc-i686.cmake - msystem: MINGW64 prefix: mingw-w64-x86_64 toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake # - msystem: CLANG64 # prefix: mingw-w64-clang-x86_64 # toolchain: ./cmake/llvm-win32-x86_64.cmake @@ -108,6 +102,7 @@ jobs: rtmidi:p libslirp:p fluidsynth:p + libserialport:p ${{ matrix.ui.packages }} - name: Checkout repository diff --git a/.gitignore b/.gitignore index 5a43dffdb..5935efd38 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,6 @@ CMakeLists.txt.user # clangd .cache + +# Jetbrains CLion +.idea diff --git a/CMakeLists.txt b/CMakeLists.txt index ca75ebc25..aa687222a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,17 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020-2021 David Hrdlička. +# Copyright 2020-2021 David Hrdlička. +# Copyright 2021-2025 Jasmine Iwanek. # cmake_minimum_required(VERSION 3.16) @@ -35,7 +36,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 4.2.1 + VERSION 4.3 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) @@ -122,48 +123,55 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) # Optional features # -# Option Description Def. -# ------ ----------- ---- -option(RELEASE "Release build" OFF) -option(DYNAREC "Dynamic recompiler" ON) -option(OPENAL "OpenAL" ON) -option(RTMIDI "RtMidi" ON) -option(FLUIDSYNTH "FluidSynth" ON) -option(MUNT "MUNT" ON) -option(VNC "VNC renderer" OFF) -option(CPPTHREADS "C++11 threads" ON) -option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) -option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) -option(GDBSTUB "Enable GDB stub server for debugging" OFF) -option(DEV_BRANCH "Development branch" OFF) -option(DISCORD "Discord Rich Presence support" ON) -option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) +# Option Description Def. +# ------ ----------- ---- +option(RELEASE "Release build" OFF) +option(DYNAREC "Dynamic recompiler" ON) +option(OPENAL "OpenAL" ON) +option(RTMIDI "RtMidi" ON) +option(FLUIDSYNTH "FluidSynth" ON) +option(MUNT "MUNT" ON) +option(VNC "VNC renderer" OFF) +option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) +option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) +option(GDBSTUB "Enable GDB stub server for debugging" OFF) +option(DEV_BRANCH "Development branch" OFF) +option(DISCORD "Discord Rich Presence support" ON) +option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) if(WIN32) set(QT ON) + option(CPPTHREADS "C++11 threads" OFF) else() option(QT "Qt GUI" ON) + option(CPPTHREADS "C++11 threads" ON) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,wxneeded") endif() # Development branch features # -# 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(CYRIX_6X86 "Cyrix 6x86" 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(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) +# 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(CYRIX_6X86 "Cyrix 6x86" 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) # Ditto but for Qt if(QT) diff --git a/CMakePresets.json b/CMakePresets.json index c19a7abc0..be6615088 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -55,6 +55,14 @@ }, "inherits": "base" }, + { + "name": "ultra_debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "UltraDebug", + "DEV_BRANCH": "ON" + }, + "inherits": "base" + }, { "name": "llvm-macos-aarch64.cmake", "displayName": "MacOS clang regular", @@ -68,7 +76,8 @@ "Qt5_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5", "MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk", "Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools", - "OpenAL_ROOT": "/opt/homebrew/opt/openal-soft" + "OpenAL_ROOT": "/opt/homebrew/opt/openal-soft", + "LIBSERIALPORT_ROOT": "/opt/homebrew/opt/libserialport" }, "inherits": "regular" }, @@ -86,6 +95,7 @@ "MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk", "Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools", "OpenAL_ROOT": "/opt/homebrew/opt/openal-soft", + "LIBSERIALPORT_ROOT": "/opt/homebrew/opt/libserialport", "CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG", "CMAKE_C_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG" }, diff --git a/README.md b/README.md index b4b4142be..c01a852b5 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ It is also recommended to use a manager application with 86Box for easier handli * [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only) * [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia) +* [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux) * [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python) * [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) @@ -53,10 +54,14 @@ We operate an IRC channel and a Discord server for discussing 86Box, its develop [![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](https://discord.gg/QXK9XTv) Contributions ---------- +------------- We welcome all contributions to the project, as long as the [contribution guidelines](CONTRIBUTING.md) are followed. +Building +--------- +For instructions on how to build 86Box from source, see the [build guide](https://86box.readthedocs.io/en/latest/dev/buildguide.html). + Licensing --------- diff --git a/cmake/flags-gcc.cmake b/cmake/flags-gcc.cmake index 885353b87..90eb52cd1 100644 --- a/cmake/flags-gcc.cmake +++ b/cmake/flags-gcc.cmake @@ -20,6 +20,8 @@ string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og") string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -ggdb -Og") +string(APPEND CMAKE_C_FLAGS_ULTRADEBUG_INIT " -O0 -ggdb -g3") +string(APPEND CMAKE_CXX_FLAGS_ULTRADEBUG_INIT " -O0 -ggdb -g3") string(APPEND CMAKE_C_FLAGS_OPTIMIZED_INIT " -march=native -mtune=native -O3 -ffp-contract=fast -flto") string(APPEND CMAKE_CXX_FLAGS_OPTIMIZED_INIT " -march=native -mtune=native -O3 -ffp-contract=fast -flto") @@ -28,7 +30,7 @@ foreach(LANG C;CXX) set(CMAKE_${LANG}_FLAGS "$ENV{${LANG}FLAGS} ${CMAKE_${LANG}_FLAGS_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during all build types.") mark_as_advanced(CMAKE_${LANG}_FLAGS) - foreach(CONFIG RELEASE;DEBUG;OPTIMIZED) + foreach(CONFIG RELEASE;DEBUG;ULTRADEBUG;OPTIMIZED) set(CMAKE_${LANG}_FLAGS_${CONFIG} "${CMAKE_${LANG}_FLAGS_${CONFIG}_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during ${CONFIG} builds.") mark_as_advanced(CMAKE_${LANG}_FLAGS_${CONFIG}) endforeach() diff --git a/debian/changelog b/debian/changelog index 78c838a01..5665ff968 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (4.2.1) UNRELEASED; urgency=medium +86box (4.3) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Fri, 26 Jul 2024 21:09:16 +0200 + -- Jasmine Iwanek Wed, 13 Nov 2024 06:31:46 +0100 diff --git a/debian/control b/debian/control index a718aee33..a11e2af48 100644 --- a/debian/control +++ b/debian/control @@ -16,7 +16,8 @@ Build-Depends: cmake (>= 3.21), libsndfile-dev, ninja-build, qttools5-dev, - qtbase5-private-dev + qtbase5-private-dev, + libserialport-dev Standards-Version: 4.6.0 Homepage: https://86box.net/ #Vcs-Browser: https://salsa.debian.org/debian/86box diff --git a/scripts/86Box-install-roms.sh b/scripts/86Box-install-roms.sh deleted file mode 100755 index b13d93acc..000000000 --- a/scripts/86Box-install-roms.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh - -URL="https://github.com/86Box/roms/archive/refs/tags/v4.2.zip" -TMP_FILE="/tmp/86Box-ROMS.zip" -EXTRACT_DIR="/tmp/86Box-ROMS-extracted" -DEFAULT_TARGET_DIR="$HOME/.local/share/86Box/roms/" -TARGET_DIR=${TARGET_DIR:-$DEFAULT_TARGET_DIR} - -install_roms() { - if [ -d "$TARGET_DIR" ] && [ "$(ls -A $TARGET_DIR)" ]; then - echo "ROMS already installed in $TARGET_DIR" - echo "To (re)install, please first remove ROMS with -r parameter" - exit 1 - fi - fetch -o "$TMP_FILE" "$URL" - - if [ $? -ne 0 ]; then - echo "Failed to download the file from $URL" - exit 1 - fi - - mkdir -p "$EXTRACT_DIR" - unzip "$TMP_FILE" -d "$EXTRACT_DIR" - - if [ $? -ne 0 ]; then - echo "Failed to decompress the file" - rm "$TMP_FILE" - exit 1 - fi - - mkdir -p "$TARGET_DIR" - cd "$EXTRACT_DIR" - TOP_LEVEL_DIR=$(find . -mindepth 1 -maxdepth 1 -type d) - - if [ -d "$TOP_LEVEL_DIR" ]; then - mv "$TOP_LEVEL_DIR"/* "$TARGET_DIR" - fi - - rm -rf "$TMP_FILE" "$EXTRACT_DIR" - echo "ROMS installed successfully in $TARGET_DIR" -} - -remove_roms() { - if [ -d "$TARGET_DIR" ]; then - rm -rf "$TARGET_DIR" - echo "ROMS removed successfully from $TARGET_DIR" - else - echo "No ROMS directory found in $TARGET_DIR" - fi -} - -help() { - echo "" - echo "$0 [-h|-i|-r]" - echo " -h : this help" - echo " -i : install (this parameter can be omitted)" - echo " -r : remove the ROMS" - echo "" -} - -case "$1" in - -h) - help - ;; - -r) - remove_roms - ;; - -i|*) - install_roms - ;; -esac - -exit 0 diff --git a/src/86box.c b/src/86box.c index 9b77263a2..764f707ba 100644 --- a/src/86box.c +++ b/src/86box.c @@ -11,6 +11,7 @@ * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, + * Jasmine Iwanek, * * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. @@ -18,7 +19,7 @@ * Copyright 2021 Laci bá' * Copyright 2021 dob205 * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. */ #include #include @@ -103,6 +104,7 @@ #include <86box/machine_status.h> #include <86box/apm.h> #include <86box/acpi.h> +#include <86box/nv/vid_nv_rivatimer.h> // Disable c99-designator to avoid the warnings about int ng #ifdef __clang__ @@ -177,6 +179,7 @@ int bugger_enabled = 0; /* (C) enable int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */ int postcard_enabled = 0; /* (C) enable POST card */ 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 isartc_type = 0; /* (C) enable ISA RTC card */ int gfxcard[GFXCARD_MAX] = { 0, 0 }; /* (C) graphics/video card */ @@ -207,6 +210,8 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether also apply when maximized. */ int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus loss */ +int hook_enabled = 1; /* (C) Keyboard hook is enabled */ +int test_mode = 0; /* (C) Test mode */ char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are @@ -252,12 +257,36 @@ static volatile atomic_int do_pause_ack = 0; static volatile atomic_int pause_ack = 0; #ifndef RELEASE_BUILD -static char buff[1024]; -static int seen = 0; + +#define LOG_SIZE_BUFFER 1024 /* Log size buffer */ + +static char buff[LOG_SIZE_BUFFER]; + +static int seen = 0; static int suppr_seen = 1; + +// Functions only used in this translation unit +void pclog_ensure_stdlog_open(void); #endif +/* + Ensures STDLOG is open for pclog_ex and pclog_ex_cyclic +*/ +void pclog_ensure_stdlog_open(void) +{ +#ifndef RELEASE_BUILD + if (stdlog == NULL) { + if (log_path[0] != '\0') { + stdlog = plat_fopen(log_path, "w"); + if (stdlog == NULL) + stdlog = stdout; + } else + stdlog = stdout; + } +#endif +} + /* * Log something to the logfile or stdout. * @@ -266,22 +295,15 @@ static int suppr_seen = 1; * being logged, and catch repeating entries. */ void -pclog_ex(const char *fmt, va_list ap) +pclog_ex(UNUSED(const char *fmt), UNUSED(va_list ap)) { #ifndef RELEASE_BUILD - char temp[1024]; + char temp[LOG_SIZE_BUFFER]; if (strcmp(fmt, "") == 0) return; - if (stdlog == NULL) { - if (log_path[0] != '\0') { - stdlog = plat_fopen(log_path, "w"); - if (stdlog == NULL) - stdlog = stdout; - } else - stdlog = stdout; - } + pclog_ensure_stdlog_open(); vsprintf(temp, fmt, ap); if (suppr_seen && !strcmp(buff, temp)) @@ -298,6 +320,8 @@ pclog_ex(const char *fmt, va_list ap) #endif } + + void pclog_toggle_suppr(void) { @@ -308,7 +332,7 @@ pclog_toggle_suppr(void) /* Log something. We only do this in non-release builds. */ void -pclog(const char *fmt, ...) +pclog(UNUSED(const char *fmt), ...) { #ifndef RELEASE_BUILD va_list ap; @@ -435,7 +459,7 @@ delete_nvr_file(uint8_t flash) int c; /* Set up the NVR file's name. */ - c = strlen(machine_get_internal_name()) + 5; + c = strlen(machine_get_nvr_name()) + 5; fn = (char *) malloc(c + 1); if (fn == NULL) @@ -443,9 +467,9 @@ delete_nvr_file(uint8_t flash) flash ? "BIOS flash" : "CMOS"); if (flash) - sprintf(fn, "%s.bin", machine_get_internal_name()); + sprintf(fn, "%s.bin", machine_get_nvr_name()); else - sprintf(fn, "%s.nvr", machine_get_internal_name()); + sprintf(fn, "%s.nvr", machine_get_nvr_name()); remove(nvr_path(fn)); @@ -453,6 +477,8 @@ delete_nvr_file(uint8_t flash) fn = NULL; } +extern void device_find_all_descs(void); + /* * Perform initial startup of the PC. * @@ -561,7 +587,9 @@ usage: #ifndef USE_SDL_UI printf("-S or --settings - show only the settings dialog\n"); #endif + printf("-T or --testmode - test mode: execute the test mode entry point on init/hard reset\n"); printf("-V or --vmname name - overrides the name of the running VM\n"); + printf("-W or --nohook - disables keyboard hook (compatibility-only outside Windows)\n"); printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n"); printf("-Y or --donothing - do not show any UI or run the emulation\n"); printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n"); @@ -631,12 +659,16 @@ usage: } else if (!strcasecmp(argv[c], "--settings") || !strcasecmp(argv[c], "-S")) { settings_only = 1; #endif + } else if (!strcasecmp(argv[c], "--testmode") || !strcasecmp(argv[c], "-T")) { + test_mode = 1; } else if (!strcasecmp(argv[c], "--noconfirm") || !strcasecmp(argv[c], "-N")) { confirm_exit_cmdl = 0; } else if (!strcasecmp(argv[c], "--missing") || !strcasecmp(argv[c], "-M")) { dump_missing = 1; } else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) { do_nothing = 1; + } else if (!strcasecmp(argv[c], "--nohook") || !strcasecmp(argv[c], "-W")) { + hook_enabled = 0; } else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) { if ((c + 1) == argc) goto usage; @@ -1086,6 +1118,27 @@ pc_send_cae(void) pc_send_ca(1); } +/* + Currently available API: + + extern void resetx86(void); + extern void softresetx86(void); + extern void hardresetx86(void); + + extern void prefetch_queue_set_pos(int pos); + extern void prefetch_queue_set_ip(uint16_t ip); + extern void prefetch_queue_set_prefetching(int p); + extern int prefetch_queue_get_pos(void); + extern uint16_t prefetch_queue_get_ip(void); + extern int prefetch_queue_get_prefetching(void); + extern int prefetch_queue_get_size(void); + */ +static void +pc_test_mode_entry_point(void) +{ + pclog("Test mode entry point\n=====================\n"); +} + void pc_reset_hard_close(void) { @@ -1287,6 +1340,9 @@ pc_reset_hard_init(void) update_mouse_msg(); + if (test_mode) + pc_test_mode_entry_point(); + ui_hard_reset_completed(); } @@ -1423,6 +1479,9 @@ pc_run(void) pc_reset_hard_init(); } + /* Update the guest-CPU independent timer for devices with independent clock speed */ + rivatimer_update_all(); + /* Run a block of code. */ startblit(); cpu_exec((int32_t) cpu_s->rspeed / 100); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a36dd796c..7d6daff9c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,25 +12,50 @@ # dob205 # # Copyright 2020-2022 David Hrdlička. -# Copyright 2021 dob205. +# Copyright 2021 dob205. +# Copyright 2024 Jasmine Iwanek. # + if(APPLE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) endif() -add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c - dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c - mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c - machine_status.c ini.c cJSON.c) +add_executable(86Box + 86box.c + config.c + log.c + random.c + timer.c + io.c + acpi.c + apm.c + dma.c + ddma.c + nmi.c + pic.c + pit.c + pit_fast.c + port_6x.c + port_92.c + ppi.c + pci.c + mca.c + usb.c + fifo.c + fifo8.c + device.c + nvr.c + nvr_at.c + nvr_ps2.c + machine_status.c + ini.c + cJSON.c +) if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1) endif() -if(PCL) - target_compile_definitions(86Box PRIVATE USE_PCL) -endif() - if(CPPTHREADS) target_sources(86Box PRIVATE thread.cpp) endif() @@ -52,10 +77,6 @@ if(DYNAREC) add_compile_definitions(USE_DYNAREC) endif() -if(DEV_BRANCH) - add_compile_definitions(DEV_BRANCH) -endif() - if(DISCORD) add_compile_definitions(DISCORD) target_sources(86Box PRIVATE discord.c) @@ -69,7 +90,10 @@ if(VNC) find_package(LibVNCServer) if(LibVNCServer_FOUND) add_compile_definitions(USE_VNC) - add_library(vnc OBJECT vnc.c vnc_keymap.c) + add_library(vnc OBJECT + vnc.c + vnc_keymap.c + ) target_link_libraries(86Box vnc LibVNCServer::vncserver) if(WIN32) target_link_libraries(86Box ws2_32) @@ -147,8 +171,10 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) include_directories(include) if(NEW_DYNAREC) include_directories(cpu codegen_new) -else() +elseif(DYNAREC) include_directories(cpu codegen) +else() + include_directories(cpu) endif() add_subdirectory(cdrom) @@ -157,7 +183,7 @@ add_subdirectory(chipset) add_subdirectory(cpu) if(NEW_DYNAREC) add_subdirectory(codegen_new) -else() +elseif(DYNAREC) add_subdirectory(codegen) endif() diff --git a/src/acpi.c b/src/acpi.c index 339ea7dcf..b33653663 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -89,7 +89,7 @@ acpi_timer_get(acpi_t *dev) } static uint8_t -acpi_gp_timer_get(acpi_t *dev) +acpi_gp_timer_get(UNUSED(acpi_t *dev)) { uint64_t clock = acpi_clock_get(); clock -= acpi_last_clock; @@ -2473,10 +2473,9 @@ acpi_init(const device_t *info) { acpi_t *dev; - dev = (acpi_t *) malloc(sizeof(acpi_t)); + dev = (acpi_t *) calloc(1, sizeof(acpi_t)); if (dev == NULL) return NULL; - memset(dev, 0x00, sizeof(acpi_t)); cpu_to_acpi = ACPI_TIMER_FREQ / cpuclock; dev->vendor = info->local; @@ -2576,7 +2575,7 @@ const device_t acpi_ali_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2590,7 +2589,7 @@ const device_t acpi_intel_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2604,7 +2603,7 @@ const device_t acpi_via_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2618,7 +2617,7 @@ const device_t acpi_via_596b_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2632,7 +2631,7 @@ const device_t acpi_smc_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2646,7 +2645,7 @@ const device_t acpi_sis_5582_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2660,7 +2659,7 @@ const device_t acpi_sis_5595_1997_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL @@ -2674,7 +2673,7 @@ const device_t acpi_sis_5595_device = { .init = acpi_init, .close = acpi_close, .reset = acpi_reset, - { .available = NULL }, + .available = NULL, .speed_changed = acpi_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/apm.c b/src/apm.c index d7ce262a3..3973f2b23 100644 --- a/src/apm.c +++ b/src/apm.c @@ -122,7 +122,7 @@ const device_t apm_device = { .init = apm_init, .close = apm_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -136,7 +136,7 @@ const device_t apm_pci_device = { .init = apm_init, .close = apm_close, .reset = apm_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -150,7 +150,7 @@ const device_t apm_pci_acpi_device = { .init = apm_init, .close = apm_close, .reset = apm_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 897b353cb..621b069b0 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -9,16 +9,28 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # find_package(PkgConfig REQUIRED) pkg_check_modules(SNDFILE REQUIRED IMPORTED_TARGET sndfile) -add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_ioctl.c cdrom_mitsumi.c) +add_library(cdrom OBJECT + cdrom.c + cdrom_image.c + cdrom_image_viso.c +) target_link_libraries(86Box PkgConfig::SNDFILE) + +if(CDROM_MITSUMI) + target_compile_definitions(cdrom PRIVATE USE_CDROM_MITSUMI) + target_sources(cdrom PRIVATE cdrom_mitsumi.c) +endif() + if (WIN32) # MSYS2 target_link_libraries(86Box -static ${SNDFILE_STATIC_LIBRARIES}) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 88811c016..8ebcfea1f 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -15,105 +15,86 @@ * Copyright 2018-2021 Miran Grca. */ #include +#ifdef ENABLE_CDROM_LOG #include +#endif #include #include #include #include #include -#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/config.h> #include <86box/cdrom.h> #include <86box/cdrom_image.h> #include <86box/cdrom_interface.h> -#include <86box/cdrom_mitsumi.h> +#include <86box/log.h> #include <86box/plat.h> +#include <86box/plat_cdrom_ioctl.h> #include <86box/scsi.h> #include <86box/scsi_device.h> +#include <86box/scsi_cdrom.h> #include <86box/sound.h> - -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#undef MSFtoLBA -#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) +#include <86box/ui.h> #define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 #define MIN_SEEK 2000 #define MAX_SEEK 333333 -#pragma pack(push, 1) -typedef struct { - uint8_t user_data[2048], - ecc[288]; -} m1_data_t; - -typedef struct { - uint8_t sub_header[8], - user_data[2328]; -} m2_data_t; - -typedef union { - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2336]; -} sector_data_t; - -typedef struct { - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; -} sector_raw_data_t; - -typedef union { - sector_raw_data_t sector_data; - uint8_t raw_data[2352]; -} sector_t; - -typedef struct { - sector_t sector; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union { - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; -#pragma pack(pop) - -static int cdrom_sector_size; -static uint8_t raw_buffer[2856]; /* Needs to be the same size as sector_buffer_t in the structs. */ -static uint8_t extra_buffer[296]; - -cdrom_t cdrom[CDROM_NUM]; +cdrom_t cdrom[CDROM_NUM] = { 0 }; int cdrom_interface_current; #ifdef ENABLE_CDROM_LOG int cdrom_do_log = ENABLE_CDROM_LOG; -void -cdrom_log(const char *fmt, ...) +static void +cdrom_log(void *priv, const char *fmt, ...) { - va_list ap; - if (cdrom_do_log) { + va_list ap; va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define cdrom_log(fmt, ...) +# define cdrom_log(priv, fmt, ...) #endif +static void process_mode1(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b); +static void process_mode2_non_xa(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b); +static void process_mode2_xa_form1(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b); +static void process_mode2_xa_form2(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b); + +typedef void (*cdrom_process_data_t)(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b); + +static cdrom_process_data_t cdrom_process_data[4] = { process_mode1, process_mode2_non_xa, + process_mode2_xa_form1, process_mode2_xa_form2 }; +#ifdef ENABLE_CDROM_LOG +static char * cdrom_req_modes[14] = { "Any", "Audio", "Mode 1", "Mode 2", + "CD-I/XA Mode 2 Form 1", "CD-I/XA Mode 2 Form 2", "Unk", "Unk", + "Any Data", "Any Data - 4", + "CD-I/XA Mode 2 Form 1", "CD-I/XA Mode 2 Form 1 - 4", + "Any CD-I/XA Data", "Any CD-I/XA Data - 4" }; +static char * cdrom_modes[4] = { "Mode 1", "Mode 2", "CD-I/XA Mode 2 Form 1", "CD-I/XA Mode 2 Form 2" }; +#endif +static uint8_t cdrom_mode_masks[14] = { 0x0f, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00, + 0x05, 0x05, 0x04, 0x04, 0x0c, 0x0c }; + +static uint8_t status_codes[2][8] = { { 0x13, 0x15, 0x15, 0x15, 0x12, 0x11, 0x13, 0x13 }, + { 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x00, 0x00 } }; +static int mult = 1; +static int part = 0; +static int ecc_diff = 288; + static const device_t cdrom_interface_none_device = { .name = "None", .internal_name = "none", @@ -122,7 +103,7 @@ static const device_t cdrom_interface_none_device = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -137,146 +118,57 @@ static const struct { // clang-format on }; -/* Reset the CD-ROM Interface, whichever one that is. */ -void -cdrom_interface_reset(void) +/* Private functions. */ +static void +cdrom_generate_name(const int type, char *name, const int internal) { - cdrom_log("CD-ROM Interface: reset(current=%d)\n", - cdrom_interface_current); + char elements[3][2048] = { 0 }; - /* If we have a valid controller, add its device. */ - if ((cdrom_interface_current > 0) && controllers[cdrom_interface_current].device) - device_add(controllers[cdrom_interface_current].device); -} + memcpy(elements[0], cdrom_drive_types[type].vendor, + strlen(cdrom_drive_types[type].vendor) + 1); + if (internal) for (int i = 0; i < strlen(elements[0]); i++) + if (elements[0][i] == ' ') + elements[0][i] = '_'; -const char * -cdrom_interface_get_internal_name(int cdinterface) -{ - return device_get_internal_name(controllers[cdinterface].device); -} + if (internal) { + int j = 0; + for (int i = 0; i <= strlen(cdrom_drive_types[type].model); i++) + if (cdrom_drive_types[type].model[i] != ':') + elements[1][j++] = cdrom_drive_types[type].model[i]; + } else + memcpy(elements[1], cdrom_drive_types[type].model, + strlen(cdrom_drive_types[type].model) + 1); + char *s = strstr(elements[1], " "); + if (s != NULL) + s[0] = 0x00; + if (internal) for (int i = 0; i < strlen(elements[1]); i++) + if (elements[1][i] == ' ') + elements[1][i] = '_'; -int -cdrom_interface_get_from_internal_name(char *s) -{ - int c = 0; + memcpy(elements[2], cdrom_drive_types[type].revision, + strlen(cdrom_drive_types[type].revision) + 1); + s = strstr(elements[2], " "); + if (s != NULL) + s[0] = 0x00; + if (internal) for (int i = 0; i < strlen(elements[2]); i++) + if (elements[2][i] == ' ') + elements[2][i] = '_'; - while (controllers[c].device != NULL) { - if (!strcmp(controllers[c].device->internal_name, s)) - return c; - c++; - } - - return 0; -} - -const device_t * -cdrom_interface_get_device(int cdinterface) -{ - return (controllers[cdinterface].device); -} - -int -cdrom_interface_has_config(int cdinterface) -{ - const device_t *dev = cdrom_interface_get_device(cdinterface); - - if (dev == NULL) - return 0; - - if (!device_has_config(dev)) - return 0; - - return 1; -} - -int -cdrom_interface_get_flags(int cdinterface) -{ - return (controllers[cdinterface].device->flags); -} - -int -cdrom_interface_available(int cdinterface) -{ - return (device_available(controllers[cdinterface].device)); -} - -char * -cdrom_getname(int type) -{ - return (char *) cdrom_drive_types[type].name; -} - -char * -cdrom_get_internal_name(int type) -{ - return (char *) cdrom_drive_types[type].internal_name; -} - -int -cdrom_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen(cdrom_drive_types[c].internal_name)) { - if (!strcmp((char *) cdrom_drive_types[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -void -cdrom_set_type(int model, int type) -{ - cdrom[model].type = type; -} - -int -cdrom_get_type(int model) -{ - return cdrom[model].type; -} - -static __inline int -bin2bcd(int x) -{ - return (x % 10) | ((x / 10) << 4); -} - -static __inline int -bcd2bin(int x) -{ - return (x >> 4) * 10 + (x & 0x0f); -} - -int -cdrom_lba_to_msf_accurate(int lba) -{ - int pos; - int m; - int s; - int f; - - pos = lba + 150; - f = pos % 75; - pos -= f; - pos /= 75; - s = pos % 60; - pos -= s; - pos /= 60; - m = pos; - - return ((m << 16) | (s << 8) | f); + if (internal) + sprintf(name, "%s_%s_%s", elements[0], elements[1], elements[2]); + else if (cdrom_drive_types[type].speed == -1) + sprintf(name, "%s %s %s", elements[0], elements[1], elements[2]); + else + sprintf(name, "%s %s %s (%ix)", elements[0], elements[1], + elements[2], cdrom_drive_types[type].speed); } static double -cdrom_get_short_seek(cdrom_t *dev) +cdrom_get_short_seek(const cdrom_t *dev) { switch (dev->cur_speed) { case 0: - fatal("CD-ROM %i: 0x speed\n", dev->id); + log_fatal(dev->log, "0x speed\n"); return 0.0; case 1: return 240.0; @@ -324,11 +216,11 @@ cdrom_get_short_seek(cdrom_t *dev) } static double -cdrom_get_long_seek(cdrom_t *dev) +cdrom_get_long_seek(const cdrom_t *dev) { switch (dev->cur_speed) { case 0: - fatal("CD-ROM %i: 0x speed\n", dev->id); + log_fatal(dev->log, "0x speed\n"); return 0.0; case 1: return 1446.0; @@ -375,113 +267,6 @@ cdrom_get_long_seek(cdrom_t *dev) } } -double -cdrom_seek_time(cdrom_t *dev) -{ - uint32_t diff = dev->seek_diff; - double sd = (double) (MAX_SEEK - MIN_SEEK); - - if (diff < MIN_SEEK) - return 0.0; - if (diff > MAX_SEEK) - diff = MAX_SEEK; - - diff -= MIN_SEEK; - - return cdrom_get_short_seek(dev) + ((cdrom_get_long_seek(dev) * ((double) diff)) / sd); -} - -void -cdrom_stop(cdrom_t *dev) -{ - if (dev->cd_status > CD_STATUS_DATA_ONLY) - dev->cd_status = CD_STATUS_STOPPED; -} - -void -cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type) -{ - int m; - int s; - int f; - - if (!dev) - return; - - cdrom_log("CD-ROM %i: Seek to LBA %08X, vendor type = %02x.\n", dev->id, pos, vendor_type); - - switch (vendor_type) { - case 0x40: - m = bcd2bin((pos >> 24) & 0xff); - s = bcd2bin((pos >> 16) & 0xff); - f = bcd2bin((pos >> 8) & 0xff); - pos = MSFtoLBA(m, s, f) - 150; - break; - case 0x80: - pos = bcd2bin((pos >> 24) & 0xff); - break; - default: - break; - } - - dev->seek_pos = pos; - cdrom_stop(dev); -} - -int -cdrom_is_pre(cdrom_t *dev, uint32_t lba) -{ - if (dev->ops && dev->ops->is_track_pre) - return dev->ops->is_track_pre(dev, lba); - - return 0; -} - -int -cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len) -{ - int ret = 1; - - if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) { - cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id); - if (dev->cd_status == CD_STATUS_PLAYING) - dev->seek_pos += (len >> 11); - memset(output, 0, len * 2); - return 0; - } - - while (dev->cd_buflen < len) { - if (dev->seek_pos < dev->cd_end) { - if (dev->ops->read_sector(dev, CD_READ_AUDIO, (uint8_t *) &(dev->cd_buffer[dev->cd_buflen]), - dev->seek_pos)) { - cdrom_log("CD-ROM %i: Read LBA %08X successful\n", dev->id, dev->seek_pos); - dev->seek_pos++; - dev->cd_buflen += (RAW_SECTOR_SIZE / 2); - ret = 1; - } else { - cdrom_log("CD-ROM %i: Read LBA %08X failed\n", dev->id, dev->seek_pos); - memset(&(dev->cd_buffer[dev->cd_buflen]), 0x00, (BUF_SIZE - dev->cd_buflen) * 2); - dev->cd_status = CD_STATUS_STOPPED; - dev->cd_buflen = len; - ret = 0; - } - } else { - cdrom_log("CD-ROM %i: Playing completed\n", dev->id); - memset(&dev->cd_buffer[dev->cd_buflen], 0x00, (BUF_SIZE - dev->cd_buflen) * 2); - dev->cd_status = CD_STATUS_PLAYING_COMPLETED; - dev->cd_buflen = len; - ret = 0; - } - } - - memcpy(output, dev->cd_buffer, len * 2); - memmove(dev->cd_buffer, &dev->cd_buffer[len], (BUF_SIZE - len) * 2); - dev->cd_buflen -= len; - - cdrom_log("CD-ROM %i: Audio callback returning %i\n", dev->id, ret); - return ret; -} - static void msf_from_bcd(int *m, int *s, int *f) { @@ -498,398 +283,1474 @@ msf_to_bcd(int *m, int *s, int *f) *f = bin2bcd(*f); } -uint8_t -cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) +static int +read_data(cdrom_t *dev, const uint32_t lba) { - track_info_t ti; - int m = 0; - int s = 0; - int f = 0; + return dev->ops->read_sector(dev->local, dev->raw_buffer, lba); +} - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; +static void +cdrom_get_subchannel(cdrom_t *dev, const uint32_t lba, + subchannel_t *subc, const int cooked) +{ + const uint8_t *scb; + uint32_t scb_offs = 0; + uint8_t q[16] = { 0 }; - cdrom_log("CD-ROM %i: Play audio - %08X %08X %i\n", dev->id, pos, len, ismsf); - if (ismsf & 0x100) { - /* Track-relative audio play. */ - dev->ops->get_track_info(dev, ismsf & 0xff, 0, &ti); - pos += MSFtoLBA(ti.m, ti.s, ti.f) - 150; - } else if ((ismsf == 2) || (ismsf == 3)) { - dev->ops->get_track_info(dev, pos, 0, &ti); - pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - if (ismsf == 2) { - /* We have to end at the *end* of the specified track, - not at the beginning. */ - dev->ops->get_track_info(dev, len, 1, &ti); - len = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + if ((lba == dev->seek_pos) && + ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED))) + scb = dev->subch_buffer; + else { + scb = (const uint8_t *) dev->raw_buffer; + scb_offs = 2352; + + memset(dev->raw_buffer, 0, 2448); + + (void) read_data(dev, lba); + } + + for (int i = 0; i < 12; i++) + for (int j = 0; j < 8; j++) + q[i] |= ((scb[scb_offs + (i << 3) + j] >> 6) & 0x01) << (7 - j); + + if (cooked) { + uint8_t temp = (q[0] >> 4) | ((q[0] & 0xf) << 4); + q[0] = temp; + + for (int i = 1; i < 10; i++) { + temp = bcd2bin(q[i]); + q[i] = temp; } - } else if (ismsf == 1) { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; + } - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) /*NEC*/ - msf_from_bcd(&m, &s, &f); + subc->attr = q[0]; + subc->track = q[1]; + subc->index = q[2]; + subc->rel_m = q[3]; + subc->rel_s = q[4]; + subc->rel_f = q[5]; + subc->abs_m = q[7]; + subc->abs_s = q[8]; + subc->abs_f = q[9]; +} - if (pos == 0xffffff) { - cdrom_log("CD-ROM %i: Playing from current position (MSF)\n", dev->id); - pos = dev->seek_pos; - } else - pos = MSFtoLBA(m, s, f) - 150; +static void +read_toc_identify_sessions(const raw_track_info_t *rti, const int num, unsigned char *b) +{ + /* Bytes 2 and 3 = Number of first and last sessions */ + b[2] = 0xff; + b[3] = 0x00; - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; + for (int i = (num - 1); i >= 0; i--) { + if (rti[i].session < b[2]) + b[2] = rti[i].session; + } - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) /*NEC*/ - msf_from_bcd(&m, &s, &f); + for (int i = 0; i < num; i++) { + if (rti[i].session > b[3]) + b[3] = rti[i].session; + } +} - len = MSFtoLBA(m, s, f) - 150; +static int +find_track(const raw_track_info_t *trti, const int num, const int first) +{ + int ret = -1; - cdrom_log("CD-ROM %i: MSF - pos = %08X len = %08X\n", dev->id, pos, len); - } else if (ismsf == 0) { - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: Playing from current position\n", dev->id); - pos = dev->seek_pos; + if (first) { + for (int i = 0; i < num; i++) + if ((trti[i].point >= 1) && (trti[i].point <= 99)) { + ret = i; + break; + } + } else { + for (int i = (num - 1); i >= 0; i--) + if ((trti[i].point >= 1) && (trti[i].point <= 99)) { + ret = i; + break; + } + } + + return ret; +} + +static int +find_last_lead_out(const raw_track_info_t *trti, const int num) +{ + int ret = -1; + + for (int i = (num - 1); i >= 0; i--) + if (trti[i].point == 0xa2) { + ret = i; + break; } - len += pos; - } - dev->audio_muted_soft = 0; - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; - } - - dev->seek_pos = pos; - dev->cd_end = len; - dev->cd_status = CD_STATUS_PLAYING; - dev->cd_buflen = 0; - return 1; + return ret; } -uint8_t -cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) +static int +find_specific_track(const raw_track_info_t *trti, const int num, const int track) { - int m = 0; - int s = 0; - int f = 0; - uint32_t pos2 = 0; + int ret = -1; - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; - - cdrom_log("Audio Track Search: MSF = %06x, type = %02x, playbit = %02x\n", pos, type, playbit); - switch (type) { - case 0x00: - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: (type 0) Search from current position\n", dev->id); - pos = dev->seek_pos; + if ((track >= 1) && (track <= 99)) { + for (int i = (num - 1); i >= 0; i--) + if (trti[i].point == track) { + ret = i; + break; } - dev->seek_pos = pos; - break; - case 0x40: - m = bcd2bin((pos >> 24) & 0xff); - s = bcd2bin((pos >> 16) & 0xff); - f = bcd2bin((pos >> 8) & 0xff); - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: (type 1) Search from current position\n", dev->id); - pos = dev->seek_pos; - } else - pos = MSFtoLBA(m, s, f) - 150; - - dev->seek_pos = pos; - break; - case 0x80: - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: (type 2) Search from current position\n", dev->id); - pos = dev->seek_pos; - } - dev->seek_pos = (pos >> 24) & 0xff; - break; - default: - break; } - pos2 = pos - 1; - if (pos2 == 0xffffffff) - pos2 = pos + 1; + return ret; +} - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos2) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: Track Search: LBA %08X not on an audio track\n", dev->id, pos); - dev->audio_muted_soft = 1; - if (dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO) - dev->audio_muted_soft = 0; +static int +read_toc_normal(const cdrom_t *dev, unsigned char *b, + const unsigned char start_track, const int msf, + const int sony) +{ + uint8_t rti[65536] = { 0 }; + uint8_t prti[65536] = { 0 }; + const raw_track_info_t *trti = (raw_track_info_t *) rti; + raw_track_info_t * tprti = (raw_track_info_t *) prti; + int num = 0; + int len = 4; + int t = -1; + + cdrom_log(dev->log, "read_toc_normal(%016" PRIXPTR ", %016" PRIXPTR ", %02X, %i)\n", + (uintptr_t) dev, (uintptr_t) b, start_track, msf, sony); + + dev->ops->get_raw_track_info(dev->local, &num, rti); + + if (num > 0) { + int j = 0; + for (int i = 0; i < num; i++) { + if ((trti[i].point >= 0x01) && (trti[i].point <= 0x63)) { + tprti[j] = trti[i]; + if ((t == -1) && (tprti[j].point >= start_track)) + t = j; + cdrom_log(dev->log, "Sorted %03i = Unsorted %03i\n", j, i); + j++; + } + } + + /* Bytes 2 and 3 = Number of first and last tracks found before lead out */ + b[2] = tprti[0].point; + b[3] = tprti[j - 1].point; + + for (int i = (num - 1); i >= 0; i--) { + if (trti[i].point == 0xa2) { + tprti[j] = trti[i]; + tprti[j].point = 0xaa; + if ((t == -1) && (tprti[j].point >= start_track)) + t = j; + cdrom_log(dev->log, "Sorted %03i = Unsorted %03i\n", j, i); + j++; + break; + } + } + + if (t != -1) for (int i = t; i < j; i++) { +#ifdef ENABLE_CDROM_LOG + uint8_t *c = &(b[len]); +#endif + + if (!sony) + b[len++] = 0; /* Reserved */ + b[len++] = tprti[i].adr_ctl; /* ADR/CTL */ + b[len++] = tprti[i].point; /* Track number */ + if (!sony) + b[len++] = 0; /* Reserved */ + + if (msf) { + b[len++] = 0; + + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) { + int m = tprti[i].pm; + int s = tprti[i].ps; + int f = tprti[i].pf; + msf_to_bcd(&m, &s, &f); + b[len++] = m; + b[len++] = s; + b[len++] = f; + } else { + b[len++] = tprti[i].pm; + b[len++] = tprti[i].ps; + b[len++] = tprti[i].pf; + } + } else { + const uint32_t temp = MSFtoLBA(tprti[i].pm, tprti[i].ps, + tprti[i].pf) - 150; + + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + +#ifdef ENABLE_CDROM_LOG + cdrom_log(dev->log, "Track %02X: %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]); +#endif + } } else - dev->audio_muted_soft = 0; + b[2] = b[3] = 0; - cdrom_log("Track Search Toshiba: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos); - dev->cd_buflen = 0; - dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; - return 1; + return len; } -uint8_t -cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit) +static int +read_toc_session(const cdrom_t *dev, unsigned char *b, const int msf) { - int m = 0; - int s = 0; - int f = 0; + uint8_t rti[65536] = { 0 }; + const raw_track_info_t *t = (raw_track_info_t *) rti; + const raw_track_info_t *first = NULL; + int num = 0; + int len = 4; - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; + dev->ops->get_raw_track_info(dev->local, &num, rti); - f = bcd2bin((pos >> 24) & 0xff); - s = bcd2bin((pos >> 16) & 0xff); - m = bcd2bin((pos >> 8) & 0xff); - if (pos == 0xffffffff) { - pos = dev->seek_pos; - } else - pos = MSFtoLBA(m, s, f) - 150; + /* Bytes 2 and 3 = Number of first and last sessions */ + read_toc_identify_sessions((raw_track_info_t *) rti, num, b); - dev->seek_pos = pos; + cdrom_log(dev->log, "read_toc_session(%016" PRIXPTR ", %016" PRIXPTR ", %i)\n", + (uintptr_t) dev, (uintptr_t) b, msf); - dev->audio_muted_soft = 0; - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; - } - - dev->cd_buflen = 0; - dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; - return 1; -} - -uint8_t -cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos) -{ - int m = 0; - int s = 0; - int f = 0; - - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; - - f = bcd2bin((pos >> 24) & 0xff); - s = bcd2bin((pos >> 16) & 0xff); - m = bcd2bin((pos >> 8) & 0xff); - pos = MSFtoLBA(m, s, f) - 150; - dev->cd_end = pos; - - dev->audio_muted_soft = 0; - dev->cd_buflen = 0; - dev->cd_status = CD_STATUS_PLAYING; - return 1; -} - -uint8_t -cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) -{ - int m = 0; - int s = 0; - int f = 0; - - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; - - /*Preliminary support, revert if too incomplete*/ - switch (type) { - case 0x00: - dev->cd_end = pos; - break; - case 0x40: - m = bcd2bin((pos >> 24) & 0xff); - s = bcd2bin((pos >> 16) & 0xff); - f = bcd2bin((pos >> 8) & 0xff); - pos = MSFtoLBA(m, s, f) - 150; - dev->cd_end = pos; - break; - case 0x80: - dev->cd_end = (pos >> 24) & 0xff; - break; - case 0xc0: - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: Playing from current position\n", dev->id); - pos = dev->cd_end; + if (num != 0) { + for (int i = 0; i < num; i++) { + if ((t[i].session == b[3]) && (t[i].point >= 0x01) && (t[i].point <= 0x63)) { + first = &(t[i]); + break; } - dev->cd_end = pos; - break; - default: - break; + } + if (first != NULL) { + b[len++] = 0x00; + b[len++] = first->adr_ctl; + b[len++] = first->point; + b[len++] = 0x00; + + if (msf) { + b[len++] = 0x00; + + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) { + int m = first->pm; + int s = first->ps; + int f = first->pf; + + msf_to_bcd(&m, &s, &f); + + b[len++] = m; + b[len++] = s; + b[len++] = f; + } else { + b[len++] = first->pm; + b[len++] = first->ps; + b[len++] = first->pf; + } + } else { + const uint32_t temp = MSFtoLBA(first->pm, first->ps, + first->pf) - 150; + + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + } + } + + if (len == 4) + memset(&(b[len += 8]), 0x00, 8); + + return len; +} + +static int +read_toc_raw(const cdrom_t *dev, unsigned char *b, const unsigned char start_track) +{ + uint8_t rti[65536] = { 0 }; + const raw_track_info_t *t = (raw_track_info_t *) rti; + int num = 0; + int len = 4; + + /* Bytes 2 and 3 = Number of first and last sessions */ + read_toc_identify_sessions((raw_track_info_t *) rti, num, b); + + cdrom_log(dev->log, "read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR ", %02X)\n", + (uintptr_t) dev, (uintptr_t) b, start_track); + + dev->ops->get_raw_track_info(dev->local, &num, rti); + + if (num != 0) for (int i = 0; i < num; i++) + if (t[i].session >= start_track) { + memcpy(&(b[len]), &(t[i]), 11); + len += 11; + } + + return len; +} + +static int +track_type_is_valid(UNUSED(const cdrom_t *dev), const int type, const int flags, const int audio, + const int mode2) +{ + if (!(flags & 0x70) && (flags & 0xf8)) { /* 0x08/0x80/0x88 are illegal modes */ + cdrom_log(dev->log, "[Any Mode] 0x08/0x80/0x88 are illegal modes\n"); + return 0; + } + + if ((type != 1) && !audio) { + if ((flags & 0x06) == 0x06) { + cdrom_log(dev->log, "[Any Data Mode] Invalid error flags\n"); + return 0; + } + + if (((flags & 0x700) == 0x300) || ((flags & 0x700) > 0x400)) { + cdrom_log(dev->log, "[Any Data Mode] Invalid subchannel data flags (%02X)\n", + flags & 0x700); + return 0; + } + + if ((flags & 0x18) == 0x08) { /* EDC/ECC without user data is an illegal mode */ + cdrom_log(dev->log, "[Any Data Mode] EDC/ECC without user data is an " + "illegal mode\n"); + return 0; + } + + if (((flags & 0xf0) == 0x90) || ((flags & 0xf0) == 0xc0)) { /* 0x90/0x98/0xC0/0xC8 are illegal modes */ + cdrom_log(dev->log, "[Any Data Mode] 0x90/0x98/0xC0/0xC8 are illegal modes\n"); + return 0; + } + + if (((type > 3) && (type != 8)) || (mode2 && (mode2 & 0x03))) { + if ((flags & 0xf0) == 0x30) { /* 0x30/0x38 are illegal modes */ + cdrom_log(dev->log, "[Any XA Mode 2] 0x30/0x38 are illegal modes\n"); + return 0; + } + if (((flags & 0xf0) == 0xb0) || ((flags & 0xf0) == 0xd0)) { /* 0xBx and 0xDx are illegal modes */ + cdrom_log(dev->log, "[Any XA Mode 2] 0xBx and 0xDx are illegal modes\n"); + return 0; + } + } } - cdrom_log("Toshiba Play Audio: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos); - dev->cd_buflen = 0; - dev->cd_status = CD_STATUS_PLAYING; return 1; } -uint8_t -cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type) +static int +read_audio(cdrom_t *dev, const uint32_t lba, uint8_t *b) { - int m = 0; - int s = 0; - int f = 0; + const int ret = dev->ops->read_sector(dev->local, dev->raw_buffer, lba); - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; + memcpy(b, dev->raw_buffer, 2352); - cdrom_log("Audio Scan: MSF = %06x, type = %02x\n", pos, type); - switch (type) { - case 0x00: - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: (type 0) Search from current position\n", dev->id); - pos = dev->seek_pos; - } - dev->seek_pos = pos; - break; - case 0x40: - m = bcd2bin((pos >> 24) & 0xff); - s = bcd2bin((pos >> 16) & 0xff); - f = bcd2bin((pos >> 8) & 0xff); - if (pos == 0xffffffff) { - cdrom_log("CD-ROM %i: (type 1) Search from current position\n", dev->id); - pos = dev->seek_pos; - } else - pos = MSFtoLBA(m, s, f) - 150; + dev->cdrom_sector_size = 2352; - dev->seek_pos = pos; - break; - case 0x80: - dev->seek_pos = (pos >> 24) & 0xff; - break; - default: - break; + return ret; +} + + +static void +process_mode1(cdrom_t *dev, const int cdrom_sector_flags, uint8_t *b) +{ + dev->cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) { + /* Sync */ + cdrom_log(dev->log, "[Mode 1] Sync\n"); + memcpy(b, dev->raw_buffer, 12); + dev->cdrom_sector_size += 12; + b += 12; } - dev->audio_muted_soft = 0; - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; + if (cdrom_sector_flags & 0x20) { + /* Header */ + cdrom_log(dev->log, "[Mode 1] Header\n"); + memcpy(b, dev->raw_buffer + 12, 4); + dev->cdrom_sector_size += 4; + b += 4; } - dev->cd_buflen = 0; + if (cdrom_sector_flags & 0x40) { + /* Sub-header */ + if (!(cdrom_sector_flags & 0x10)) { + /* No user data */ + cdrom_log(dev->log, "[Mode 1] Sub-header\n"); + memcpy(b, dev->raw_buffer + 16, 8); + dev->cdrom_sector_size += 8; + b += 8; + } + } + + if (cdrom_sector_flags & 0x10) { + /* User data */ + cdrom_log(dev->log, "[Mode 1] User data\n"); + if (mult > 1) { + memcpy(b, dev->raw_buffer + 16 + (part * dev->sector_size), + dev->sector_size); + dev->cdrom_sector_size += dev->sector_size; + b += dev->sector_size; + } else { + memcpy(b, dev->raw_buffer + 16, 2048); + dev->cdrom_sector_size += 2048; + b += 2048; + } + } + + if (cdrom_sector_flags & 0x08) { + /* EDC/ECC */ + cdrom_log(dev->log, "[Mode 1] EDC/ECC\n"); + memcpy(b, dev->raw_buffer + 2064, (288 - ecc_diff)); + dev->cdrom_sector_size += (288 - ecc_diff); + } +} + +static void +process_mode2_non_xa(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b) +{ + dev->cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) { + /* Sync */ + cdrom_log(dev->log, "[Mode 2 Formless] Sync\n"); + memcpy(b, dev->raw_buffer, 12); + dev->cdrom_sector_size += 12; + b += 12; + } + + if (cdrom_sector_flags & 0x20) { + /* Header */ + cdrom_log(dev->log, "[Mode 2 Formless] Header\n"); + memcpy(b, dev->raw_buffer + 12, 4); + dev->cdrom_sector_size += 4; + b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) { + /* Sub-header */ + cdrom_log(dev->log, "[Mode 2 Formless] Sub-header\n"); + memcpy(b, dev->raw_buffer + 16, 8); + dev->cdrom_sector_size += 8; + b += 8; + } + + if (cdrom_sector_flags & 0x10) { + /* User data */ + cdrom_log(dev->log, "[Mode 2 Formless] User data\n"); + memcpy(b, dev->raw_buffer + 24, (2336 - ecc_diff)); + dev->cdrom_sector_size += (2336 - ecc_diff); + } +} + +static void +process_mode2_xa_form1(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b) +{ + dev->cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) { + /* Sync */ + cdrom_log(dev->log, "[XA Mode 2 Form 1] Sync\n"); + memcpy(b, dev->raw_buffer, 12); + dev->cdrom_sector_size += 12; + b += 12; + } + + if (cdrom_sector_flags & 0x20) { + /* Header */ + cdrom_log(dev->log, "[XA Mode 2 Form 1] Header\n"); + memcpy(b, dev->raw_buffer + 12, 4); + dev->cdrom_sector_size += 4; + b += 4; + } + + if (cdrom_sector_flags & 0x40) { + /* Sub-header */ + cdrom_log(dev->log, "[XA Mode 2 Form 1] Sub-header\n"); + memcpy(b, dev->raw_buffer + 16, 8); + dev->cdrom_sector_size += 8; + b += 8; + } + + if (cdrom_sector_flags & 0x10) { + /* User data */ + cdrom_log(dev->log, "[XA Mode 2 Form 1] User data\n"); + if (mult > 1) { + memcpy(b, dev->raw_buffer + 24 + (part * dev->sector_size), + dev->sector_size); + dev->cdrom_sector_size += dev->sector_size; + b += dev->sector_size; + } else { + memcpy(b, dev->raw_buffer + 24, 2048); + dev->cdrom_sector_size += 2048; + b += 2048; + } + } + + if (cdrom_sector_flags & 0x08) { + /* EDC/ECC */ + cdrom_log(dev->log, "[XA Mode 2 Form 1] EDC/ECC\n"); + memcpy(b, dev->raw_buffer + 2072, (280 - ecc_diff)); + dev->cdrom_sector_size += (280 - ecc_diff); + } +} + +static void +process_mode2_xa_form2(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b) +{ + dev->cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) { + /* Sync */ + cdrom_log(dev->log, "[XA Mode 2 Form 2] Sync\n"); + memcpy(b, dev->raw_buffer, 12); + dev->cdrom_sector_size += 12; + b += 12; + } + + if (cdrom_sector_flags & 0x20) { + /* Header */ + cdrom_log(dev->log, "[XA Mode 2 Form 2] Header\n"); + memcpy(b, dev->raw_buffer + 12, 4); + dev->cdrom_sector_size += 4; + b += 4; + } + + if (cdrom_sector_flags & 0x40) { + /* Sub-header */ + cdrom_log(dev->log, "[XA Mode 2 Form 2] Sub-header\n"); + memcpy(b, dev->raw_buffer + 16, 8); + dev->cdrom_sector_size += 8; + b += 8; + } + + if (cdrom_sector_flags & 0x10) { + /* User data */ + cdrom_log(dev->log, "[XA Mode 2 Form 2] User data\n"); + memcpy(b, dev->raw_buffer + 24, (2328 - ecc_diff)); + dev->cdrom_sector_size += (2328 - ecc_diff); + } +} + +static void +process_ecc_and_subch(cdrom_t *dev, const int cdrom_sector_flags, + uint8_t *b) +{ + if ((cdrom_sector_flags & 0x06) == 0x02) { + /* Add error flags. */ + cdrom_log(dev->log, "Error flags\n"); + memcpy(b + dev->cdrom_sector_size, dev->extra_buffer, 294); + dev->cdrom_sector_size += 294; + } else if ((cdrom_sector_flags & 0x06) == 0x04) { + /* Add error flags. */ + cdrom_log(dev->log, "Full error flags\n"); + memcpy(b + dev->cdrom_sector_size, dev->extra_buffer, 296); + dev->cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) { + cdrom_log(dev->log, "Raw subchannel data\n"); + memcpy(b + dev->cdrom_sector_size, dev->raw_buffer + 2352, 96); + dev->cdrom_sector_size += 96; + } else if ((cdrom_sector_flags & 0x700) == 0x200) { + cdrom_log(dev->log, "Q subchannel data\n"); + memcpy(b + dev->cdrom_sector_size, dev->raw_buffer + 2352, 16); + dev->cdrom_sector_size += 16; + } else if ((cdrom_sector_flags & 0x700) == 0x400) { + cdrom_log(dev->log, "R/W subchannel data\n"); + memcpy(b + dev->cdrom_sector_size, dev->raw_buffer + 2352, 96); + dev->cdrom_sector_size += 96; + } +} + +static void +cdrom_drive_reset(cdrom_t *dev) +{ + dev->priv = NULL; + dev->insert = NULL; + dev->close = NULL; + dev->get_volume = NULL; + dev->get_channel = NULL; + + if (cdrom_drive_types[dev->type].speed == -1) + dev->real_speed = dev->speed; + else + dev->real_speed = cdrom_drive_types[dev->type].speed; +} + +static void +cdrom_unload(cdrom_t *dev) +{ + if (dev->log != NULL) { + cdrom_log(dev->log, "CDROM: cdrom_unload(%s)\n", dev->image_path); + } + + dev->cd_status = CD_STATUS_EMPTY; + + if (dev->local != NULL) { + dev->ops->close(dev->local); + dev->local = NULL; + } + + dev->ops = NULL; +} + +/* Reset the CD-ROM Interface, whichever one that is. */ +void +cdrom_interface_reset(void) +{ + /* If we have a valid controller, add its device. */ + if ((cdrom_interface_current > 0) && + controllers[cdrom_interface_current].device) + device_add(controllers[cdrom_interface_current].device); +} + +const char * +cdrom_interface_get_internal_name(const int cdinterface) +{ + return device_get_internal_name(controllers[cdinterface].device); +} + +int +cdrom_interface_get_from_internal_name(const char *s) +{ + int c = 0; + + while (controllers[c].device != NULL) { + if (!strcmp(controllers[c].device->internal_name, s)) + return c; + c++; + } + + return 0; +} + +const device_t * +cdrom_interface_get_device(const int cdinterface) +{ + return (controllers[cdinterface].device); +} + +int +cdrom_interface_has_config(const int cdinterface) +{ + const device_t *dev = cdrom_interface_get_device(cdinterface); + + if (dev == NULL) + return 0; + + if (!device_has_config(dev)) + return 0; + return 1; } +int +cdrom_interface_get_flags(const int cdinterface) +{ + return (controllers[cdinterface].device->flags); +} + +int +cdrom_interface_available(const int cdinterface) +{ + return (device_available(controllers[cdinterface].device)); +} + +char * +cdrom_get_vendor(const int type) +{ + return (char *) cdrom_drive_types[type].vendor; +} + void -cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume) +cdrom_get_model(const int type, char *name, const int id) { - if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) - dev->cd_status = (dev->cd_status & 0xfe) | (resume & 0x01); + if (!strcmp(cdrom_drive_types[type].vendor, EMU_NAME)) + sprintf(name, "%s%02i", cdrom_drive_types[type].model, id); + else + sprintf(name, "%s", cdrom_drive_types[type].model); +} + +char * +cdrom_get_revision(const int type) +{ + return (char *) cdrom_drive_types[type].revision; +} + +int +cdrom_get_scsi_std(const int type) +{ + return cdrom_drive_types[type].scsi_std; +} + +int +cdrom_is_early(const int type) +{ + return (cdrom_drive_types[type].scsi_std == 1); +} + +int +cdrom_is_generic(const int type) +{ + return (cdrom_drive_types[type].speed == -1); +} + +int +cdrom_has_date(const int type) +{ + /* This will do for now. */ + return !strcmp(cdrom_drive_types[type].vendor, "PIONEER"); +} + +int +cdrom_is_sony(const int type) +{ + /* This will do for now. */ + return (cdrom_drive_types[type].bus_type == BUS_TYPE_SCSI) && + (!strcmp(cdrom_drive_types[type].vendor, "DEC") || + !strcmp(cdrom_drive_types[type].vendor, "ShinaKen") || + !strcmp(cdrom_drive_types[type].vendor, "SONY") || + !strcmp(cdrom_drive_types[type].vendor, "TEXEL")); +} + +int +cdrom_is_caddy(const int type) +{ + return cdrom_drive_types[type].caddy; +} + +int +cdrom_get_speed(const int type) +{ + return cdrom_drive_types[type].speed; +} + +int +cdrom_get_inquiry_len(const int type) +{ + return cdrom_drive_types[type].inquiry_len; +} + +int +cdrom_get_transfer_max(const int type, const int mode) +{ + return cdrom_drive_types[type].transfer_max[mode]; +} + +int +cdrom_has_dma(const int type) +{ + return (cdrom_drive_types[type].transfer_max[2] != -1); +} + +int +cdrom_get_type_count(void) +{ + int count = 0; + + while (1) { + if (strlen(cdrom_drive_types[count].vendor) == 0) + break; + else + count++; + } + + return count; +} + +void +cdrom_get_identify_model(const int type, char *name, const int id) +{ + char elements[2][2048] = { 0 }; + + memcpy(elements[0], cdrom_drive_types[type].vendor, + strlen(cdrom_drive_types[type].vendor) + 1); + + memcpy(elements[1], cdrom_drive_types[type].model, + strlen(cdrom_drive_types[type].model) + 1); + + char *s = strstr(elements[1], " "); + + if (s != NULL) + s[0] = 0x00; + + if (!strcmp(cdrom_drive_types[type].vendor, EMU_NAME)) + sprintf(name, "%s%02i", elements[1], id); + else if (!strcmp(cdrom_drive_types[type].vendor, "ASUS")) + sprintf(name, "%s %s", elements[0], elements[1]); + else if (!strcmp(cdrom_drive_types[type].vendor, "NEC")) + sprintf(name, "%s %s", elements[0], elements[1]); + else if (!strcmp(cdrom_drive_types[type].vendor, "LITE-ON")) + sprintf(name, "%s", elements[1]); + else + sprintf(name, "%s %s", elements[0], elements[1]); +} + +void +cdrom_get_name(const int type, char *name) +{ + char n[2048] = { 0 }; + + cdrom_generate_name(type, n, 0); + + if (cdrom_drive_types[type].bus_type == BUS_TYPE_SCSI) + sprintf(name, "[SCSI-%i] %s", cdrom_drive_types[type].scsi_std, n); + else + sprintf(name, "%s", n); +} + +char * +cdrom_get_internal_name(const int type) +{ + return (char *) cdrom_drive_types[type].internal_name; +} + +int +cdrom_get_from_internal_name(const char *s) +{ + int c = 0; + int found = 0; + + while (strlen(cdrom_drive_types[c].internal_name) > 0) { + if (!strcmp((char *) cdrom_drive_types[c].internal_name, s)) { + found = 1; + break; + } + c++; + } + + if (!found) + c = -1; + + return c; +} + +/* TODO: Configuration migration, remove when no longer needed. */ +int +cdrom_get_from_name(const char *s) +{ + int c = 0; + int found = 0; + char n[2048] = { 0 }; + + if (strcmp(s, "none")) { + while (strlen(cdrom_drive_types[c].internal_name) > 0) { + memset(n, 0x00, 2048); + cdrom_generate_name(c, n, 1); + /* Special case some names. */ + if ((!strcmp(s, "86BOX_CD-ROM_1.00") && !strcmp(n, "86Box_86B_CD_3.50")) || + (!strcmp(s, "TEAC_CD_532E_2.0A") && !strcmp(n, "TEAC_CD-532E_2.0A")) || + !strcmp(n, s)) { + found = 1; + break; + } + c++; + } + } + + if (!found) { + if (strcmp(s, "none")) { + wchar_t tempmsg[2048]; + sprintf(n, "WARNING: CD-ROM \"%s\" not found - contact 86Box support\n", s); + swprintf(tempmsg, sizeof_w(tempmsg), L"%hs", n); + pclog(n); + ui_msgbox_header(MBX_INFO, + plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), + tempmsg); + } + c = -1; + } + + return c; +} + +void +cdrom_set_type(const int model, const int type) +{ + cdrom[model].type = type; +} + +int +cdrom_get_type(const int model) +{ + return cdrom[model].type; +} + +int +cdrom_lba_to_msf_accurate(const int lba) +{ + int pos = lba + 150; + const int f = pos % 75; + pos -= f; + pos /= 75; + const int s = pos % 60; + pos -= s; + pos /= 60; + const int m = pos; + + return ((m << 16) | (s << 8) | f); +} + +double +cdrom_seek_time(const cdrom_t *dev) +{ + uint32_t diff = dev->seek_diff; + const double sd = (double) (MAX_SEEK - MIN_SEEK); + + if (diff < MIN_SEEK) + return 0.0; + if (diff > MAX_SEEK) + diff = MAX_SEEK; + + diff -= MIN_SEEK; + + return cdrom_get_short_seek(dev) + + ((cdrom_get_long_seek(dev) * ((double) diff)) / sd); +} + +void +cdrom_stop(cdrom_t *dev) +{ + if (dev->cd_status > CD_STATUS_DVD) + dev->cd_status = CD_STATUS_STOPPED; +} + +void +cdrom_seek(cdrom_t *dev, const uint32_t pos, const uint8_t vendor_type) +{ + int m; + int s; + int f; + uint32_t real_pos = pos; + + if (dev == NULL) + return; + + cdrom_log(dev->log, "Seek to LBA %08X, vendor type = %02x.\n", pos, vendor_type); + + switch (vendor_type) { + case 0x40: + m = bcd2bin((pos >> 24) & 0xff); + s = bcd2bin((pos >> 16) & 0xff); + f = bcd2bin((pos >> 8) & 0xff); + real_pos = MSFtoLBA(m, s, f) - 150; + break; + case 0x80: + real_pos = bcd2bin((pos >> 24) & 0xff); + break; + default: + break; + } + + dev->seek_pos = real_pos; + cdrom_stop(dev); +} + +int +cdrom_is_pre(const cdrom_t *dev, const uint32_t lba) +{ + if (dev->ops && dev->ops->is_track_pre) + return dev->ops->is_track_pre(dev->local, lba); + + return 0; +} + +int +cdrom_audio_callback(cdrom_t *dev, int16_t *output, const int len) +{ + int ret = 1; + + if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) { + // cdrom_log(dev->log, "Audio callback while not playing\n"); + if (dev->cd_status == CD_STATUS_PLAYING) + dev->seek_pos += (len >> 11); + memset(output, 0, len * 2); + return 0; + } + + while (dev->cd_buflen < len) { + if (dev->seek_pos < dev->cd_end) { + if (dev->ops->read_sector(dev->local, + (uint8_t *) &(dev->cd_buffer[dev->cd_buflen]), dev->seek_pos)) { + cdrom_log(dev->log, "Read LBA %08X successful\n", dev->seek_pos); + memcpy(dev->subch_buffer, + ((uint8_t *) &(dev->cd_buffer[dev->cd_buflen])) + 2352, 96); + dev->seek_pos++; + dev->cd_buflen += (RAW_SECTOR_SIZE / 2); + ret = 1; + } else { + cdrom_log(dev->log, "Read LBA %08X failed\n", dev->seek_pos); + memset(&(dev->cd_buffer[dev->cd_buflen]), 0x00, + (BUF_SIZE - dev->cd_buflen) * 2); + dev->cd_status = CD_STATUS_STOPPED; + dev->cd_buflen = len; + ret = 0; + } + } else { + cdrom_log(dev->log, "Playing completed\n"); + memset(&dev->cd_buffer[dev->cd_buflen], 0x00, (BUF_SIZE - dev->cd_buflen) * 2); + dev->cd_status = CD_STATUS_PLAYING_COMPLETED; + dev->cd_buflen = len; + ret = 0; + } + } + + memcpy(output, dev->cd_buffer, len * 2); + memmove(dev->cd_buffer, &dev->cd_buffer[len], (BUF_SIZE - len) * 2); + dev->cd_buflen -= len; + + cdrom_log(dev->log, "Audio callback returning %i\n", ret); + return ret; } uint8_t -cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) +cdrom_audio_play(cdrom_t *dev, const uint32_t pos, const uint32_t len, const int ismsf) { - uint8_t ret; - subchannel_t subc; - int pos = 1; - int m; - int s; - int f; - uint32_t dat; + track_info_t ti; + uint32_t pos2 = pos; + uint32_t len2 = len; + int ret = 0; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { + cdrom_log(dev->log, "Play audio - %08X %08X %i\n", pos2, len, ismsf); - if (dev->cd_status == CD_STATUS_DATA_ONLY) - ret = 0x15; - else { - if (dev->cd_status == CD_STATUS_PLAYING) - ret = 0x11; - else if (dev->cd_status == CD_STATUS_PAUSED) - ret = 0x12; + if (ismsf & 0x100) { + /* Track-relative audio play. */ + ret = dev->ops->get_track_info(dev->local, ismsf & 0xff, 0, &ti); + if (ret) + pos2 += 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); + cdrom_stop(dev); + } + } else if ((ismsf == 2) || (ismsf == 3)) { + ret = dev->ops->get_track_info(dev->local, pos2, 0, &ti); + if (ret) { + pos2 = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + if (ismsf == 2) { + /* We have to end at the *end* of the specified track, + not at the beginning. */ + ret = dev->ops->get_track_info(dev->local, len, 1, &ti); + if (ret) + len2 = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + else { + cdrom_log(dev->log, "Unable to get the ending position for " + "track %08X\n", pos2); + cdrom_stop(dev); + } + } + } else { + cdrom_log(dev->log, "Unable to get the starting position for " + "track %08X\n", pos2); + cdrom_stop(dev); + } + } else if (ismsf == 1) { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) + msf_from_bcd(&m, &s, &f); + + if (pos == 0xffffff) { + cdrom_log(dev->log, "Playing from current position (MSF)\n"); + pos2 = dev->seek_pos; + } else + pos2 = MSFtoLBA(m, s, f) - 150; + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) + msf_from_bcd(&m, &s, &f); + + len2 = MSFtoLBA(m, s, f) - 150; + + ret = 1; + + cdrom_log(dev->log, "MSF - pos = %08X len = %08X\n", pos2, len); + } else if (ismsf == 0) { + if (pos == 0xffffffff) { + cdrom_log(dev->log, "Playing from current position\n"); + pos2 = dev->seek_pos; + } + len2 += pos2; + + ret = 1; + } + } + + if (ret) { + dev->audio_muted_soft = 0; + + /* + Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. + */ + ret = (dev->ops->get_track_type(dev->local, pos2) == CD_TRACK_AUDIO); + + if (ret) { + dev->seek_pos = pos2; + dev->cd_end = len2; + dev->cd_status = CD_STATUS_PLAYING; + dev->cd_buflen = 0; + } else { + cdrom_log(dev->log, "LBA %08X not on an audio track\n", pos); + cdrom_stop(dev); + } + } + + return ret; +} + +uint8_t +cdrom_audio_track_search(cdrom_t *dev, const uint32_t pos, + const int type, const uint8_t playbit) +{ + uint32_t pos2 = pos; + uint8_t ret = 0; + + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { + cdrom_log(dev->log, "Audio Track Search: MSF = %06x, type = %02x, " + "playbit = %02x\n", pos, type, playbit); + + switch (type) { + case 0x00: + if (pos == 0xffffffff) { + cdrom_log(dev->log, "(Type 0) Search from current position\n"); + pos2 = dev->seek_pos; + } + dev->seek_pos = pos2; + break; + case 0x40: { + const int m = bcd2bin((pos >> 24) & 0xff); + const int s = bcd2bin((pos >> 16) & 0xff); + const int f = bcd2bin((pos >> 8) & 0xff); + if (pos == 0xffffffff) { + cdrom_log(dev->log, "(Type 1) Search from current position\n"); + pos2 = dev->seek_pos; + } else + pos2 = MSFtoLBA(m, s, f) - 150; + + dev->seek_pos = pos2; + break; + } case 0x80: + if (pos == 0xffffffff) { + cdrom_log(dev->log, "(Type 2) Search from current position\n"); + pos2 = dev->seek_pos; + } + dev->seek_pos = (pos2 >> 24) & 0xff; + break; + default: + break; + } + + if (pos2 != 0x00000000) + pos2--; + + /* + Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. + */ + if (dev->ops->get_track_type(dev->local, pos2) & CD_TRACK_AUDIO) + dev->audio_muted_soft = 0; + else { + cdrom_log(dev->log, "Track Search: LBA %08X not on an audio track\n", pos); + dev->audio_muted_soft = 1; + if (dev->ops->get_track_type(dev->local, pos) & CD_TRACK_AUDIO) + dev->audio_muted_soft = 0; + } + + cdrom_log(dev->log, "Track Search Toshiba: Muted?=%d, LBA=%08X.\n", + dev->audio_muted_soft, pos); + dev->cd_buflen = 0; + + dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; + + ret = 1; + } + + return ret; +} + +uint8_t +cdrom_audio_track_search_pioneer(cdrom_t *dev, const uint32_t pos, const uint8_t playbit) +{ + uint8_t ret = 0; + + if (dev->cd_status &= CD_STATUS_HAS_AUDIO) { + const int f = bcd2bin((pos >> 24) & 0xff); + const int s = bcd2bin((pos >> 16) & 0xff); + const int m = bcd2bin((pos >> 8) & 0xff); + uint32_t pos2; + + if (pos == 0xffffffff) + pos2 = dev->seek_pos; else - ret = 0x13; + pos2 = MSFtoLBA(m, s, f) - 150; + + dev->seek_pos = pos2; + + dev->audio_muted_soft = 0; + + /* + Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. + */ + if (dev->ops->get_track_type(dev->local, pos2) & CD_TRACK_AUDIO) { + dev->cd_buflen = 0; + dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; + + ret = 1; + } else { + cdrom_log(dev->log, "LBA %08X not on an audio track\n", pos); + cdrom_stop(dev); + } } - cdrom_log("CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, relative at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, ret, dev->seek_pos, dev->cd_end); + return ret; +} - if (b[pos] > 1) { - cdrom_log("B[%i] = %02x, ret = %02x.\n", pos, b[pos], ret); - return ret; +uint8_t +cdrom_audio_play_pioneer(cdrom_t *dev, const uint32_t pos) +{ + uint8_t ret = 0; + + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { + const int f = bcd2bin((pos >> 24) & 0xff); + const int s = bcd2bin((pos >> 16) & 0xff); + const int m = bcd2bin((pos >> 8) & 0xff); + uint32_t pos2 = MSFtoLBA(m, s, f) - 150; + dev->cd_end = pos2; + + dev->audio_muted_soft = 0; + dev->cd_buflen = 0; + + dev->cd_status = CD_STATUS_PLAYING; + + ret = 1; } - b[pos++] = subc.attr; - b[pos++] = subc.track; - b[pos++] = subc.index; + return ret; +} - if (msf) { - b[pos] = 0; +uint8_t +cdrom_audio_play_toshiba(cdrom_t *dev, const uint32_t pos, const int type) +{ + uint32_t pos2 = pos; + uint8_t ret = 0; - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = subc.abs_m; - s = subc.abs_s; - f = subc.abs_f; - msf_to_bcd(&m, &s, &f); - b[pos + 1] = m; - b[pos + 2] = s; - b[pos + 3] = f; - } else { - b[pos + 1] = subc.abs_m; - b[pos + 2] = subc.abs_s; - b[pos + 3] = subc.abs_f; + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { + /* Preliminary support, revert if too incomplete. */ + switch (type) { + case 0x00: + dev->cd_end = pos2; + break; + case 0x40: { + const int m = bcd2bin((pos >> 24) & 0xff); + const int s = bcd2bin((pos >> 16) & 0xff); + const int f = bcd2bin((pos >> 8) & 0xff); + pos2 = MSFtoLBA(m, s, f) - 150; + dev->cd_end = pos2; + break; + } case 0x80: + dev->cd_end = (pos2 >> 24) & 0xff; + break; + case 0xc0: + if (pos == 0xffffffff) { + cdrom_log(dev->log, "Playing from current position\n"); + pos2 = dev->cd_end; + } + dev->cd_end = pos2; + break; + default: + break; } - pos += 4; + cdrom_log(dev->log, "Toshiba Play Audio: Muted?=%d, LBA=%08X.\n", + dev->audio_muted_soft, pos2); + dev->cd_buflen = 0; - b[pos] = 0; + dev->cd_status = CD_STATUS_PLAYING; - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = subc.rel_m; - s = subc.rel_s; - f = subc.rel_f; - msf_to_bcd(&m, &s, &f); - b[pos + 1] = m; - b[pos + 2] = s; - b[pos + 3] = f; - } else { - b[pos + 1] = subc.rel_m; - b[pos + 2] = subc.rel_s; - b[pos + 3] = subc.rel_f; + ret = 1; + } + + return ret; +} + +uint8_t +cdrom_audio_scan(cdrom_t *dev, const uint32_t pos, const int type) +{ + uint32_t pos2 = 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); + + switch (type) { + case 0x00: + if (pos == 0xffffffff) { + cdrom_log(dev->log, "(Type 0) Search from current position\n"); + pos2 = dev->seek_pos; + } + dev->seek_pos = pos2; + break; + case 0x40: { + const int m = bcd2bin((pos >> 24) & 0xff); + const int s = bcd2bin((pos >> 16) & 0xff); + const int f = bcd2bin((pos >> 8) & 0xff); + if (pos == 0xffffffff) { + cdrom_log(dev->log, "(Type 1) Search from current position\n"); + pos2 = dev->seek_pos; + } else + pos2 = MSFtoLBA(m, s, f) - 150; + + dev->seek_pos = pos2; + break; + } case 0x80: + dev->seek_pos = (pos >> 24) & 0xff; + break; + default: + break; } - pos += 4; - } else { - dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; + dev->audio_muted_soft = 0; + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (dev->ops->get_track_type(dev->local, pos) & CD_TRACK_AUDIO) { + dev->cd_buflen = 0; + ret = 1; + } else { + cdrom_log(dev->log, "LBA %08X not on an audio track\n", pos); + cdrom_stop(dev); + } } return ret; } void -cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf) +cdrom_audio_pause_resume(cdrom_t *dev, const uint8_t resume) +{ + if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) + dev->cd_status = (dev->cd_status & 0xfe) | (resume & 0x01); +} + +uint8_t +cdrom_get_current_status(const cdrom_t *dev) +{ + const uint8_t is_chinon = !strcmp(cdrom_drive_types[dev->type].vendor, "CHINON"); + const uint8_t ret = status_codes[is_chinon][dev->cd_status & CD_STATUS_MASK]; + + return ret; +} + +void +cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, const int msf) { subchannel_t subc; - uint32_t dat; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 1); - cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x, msf = %x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end, msf); + cdrom_log(dev->log, "Returned subchannel absolute at %02i:%02i.%02i, " + "relative at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x.\n", + subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, + dev->seek_pos, dev->cd_end); + + /* Format code. */ + switch (b[0]) { + /* + Mode 0 = Q subchannel mode, first 16 bytes are indentical to mode 1 (current + position), the rest are stuff like ISRC etc., which can be all zeroes. + */ + case 0x01: + /* Current position. */ + b[1] = subc.attr; + b[2] = subc.track; + b[3] = subc.index; + + if (msf) { + b[4] = b[8] = 0x00; + + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) { + b[5] = bin2bcd(subc.abs_m); + b[6] = bin2bcd(subc.abs_s); + b[7] = bin2bcd(subc.abs_f); + + b[9] = bin2bcd(subc.rel_m); + b[10] = bin2bcd(subc.rel_s); + b[11] = bin2bcd(subc.rel_f); + } else { + b[5] = subc.abs_m; + b[6] = subc.abs_s; + b[7] = subc.abs_f; + + b[9] = subc.rel_m; + b[10] = subc.rel_s; + b[11] = subc.rel_f; + } + } else { + uint32_t dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; + b[4] = (dat >> 24) & 0xff; + b[5] = (dat >> 16) & 0xff; + b[6] = (dat >> 8) & 0xff; + b[7] = dat & 0xff; + + dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); + b[8] = (dat >> 24) & 0xff; + b[9] = (dat >> 16) & 0xff; + b[10] = (dat >> 8) & 0xff; + b[11] = dat & 0xff; + } + break; + case 0x02: + /* UPC - TODO: Finding and reporting the actual UPC data. */ + memset(&(b[1]), 0x00, 19); + memset(&(b[5]), 0x30, 13); + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) + b[19] = bin2bcd(subc.abs_f); + else + b[19] = subc.abs_f; + break; + case 0x03: + /* ISRC - TODO: Finding and reporting the actual ISRC data. */ + memset(&(b[1]), 0x00, 19); + memset(&(b[5]), 0x30, 12); + /* NEC CDR-260 speaks BCD. */ + if (dev->is_early) + b[18] = bin2bcd(subc.abs_f); + else + b[18] = subc.abs_f; + break; + default: + cdrom_log(dev->log, "b[0] = %02X\n", b[0]); + break; + } +} + +void +cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, const int msf) +{ + subchannel_t subc; + + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 1); + + cdrom_log(dev->log, "Returned subchannel at %02i:%02i.%02i, seek pos = %08x, " + "cd_end = %08x, msf = %x.\n", + subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end, msf); b[0] = subc.attr; b[1] = subc.track; @@ -903,7 +1764,7 @@ cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf) b[7] = subc.abs_s; b[8] = subc.abs_f; } else { - dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); + uint32_t dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f); b[3] = (dat >> 16) & 0xff; b[4] = (dat >> 8) & 0xff; b[5] = dat & 0xff; @@ -920,46 +1781,43 @@ cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b) uint8_t ret; subchannel_t subc; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 0); - if (dev->cd_status == CD_STATUS_DATA_ONLY) - ret = 0x05; - else { + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { if (dev->cd_status == CD_STATUS_PLAYING) ret = dev->sound_on ? 0x00 : 0x02; else if (dev->cd_status == CD_STATUS_PAUSED) ret = 0x01; else ret = 0x03; - } + } else + ret = 0x05; b[0] = 0; - b[1] = bin2bcd(subc.abs_m); - b[2] = bin2bcd(subc.abs_s); - b[3] = bin2bcd(subc.abs_f); + b[1] = subc.abs_m; + b[2] = subc.abs_s; + b[3] = subc.abs_f; return ret; } uint8_t -cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) +cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, const int msf) { uint8_t ret; subchannel_t subc; - uint32_t dat; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 1); - if (dev->cd_status == CD_STATUS_DATA_ONLY) - ret = 0x05; - else { + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { if (dev->cd_status == CD_STATUS_PLAYING) ret = dev->sound_on ? 0x00 : 0x02; else if (dev->cd_status == CD_STATUS_PAUSED) ret = 0x01; else ret = 0x03; - } + } else + ret = 0x05; if (msf) { b[0] = 0; @@ -967,7 +1825,7 @@ cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf) b[2] = subc.abs_s; b[3] = subc.abs_f; } else { - dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; + const uint32_t dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150; b[0] = (dat >> 24) & 0xff; b[1] = (dat >> 16) & 0xff; b[2] = (dat >> 8) & 0xff; @@ -982,28 +1840,28 @@ cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b) { subchannel_t subc; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_subchannel(dev, dev->seek_pos, &subc, 0); b[0] = subc.attr; - b[1] = bin2bcd(subc.track); - b[2] = bin2bcd(subc.index); - b[3] = bin2bcd(subc.rel_m); - b[4] = bin2bcd(subc.rel_s); - b[5] = bin2bcd(subc.rel_f); - b[6] = bin2bcd(subc.abs_m); - b[7] = bin2bcd(subc.abs_s); - b[8] = bin2bcd(subc.abs_f); + b[1] = subc.track; + b[2] = subc.index; + b[3] = subc.rel_m; + b[4] = subc.rel_s; + b[5] = subc.rel_f; + b[6] = subc.abs_m; + b[7] = subc.abs_s; + b[8] = subc.abs_f; } uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) { uint8_t ret; - subchannel_t subc; - dev->ops->get_subchannel(dev, dev->seek_pos, &subc); + cdrom_get_current_subcodeq(dev, b); if ((dev->cd_status == CD_STATUS_DATA_ONLY) || + (dev->cd_status == CD_STATUS_DVD) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED) || (dev->cd_status == CD_STATUS_STOPPED)) ret = 0x03; @@ -1011,278 +1869,32 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b) ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op; /*If a valid audio track is detected with audio on, unmute it.*/ - if (dev->ops->track_type(dev, dev->seek_pos) & CD_TRACK_AUDIO) + if (dev->ops->get_track_type(dev->local, dev->seek_pos) & CD_TRACK_AUDIO) dev->audio_muted_soft = 0; - cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", dev->seek_pos, dev->cd_end, dev->audio_muted_soft); - b[0] = subc.attr; - b[1] = bin2bcd(subc.track); - b[2] = bin2bcd(subc.index); - b[3] = bin2bcd(subc.rel_m); - b[4] = bin2bcd(subc.rel_s); - b[5] = bin2bcd(subc.rel_f); - b[6] = bin2bcd(subc.abs_m); - b[7] = bin2bcd(subc.abs_s); - b[8] = bin2bcd(subc.abs_f); + cdrom_log(dev->log, "SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", + dev->seek_pos, dev->cd_end, dev->audio_muted_soft); return ret; } -static int -read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf) -{ - track_info_t ti; - int i; - int len = 4; - int m; - int s; - int f; - int first_track; - int last_track; - uint32_t temp; - - cdrom_log("read_toc_normal(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf); - - dev->ops->get_tracks(dev, &first_track, &last_track); - - /* Byte 2 = Number of the first track */ - dev->ops->get_track_info(dev, 1, 0, &ti); - b[2] = ti.number; - cdrom_log(" b[2] = %02X\n", b[2]); - - /* Byte 3 = Number of the last track before the lead-out track */ - dev->ops->get_track_info(dev, last_track, 0, &ti); - b[3] = ti.number; - cdrom_log(" b[3] = %02X\n", b[2]); - - if (start_track == 0x00) - first_track = 0; - else { - first_track = -1; - for (i = 0; i <= last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); - if (ti.number >= start_track) { - first_track = i; - break; - } - } - } - cdrom_log(" first_track = %i, last_track = %i\n", first_track, last_track); - - /* No suitable starting track, return with error. */ - if (first_track == -1) { - cdrom_log(" [ERROR] No suitable track found\n"); - return -1; - } - - for (i = first_track; i <= last_track; i++) { - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - dev->ops->get_track_info(dev, i + 1, 0, &ti); - - b[len++] = 0; /* reserved */ - b[len++] = ti.attr; - b[len++] = ti.number; /* track number */ - b[len++] = 0; /* reserved */ - - if (msf) { - b[len++] = 0; - - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[len++] = m; - b[len++] = s; - b[len++] = f; - } else { - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; - } - } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - } - - return len; -} - -static int -read_toc_session(cdrom_t *dev, unsigned char *b, int msf) -{ - track_info_t ti; - int len = 4; - int m; - int s; - int f; - uint32_t temp; - - cdrom_log("read_toc_session(%08X, %08X, %i)\n", dev, b, msf); - - /* Bytes 2 and 3 = Number of first and last sessions */ - b[2] = b[3] = 1; - - dev->ops->get_track_info(dev, 1, 0, &ti); - - cdrom_log(" tracks(0) = %02X, %02X, %i:%02i.%02i\n", ti.attr, ti.number, ti.m, ti.s, ti.f); - - b[len++] = 0; /* reserved */ - b[len++] = ti.attr; - b[len++] = ti.number; /* track number */ - b[len++] = 0; /* reserved */ - - if (msf) { - b[len++] = 0; - - /* NEC CDR-260 speaks BCD. */ - if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/ - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[len++] = m; - b[len++] = s; - b[len++] = f; - } else { - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; - } - } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - return len; -} - -static int -read_toc_raw(cdrom_t *dev, unsigned char *b) -{ - track_info_t ti; - int len = 4; - int first_track; - int last_track; - - cdrom_log("read_toc_raw(%08X, %08X)\n", dev, b); - - dev->ops->get_tracks(dev, &first_track, &last_track); - - /* Bytes 2 and 3 = Number of first and last sessions */ - b[2] = b[3] = 1; - - for (int i = 0; i <= last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); - - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - - b[len++] = 1; /* Session number */ - b[len++] = ti.attr; /* Track ADR and Control */ - b[len++] = 0; /* TNO (always 0) */ - b[len++] = ti.number; /* Point (for track points - track number) */ - b[len++] = ti.m; /* M */ - b[len++] = ti.s; /* S */ - b[len++] = ti.f; /* F */ - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - } - - return len; -} - -static int -read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf) -{ - track_info_t ti; - int i; - int len = 4; - int first_track; - int last_track; - uint32_t temp; - - cdrom_log("read_toc_sony(%08X, %08X, %02X, %i)\n", dev, b, start_track, msf); - - dev->ops->get_tracks(dev, &first_track, &last_track); - - /* Byte 2 = Number of the first track */ - dev->ops->get_track_info(dev, 1, 0, &ti); - b[2] = ti.number; - cdrom_log(" b[2] = %02X\n", b[2]); - - /* Byte 3 = Number of the last track before the lead-out track */ - dev->ops->get_track_info(dev, last_track, 0, &ti); - b[3] = ti.number; - cdrom_log(" b[3] = %02X\n", b[2]); - - if (start_track == 0x00) - first_track = 0; - else { - first_track = -1; - for (i = 0; i <= last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); - if (ti.number >= start_track) { - first_track = i; - break; - } - } - } - cdrom_log(" first_track = %i, last_track = %i\n", first_track, last_track); - - /* No suitable starting track, return with error. */ - if (first_track == -1) { - cdrom_log(" [ERROR] No suitable track found\n"); - return -1; - } - - for (i = first_track; i <= last_track; i++) { - cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); - dev->ops->get_track_info(dev, i + 1, 0, &ti); - - b[len++] = ti.number; /* track number */ - b[len++] = ti.attr; - - if (msf) { - b[len++] = 0; - b[len++] = ti.m; - b[len++] = ti.s; - b[len++] = ti.f; - } else { - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - } - return len; -} - int -cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_track, int msf, int max_len) +cdrom_read_toc(const cdrom_t *dev, uint8_t *b, const int type, + const uint8_t start_track, const int msf, const int max_len) { int len; switch (type) { case CD_TOC_NORMAL: - len = read_toc_normal(dev, b, start_track, msf); + len = read_toc_normal(dev, b, start_track, msf, 0); break; case CD_TOC_SESSION: len = read_toc_session(dev, b, msf); break; case CD_TOC_RAW: - len = read_toc_raw(dev, b); + len = read_toc_raw(dev, b, start_track); break; default: - cdrom_log("CD-ROM %i: Unknown TOC read type: %i\n", dev->id, type); + cdrom_log(dev->log, "Unknown TOC read type: %i\n", type); return 0; } @@ -1295,11 +1907,10 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra } int -cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf, int max_len) +cdrom_read_toc_sony(const cdrom_t *dev, uint8_t *b, const uint8_t start_track, + const int msf, const int max_len) { - int len; - - len = read_toc_sony(dev, b, start_track, msf); + int len = read_toc_normal(dev, b, start_track, msf, 1); len = MIN(len, max_len); @@ -1309,612 +1920,868 @@ cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, i return len; } +#ifdef USE_CDROM_MITSUMI /* New API calls for Mitsumi CD-ROM. */ void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf) { - track_info_t ti; - int first_track; - int last_track; + uint8_t rti[65536] = { 0 }; + raw_track_info_t *trti = (raw_track_info_t *) rti; + int num = 0; + int first = -1; + int last = -1; - if (dev != NULL) { - dev->ops->get_tracks(dev, &first_track, &last_track); - buf[0] = 1; - buf[1] = last_track + 1; - dev->ops->get_track_info(dev, 1, 0, &ti); - buf[2] = ti.m; - buf[3] = ti.s; - buf[4] = ti.f; - dev->ops->get_track_info(dev, last_track + 1, 0, &ti); - buf[5] = ti.m; - buf[6] = ti.s; - buf[7] = ti.f; - buf[8] = 0x00; - } else - memset(buf, 0x00, 9); + if (dev != NULL) + dev->ops->get_raw_track_info(dev->local, &num, rti); + + if (num > 0) { + first = find_track(trti, num, 1); + last = find_track(trti, num, 0); + } + + if (first != -1) { + buf[0] = trti[first].point; + buf[2] = trti[first].pm; + buf[3] = trti[first].ps; + buf[4] = trti[first].pf; + } else { + buf[0] = 0x01; + buf[2] = 0x00; + buf[3] = 0x02; + buf[4] = 0x00; + } + + if (last != -1) { + buf[1] = trti[last].point; + buf[5] = trti[first].pm; + buf[6] = trti[first].ps; + buf[7] = trti[first].pf; + } else { + buf[1] = 0x01; + buf[5] = 0x00; + buf[6] = 0x02; + buf[7] = 0x00; + } + + buf[8] = 0x00; } +/* TODO: Actually implement this properly. */ void -cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode) +cdrom_get_q(UNUSED(cdrom_t *dev), uint8_t *buf, UNUSED(int *curtoctrk), UNUSED(uint8_t mode)) { - track_info_t ti; - int first_track; - int last_track; - - if (dev != NULL) { - dev->ops->get_tracks(dev, &first_track, &last_track); - dev->ops->get_track_info(dev, *curtoctrk, 0, &ti); - buf[0] = (ti.attr << 4) & 0xf0; - buf[1] = ti.number; - buf[2] = bin2bcd(*curtoctrk + 1); - buf[3] = ti.m; - buf[4] = ti.s; - buf[5] = ti.f; - buf[6] = 0x00; - dev->ops->get_track_info(dev, 1, 0, &ti); - buf[7] = ti.m; - buf[8] = ti.s; - buf[9] = ti.f; - if (*curtoctrk >= (last_track + 1)) - *curtoctrk = 0; - else if (mode) - *curtoctrk = *curtoctrk + 1; - } else - memset(buf, 0x00, 10); + memset(buf, 0x00, 10); } uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len) { track_info_t ti; + int ret = 0; - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; + if (dev->cd_status & CD_STATUS_HAS_AUDIO) { + cdrom_log(dev->log, "Play Mitsumi audio - %08X %08X\n", pos, len); - cdrom_log("CD-ROM 0: Play Mitsumi audio - %08X %08X\n", pos, len); - dev->ops->get_track_info(dev, pos, 0, &ti); - pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - dev->ops->get_track_info(dev, len, 1, &ti); - len = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + ret = dev->ops->get_track_info(dev->local, pos, 0, &ti); - /* Do this at this point, since it's at this point that we know the - actual LBA position to start playing from. */ - if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { - cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); - cdrom_stop(dev); - return 0; + if (ret) { + pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + ret = dev->ops->get_track_info(dev->local, len, 1, &ti); + + if (ret) { + len = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + + /* + Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. + */ + ret = (dev->ops->get_track_type(dev->local, pos) == CD_TRACK_AUDIO); + + if (ret) { + dev->seek_pos = pos; + dev->cd_end = len; + dev->cd_status = CD_STATUS_PLAYING; + dev->cd_buflen = 0; + } else { + cdrom_log(dev->log, "LBA %08X not on an audio track\n", pos); + cdrom_stop(dev); + } + } else { + cdrom_log(dev->log, "Unable to get the ending position for track %08X\n", + len); + cdrom_stop(dev); + } + } else { + cdrom_log(dev->log, "Unable to get the starting position for track %08X\n", pos); + cdrom_stop(dev); + } } - dev->seek_pos = pos; - dev->cd_end = len; - dev->cd_status = CD_STATUS_PLAYING; - dev->cd_buflen = 0; - - return 1; + return ret; } +#endif uint8_t -cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type) +cdrom_read_disc_info_toc(cdrom_t *dev, uint8_t *b, + const uint8_t track, const int type) { - track_info_t ti; - int first_track; - int last_track; - int m = 0; - int s = 0; - int f = 0; - uint32_t temp; + uint8_t rti[65536] = { 0 }; + const raw_track_info_t *trti = (raw_track_info_t *) rti; + int num = 0; + int first = -1; + int t = -1; + uint8_t ret = 1; + uint32_t temp; - dev->ops->get_tracks(dev, &first_track, &last_track); + cdrom_log(dev->log, "Read DISC Info TOC Type = %d, track = %d\n", type, track); + + dev->inv_field = track; + dev->ops->get_raw_track_info(dev->local, &num, rti); - cdrom_log("Read DISC Info TOC Type = %d, track = %d, first_track = %d, last_track = %d.\n", type, track, first_track, last_track); switch (type) { case 0: - b[0] = bin2bcd(first_track); - b[1] = bin2bcd(last_track); - b[2] = 0; - b[3] = 0; - cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 0) at %02i:%02i\n", dev->id, b[0], b[1]); + if (num > 0) { + first = find_track(trti, num, 1); + const int last = find_track(trti, num, 0); + + if ((first == -1) || (last == -1)) + ret = 0; + else { + b[0] = bin2bcd(first); + b[1] = bin2bcd(last); + b[2] = 0x00; + b[3] = 0x00; + + cdrom_log(dev->log, "Returned Toshiba/NEC disc information (type 0) " + "at %02i:%02i\n", b[0], b[1]); + } + } else + ret = 0; break; case 1: - dev->ops->get_track_info(dev, 0xaa, 0, &ti); - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[0] = m; - b[1] = s; - b[2] = f; - b[3] = 0; - cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 1) at %02i:%02i.%02i, track=%d\n", dev->id, b[0], b[1], b[2], bcd2bin(track)); + if (num > 0) + t = find_last_lead_out(trti, num); + + if (t == -1) + ret = 0; + else { + b[0] = bin2bcd(trti[t].pm); + b[1] = bin2bcd(trti[t].ps); + b[2] = bin2bcd(trti[t].pf); + b[3] = 0x00; + + cdrom_log(dev->log, "Returned Toshiba/NEC disc information (type 1) at " + "%02i:%02i.%02i\n", b[0], b[1], b[2]); + } break; case 2: - if (track > bin2bcd(last_track)) - return 0; + if (num > 0) + t = find_specific_track(trti, num, bcd2bin(track)); - dev->ops->get_track_info(dev, bcd2bin(track), 0, &ti); - m = ti.m; - s = ti.s; - f = ti.f; - msf_to_bcd(&m, &s, &f); - b[0] = m; - b[1] = s; - b[2] = f; - b[3] = ti.attr; - cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), m, s, f, ti.attr); + if (t == -1) + ret = 0; + else { + b[0] = bin2bcd(trti[t].pm); + b[1] = bin2bcd(trti[t].ps); + b[2] = bin2bcd(trti[t].pf); + b[3] = trti[t].adr_ctl; + + cdrom_log(dev->log, "Returned Toshiba/NEC disc information (type 2) at " + "%02i:%02i.%02i, track=%d, attr=%02x.\n", b[0], b[1], + b[2], bcd2bin(track), b[3]); + } break; case 3: /* Undocumented on NEC CD-ROM's, from information based on sr_vendor.c from the Linux kernel */ - switch (dev->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - dev->ops->get_track_info(dev, 1, 0, &ti); - b[0x0e] = 0; - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; + if (dev->is_nec) { + b[0x0e] = 0x00; + + if (num > 0) + first = find_track(trti, num, 1); + + if (first == -1) + ret = 0; + else { + temp = MSFtoLBA(trti[first].pm, trti[first].ps, trti[first].pf) - 150; b[0x0f] = temp >> 24; b[0x10] = temp >> 16; b[0x11] = temp >> 8; b[0x12] = temp; - break; + } + } else { + b[0] = 0x00; /* Audio or CDROM disc. */ - default: - dev->ops->get_track_info(dev, 1, 0, &ti); - b[0] = 0; - temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150; - b[1] = temp >> 24; - b[2] = temp >> 16; - b[3] = temp >> 8; - break; + if (num > 0) + first = find_track(trti, num, 1); + + if (first == -1) + ret = 0; + else { + temp = MSFtoLBA(trti[first].pm, trti[first].ps, trti[first].pf) - 150; + b[0x1] = temp >> 24; + b[0x2] = temp >> 16; + b[0x3] = temp >> 8; + } } break; default: break; } - return 1; + return ret; } -static int -track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode2) +int +cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int ismsf, + int cdrom_sector_type, const int cdrom_sector_flags, + int *len, const uint8_t vendor_type) { - if (!(flags & 0x70) && (flags & 0xf8)) { /* 0x08/0x80/0x88 are illegal modes */ - cdrom_log("CD-ROM %i: [Any Mode] 0x08/0x80/0x88 are illegal modes\n", id); - return 0; + int pos = sector; + int ret = 0; + + if ((cdrom_sector_type & 0x0f) >= 0x08) { + mult = cdrom_sector_type >> 4; + cdrom_sector_type &= 0x0f; + part = pos % mult; + pos /= mult; + ecc_diff = (cdrom_sector_type & 0x01) ? 4 : 0; + } else { + mult = 1; + part = 0; + ecc_diff = 0; } - if ((type != 1) && !audio) { - if ((flags & 0x06) == 0x06) { - cdrom_log("CD-ROM %i: [Any Data Mode] Invalid error flags\n", id); - return 0; - } + if (dev->cd_status != CD_STATUS_EMPTY) { + uint8_t *temp_b; + uint8_t *b = temp_b = buffer; + int audio = 0; + uint32_t lba; + int mode2 = 0; - if (((flags & 0x700) == 0x300) || ((flags & 0x700) > 0x400)) { - cdrom_log("CD-ROM %i: [Any Data Mode] Invalid subchannel data flags (%02X)\n", id, flags & 0x700); - return 0; - } + *len = 0; - if ((flags & 0x18) == 0x08) { /* EDC/ECC without user data is an illegal mode */ - cdrom_log("CD-ROM %i: [Any Data Mode] EDC/ECC without user data is an illegal mode\n", id); - return 0; - } + if (ismsf) { + const int m = (pos >> 16) & 0xff; + const int s = (pos >> 8) & 0xff; + const int f = pos & 0xff; - if (((flags & 0xf0) == 0x90) || ((flags & 0xf0) == 0xc0)) { /* 0x90/0x98/0xC0/0xC8 are illegal modes */ - cdrom_log("CD-ROM %i: [Any Data Mode] 0x90/0x98/0xC0/0xC8 are illegal modes\n", id); - return 0; - } + lba = MSFtoLBA(m, s, f) - 150; + } else { + switch (vendor_type) { + case 0x00: + lba = pos; + break; + case 0x40: { + const int m = bcd2bin((pos >> 24) & 0xff); + const int s = bcd2bin((pos >> 16) & 0xff); + const int f = bcd2bin((pos >> 8) & 0xff); - if (((type > 3) && (type != 8)) || (mode2 && (mode2 & 0x03))) { - if ((flags & 0xf0) == 0x30) { /* 0x30/0x38 are illegal modes */ - cdrom_log("CD-ROM %i: [Any XA Mode 2] 0x30/0x38 are illegal modes\n", id); - return 0; + lba = MSFtoLBA(m, s, f) - 150; + break; + } case 0x80: + lba = bcd2bin((pos >> 24) & 0xff); + break; + /* Never used values but the compiler complains. */ + default: + lba = 0; } - if (((flags & 0xf0) == 0xb0) || ((flags & 0xf0) == 0xd0)) { /* 0xBx and 0xDx are illegal modes */ - cdrom_log("CD-ROM %i: [Any XA Mode 2] 0xBx and 0xDx are illegal modes\n", id); - return 0; + } + + if (dev->ops->get_track_type) + audio = dev->ops->get_track_type(dev->local, lba); + + const int dm = audio & CD_TRACK_MODE_MASK; + audio &= CD_TRACK_AUDIO; + + if (dm != CD_TRACK_NORMAL) + mode2 = 1; + + memset(dev->raw_buffer, 0, 2448); + memset(dev->extra_buffer, 0, 296); + + if ((cdrom_sector_flags & 0xf8) == 0x08) { + /* 0x08 is an illegal mode */ + cdrom_log(dev->log, "[Mode 1] 0x08 is an illegal mode\n"); + } else if ((cdrom_sector_type > 5) && (cdrom_sector_type < 8)) { + cdrom_log(dev->log, "Attempting to read an unrecognized sector " + "type from an image\n"); + return 0; + } else { + if ((cdrom_sector_type > 1) && audio && + (dev->cd_status & CD_STATUS_HAS_AUDIO)) { + cdrom_log(dev->log, "[%s] Attempting to read a data sector " + "from an audio track\n", + cdrom_req_modes[cdrom_sector_type]); + } else if ((cdrom_sector_type == 1) && + (!audio || !(dev->cd_status & CD_STATUS_HAS_AUDIO))) { + cdrom_log(dev->log, "[Audio] Attempting to read an audio " + "sector from a data track\n"); + } else if (audio) { + if (!track_type_is_valid(dev, cdrom_sector_type, + cdrom_sector_flags, 1, 0x00)) + ret = 0; + else + ret = read_audio(dev, lba, temp_b); + } else { + ret = read_data(dev, lba); + + /* Return with error if we had one. */ + if (ret > 0) { + int form = 0; + + if ((dev->raw_buffer[0x000f] == 0x00) || + (dev->raw_buffer[0x000f] > 0x02)) { + cdrom_log(dev->log, "[%s] Unknown mode: %02X\n", + cdrom_req_modes[cdrom_sector_type], + dev->raw_buffer[0x000f]); + ret = 0; + } else if (mode2) { + if (dev->raw_buffer[0x000f] == 0x01) + /* + Use Mode 1, since evidently specification-violating + discs exist. + */ + mode2 = 0; + else if (dev->raw_buffer[0x0012] != + dev->raw_buffer[0x0016]) { + cdrom_log(dev->log, "[%s] XA Mode 2 sector with " + "malformed sub-header\n", + cdrom_req_modes[cdrom_sector_type]); + ret = 0; + } else + form = ((dev->raw_buffer[0x0012] & 0x20) >> 5) + 1; + } else if (dev->raw_buffer[0x000f] == 0x02) + mode2 = 1; + + if (ret > 0) { + const int mode_id = mode2 + form; + + cdrom_log(dev->log, "[%s] %s detected\n", + cdrom_req_modes[cdrom_sector_type], + cdrom_modes[mode_id]); + + if (!track_type_is_valid(dev, cdrom_sector_type, + cdrom_sector_flags, 0, + (mode2 << 2) + form)) { + cdrom_log(dev->log, "[%s] Invalid track type\n", + cdrom_req_modes[cdrom_sector_type]); + ret = 0; + } else if (cdrom_mode_masks[cdrom_sector_type] & + (1 << mode_id)) + cdrom_process_data[mode_id](dev, cdrom_sector_flags, + temp_b); + else { + cdrom_log(dev->log, "[%s] Attempting to read a " + "%s sector\n", + cdrom_req_modes[cdrom_sector_type], + cdrom_modes[mode_id]); + ret = 0; + } + } + } + } + + if (ret > 0) { + process_ecc_and_subch(dev, cdrom_sector_flags, b); + *len = dev->cdrom_sector_size; } } } - return 1; + return ret; } -static void -read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len) +/* + Read DVD Structure + + Yes, +2 instead of +4 is correct, I have verified this via Windows IOCTL, and it also matches + the MMC specification. + */ +int +cdrom_read_dvd_structure(const cdrom_t *dev, const uint8_t layer, const uint8_t format, + uint8_t *buffer, uint32_t *info) { - uint8_t *bb = rbuf; - const int offset = (!!(mode2 & 0x03)) ? 24 : 16; + int max_layer = 0; + int ret = 0; + uint64_t total_sectors; - dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba); - - /* Sync bytes */ - bb[0] = 0; - memset(bb + 1, 0xff, 10); - bb[11] = 0; - bb += 12; - - /* Sector header */ - bb[0] = (msf >> 16) & 0xff; - bb[1] = (msf >> 8) & 0xff; - bb[2] = msf & 0xff; - - bb[3] = 1; /* mode 1 data */ - bb += mode2 ? 12 : 4; - bb += len; - if (mode2 && ((mode2 & 0x03) == 1)) - memset(bb, 0, 280); - else if (!mode2) - memset(bb, 0, 288); -} - -static void -read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b) -{ - dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); - - memcpy(b, raw_buffer, 2352); - - cdrom_sector_size = 2352; -} - -static void -read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048)) - read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048); - else - dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { - /* Sync */ - cdrom_log("CD-ROM %i: [Mode 1] Sync\n", dev->id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; + if (format < 0xc0) { + if (dev->cd_status != CD_STATUS_DVD) { + *info = format; + ret = -(SENSE_ILLEGAL_REQUEST << 16) | (ASC_INCOMPATIBLE_FORMAT << 8); + } else if ((dev->ops != NULL) && (dev->ops->read_dvd_structure != NULL)) + ret = dev->ops->read_dvd_structure(dev->local, layer, format, buffer, info); } - if (cdrom_sector_flags & 0x20) { - /* Header */ - cdrom_log("CD-ROM %i: [Mode 1] Header\n", dev->id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; + if (ret == 0) switch (format) { + case 0x00: /* Physical format information */ + total_sectors = (uint64_t) dev->cdrom_capacity; + + if (total_sectors > DVD_LAYER_0_SECTORS) + max_layer++; + + if (layer > max_layer) { + *info = layer; + ret = -(SENSE_ILLEGAL_REQUEST << 16) | (ASC_INV_FIELD_IN_CMD_PACKET << 8); + } else { + if (total_sectors == 0) { + *info = 0x00000000; + ret = -(SENSE_NOT_READY << 16) | (ASC_MEDIUM_NOT_PRESENT << 8); + } else { + buffer[4] = 0x01; /* DVD-ROM, part version 1. */ + buffer[5] = 0x0f; /* 120mm disc, minimum rate unspecified .*/ + if (max_layer == 1) + /* Two layers, OTP track path, read-only (per MMC-2 spec). */ + buffer[6] = 0x31; + else + /* One layer, read-only (per MMC-2 spec). */ + buffer[6] = 0x01; + buffer[7] = 0x10; /* Default densities. */ + + /* Start sector. */ + buffer[8] = 0x00; + buffer[9] = (0x030000 >> 16) & 0xff; + buffer[10] = (0x030000 >> 8) & 0xff; + buffer[11] = 0x030000 & 0xff; + + /* End sector. */ + buffer[12] = 0x00; + if (layer == 1) { + buffer[13] = ((total_sectors - DVD_LAYER_0_SECTORS) >> 16) & 0xff; + buffer[14] = ((total_sectors - DVD_LAYER_0_SECTORS) >> 8) & 0xff; + buffer[15] = (total_sectors - DVD_LAYER_0_SECTORS) & 0xff; + } else if (max_layer == 1) { + buffer[13] = (DVD_LAYER_0_SECTORS >> 16) & 0xff; + buffer[14] = (DVD_LAYER_0_SECTORS >> 8) & 0xff; + buffer[15] = DVD_LAYER_0_SECTORS & 0xff; + } else { + buffer[13] = (total_sectors >> 16) & 0xff; + buffer[14] = (total_sectors >> 8) & 0xff; + buffer[15] = total_sectors & 0xff; + } + + /* Layer 0 end sector. */ + buffer[16] = 0x00; + buffer[17] = (total_sectors >> 16) & 0xff; + buffer[18] = (total_sectors >> 8) & 0xff; + buffer[19] = total_sectors & 0xff; + + buffer[20] = 0x00; /* No BCA */ + + /* 2048 bytes of data + 2 byte header */ + ret = (2048 + 2); + } + } + break; + + case 0x01: /* DVD copyright information */ + buffer[4] = 0; /* No copyright data. */ + buffer[5] = 0; /* No region restrictions. */ + + /* 4 bytes of data + 2 byte header. */ + ret = (4 + 2); + break; + + case 0x04: /* DVD disc manufacturing information. */ + /* 2048 bytes of data + 2 byte header */ + ret = (2048 + 2); + break; + + case 0xff: + /* + * This lists all the command capabilities above. Add new ones + * in order and update the length and buffer return values. + */ + + buffer[4] = 0x00; /* Physical format */ + buffer[5] = 0x40; /* Not writable, is readable */ + buffer[6] = ((2048 + 4) >> 8) & 0xff; + buffer[7] = (2048 + 4) & 0xff; + + buffer[8] = 0x01; /* Copyright info */ + buffer[9] = 0x40; /* Not writable, is readable */ + buffer[10] = ((4 + 2) >> 8) & 0xff; + buffer[11] = (4 + 2) & 0xff; + + buffer[12] = 0x03; /* BCA info */ + buffer[13] = 0x40; /* Not writable, is readable */ + buffer[14] = ((188 + 2) >> 8) & 0xff; + buffer[15] = (188 + 2) & 0xff; + + buffer[16] = 0x04; /* Manufacturing info */ + buffer[17] = 0x40; /* Not writable, is readable */ + buffer[18] = ((2048 + 2) >> 8) & 0xff; + buffer[19] = (2048 + 2) & 0xff; + + /* data written + 4 byte header */ + ret = (16 + 2); + break; + + default: + *info = format; + ret = -(SENSE_ILLEGAL_REQUEST << 16) | (ASC_INV_FIELD_IN_CMD_PACKET << 8); + break; } - if (cdrom_sector_flags & 0x40) { - /* Sub-header */ - if (!(cdrom_sector_flags & 0x10)) { - /* No user data */ - cdrom_log("CD-ROM %i: [Mode 1] Sub-header\n", dev->id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; + return ret; +} + +void +cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer) +{ + uint8_t rti[65536] = { 0 }; + raw_track_info_t *t = (raw_track_info_t *) rti; + int num = 0; + int first = 0; + int sessions = 0; + int ls_first = 0; + int ls_last = 0; + int t_b0 = -1; + + dev->ops->get_raw_track_info(dev->local, &num, rti); + + for (int i = 0; i < num; i++) + if (t[i].session > sessions) + sessions = t[i].session; + else if ((first == 0) && (t[i].point >= 1) && (t[i].point <= 99)) + first = t[i].point; + + for (int i = 0; i < num; i++) + if ((t[i].session == sessions) && (t[i].point >= 1) && (t[i].point <= 99)) { + ls_first = t[i].point; + break; } - } - if (cdrom_sector_flags & 0x10) { - /* User data */ - cdrom_log("CD-ROM %i: [Mode 1] User data\n", dev->id); - memcpy(b, raw_buffer + 16, 2048); - cdrom_sector_size += 2048; - b += 2048; - } + for (int i = (num - 1); i >= 0; i--) + if ((t[i].session == sessions) && (t[i].point >= 1) && (t[i].point <= 99)) { + ls_last = t[i].point; + break; + } - if (cdrom_sector_flags & 0x08) { - /* EDC/ECC */ - cdrom_log("CD-ROM %i: [Mode 1] EDC/ECC\n", dev->id); - memcpy(b, raw_buffer + 2064, 288); - cdrom_sector_size += 288; - b += 288; - } -} + for (int i = (num - 1); i >= 0; i--) + if (t[i].point == 0xb0) { + t_b0 = i; + break; + } -static void -read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2336)) - read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336); - else - dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); + memset(buffer, 0x00, 34); - cdrom_sector_size = 0; + buffer[ 0] = 0x00; /* Disc Information Length (MSB) */ + buffer[ 1] = 0x20; /* Disc Information Lenght (LSB) */ + buffer[ 2] = 0x0e; /* Last session complete, disc finalized */ + 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[ 7] = 0x20; /* Unrestricted use */ + buffer[ 8] = t[0].ps; /* Disc Type */ + buffer[ 9] = 0x00; /* Number Of Sessions (MSB) */ + buffer[10] = 0x00; /* First Track Number in Last Session (MSB) */ + buffer[11] = 0x00; /* Last Track Number in Last Session (MSB) */ - if (cdrom_sector_flags & 0x80) { - /* Sync */ - cdrom_log("CD-ROM %i: [Mode 2 Formless] Sync\n", dev->id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } + if (t_b0 == -1) { + /* Single-session disc. */ - if (cdrom_sector_flags & 0x20) { - /* Header */ - cdrom_log("CD-ROM %i: [Mode 2 Formless] Header\n", dev->id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } + /* Last Session Lead-in Start Time MSF is 00:00:00 */ - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) { - /* Sub-header */ - cdrom_log("CD-ROM %i: [Mode 2 Formless] Sub-header\n", dev->id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } + /* Last Possible Start Time for Start of Lead-out */ + buffer[20] = t[2].pm; + buffer[21] = t[2].ps; + buffer[22] = t[2].pf; + } else { + /* Multi-session disc. */ - if (cdrom_sector_flags & 0x10) { - /* User data */ - cdrom_log("CD-ROM %i: [Mode 2 Formless] User data\n", dev->id); - memcpy(b, raw_buffer + 24, 2336); - cdrom_sector_size += 2336; - b += 2336; - } -} + /* Last Session Lead-in Start Time MSF */ + buffer[17] = t[t_b0].m; + buffer[18] = t[t_b0].s; + buffer[19] = t[t_b0].f; -static void -read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048)) - read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048); - else - dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { - /* Sync */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", dev->id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } - - if (cdrom_sector_flags & 0x20) { - /* Header */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", dev->id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } - - if (cdrom_sector_flags & 0x40) { - /* Sub-header */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", dev->id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } - - if (cdrom_sector_flags & 0x10) { - /* User data */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", dev->id); - memcpy(b, raw_buffer + 24, 2048); - cdrom_sector_size += 2048; - b += 2048; - } - - if (cdrom_sector_flags & 0x08) { - /* EDC/ECC */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", dev->id); - memcpy(b, raw_buffer + 2072, 280); - cdrom_sector_size += 280; - b += 280; - } -} - -static void -read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) -{ - if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2324)) - read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324); - else - dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) { - /* Sync */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 2] Sync\n", dev->id); - memcpy(b, raw_buffer, 12); - cdrom_sector_size += 12; - b += 12; - } - - if (cdrom_sector_flags & 0x20) { - /* Header */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 2] Header\n", dev->id); - memcpy(b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - b += 4; - } - - if (cdrom_sector_flags & 0x40) { - /* Sub-header */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 2] Sub-header\n", dev->id); - memcpy(b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - b += 8; - } - - if (cdrom_sector_flags & 0x10) { - /* User data */ - cdrom_log("CD-ROM %i: [XA Mode 2 Form 2] User data\n", dev->id); - memcpy(b, raw_buffer + 24, 2328); - cdrom_sector_size += 2328; - b += 2328; + /* Last Possible Start Time for Start of Lead-out */ + buffer[20] = t[t_b0].pm; + buffer[21] = t[t_b0].ps; + buffer[22] = t[t_b0].pf; } } int -cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, - int cdrom_sector_flags, int *len, uint8_t vendor_type) +cdrom_read_track_information(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer) { - uint8_t *b; - uint8_t *temp_b; - uint32_t msf; - uint32_t lba; - int audio = 0; - int mode2 = 0; - int m; - int s; - int f; + uint8_t rti[65536] = { 0 }; + const raw_track_info_t *t = (raw_track_info_t *) rti; + const raw_track_info_t *track = NULL; + const raw_track_info_t lead_in = { 0 }; + const uint32_t pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; + uint32_t real_pos = pos; + int num = 0; + int ret; - if (dev->cd_status == CD_STATUS_EMPTY) - return 0; + dev->ops->get_raw_track_info(dev->local, &num, rti); - b = temp_b = buffer; + switch (cdb[1] & 0x03) { + default: + ret = -cdb[1]; + break; + case 0x00: + if (num < 4) + ret = -pos; + else { + for (int i = 0; i < num; i++) { + const raw_track_info_t *ct = &(t[i]); + const uint32_t start = ((ct->pm * 60 * 75) + (ct->ps * 75) + + ct->pf) - 150; + if (pos > start) { + track = ct; + break; + } + } - *len = 0; + if (track == NULL) + ret = -cdb[1]; + else + ret = 36; + } + break; + case 0x01: + switch (pos) { + default: + /* + TODO: Does READ TRACK INFORMATION use track AAh + or the raw A0h, A1h, and A2h? + */ + if (pos == 0xaa) + real_pos = 0xa2; - if (ismsf) { - m = (sector >> 16) & 0xff; - s = (sector >> 8) & 0xff; - f = sector & 0xff; - lba = MSFtoLBA(m, s, f) - 150; - msf = sector; + for (int i = 0; i < num; i++) { + const raw_track_info_t *ct = &(t[i]); + if (ct->point == real_pos) { + track = ct; + break; + } + } + + if (track == NULL) + ret = -pos; + else + ret = 36; + break; + case 0x00: + track = &lead_in; + ret = 36; + break; + case 0xff: + ret = -pos; + break; + } + break; + case 0x02: + for (int i = 0; i < num; i++) { + const raw_track_info_t *ct = &(t[i]); + if ((ct->session == pos) && (ct->point >= 1) && (ct->point <= 99)) { + track = ct; + break; + } + } + + if (track == NULL) + ret = -pos; + else + ret = 36; + break; + } + + if (ret == 36) { + uint32_t start = ((track->pm * 60 * 75) + (track->ps * 75) + + track->pf) - 150; + uint32_t len = 0x00000000; + uint8_t mode = 0xf; + + memset(buffer, 0, 36); + buffer[0] = 0x00; + buffer[1] = 0x22; + buffer[2] = track->point; /* Track number (LSB). */ + buffer[3] = track->session; /* Session number (LSB). */ + /* Not damaged, primary copy. */ + buffer[5] = track->adr_ctl & 0x04; + + if ((track->point >= 1) && (track->point >= 99)) { + for (int i = 0; i < num; i++) { + const raw_track_info_t *ct = &(t[i]); + const uint32_t ts = ((ct->pm * 60 * 75) + (ct->ps * 75) + + ct->pf) - 150; + if ((ts > start) && ((ct->point == 0xa2) || ((ct->point >= 1) && + (ct->point <= 99)))) { + len = ts - start; + break; + } + } + + if (track->adr_ctl & 0x04) { + ret = read_data(dev, start); + mode = dev->raw_buffer[3]; + } + } else if (track->point != 0xa2) + start = 0x00000000; + + /* Not reserved track, not blank, not packet writing, not fixed packet. */ + buffer[ 6] = mode << 0; + /* Last recorded address not valid, next recordable address not valid. */ + buffer[ 7] = 0x00; + + buffer[ 8] = (start >> 24) & 0xff; + buffer[ 9] = (start >> 16) & 0xff; + buffer[10] = (start >> 8) & 0xff; + buffer[11] = start & 0xff; + + buffer[24] = (len >> 24) & 0xff; + buffer[25] = (len >> 16) & 0xff; + buffer[26] = (len >> 8) & 0xff; + buffer[27] = len & 0xff; + } + + return ret; +} + +int +cdrom_is_empty(const uint8_t id) +{ + const cdrom_t *dev = &cdrom[id]; + int ret = 0; + + /* This entire block should be in cdrom.c/cdrom_eject(dev*) ... */ + if (strlen(dev->image_path) == 0) + /* Switch from empty to empty. Do nothing. */ + ret = 1; + + return ret; +} + +#ifdef ENABLE_CDROM_LOG +static void +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); + 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); + 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); + cdrom_log(dev->log, "Written session TOC of %i bytes to %s\n", len, fn2); +} +#endif + +void +cdrom_set_empty(cdrom_t *dev) +{ + dev->cd_status = CD_STATUS_EMPTY; +} + +void +cdrom_update_status(cdrom_t *dev) +{ + const int was_empty = (dev->cd_status == CD_STATUS_EMPTY); + + if (dev->ops->load != NULL) + dev->ops->load(dev->local); + + /* All good, reset state. */ + dev->seek_pos = 0; + dev->cd_buflen = 0; + + 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 + dev->cd_status = dev->ops->has_audio(dev->local) ? CD_STATUS_STOPPED : + CD_STATUS_DATA_ONLY; + + dev->cdrom_capacity = dev->ops->get_last_block(dev->local); + + if (dev->cd_status != CD_STATUS_EMPTY) { + /* Signal media change to the emulated machine. */ + cdrom_insert(dev->id); + + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + cdrom_insert(dev->id); + } +} + +int +cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert) +{ + const int was_empty = cdrom_is_empty(dev->id); + int ret = 0; + + /* Make sure to not STRCPY if the two are pointing + at the same place. */ + if (fn != dev->image_path) + strcpy(dev->image_path, fn); + + /* Open the target. */ + if ((strlen(dev->image_path) != 0) && + (strstr(dev->image_path, "ioctl://") == dev->image_path)) + dev->local = ioctl_open(dev, dev->image_path); + else + dev->local = image_open(dev, dev->image_path); + + if (dev->local == NULL) { + dev->ops = NULL; + dev->image_path[0] = 0; + + ret = 1; } else { - switch (vendor_type) { - case 0x00: - lba = sector; - msf = cdrom_lba_to_msf_accurate(sector); - break; - case 0x40: - m = bcd2bin((sector >> 24) & 0xff); - s = bcd2bin((sector >> 16) & 0xff); - f = bcd2bin((sector >> 8) & 0xff); - lba = MSFtoLBA(m, s, f) - 150; - msf = sector; - break; - case 0x80: - lba = bcd2bin((sector >> 24) & 0xff); - msf = sector; - break; - /* Never used values but the compiler complains. */ - default: - lba = msf = 0; - } + /* All good, reset state. */ + dev->seek_pos = 0; + dev->cd_buflen = 0; + + if ((dev->ops->is_empty != NULL) && dev->ops->is_empty(dev->local)) + dev->cd_status = CD_STATUS_EMPTY; + if (dev->ops->is_dvd(dev->local)) + dev->cd_status = CD_STATUS_DVD; + else + dev->cd_status = dev->ops->has_audio(dev->local) ? CD_STATUS_STOPPED : + CD_STATUS_DATA_ONLY; + + dev->cdrom_capacity = dev->ops->get_last_block(dev->local); + + cdrom_log(dev->log, "CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", + dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); } - if (dev->ops->track_type) - audio = dev->ops->track_type(dev, lba); +#ifdef ENABLE_CDROM_LOG + cdrom_toc_dump(dev); +#endif - mode2 = audio & ~CD_TRACK_AUDIO; - audio &= CD_TRACK_AUDIO; + if (!skip_insert && (dev->cd_status != CD_STATUS_EMPTY)) { + /* Signal media change to the emulated machine. */ + cdrom_insert(dev->id); - memset(raw_buffer, 0, 2448); - memset(extra_buffer, 0, 296); - - if ((cdrom_sector_flags & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - cdrom_log("CD-ROM %i: [Mode 1] 0x08 is an illegal mode\n", dev->id); - return 0; + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + cdrom_insert(dev->id); } - if (!track_type_is_valid(dev->id, cdrom_sector_type, cdrom_sector_flags, audio, mode2)) - return 0; - - if ((cdrom_sector_type > 5) && (cdrom_sector_type != 8)) { - cdrom_log("CD-ROM %i: Attempting to read an unrecognized sector type from an image\n", dev->id); - return 0; - } else if (cdrom_sector_type == 1) { - if (!audio || (dev->cd_status == CD_STATUS_DATA_ONLY)) { - cdrom_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", dev->id); - return 0; - } - - read_audio(dev, lba, temp_b); - } else if (cdrom_sector_type == 2) { - if (audio || mode2) { - cdrom_log("CD-ROM %i: [Mode 1] Attempting to read a sector of another type\n", dev->id); - return 0; - } - - read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 3) { - if (audio || !mode2 || (mode2 & 0x03)) { - cdrom_log("CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type\n", dev->id); - return 0; - } - - read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 4) { - if (audio || !mode2 || ((mode2 & 0x03) != 1)) { - cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type\n", dev->id); - return 0; - } - - read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 5) { - if (audio || !mode2 || ((mode2 & 0x03) != 2)) { - cdrom_log("CD-ROM %i: [XA Mode 2 Form 2] Attempting to read a sector of another type\n", dev->id); - return 0; - } - - read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else if (cdrom_sector_type == 8) { - if (audio) { - cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", dev->id); - return 0; - } - - if (mode2 && ((mode2 & 0x03) == 1)) - read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - else if (!mode2) - read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - else { - cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", dev->id); - return 0; - } - } else { - if (mode2) { - if ((mode2 & 0x03) == 0x01) - read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - else if ((mode2 & 0x03) == 0x02) - read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - else - read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - } else { - if (audio) - read_audio(dev, lba, temp_b); - else - read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b); - } - } - - if ((cdrom_sector_flags & 0x06) == 0x02) { - /* Add error flags. */ - cdrom_log("CD-ROM %i: Error flags\n", dev->id); - memcpy(b + cdrom_sector_size, extra_buffer, 294); - cdrom_sector_size += 294; - } else if ((cdrom_sector_flags & 0x06) == 0x04) { - /* Add error flags. */ - cdrom_log("CD-ROM %i: Full error flags\n", dev->id); - memcpy(b + cdrom_sector_size, extra_buffer, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) { - cdrom_log("CD-ROM %i: Raw subchannel data\n", dev->id); - memcpy(b + cdrom_sector_size, raw_buffer + 2352, 96); - cdrom_sector_size += 96; - } else if ((cdrom_sector_flags & 0x700) == 0x200) { - cdrom_log("CD-ROM %i: Q subchannel data\n", dev->id); - memcpy(b + cdrom_sector_size, raw_buffer + 2352, 16); - cdrom_sector_size += 16; - } else if ((cdrom_sector_flags & 0x700) == 0x400) { - cdrom_log("CD-ROM %i: R/W subchannel data\n", dev->id); - memcpy(b + cdrom_sector_size, raw_buffer + 2352, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; + return ret; } /* Peform a master init on the entire module. */ @@ -1925,30 +2792,28 @@ cdrom_global_init(void) memset(cdrom, 0x00, sizeof(cdrom)); } -static void -cdrom_drive_reset(cdrom_t *dev) -{ - dev->priv = NULL; - dev->insert = NULL; - dev->close = NULL; - dev->get_volume = NULL; - dev->get_channel = NULL; -} - void cdrom_hard_reset(void) { - cdrom_t *dev; - for (uint8_t i = 0; i < CDROM_NUM; i++) { - dev = &cdrom[i]; - if (dev->bus_type) { - cdrom_log("CD-ROM %i: Hard reset\n", i); + cdrom_t *dev = &cdrom[i]; - dev->id = i; + if (dev->bus_type) { + dev->id = i; + + dev->is_early = cdrom_is_early(dev->type); + dev->is_nec = (dev->bus_type == CDROM_BUS_SCSI) && + !strcmp(cdrom_drive_types[dev->type].vendor, "NEC"); cdrom_drive_reset(dev); + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i ", i + 1); + dev->log = log_open(n); + + cdrom_log(dev->log, "Hard reset\n"); + switch (dev->bus_type) { case CDROM_BUS_ATAPI: case CDROM_BUS_SCSI: @@ -1971,10 +2836,7 @@ cdrom_hard_reset(void) dev->image_path[strlen(dev->image_path) - 1] = '/'; #endif - if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path)) - cdrom_ioctl_open(dev, dev->image_path); - else - cdrom_image_open(dev, dev->image_path); + cdrom_load(dev, dev->image_path, 0); } } } @@ -1985,10 +2847,8 @@ cdrom_hard_reset(void) void cdrom_close(void) { - cdrom_t *dev; - for (uint8_t i = 0; i < CDROM_NUM; i++) { - dev = &cdrom[i]; + cdrom_t *dev = &cdrom[i]; if (dev->bus_type == CDROM_BUS_SCSI) memset(&scsi_devices[dev->scsi_device_id], 0x00, sizeof(scsi_device_t)); @@ -1996,64 +2856,79 @@ cdrom_close(void) if (dev->close) dev->close(dev->priv); - if (dev->ops && dev->ops->exit) - dev->ops->exit(dev); + cdrom_unload(dev); dev->ops = NULL; dev->priv = NULL; cdrom_drive_reset(dev); + + if (dev->log != NULL) { + cdrom_log(dev->log, "Log closed\n"); + + log_close(dev->log); + dev->log = NULL; + } } } /* Signal disc change to the emulated machine. */ void -cdrom_insert(uint8_t id) +cdrom_insert(const uint8_t id) { - cdrom_t *dev = &cdrom[id]; + const cdrom_t *dev = &cdrom[id]; if (dev->bus_type && dev->insert) dev->insert(dev->priv); } -/* The mechanics of ejecting a CD-ROM from a drive. */ void -cdrom_eject(uint8_t id) +cdrom_exit(const uint8_t id) { cdrom_t *dev = &cdrom[id]; - /* This entire block should be in cdrom.c/cdrom_eject(dev*) ... */ - if (strlen(dev->image_path) == 0) { - /* Switch from empty to empty. Do nothing. */ - return; - } - strcpy(dev->prev_image_path, dev->image_path); - dev->ops->exit(dev); - dev->ops = NULL; + if (dev->ops) { + cdrom_unload(dev); + + dev->ops = NULL; + } + memset(dev->image_path, 0, sizeof(dev->image_path)); + cdrom_log(dev->log, "cdrom_exit(): cdrom_insert()\n"); cdrom_insert(id); +} - plat_cdrom_ui_update(id, 0); +/* The mechanics of ejecting a CD-ROM from a drive. */ +void +cdrom_eject(const uint8_t id) +{ + const cdrom_t *dev = &cdrom[id]; - config_save(); + if (strlen(dev->image_path) != 0) { + cdrom_exit(id); + + plat_cdrom_ui_update(id, 0); + + config_save(); + } } /* The mechanics of re-loading a CD-ROM drive. */ void -cdrom_reload(uint8_t id) +cdrom_reload(const uint8_t id) { - cdrom_t *dev = &cdrom[id]; + cdrom_t *dev = &cdrom[id]; if ((strcmp(dev->image_path, dev->prev_image_path) == 0) || (strlen(dev->prev_image_path) == 0) || (strlen(dev->image_path) > 0)) { /* Switch from empty to empty. Do nothing. */ return; } - if (dev->ops && dev->ops->exit) - dev->ops->exit(dev); + cdrom_unload(dev); + dev->ops = NULL; memset(dev->image_path, 0, sizeof(dev->image_path)); @@ -2063,23 +2938,16 @@ cdrom_reload(uint8_t id) strcpy(dev->image_path, dev->prev_image_path); #ifdef _WIN32 - if (strlen(dev->prev_image_path) > 0) { - if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) - dev->image_path[strlen(dev->image_path) - 1] = '\\'; - } + if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) && + (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; #else - if (strlen(dev->prev_image_path) > 0) { - if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) - dev->image_path[strlen(dev->image_path) - 1] = '/'; - } + if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) && + (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; #endif - if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path)) - cdrom_ioctl_open(dev, dev->image_path); - else - cdrom_image_open(dev, dev->image_path); - - cdrom_insert(id); + cdrom_load(dev, dev->image_path, 0); } plat_cdrom_ui_update(id, 1); diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 113d426c6..271a290cb 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -6,310 +6,2035 @@ * * This file is part of the 86Box distribution. * - * CD-ROM image support. + * CD-ROM image file handling module. * + * Authors: Miran Grca, + * RichardG, + * Cacodemon345 * - * - * Authors: RichardG867, - * Miran Grca, - * bit, - * - * Copyright 2015-2019 Richardg867. - * Copyright 2015-2019 Miran Grca. - * Copyright 2017-2019 bit. + * Copyright 2016-2025 Miran Grca. + * Copyright 2016-2025 RichardG. + * Copyright 2024-2025 Cacodemon345. */ +#define __STDC_FORMAT_MACROS +#include #include +#ifdef ENABLE_IMAGE_LOG #include -#include +#endif #include -#include +#include #include -#include -#define HAVE_STDARG_H +#include +#include +#ifndef _WIN32 +# include +#endif #include <86box/86box.h> -#include <86box/config.h> +#include <86box/log.h> #include <86box/path.h> #include <86box/plat.h> -#include <86box/scsi_device.h> -#include <86box/cdrom_image_backend.h> #include <86box/cdrom.h> #include <86box/cdrom_image.h> +#include <86box/cdrom_image_viso.h> -#ifdef ENABLE_CDROM_IMAGE_LOG -int cdrom_image_do_log = ENABLE_CDROM_IMAGE_LOG; +#include + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +static char temp_keyword[1024]; + +#define INDEX_SPECIAL -2 /* Track A0h onwards. */ +#define INDEX_NONE -1 /* Empty block. */ +#define INDEX_ZERO 0 /* Block not in the file, return all 0x00's. */ +#define INDEX_NORMAL 1 /* Block in the file. */ + +typedef struct track_index_t { + /* + Is the current block in the file? If not, return all 0x00's. -1 means not + yet loaded. + */ + int32_t type; + /* The amount of bytes to skip at the beginning of each sector. */ + int32_t skip; + /* + Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1 + to read the pregap of track 1. + */ + uint64_t start; + uint64_t length; + uint64_t file_start; + uint64_t file_length; + track_file_t *file; +} track_index_t; + +typedef struct track_t { + uint8_t session; + uint8_t attr; + uint8_t tno; + uint8_t point; + uint8_t extra[4]; + uint8_t mode; + uint8_t form; + uint8_t subch_type; + uint8_t skip; + uint32_t sector_size; + track_index_t idx[3]; +} track_t; + +typedef struct cd_image_t { + cdrom_t *dev; + void *log; + int is_dvd; + int has_audio; + int32_t tracks_num; + uint32_t bad_sectors_num; + track_t *tracks; + uint32_t *bad_sectors; +} cd_image_t; + +#ifdef ENABLE_IMAGE_LOG +int image_do_log = ENABLE_IMAGE_LOG; void -cdrom_image_log(const char *fmt, ...) +image_log(void *priv, const char *fmt, ...) { va_list ap; - if (cdrom_image_do_log) { + if (image_do_log) { va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } + +static char *cit[4] = { "SPECIAL", "NONE", "ZERO", "NORMAL" }; #else -# define cdrom_image_log(fmt, ...) +# define image_log(priv, fmt, ...) #endif -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) +typedef struct audio_file_t { + SNDFILE *file; + SF_INFO info; +} audio_file_t; -static void -image_get_tracks(cdrom_t *dev, int *first, int *last) +/* Audio file functions */ +static int +audio_read(void *priv, uint8_t *buffer, const uint64_t seek, const size_t count) { - cd_img_t *img = (cd_img_t *) dev->image; - TMSF tmsf; + const track_file_t *tf = (track_file_t *) priv; + const audio_file_t *audio = (audio_file_t *) tf->priv; + const uint64_t samples_seek = seek / 4; + const uint64_t samples_count = count / 4; - cdi_get_audio_tracks(img, first, last, &tmsf); + if ((seek & 3) || (count & 3)) { + image_log(tf->log, "CD Audio file: Reading on non-4-aligned boundaries.\n"); + } + + const sf_count_t res = sf_seek(audio->file, samples_seek, SEEK_SET); + + if (res == -1) + return 0; + + return !!sf_readf_short(audio->file, (short *) buffer, samples_count); +} + +static uint64_t +audio_get_length(void *priv) +{ + const track_file_t *tf = (track_file_t *) priv; + const audio_file_t *audio = (audio_file_t *) tf->priv; + + /* Assume 16-bit audio, 2 channel. */ + return audio->info.frames * 4ull; } static void -image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) +audio_close(void *priv) { - cd_img_t *img = (cd_img_t *) dev->image; - TMSF tmsf; + track_file_t *tf = (track_file_t *) priv; + audio_file_t *audio = (audio_file_t *) tf->priv; - cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr); + memset(tf->fn, 0x00, sizeof(tf->fn)); + if (audio && audio->file) + sf_close(audio->file); + free(audio); + free(tf); +} - ti->m = tmsf.min; - ti->s = tmsf.sec; - ti->f = tmsf.fr; +static track_file_t * +audio_init(const uint8_t id, const char *filename, int *error) +{ + track_file_t *tf = (track_file_t *) calloc(sizeof(track_file_t), 1); + audio_file_t *audio = (audio_file_t *) calloc(sizeof(audio_file_t), 1); +#ifdef _WIN32 + wchar_t filename_w[4096]; +#endif + + if (tf == NULL || audio == NULL) { + goto cleanup_error; + } + + memset(tf->fn, 0x00, sizeof(tf->fn)); + strncpy(tf->fn, filename, sizeof(tf->fn) - 1); +#ifdef _WIN32 + mbstowcs(filename_w, filename, 4096); + audio->file = sf_wchar_open(filename_w, SFM_READ, &audio->info); +#else + audio->file = sf_open(filename, SFM_READ, &audio->info); +#endif + + if (audio->file == NULL) { + image_log(tf->log, "Audio file open error!"); + goto cleanup_error; + } + + if (audio->info.channels != 2 || audio->info.samplerate != 44100 || !audio->info.seekable) { + image_log(tf->log, "Audio file not seekable or in non-CD format!"); + sf_close(audio->file); + goto cleanup_error; + } + + *error = 0; + + tf->priv = audio; + tf->fp = NULL; + tf->close = audio_close; + tf->get_length = audio_get_length; + tf->read = audio_read; + + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i Audio", id + 1); + tf->log = log_open(n); + + return tf; +cleanup_error: + free(tf); + free(audio); + *error = 1; + return NULL; +} + +/* Binary file functions. */ +static int +bin_read(void *priv, uint8_t *buffer, const uint64_t seek, const size_t count) +{ + const track_file_t *tf = (track_file_t *) priv; + + if (tf->fp == NULL) + return 0; + + image_log(tf->log, "binary_read(%08lx, pos=%" PRIu64 " count=%lu)\n", + tf->fp, seek, count); + + if (fseeko64(tf->fp, seek, SEEK_SET) == -1) { + image_log(tf->log, "binary_read failed during seek!\n"); + + return -1; + } + + if (fread(buffer, count, 1, tf->fp) != 1) { + image_log(tf->log, "binary_read failed during read!\n"); + + return -1; + } + + if (UNLIKELY(tf->motorola)) { + for (uint64_t i = 0; i < count; i += 2) { + const uint8_t buffer0 = buffer[i]; + const uint8_t buffer1 = buffer[i + 1]; + buffer[i] = buffer1; + buffer[i + 1] = buffer0; + } + } + + return 1; +} + +static uint64_t +bin_get_length(void *priv) +{ + const track_file_t *tf = (track_file_t *) priv; + + if (tf->fp == NULL) + return 0; + + fseeko64(tf->fp, 0, SEEK_END); + const off64_t len = ftello64(tf->fp); + image_log(tf->log, "binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len); + + return len; } static void -image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) +bin_close(void *priv) { - cd_img_t *img = (cd_img_t *) dev->image; - TMSF rel_pos; - TMSF abs_pos; + track_file_t *tf = (track_file_t *) priv; - cdi_get_audio_sub(img, lba, &subc->attr, &subc->track, &subc->index, - &rel_pos, &abs_pos); + if (tf == NULL) + return; - subc->abs_m = abs_pos.min; - subc->abs_s = abs_pos.sec; - subc->abs_f = abs_pos.fr; + if (tf->fp != NULL) { + fclose(tf->fp); + tf->fp = NULL; + } - subc->rel_m = rel_pos.min; - subc->rel_s = rel_pos.sec; - subc->rel_f = rel_pos.fr; + memset(tf->fn, 0x00, sizeof(tf->fn)); - cdrom_image_log("image_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); + free(priv); +} + +static track_file_t * +bin_init(const uint8_t id, const char *filename, int *error) +{ + track_file_t *tf = (track_file_t *) calloc(1, sizeof(track_file_t)); + struct stat stats; + + if (tf == NULL) { + *error = 1; + return NULL; + } + + memset(tf->fn, 0x00, sizeof(tf->fn)); + strncpy(tf->fn, filename, sizeof(tf->fn) - 1); + tf->fp = plat_fopen64(tf->fn, "rb"); + image_log(tf->log, "binary_open(%s) = %08lx\n", tf->fn, tf->fp); + + if (stat(tf->fn, &stats) != 0) { + /* Use a blank structure if stat failed. */ + memset(&stats, 0, sizeof(struct stat)); + } + *error = ((tf->fp == NULL) || ((stats.st_mode & S_IFMT) == S_IFDIR)); + + /* Set the function pointers. */ + if (!*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. + * However, we need to make sure the descriptor is closed. */ + if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { + /* tf is freed by bin_close */ + bin_close(tf); + } else + free(tf); + tf = NULL; + } + + return tf; +} + +static track_file_t * +index_file_init(const uint8_t id, const char *filename, int *error, int *is_viso) +{ + track_file_t *tf = NULL; + + *is_viso = 0; + + /* Current we only support .BIN files, either combined or one per + track. In the future, more is planned. */ + tf = bin_init(id, filename, error); + + if (*error) { + if ((tf != NULL) && (tf->close != NULL)) { + tf->close(tf); + tf = NULL; + } + + tf = viso_init(id, filename, error); + + if (!*error) + *is_viso = 1; + } + + return tf; +} + +static void +index_file_close(track_index_t *idx) +{ + if ((idx == NULL) || (idx->file == NULL)) + return; + + image_log(idx->file->log, "Log closed\n"); + + if (idx->file->log != NULL) { + log_close(idx->file->log); + idx->file->log = NULL; + } + + if (idx->file->close != NULL) + idx->file->close(idx->file); + + idx->file = NULL; +} + +/* Internal functions. */ +static int +image_get_track(const cd_image_t *img, const uint32_t sector) +{ + int ret = -1; + + for (int i = 0; i < img->tracks_num; i++) { + track_t *ct = &(img->tracks[i]); + for (int j = 0; j < 3; j++) { + const track_index_t *ci = &(ct->idx[j]); + if ((ci->type >= INDEX_ZERO) && (ci->length != 0ULL) && + ((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) { + ret = i; + break; + } + } + } + + return ret; +} + +static void +image_get_track_and_index(const cd_image_t *img, const uint32_t sector, + int *track, int *index) +{ + *track = -1; + *index = -1; + + for (int i = 0; i < img->tracks_num; i++) { + track_t *ct = &(img->tracks[i]); + for (int j = 0; j < 3; j++) { + track_index_t *ci = &(ct->idx[j]); + if ((ci->type >= INDEX_ZERO) && (ci->length != 0ULL) && + ((sector + 150) >= ci->start) && ((sector + 150) <= (ci->start + ci->length - 1))) { + *track = i; + *index = j; + break; + } + } + } } static int -image_get_capacity(cdrom_t *dev) +image_is_sector_bad(const cd_image_t *img, const uint32_t sector) { - cd_img_t *img = (cd_img_t *) dev->image; - int first_track; - int last_track; - int number; - unsigned char attr; - uint32_t address = 0; - uint32_t lb = 0; + int ret = 0; - if (!img) + if (img->bad_sectors_num > 0) for (int i = 0; i < img->bad_sectors_num; i++) + if (img->bad_sectors[i] == sector) { + ret = 1; + break; + } + + return ret; +} + +static int +image_is_track_audio(const cd_image_t *img, const uint32_t pos) +{ + int ret = 0; + + if (img->has_audio) { + const int track = image_get_track(img, pos); + + if (track >= 0) { + const track_t *trk = &(img->tracks[track]); + + ret = (trk->mode == 0); + } + } + + return ret; +} + +static int +image_can_read_pvd(track_file_t *file, const uint64_t start, + const uint64_t sector_size, const int xa) +{ + uint8_t buf[2448] = { 0 }; + /* First VD is located at sector 16. */ + uint64_t seek = start + (16ULL * sector_size); + uint8_t *pvd = (uint8_t *) buf; + + if (sector_size >= RAW_SECTOR_SIZE) { + if (xa) + pvd = &(buf[24]); + else + pvd = &(buf[16]); + } else if (sector_size >= 2332) { + if (xa) + pvd = &(buf[8]); + } + + file->read(file, buf, seek, sector_size); + + int ret = (((pvd[0] == 1) && + !strncmp((char *) &(pvd[1]), "CD001", 5) && + (pvd[6] == 1)) || + ((pvd[8] == 1) && + !strncmp((char *) &(pvd[9]), "CDROM", 5) && + (pvd[14] == 1))); + + if (ret) { + if (sector_size >= RAW_SECTOR_SIZE) { + if (xa) + /* Mode 2 XA, Form from the sub-header. */ + ret = 0x20 | (((buf[18] & 0x20) >> 5) + 1); + else + /* Mode from header. */ + ret = buf[15] << 4; + } else if (sector_size >= 2332) { + if (xa) + /* Mode 2 XA, Form from the sub-header. */ + ret = 0x20 | (((buf[2] & 0x20) >> 5) + 1); + else + /* Mode 2 non-XA. */ + ret = 0x20; + } else if (sector_size >= 2324) + /* Mode 2 XA Form 2. */ + ret = 0x22; + else if (!strncmp((char *) &(pvd[0x400]), "CD-XA001", 8)) + /* Mode 2 XA Form 1. */ + ret = 0x21; + else + /* Mode 1. */ + ret = 0x10; + } + + return ret; +} + +static int +image_cue_get_buffer(char *str, char **line, const int up) +{ + char *s = *line; + char *p = str; + int quote = 0; + int done = 0; + int space = 1; + + /* Copy to local buffer until we have end of string or whitespace. */ + while (!done) { + switch (*s) { + case '\0': + if (quote) { + /* Ouch, unterminated string.. */ + return 0; + } + done = 1; + break; + + case '\"': + quote ^= 1; + break; + + case ' ': + case '\t': + if (space) + break; + + if (!quote) { + done = 1; + break; + } + fallthrough; + + default: + if (up && islower((int) *s)) + *p++ = toupper((int) *s); + else + *p++ = *s; + space = 0; + break; + } + + if (!done) + s++; + } + *p = '\0'; + + *line = s; + + return 1; +} + +static int +image_cue_get_keyword(char **dest, char **line) +{ + const int success = image_cue_get_buffer(temp_keyword, line, 1); + + if (success) + *dest = temp_keyword; + + return success; +} + +/* Get a string from the input line, handling quotes properly. */ +static uint64_t +image_cue_get_number(char **line) +{ + char temp[128]; + uint64_t num; + + if (!image_cue_get_buffer(temp, line, 0)) return 0; - cdi_get_audio_tracks_lba(img, &first_track, &last_track, &lb); + if (sscanf(temp, "%" PRIu64, &num) != 1) + return 0; - for (int c = 0; c <= last_track; c++) { - cdi_get_audio_track_info_lba(img, 0, c + 1, &number, &address, &attr); - if (address > lb) - lb = address; + return num; +} + +static int +image_cue_get_frame(uint64_t *frames, char **line) +{ + char temp[128]; + int min = 0; + int sec = 0; + int fr = 0; + + int success = image_cue_get_buffer(temp, line, 0); + if (!success) + return 0; + + success = sscanf(temp, "%d:%d:%d", &min, &sec, &fr) == 3; + if (!success) + return 0; + + *frames = MSF_TO_FRAMES(min, sec, fr); + + return 1; +} + +static int +image_cue_get_flags(track_t *cur, char **line) +{ + char temp[128]; + char temp2[128]; + + int success = image_cue_get_buffer(temp, line, 0); + if (!success) + return 0; + + memset(temp2, 0x00, sizeof(temp2)); + success = sscanf(temp, "%s", temp2) == 1; + if (!success) + return 0; + + if (strstr(temp2, "PRE") != NULL) + cur->attr |= 0x01; + if (strstr(temp2, "DCP") != NULL) + cur->attr |= 0x02; + if (strstr(temp2, "4CH") != NULL) + cur->attr |= 0x08; + + return 1; +} + +static track_t * +image_insert_track(cd_image_t *img, const uint8_t session, const uint8_t point) +{ + track_t *ct = NULL; + + img->tracks_num++; + if (img->tracks == NULL) { + img->tracks = calloc(1, sizeof(track_t)); + ct = &(img->tracks[0]); + } else { + img->tracks = realloc(img->tracks, img->tracks_num * sizeof(track_t)); + ct = &(img->tracks[img->tracks_num - 1]); + } + + image_log(img->log, " [TRACK ] Insert %02X: img->tracks[%2i]\n", + point, img->tracks_num - 1); + + memset(ct, 0x00, sizeof(track_t)); + + ct->session = session; + ct->point = point; + + for (int i = 0; i < 3; i++) + ct->idx[i].type = (point > 99) ? INDEX_SPECIAL : INDEX_NONE; + + if (point >= 0xb0) + ct->attr = 0x50; + + return ct; +} + +static void +image_process(cd_image_t *img) +{ + track_t *ct = NULL; + track_t *lt = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + uint64_t tf_len = 0ULL; + uint64_t cur_pos = 0ULL; + int pos = 0; + int ls = 0; + int map[256] = { 0 }; + int lead[3] = { 0 }; + uint64_t spg[256] = { 0ULL }; + track_t *lo[256] = { 0 }; + + /* + Pass 2 - adjusting pre-gaps of the first track of every session and creating the + map so we can map from <01-99> to <01-99> + so that their times and length can be adjusted correctly in the third and fourth + passes - especially important for multi-session Cue files. + + We have to do that because Cue sheets do not explicitly indicate those pre-gaps + but they are required so we have the correct frames - the first track of each + session always has a pre-gap of at least 0:02:00. We do not adjust it if it is + already present. + */ + image_log(img->log, "Pass 2 (adjusting pre-gaps and preparing map)...\n"); + + /* Pre-gap of the first track of the first session. */ + ct = &(img->tracks[3]); + ci = &(ct->idx[0]); + + if (ci->type == INDEX_NONE) { + ci->type = INDEX_ZERO; + ci->start = 0ULL; + ci->length = 150ULL; + } + + image_log(img->log, " [PREGAP ] Adjusted pre-gap of track %02X (first in " + "session %i)\n", ct->point, ct->session); + + /* The other pre-gaps and the preparation of the map. */ + for (int i = 0; i < img->tracks_num; i++) { + ct = &(img->tracks[i]); + if (((ct->point >= 1) && (ct->point <= 99)) || (ct->point >= 0xb0)) { + if (ct->point == 0xb0) { + /* The first track of a session always has a pre-gap of at least 0:02:00. */ + track_t *ft = &(img->tracks[i + (ct->session == 1) + 4]); + ci = &(ft->idx[0]); + + if (ci->type == INDEX_NONE) { + if (ft->idx[1].type == INDEX_NORMAL) { + ci->type = INDEX_NORMAL; + ci->file_start = ft->idx[1].file_start - 150ULL; + } else { + ci->type = INDEX_ZERO; + ci->start = 0ULL; + ci->length = 150ULL; + } + } + + image_log(img->log, " [PREGAP ] Adjusted pre-gap of track %02X " + "(first in session %i)\n", ft->point, ct->session); + + /* Point B0h found, add the previous three lead tracks. */ + for (int j = 0; j < 3; j++) { + map[pos] = lead[j]; + image_log(img->log, " [REMAP ] Remap %3i to %3i (%02X)\n", pos, + map[pos], 0xa0 + j); + pos++; + } + } + + /* Add the current track. */ + map[pos] = i; + image_log(img->log, " [NORMAL ] Remap %3i to %3i\n", pos, map[pos]); + pos++; + } else if ((ct->point >= 0xa0) && (ct->point <= 0xa2)) { + /* + Collect lead track (A0 = first track in session, A1 = last track in session, + A2 = lead out). + */ + lead[ct->point & 0x03] = i; + + image_log(img->log, " [LEAD ] Lead %i = %3i (%02X)\n", ct->point & 0x03, i, + ct->point); + } + } + + /* Add the last three lead tracks. */ + for (int i = 0; i < 3; i++) { + map[pos] = lead[i]; + image_log(img->log, " [REMAP ] Remap %3i to %3i (%02X)\n", pos, map[pos], + 0xa0 + i); + pos++; + } + + /* + If these two mismatch, it is a fatal condition since it means something + has gone wrong enough that the Cue sheet processing has been messed up. + */ + if (pos != img->tracks_num) + log_fatal(img->log, "Something has gone wrong and we have remappped %3i tracks " + "instead of the expected %3i\n", pos, img->tracks_num); + + /* + Pass 3 - adjusting the time lengths of each index of track according to the + files. + + We have to do that because Cue sheets do not explicitly indicate the lengths + of track, so we have to deduce them from what the combination of the Cue sheet + and the various files give us. + */ + image_log(img->log, "Pass 3 (adjusting track file lengths according to the files)...\n"); + for (int i = (img->tracks_num - 1); i >= 0; i--) { + ct = &(img->tracks[map[i]]); + if (ct->idx[1].type != INDEX_SPECIAL) { + for (int j = 2; j >= 0; j--) { + ci = &(ct->idx[j]); + + /* + If the file is not NULL and is different from the previous file, + open it and read its length. + */ + if ((ci->file != NULL) && (ci->file != tf)) { + tf = ci->file; + if (tf != NULL) { + tf_len = tf->get_length(tf) / ct->sector_size; + image_log(img->log, " [FILE ] File length: %016" + PRIX64 " sectors\n", tf_len); + } + } + + if ((ci->type < INDEX_SPECIAL) || (ci->type > INDEX_NORMAL)) { + image_log(img->log, " [TRACK ] %02X, INDEX %02X, ATTR %02X,\n", + ci->type, j, + ct->attr); + log_fatal(img->log, " Unrecognized index type during " + "Pass 3: %2i\n", + ci->type); + } else if (ci->type == INDEX_NORMAL) { + /* Index was in the cue sheet and is present in the file. */ + ci->file_length = tf_len - ci->file_start; + tf_len -= ci->file_length; + } else { + /* Index was not in the cue sheet or is not present in the file, + keep its length at zero. */ + ci->file_start = tf_len; + } + + image_log(img->log, " [TRACK ] %02X/%02X, INDEX %02X, ATTR %02X, " + "MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, j, + ct->attr, + ct->mode, ct->form, + cit[ci->type + 2]); + image_log(img->log, " file_start = %016" + PRIX64 " (%2i:%02i:%02i),\n", + ci->file_start, + (int) ((ci->file_start / 75) / 60), + (int) ((ci->file_start / 75) % 60), + (int) (ci->file_start % 75)); + image_log(img->log, " file_length = %016" + PRIX64 " (%2i:%02i:%02i),\n", + ci->file_length, + (int) ((ci->file_length / 75) / 60), + (int) ((ci->file_length / 75) % 60), + (int) (ci->file_length % 75)); + image_log(img->log, " remaining = %016" + PRIX64 " (%2i:%02i:%02i)\n", + tf_len, + (int) ((tf_len / 75) / 60), + (int) ((tf_len / 75) % 60), + (int) (tf_len % 75)); + } + } + } + + /* + Pass 4 - calculating the actual track starts and lengths for the TOC. + */ + image_log(img->log, "Pass 4 (calculating the actual track starts " + "and lengths for the TOC)...\n"); + for (int i = 0; i < img->tracks_num; i++) { + ct = &(img->tracks[map[i]]); + if (ct->idx[1].type != INDEX_SPECIAL) { + int session_changed = 0; + + /* + If the session has changed, store the last session + and mark that it has changed. + */ + if (ct->session != ls) { + ls = ct->session; + session_changed = 1; + } + + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + + if ((ci->type < INDEX_SPECIAL) || (ci->type > INDEX_NORMAL)) { + image_log(img->log, " [TRACK ] %02X, INDEX %02X, ATTR %02X,\n", + ci->type, j, + ct->attr); + log_fatal(img->log, " Unrecognized index type during " + "Pass 4: %2i\n", + ci->type); + } else if (ci->type <= INDEX_NONE) + /* Index was not in the cue sheet, keep its length at zero. */ + ci->start = cur_pos; + else if (ci->type == INDEX_ZERO) { + /* Index was in the cue sheet and is not present in the file. */ + ci->start = cur_pos; + cur_pos += ci->length; + } else if (ci->type == INDEX_NORMAL) { + /* Index was in the cue sheet and is present in the file. */ + ci->start = cur_pos; + ci->length = ci->file_length; + cur_pos += ci->file_length; + } + + image_log(img->log, " [TRACK ] %02X/%02X, INDEX %02X, ATTR %02X, " + "MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, j, + ct->attr, + ct->mode, ct->form, + cit[ci->type + 2]); + image_log(img->log, " start = %016" + PRIX64 " (%2i:%02i:%02i),\n", + ci->start, + (int) ((ci->start / 75) / 60), + (int) ((ci->start / 75) % 60), + (int) (ci->start % 75)); + image_log(img->log, " length = %016" + PRIX64 " (%2i:%02i:%02i),\n", + ci->length, + (int) ((ci->length / 75) / 60), + (int) ((ci->length / 75) % 60), + (int) (ci->length % 75)); + image_log(img->log, " cur_pos = %016" + PRIX64 " (%2i:%02i:%02i)\n", + cur_pos, + (int) ((cur_pos / 75) / 60), + (int) ((cur_pos / 75) % 60), + (int) (cur_pos % 75)); + + /* Set the pre-gap of the first track of this session. */ + if (session_changed) + spg[ct->session] = ct->idx[0].start; + } + } + } + + /* + Pass 5 - setting the lead out starts for all sessions. + */ + image_log(img->log, "Pass 5 (setting the lead out starts for all sessions)...\n"); + for (int i = 0; i <= ls; i++) { + lo[i] = NULL; + for (int j = (img->tracks_num - 1); j >= 0; j--) { + const track_t *jt = &(img->tracks[j]); + if ((jt->session == i) && (jt->point >= 1) && (jt->point <= 99)) { + lo[i] = &(img->tracks[j]); + image_log(img->log, " [TRACK ] %02X/%02X, INDEX %02X, ATTR %02X, " + "MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, j, + ct->attr, + ct->mode, ct->form, + cit[ci->type + 2]); + image_log(img->log, " using to calculate the start of session " + "%02X lead out\n", + ct->session); + break; + } + } + } + + /* + Pass 6 - refinining modes and forms, and finalizing all the special tracks. + */ + image_log(img->log, "Pass 6 (refinining modes and forms, and finalizing " + "all the special tracks)...\n"); + for (int i = 0; i < img->tracks_num; i++) { + ct = &(img->tracks[i]); + lt = NULL; + switch (ct->point) { + default: + break; + case 1 ... 99: + ci = &(ct->idx[1]); + + if ((ci->type == INDEX_NORMAL) && (ct->mode >= 1)) { + image_log(img->log, " [TRACK ] %02X/01, INDEX %02X, ATTR %02X, " + "MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, + ct->attr, + ct->mode, ct->form, + cit[ct->idx[1].type + 2]); + + /* Override the loaded modes with that we determine here. */ + int can_read_pvd = image_can_read_pvd(ci->file, + ci->file_start * ct->sector_size, + ct->sector_size, 0); + ct->skip = 0; + if (can_read_pvd) { + ct->mode = can_read_pvd >> 4; + ct->form = can_read_pvd & 0xf; + if (((ct->sector_size == 2332) || (ct->sector_size == 2336)) && + (ct->form >= 1)) + ct->skip = 8; + } else if (ct->sector_size >= 2332) { + can_read_pvd = image_can_read_pvd(ci->file, + ci->file_start * ct->sector_size, + ct->sector_size, 1); + if (can_read_pvd) { + ct->mode = can_read_pvd >> 4; + ct->form = can_read_pvd & 0xf; + if (((ct->sector_size == 2332) || (ct->sector_size == 2336)) && + (ct->form >= 1)) + ct->skip = 8; + } + } + + image_log(img->log, " NEW MODE: %02X/%02X\n", + ct->mode, ct->form); + } + break; + case 0xa0: + for (int j = 0; j < img->tracks_num; j++) { + track_t *jt = &(img->tracks[j]); + if ((jt->session == ct->session) && + (jt->point >= 1) && (jt->point <= 99)) { + lt = jt; + break; + } + } + + if (lt != NULL) { + int disc_type = 0x00; + + ct->attr = lt->attr; + + ct->mode = lt->mode; + ct->form = lt->form; + + if (lt->mode == 2) + disc_type = 0x20; + + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + ci->type = INDEX_ZERO; + ci->start = (lt->point * 60 * 75) + (disc_type * 75); + ci->length = 0; + + image_log(img->log, " [TRACK ] %02X/%02X, INDEX %02X, " + "ATTR %02X, MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, j, + ct->attr, + ct->mode, ct->form, + cit[ci->type + 2]); + image_log(img->log, " first track = %02X, " + "disc type = %02X\n", + lt->point, disc_type); + } + } + break; + case 0xa1: + for (int j = (img->tracks_num - 1); j >= 0; j--) { + track_t *jt = &(img->tracks[j]); + if ((jt->session == ct->session) && (jt->point >= 1) && (jt->point <= 99)) { + lt = jt; + break; + } + } + + if (lt != NULL) { + ct->attr = lt->attr; + + ct->mode = lt->mode; + ct->form = lt->form; + + for (int j = 0; j < 3; j++) { + ci = &(ct->idx[j]); + ci->type = INDEX_ZERO; + ci->start = (lt->point * 60 * 75); + ci->length = 0; + + image_log(img->log, " [TRACK ] %02X/%02X, INDEX %02X, " + "ATTR %02X, MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, j, + ct->attr, + ct->mode, ct->form, + cit[ci->type + 2]); + image_log(img->log, " last track = %02X\n", + lt->point); + } + } + break; + case 0xa2: + if (lo[ct->session] != NULL) { + /* + We have a track to use for the calculation, first adjust the track's + attribute (ADR/Ctrl), mode, and form to match the last non-special track. + */ + lt = lo[ct->session]; + + ct->attr = lt->attr; + + ct->mode = lt->mode; + ct->form = lt->form; + + if (ct->idx[1].type != INDEX_NORMAL) { + /* + Index not normal, therefore, this is not a lead out track from a + second or afterwards session of a multi-session Cue sheet, calculate + the starting time and update all the indexes accordingly. + */ + const track_index_t *li = &(lt->idx[2]); + + for (int j = 0; j < 3; j++) { + image_log(img->log, " [TRACK ] %02X/%02X, INDEX %02X, " + "ATTR %02X, MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, j, + ct->attr, + ct->mode, ct->form, + cit[ci->type + 2]); + + ci = &(ct->idx[j]); + ci->type = INDEX_ZERO; + ci->start = li->start + li->length; + ci->length = 0; + + image_log(img->log, " start = %016" PRIX64 + " (%2i:%02i:%02i)\n", + ci->start, + (int) ((ci->start / 75) / 60), + (int) ((ci->start / 75) % 60), + (int) (ci->start % 75)); + } + } +#ifdef ENABLE_IMAGE_LOG + else + image_log(img->log, " no start calculation done, " + "already specified\n"); +#endif + } +#ifdef ENABLE_IMAGE_LOG + else + image_log(img->log, " nothing done, no suitable last track " + "found\n"); +#endif + break; + case 0xb0: + /* + B0: MSF points to the beginning of the pre-gap + of the following session's first track. + */ + ct->extra[0] = (spg[ct->session + 1] / 75) / 60; + ct->extra[1] = (spg[ct->session + 1] / 75) % 60; + ct->extra[2] = spg[ct->session + 1] % 75; + + image_log(img->log, " [TRACK ] %02X/%02X, INDEX 01, " + "ATTR %02X, MODE %02X/%02X, %8s,\n", + ct->session, + ct->point, + ct->attr, + ct->mode, ct->form, + cit[ct->idx[1].type + 2]); + image_log(img->log, " %02X:%02X:%02X, %02X,\n", + ct->extra[0], ct->extra[1], ct->extra[2], ct->extra[3]); + + /* + B0 PMSF points to the start of the lead out track + of the last session. + */ + if (lo[ls] != NULL) { + lt = lo[ls]; + const track_index_t *li = &(lt->idx[2]); + + ct->idx[1].start = li->start + li->length; + + image_log(img->log, " start = %016" PRIX64 + " (%2i:%02i:%02i)\n", + ct->idx[1].start, + (int) ((ct->idx[1].start / 75) / 60), + (int) ((ct->idx[1].start / 75) % 60), + (int) (ct->idx[1].start % 75)); + } +#ifdef ENABLE_IMAGE_LOG + else + image_log(img->log, " no start calculation done, " + "no suitable last track found\n"); +#endif + break; + } + } + +#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 +} + +static void +image_set_track_subch_type(track_t *ct) +{ + if (ct->sector_size == 2448) + ct->subch_type = 0x08; + else if (ct->sector_size == 2368) + ct->subch_type = 0x10; + else + ct->subch_type = 0x00; +} + +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; + int sector_sizes[8] = { 2448, 2368, RAW_SECTOR_SIZE, 2336, + 2332, 2328, 2324, COOKED_SECTOR_SIZE }; + + img->tracks = NULL; + /* + Pass 1 - loading the ISO image. + */ + image_log(img->log, "Pass 1 (loading the ISO image)...\n"); + img->tracks_num = 0; + + image_insert_track(img, 1, 0xa0); + image_insert_track(img, 1, 0xa1); + image_insert_track(img, 1, 0xa2); + + /* Data track (shouldn't there be a lead in track?). */ + tf = index_file_init(img->dev->id, filename, &error, &is_viso); + + if (error) { + if (tf != NULL) { + tf->close(tf); + tf = NULL; + } + + success = 0; + } else if (is_viso) + success = 3; + + if (success) { + ct = image_insert_track(img, 1, 1); + ci = &(ct->idx[1]); + + ct->form = 0; + ct->mode = 0; + + for (int i = 0; i < 3; i++) + ct->idx[i].type = INDEX_NONE; + + ct->attr = DATA_TRACK; + + /* Try to detect ISO type. */ + ct->mode = 1; + ct->form = 0; + + ci->type = INDEX_NORMAL; + ci->file_start = 0ULL; + + ci->file = tf; + + for (int i = 0; i < 8; i++) { + ct->sector_size = sector_sizes[i]; + int can_read_pvd = image_can_read_pvd(ci->file, 0, ct->sector_size, 0); + if (can_read_pvd) { + ct->mode = can_read_pvd >> 4; + ct->form = can_read_pvd & 0xf; + if (((ct->sector_size == 2332) || (ct->sector_size == 2336)) && + (ct->form >= 1)) + ct->skip = 8; + break; + } else if (ct->sector_size >= 2332) { + can_read_pvd = image_can_read_pvd(ci->file, 0, ct->sector_size, 1); + if (can_read_pvd) { + ct->mode = can_read_pvd >> 4; + ct->form = can_read_pvd & 0xf; + if (((ct->sector_size == 2332) || (ct->sector_size == 2336)) && + (ct->form >= 1)) + ct->skip = 8; + break; + } + } + } + + image_set_track_subch_type(ct); + + image_log(img->log, " [TRACK ] %02X/%02X, ATTR %02X, MODE %02X/%02X,\n", + ct->session, + ct->point, + ct->attr, + ct->mode, ct->form); + image_log(img->log, " %02X:%02X:%02X, %02X, %i\n", + ct->sector_size); + } + + if (success) for (int i = 2; i >= 0; i--) { + if (ct->idx[i].file == NULL) + ct->idx[i].file = tf; + else + break; + } + + tf = NULL; + + if (success) + image_process(img); + else { + image_log(img->log, " [ISO ] Unable to open image or folder \"%s\"\n", + filename); + return 0; + } + + return success; +} + +static int +image_load_cue(cd_image_t *img, const char *cuefile) +{ + track_t *ct = NULL; + track_index_t *ci = NULL; + track_file_t *tf = NULL; + uint64_t frame = 0ULL; + uint64_t last = 0ULL; + uint8_t session = 1; + int last_t = -1; + int is_viso = 0; + int lead[3] = { 0 }; + int error; + char pathname[MAX_FILENAME_LENGTH]; + char buf[MAX_LINE_LENGTH]; + char *line; + char *command; + char *type; + char temp; + + 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, cuefile); + + /* Open the file. */ + FILE *fp = plat_fopen(cuefile, "r"); + if (fp == NULL) + return 0; + + int success = 0; + + /* + Pass 1 - loading the Cue sheet. + */ + image_log(img->log, "Pass 1 (loading the Cue sheet)...\n"); + img->tracks_num = 0; + + for (int i = 0; i < 3; i++) { + lead[i] = img->tracks_num; + (void) image_insert_track(img, session, 0xa0 + i); + } + + while (1) { + line = buf; + + /* Read a line from the cuesheet file. */ + if (feof(fp) || (fgets(buf, sizeof(buf), fp) == NULL) || ferror(fp)) + break; + + /* Do two iterations to make sure to nuke even if it's \r\n or \n\r, + but do checks to make sure we're not nuking other bytes. */ + for (uint8_t i = 0; i < 2; i++) { + if (strlen(buf) > 0) { + if (buf[strlen(buf) - 1] == '\n') + buf[strlen(buf) - 1] = '\0'; + /* nuke trailing newline */ + else if (buf[strlen(buf) - 1] == '\r') + buf[strlen(buf) - 1] = '\0'; + /* nuke trailing newline */ + } + } + image_log(img->log, " [LINE ] \"%s\"\n", line); + + (void) image_cue_get_keyword(&command, &line); + + if (!strcmp(command, "FILE")) { + /* The file for the track. */ + char filename[MAX_FILENAME_LENGTH]; + char ansi[MAX_FILENAME_LENGTH]; + + tf = NULL; + + memset(ansi, 0, MAX_FILENAME_LENGTH * sizeof(char)); + memset(filename, 0, MAX_FILENAME_LENGTH * sizeof(char)); + + success = image_cue_get_buffer(ansi, &line, 0); + if (!success) + break; + success = image_cue_get_keyword(&type, &line); + if (!success) + break; + + error = 1; + is_viso = 0; + + if (!strcmp(type, "BINARY") || !strcmp(type, "MOTOROLA")) { + if (!path_abs(ansi)) + path_append_filename(filename, pathname, ansi); + else + strcpy(filename, ansi); + + tf = index_file_init(img->dev->id, filename, &error, &is_viso); + + if (tf) + tf->motorola = !strcmp(type, "MOTOROLA"); + } else if (!strcmp(type, "WAVE") || !strcmp(type, "AIFF") || + !strcmp(type, "MP3")) { + if (!path_abs(ansi)) + path_append_filename(filename, pathname, ansi); + else + strcpy(filename, ansi); + tf = audio_init(img->dev->id, filename, &error); + } + if (error) { + if (tf != NULL) { + tf->close(tf); + tf = NULL; + } + success = 0; + } else if (is_viso) + success = 3; + +#ifdef ENABLE_IMAGE_LOG + if (!success) + image_log(img->log, " [FILE ] Unable to open file \"%s\" " + "specified in cue sheet\n", filename); +#endif + } else if (!strcmp(command, "TRACK")) { + int t = image_cue_get_number(&line); + success = image_cue_get_keyword(&type, &line); + + if (!success) + break; + + if (last_t != -1) { + /* + Important: This has to be done like this because pointers + change due to realloc. + */ + ct = &(img->tracks[t]); + + for (int i = 2; i >= 0; i--) { + if (ct->idx[i].file == NULL) + ct->idx[i].file = tf; + else + break; + } + } + + last_t = t; + ct = image_insert_track(img, session, t); + + ct->form = 0; + ct->mode = 0; + + if (!strcmp(type, "AUDIO")) { + ct->sector_size = RAW_SECTOR_SIZE; + ct->attr = AUDIO_TRACK; + } else if (!memcmp(type, "MODE", 4)) { + uint32_t mode; + ct->attr = DATA_TRACK; + sscanf(type, "MODE%" PRIu32 "/%" PRIu32, + &mode, &(ct->sector_size)); + ct->mode = mode; + if (ct->mode == 2) switch(ct->sector_size) { + default: + break; + case 2324: case 2328: + ct->form = 2; + break; + case 2048: case 2332: case 2336: case 2352: case 2368: case 2448: + ct->form = 1; + break; + } + if (((ct->sector_size == 2336) || (ct->sector_size == 2332)) && (ct->mode == 2) && (ct->form == 1)) + ct->skip = 8; + } else if (!memcmp(type, "CD", 2)) { + ct->attr = DATA_TRACK; + ct->mode = 2; + sscanf(type, "CD%c/%i", &temp, &(ct->sector_size)); + } else + success = 0; + + if (success) { + image_set_track_subch_type(ct); + + last = ct->sector_size; + + image_log(img->log, " [TRACK ] %02X/%02X, ATTR %02X, MODE %02X/%02X,\n", + ct->session, + ct->point, + ct->attr, + ct->mode, ct->form); + image_log(img->log, " %i\n", + ct->sector_size); + } +#ifdef ENABLE_IMAGE_LOG + else + image_log(img->log, " [TRACK ] Unable to initialize track %02X " + "specified in Cue sheet\n", t); +#endif + } else if (!strcmp(command, "INDEX")) { + int t = image_cue_get_number(&line); + ci = &(ct->idx[t]); + + ci->type = INDEX_NORMAL; + ci->file = tf; + success = image_cue_get_frame(&frame, &line); + ci->file_start = frame; + + image_log(img->log, " [INDEX ] %02X (%8s): Initialization %s\n", + t, cit[ci->type + 2], success ? "successful" : "failed"); + } else if (!strcmp(command, "PREGAP")) { + ci = &(ct->idx[0]); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = image_cue_get_frame(&frame, &line); + ci->length = frame; + + image_log(img->log, " [INDEX ] 00 (%8s): Initialization %s\n", + cit[ci->type + 2], success ? "successful" : "failed"); + } else if (!strcmp(command, "PAUSE") || !strcmp(command, "ZERO")) { + ci = &(ct->idx[1]); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = image_cue_get_frame(&frame, &line); + ci->length = frame; + + image_log(img->log, " [INDEX ] 01 (%8s): Initialization %s\n", + cit[ci->type + 2], success ? "successful" : "failed"); + } else if (!strcmp(command, "POSTGAP")) { + ci = &(ct->idx[2]); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = image_cue_get_frame(&frame, &line); + ci->length = frame; + + image_log(img->log, " [INDEX ] 02 (%8s): Initialization %s\n", + cit[ci->type + 2], success ? "successful" : "failed"); + } else if (!strcmp(command, "FLAGS")) { + success = image_cue_get_flags(ct, &line); + + image_log(img->log, " [FLAGS ] Initialization %s\n", + success ? "successful" : "failed"); + } else if (!strcmp(command, "REM")) { + success = 1; + char *space = strstr(line, " "); + if (space != NULL) { + space++; + if (space < (line + strlen(line))) { + (void) image_cue_get_keyword(&command, &space); + if (!strcmp(command, "LEAD-OUT")) { + ct = &(img->tracks[lead[2]]); + /* + Mark it this way so file pointers on it are not + going to be adjusted. + */ + last_t = -1; + ct->sector_size = last; + ci = &(ct->idx[1]); + ci->type = INDEX_NORMAL; + ci->file = tf; + success = image_cue_get_frame(&frame, &space); + ci->file_start = frame; + + image_log(img->log, " [LEAD-OUT] Initialization %s\n", + success ? "successful" : "failed"); + } else if (!strcmp(command, "SESSION")) { + session = image_cue_get_number(&space); + + if (session > 1) { + ct = image_insert_track(img, session - 1, 0xb0); + /* + Mark it this way so file pointers on it are not + going to be adjusted. + */ + last_t = -1; + ci = &(ct->idx[1]); + ci->start = (0x40 * 60 * 75) + (0x02 * 75); + + if (session == 2) { + ct->extra[3] = 0x02; + + /* + 00:00:00 on Wembley, C0:00:00 in the spec. + And what's in PMSF? + */ + ct = image_insert_track(img, session - 1, 0xc0); + /* + Mark it this way so file pointers on it are not + going to be adjusted. + */ + last_t = -1; + ci = &(ct->idx[1]); + /* Queen - Live at Wembley '86 CD 1. */ + ci->start = (0x5f * 75 * 60); + /* Optimum recording power. */ + ct->extra[0] = 0x00; + } else + ct->extra[3] = 0x01; + + for (int i = 0; i < 3; i++) { + lead[i] = img->tracks_num; + (void) image_insert_track(img, session, 0xa0 + i); + } + } + + image_log(img->log, " [SESSION ] Initialization successful\n"); + } + } + } + } else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || + !strcmp(command, "ISRC") || !strcmp(command, "PERFORMER") || + !strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || + !strcmp(command, "")) { + /* Ignored commands. */ + image_log(img->log, " [CUE ] Ignored command \"%s\" in Cue sheet\n", + command); + success = 1; + } else { + image_log(img->log, " [CUE ] Unsupported command \"%s\" in Cue sheet\n", + command); + success = 0; + } + + if (!success) + break; + } + + if (success && (ct != NULL)) for (int i = 2; i >= 0; i--) { + if (ct->idx[i].file == NULL) + ct->idx[i].file = tf; + else + break; + } + + tf = NULL; + + fclose(fp); + + if (success) + image_process(img); + else { + image_log(img->log, " [CUE ] Unable to open Cue sheet \"%s\"\n", cuefile); + return 0; + } + + return success; +} + +/* Root functions. */ +static void +image_clear_tracks(cd_image_t *img) +{ + const track_file_t *last = NULL; + track_t *cur = NULL; + track_index_t *idx = NULL; + + if ((img->tracks != NULL) && (img->tracks_num > 0)) { + for (int i = 0; i < img->tracks_num; i++) { + cur = &img->tracks[i]; + + if (((cur->point >= 1) && (cur->point <= 99)) || + (cur->point == 0xa2)) for (int j = 0; j < 3; j++) { + idx = &(cur->idx[j]); + /* Make sure we do not attempt to close a NULL file. */ + if ((idx->file != NULL) && (idx->type == INDEX_NORMAL)) { + if (idx->file != last) { + last = idx->file; + index_file_close(idx); + } else + idx->file = NULL; + } + } + } + + /* Now free the array. */ + free(img->tracks); + img->tracks = NULL; + + /* Mark that there's no tracks. */ + img->tracks_num = 0; + } +} + +/* Shared functions. */ +static int +image_get_track_info(const void *local, const uint32_t track, + const int end, track_info_t *ti) +{ + const cd_image_t *img = (const cd_image_t *) local; + const track_t *ct = NULL; + int ret = 0; + + for (int i = 0; i < img->tracks_num; i++) { + ct = &(img->tracks[i]); + if (ct->point == track) + break; + } + + if (ct != NULL) { + const uint32_t pos = end ? ct->idx[1].start : + (ct->idx[1].start + ct->idx[1].length); + + ti->number = ct->point; + ti->attr = ct->attr; + ti->m = (pos / 75) / 60; + ti->s = (pos / 75) % 60; + ti->f = pos % 75; + + ret = 1; + } + + return ret; +} + +static void +image_get_raw_track_info(const void *local, int *num, uint8_t *buffer) +{ + const cd_image_t *img = (const cd_image_t *) local; + int len = 0; + + image_log(img->log, "img->tracks_num = %i\n", img->tracks_num); + + for (int i = 0; i < img->tracks_num; i++) { + const track_t *ct = &(img->tracks[i]); +#ifdef ENABLE_IMAGE_LOG + int old_len = len; +#endif + buffer[len++] = ct->session; /* Session number. */ + buffer[len++] = ct->attr; /* Track ADR and Control. */ + buffer[len++] = ct->tno; /* TNO (always 0). */ + buffer[len++] = ct->point; /* Point (track number). */ + for (int j = 0; j < 4; j++) + buffer[len++] = ct->extra[j]; + buffer[len++] = (ct->idx[1].start / 75) / 60; + buffer[len++] = (ct->idx[1].start / 75) % 60; + buffer[len++] = ct->idx[1].start % 75; + image_log(img->log, "%i: %02X %02X %02X %02X %02X %02X %02X\n", i, + buffer[old_len], buffer[old_len + 1], + buffer[old_len + 2], buffer[old_len + 3], + buffer[old_len + 8], buffer[old_len + 9], + buffer[old_len + 10]); + } + + *num = img->tracks_num; +} + +static int +image_is_track_pre(const void *local, const uint32_t sector) +{ + const cd_image_t *img = (const cd_image_t *) local; + int ret = 0; + + if (img->has_audio) { + const int track = image_get_track(img, sector); + + if (track >= 0) { + const track_t *trk = &(img->tracks[track]); + + ret = !!(trk->attr & 0x01); + } + } + + return ret; +} + +static int +image_read_sector(const void *local, uint8_t *buffer, + const uint32_t sector) +{ + const cd_image_t *img = (const cd_image_t *) local; + int m = 0; + int s = 0; + int f = 0; + int ret = 0; + uint32_t lba = sector; + int track; + int index; + uint8_t q[16] = { 0x00 }; + + if (sector == 0xffffffff) + lba = img->dev->seek_pos; + + const uint64_t sect = (uint64_t) lba; + + image_get_track_and_index(img, lba, &track, &index); + + const track_t *trk = &(img->tracks[track]); + const track_index_t *idx = &(trk->idx[index]); + const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || + (trk->sector_size == 2448)); + const uint64_t seek = ((sect + 150 - idx->start + idx->file_start) * + trk->sector_size) + trk->skip; + + if (track >= 0) { + /* Signal CIRC error to the guest if sector is bad. */ + ret = image_is_sector_bad(img, lba) ? -1 : 1; + + if (ret > 0) { + uint64_t offset = 0ULL; + + image_log(img->log, "cdrom_read_sector(%08X): track %02X, index %02X, %016" + PRIX64 ", %i, %i, %i, %i\n", + lba, track, index, idx->start, trk->sector_size, track_is_raw, + trk->mode, trk->form); + + memset(buffer, 0x00, 2448); + + if ((trk->attr & 0x04) && ((idx->type < INDEX_NORMAL) || !track_is_raw)) { + offset += 16ULL; + + /* Construct the header. */ + memset(buffer + 1, 0xff, 10); + buffer += 12; + FRAMES_TO_MSF(sector + 150, &m, &s, &f); + /* These have to be BCD. */ + buffer[0] = bin2bcd(m & 0xff); + buffer[1] = bin2bcd(s & 0xff); + buffer[2] = bin2bcd(f & 0xff); + /* Data, should reflect the actual sector type. */ + buffer[3] = trk->mode; + buffer += 4; + if (trk->form >= 1) { + offset += 8ULL; + + /* Construct the CD-I/XA sub-header. */ + buffer[2] = buffer[6] = (trk->form - 1) << 5; + buffer += 8; + } + } + + if (idx->type >= INDEX_NORMAL) { + /* Read the data from the file. */ + ret = idx->file->read(idx->file, buffer, seek, trk->sector_size); + } else + /* Index is not in the file, no read to fail here. */ + ret = 1; + + if ((ret > 0) && ((idx->type < INDEX_NORMAL) || (trk->subch_type != 0x08))) { + buffer -= offset; + + if (trk->subch_type == 0x10) + memcpy(q, &(buffer[2352]), 12); + else { + /* Construct Q. */ + q[0] = (trk->attr >> 4) | ((trk->attr & 0xf) << 4); + q[1] = bin2bcd(trk->point); + q[2] = index; + if (index == 0) { + /* + Pre-gap sector relative frame addresses count from + 00:01:74 downwards. + */ + FRAMES_TO_MSF((int32_t) (149 - (lba + 150 - idx->start)), &m, &s, &f); + } else { + FRAMES_TO_MSF((int32_t) (lba + 150 - idx->start), &m, &s, &f); + } + q[3] = bin2bcd(m & 0xff); + q[4] = bin2bcd(s & 0xff); + q[5] = bin2bcd(f & 0xff); + FRAMES_TO_MSF(lba + 150, &m, &s, &f); + q[7] = bin2bcd(m & 0xff); + q[8] = bin2bcd(s & 0xff); + q[9] = bin2bcd(f & 0xff); + } + + /* Construct raw subchannel data from Q only. */ + for (int i = 0; i < 12; i++) + for (int j = 0; j < 8; j++) + buffer[2352 + (i << 3) + j] = ((q[i] >> (7 - j)) & 0x01) << 6; + } + } + } + + return ret; +} + +static uint8_t +image_get_track_type(const void *local, const uint32_t sector) +{ + const cd_image_t *img = (cd_image_t *) local; + const int track = image_get_track(img, sector); + const track_t * trk = &(img->tracks[track]); + int ret = 0x00; + + if (image_is_track_audio(img, sector)) + ret = CD_TRACK_AUDIO; + else if (track >= 0) for (int i = 0; i < img->tracks_num; i++) { + const track_t *ct = &(img->tracks[i]); + const track_t *nt = &(img->tracks[i + 1]); + + if (ct->point == 0xa0) { + const uint8_t first = (ct->idx[1].start / 75 / 60); + const uint8_t last = (nt->idx[1].start / 75 / 60); + + if ((trk->point >= first) && (trk->point <= last)) { + ret = (ct->idx[1].start / 75) % 60; + break; + } + } + } + + return ret; +} + +static uint32_t +image_get_last_block(const void *local) +{ + const cd_image_t *img = (const cd_image_t *) local; + uint32_t lb = 0x00000000; + + if (img != NULL) { + const track_t *lo = NULL; + + for (int i = (img->tracks_num - 1); i >= 0; i--) { + if (img->tracks[i].point == 0xa2) { + lo = &(img->tracks[i]); + break; + } + } + + if (lo != NULL) + lb = lo->idx[1].start - 1; } return lb; } static int -image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) -{ - cd_img_t *img = (cd_img_t *) dev->image; - uint8_t attr; - TMSF tmsf; - int m; - int s; - int f; - int number; - int track; - - if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY)) - return 0; - - if (ismsf) { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f) - 150; - } - - /* GetTrack requires LBA. */ - track = cdi_get_track(img, pos); - if (track == -1) - return 0; - else { - cdi_get_audio_track_info(img, 0, track, &number, &tmsf, &attr); - return attr == AUDIO_TRACK; - } -} - -static int -image_is_track_pre(cdrom_t *dev, uint32_t lba) -{ - cd_img_t *img = (cd_img_t *) dev->image; - int track; - - /* GetTrack requires LBA. */ - track = cdi_get_track(img, lba); - - if (track != -1) - return cdi_get_audio_track_pre(img, track); - - return 0; -} - -static int -image_sector_size(struct cdrom *dev, uint32_t lba) -{ - cd_img_t *img = (cd_img_t *) dev->image; - - return cdi_get_sector_size(img, lba); -} - -static int -image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba) -{ - cd_img_t *img = (cd_img_t *) dev->image; - - switch (type) { - case CD_READ_DATA: - return cdi_read_sector(img, b, 0, lba); - case CD_READ_AUDIO: - return cdi_read_sector(img, b, 1, lba); - case CD_READ_RAW: - if (cdi_get_sector_size(img, lba) == 2352) - return cdi_read_sector(img, b, 1, lba); - else - return cdi_read_sector_sub(img, b, lba); - default: - cdrom_image_log("CD-ROM %i: Unknown CD read type\n", dev->id); - return 0; - } -} - -static int -image_track_type(cdrom_t *dev, uint32_t lba) -{ - cd_img_t *img = (cd_img_t *) dev->image; - - if (img) { - if (image_is_track_audio(dev, lba, 0)) - return CD_TRACK_AUDIO; - else { - if (cdi_is_mode2(img, lba)) - return CD_TRACK_MODE2 | cdi_get_mode2_form(img, lba); - } - } - - return 0; -} - -static int -image_ext_medium_changed(cdrom_t *dev) +image_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t format, + uint8_t *buffer, uint32_t *info) { return 0; } +static int +image_is_dvd(const void *local) +{ + const cd_image_t *img = (const cd_image_t *) local; + + return img->is_dvd; +} + +static int +image_has_audio(const void *local) +{ + const cd_image_t *img = (const cd_image_t *) local; + + return img->has_audio; +} + static void -image_exit(cdrom_t *dev) +image_close(void *local) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_image_t *img = (cd_image_t *) local; - cdrom_image_log("CDROM: image_exit(%s)\n", dev->image_path); - dev->cd_status = CD_STATUS_EMPTY; + if (img != NULL) { + image_clear_tracks(img); - if (img) { - cdi_close(img); - dev->image = NULL; + image_log(img->log, "Log closed\n"); + + log_close(img->log); + img->log = NULL; + + free(img); } - - dev->ops = NULL; } -static const cdrom_ops_t cdrom_image_ops = { - image_get_tracks, +static const cdrom_ops_t image_ops = { image_get_track_info, - image_get_subchannel, + image_get_raw_track_info, image_is_track_pre, - image_sector_size, image_read_sector, - image_track_type, - image_ext_medium_changed, - image_exit + image_get_track_type, + image_get_last_block, + image_read_dvd_structure, + image_is_dvd, + image_has_audio, + NULL, + image_close, + NULL }; -static int -image_open_abort(cdrom_t *dev) +/* Public functions. */ +void * +image_open(cdrom_t *dev, const char *path) { - cdrom_image_close(dev); - dev->ops = NULL; - dev->image_path[0] = 0; - return 1; -} - -int -cdrom_image_open(cdrom_t *dev, const char *fn) -{ - cd_img_t *img; - - /* Make sure to not STRCPY if the two are pointing - at the same place. */ - if (fn != dev->image_path) - strcpy(dev->image_path, fn); - - /* Create new instance of the CDROM_Image class. */ - img = (cd_img_t *) malloc(sizeof(cd_img_t)); - - /* This guarantees that if ops is not NULL, then - neither is the image pointer. */ - if (!img) - return image_open_abort(dev); - - memset(img, 0, sizeof(cd_img_t)); - dev->image = img; - - /* Open the image. */ - int i = cdi_set_device(img, fn); - if (!i) - return image_open_abort(dev); - - /* All good, reset state. */ - if (i >= 2) - dev->cd_status = CD_STATUS_DATA_ONLY; - else - dev->cd_status = CD_STATUS_STOPPED; - dev->seek_pos = 0; - dev->cd_buflen = 0; - dev->cdrom_capacity = image_get_capacity(dev); - cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); - - /* Attach this handler to the drive. */ - dev->ops = &cdrom_image_ops; - - return 0; -} - -void -cdrom_image_close(cdrom_t *dev) -{ - cdrom_image_log("CDROM: image_close(%s)\n", dev->image_path); - - if (dev && dev->ops && dev->ops->exit) - dev->ops->exit(dev); + const uintptr_t ext = path + strlen(path) - strrchr(path, '.'); + cd_image_t *img = (cd_image_t *) calloc(1, sizeof(cd_image_t)); + + if (img != NULL) { + int ret; + const int is_cue = ((ext == 4) && !stricmp(path + strlen(path) - ext + 1, "CUE")); + + img->dev = dev; + + if (is_cue) { + ret = image_load_cue(img, path); + + if (ret >= 2) + img->has_audio = 0; + else if (ret) + img->has_audio = 1; + } else { + ret = image_load_iso(img, path); + + if (!ret) { + image_close(img); + img = NULL; + } else + img->has_audio = 0; + } + + if (ret) { + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i Image", dev->id + 1); + img->log = log_open(n); + + dev->ops = &image_ops; + } + } + + return img; } diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c deleted file mode 100644 index 7dcde1cdb..000000000 --- a/src/cdrom/cdrom_image_backend.c +++ /dev/null @@ -1,1233 +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. - * - * CD-ROM image file handling module, translated to C from - * cdrom_dosbox.cpp. - * - * - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * The DOSBox Team, - * Cacodemon345 - * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2002-2020 The DOSBox Team. - * Copyright 2024 Cacodemon345. - */ -#define __STDC_FORMAT_MACROS -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _WIN32 -# include -# include -#else -# include -#endif -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/path.h> -#include <86box/plat.h> -#include <86box/cdrom_image_backend.h> - -#include - -#define CDROM_BCD(x) (((x) % 10) | (((x) / 10) << 4)) - -#define MAX_LINE_LENGTH 512 -#define MAX_FILENAME_LENGTH 256 -#define CROSS_LEN 512 - -static char temp_keyword[1024]; - -#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG -int cdrom_image_backend_do_log = ENABLE_CDROM_IMAGE_BACKEND_LOG; - -void -cdrom_image_backend_log(const char *fmt, ...) -{ - va_list ap; - - if (cdrom_image_backend_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define cdrom_image_backend_log(fmt, ...) -#endif - -typedef struct audio_file_t { - SNDFILE *file; - SF_INFO info; -} audio_file_t; - -/* Audio file functions */ -static int -audio_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) -{ - track_file_t *tf = (track_file_t *) priv; - audio_file_t *audio = (audio_file_t *) tf->priv; - uint64_t samples_seek = seek / 4; - uint64_t samples_count = count / 4; - - if ((seek & 3) || (count & 3)) { - cdrom_image_backend_log("CD Audio file: Reading on non-4-aligned boundaries.\n"); - } - - sf_count_t res = sf_seek(audio->file, samples_seek, SEEK_SET); - - if (res == -1) - return 0; - - return !!sf_readf_short(audio->file, (short *) buffer, samples_count); -} - -static uint64_t -audio_get_length(void *priv) -{ - track_file_t *tf = (track_file_t *) priv; - audio_file_t *audio = (audio_file_t *) tf->priv; - - /* Assume 16-bit audio, 2 channel. */ - return audio->info.frames * 4ull; -} - -static void -audio_close(void *priv) -{ - track_file_t *tf = (track_file_t *) priv; - audio_file_t *audio = (audio_file_t *) tf->priv; - - memset(tf->fn, 0x00, sizeof(tf->fn)); - if (audio && audio->file) - sf_close(audio->file); - free(audio); - free(tf); -} - -static track_file_t * -audio_init(const char *filename, int *error) -{ - track_file_t *tf = (track_file_t *) calloc(sizeof(track_file_t), 1); - audio_file_t *audio = (audio_file_t *) calloc(sizeof(audio_file_t), 1); -#ifdef _WIN32 - wchar_t filename_w[4096]; -#endif - - if (tf == NULL || audio == NULL) { - goto cleanup_error; - } - - memset(tf->fn, 0x00, sizeof(tf->fn)); - strncpy(tf->fn, filename, sizeof(tf->fn) - 1); -#ifdef _WIN32 - mbstowcs(filename_w, filename, 4096); - audio->file = sf_wchar_open(filename_w, SFM_READ, &audio->info); -#else - audio->file = sf_open(filename, SFM_READ, &audio->info); -#endif - - if (!audio->file) { - cdrom_image_backend_log("Audio file open error!"); - goto cleanup_error; - } - - if (audio->info.channels != 2 || audio->info.samplerate != 44100 || !audio->info.seekable) { - cdrom_image_backend_log("Audio file not seekable or in non-CD format!"); - sf_close(audio->file); - goto cleanup_error; - } - - *error = 0; - tf->priv = audio; - tf->fp = NULL; - tf->close = audio_close; - tf->get_length = audio_get_length; - tf->read = audio_read; - return tf; -cleanup_error: - free(tf); - free(audio); - *error = 1; - return NULL; -} - -/* Binary file functions. */ -static int -bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) -{ - track_file_t *tf = NULL; - - if ((tf = (track_file_t *) priv)->fp == NULL) - return 0; - - cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu)\n", - tf->fp, seek, count); - - if (fseeko64(tf->fp, seek, SEEK_SET) == -1) { - cdrom_image_backend_log("CDROM: binary_read failed during seek!\n"); - - return 0; - } - - if (fread(buffer, count, 1, tf->fp) != 1) { - cdrom_image_backend_log("CDROM: binary_read failed during read!\n"); - - return 0; - } - - if (UNLIKELY(tf->motorola)) { - for (uint64_t i = 0; i < count; i += 2) { - uint8_t buffer0 = buffer[i]; - uint8_t buffer1 = buffer[i + 1]; - buffer[i] = buffer1; - buffer[i + 1] = buffer0; - } - } - - return 1; -} - -static uint64_t -bin_get_length(void *priv) -{ - track_file_t *tf = NULL; - - if ((tf = (track_file_t *) priv)->fp == NULL) - return 0; - - fseeko64(tf->fp, 0, SEEK_END); - const off64_t len = ftello64(tf->fp); - cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len); - - return len; -} - -static void -bin_close(void *priv) -{ - track_file_t *tf = (track_file_t *) priv; - - if (tf == NULL) - return; - - if (tf->fp != NULL) { - fclose(tf->fp); - tf->fp = NULL; - } - - memset(tf->fn, 0x00, sizeof(tf->fn)); - - free(priv); -} - -static track_file_t * -bin_init(const char *filename, int *error) -{ - track_file_t *tf = (track_file_t *) calloc(1, sizeof(track_file_t)); - struct stat stats; - - if (tf == NULL) { - *error = 1; - return NULL; - } - - memset(tf->fn, 0x00, sizeof(tf->fn)); - strncpy(tf->fn, filename, sizeof(tf->fn) - 1); - tf->fp = plat_fopen64(tf->fn, "rb"); - cdrom_image_backend_log("CDROM: binary_open(%s) = %08lx\n", tf->fn, tf->fp); - - if (stat(tf->fn, &stats) != 0) { - /* Use a blank structure if stat failed. */ - memset(&stats, 0, sizeof(struct stat)); - } - *error = ((tf->fp == NULL) || ((stats.st_mode & S_IFMT) == S_IFDIR)); - - /* Set the function pointers. */ - if (!*error) { - tf->read = bin_read; - tf->get_length = bin_get_length; - tf->close = bin_close; - } 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. - * However, we need to make sure the descriptor is closed. */ - if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) { - /* tf is freed by bin_close */ - bin_close(tf); - } else { - free(tf); - } - tf = NULL; - } - - return tf; -} - -static track_file_t * -track_file_init(const char *filename, int *error) -{ - /* Current we only support .BIN files, either combined or one per - track. In the future, more is planned. */ - return bin_init(filename, error); -} - -static void -track_file_close(track_t *trk) -{ - if (trk == NULL) - return; - - if (trk->file == NULL) - return; - - if (trk->file->close == NULL) - return; - - trk->file->close(trk->file); - trk->file = NULL; -} - -/* Root functions. */ -static void -cdi_clear_tracks(cd_img_t *cdi) -{ - const track_file_t *last = NULL; - track_t *cur = NULL; - - if ((cdi->tracks == NULL) || (cdi->tracks_num == 0)) - return; - - for (int i = 0; i < cdi->tracks_num; i++) { - cur = &cdi->tracks[i]; - - /* Make sure we do not attempt to close a NULL file. */ - if (cur->file != last) { - last = cur->file; - track_file_close(cur); - } else - cur->file = NULL; - } - - /* Now free the array. */ - free(cdi->tracks); - cdi->tracks = NULL; - - /* Mark that there's no tracks. */ - cdi->tracks_num = 0; -} - -void -cdi_close(cd_img_t *cdi) -{ - cdi_clear_tracks(cdi); - free(cdi); -} - -int -cdi_set_device(cd_img_t *cdi, const char *path) -{ - int ret; - - if ((ret = cdi_load_cue(cdi, path))) - return ret; - - if ((ret = cdi_load_iso(cdi, path))) - return ret; - - return 0; -} - -void -cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out) -{ - *st_track = 1; - *end = cdi->tracks_num - 1; - FRAMES_TO_MSF(cdi->tracks[*end].start + 150, &lead_out->min, &lead_out->sec, &lead_out->fr); -} - -void -cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out) -{ - *st_track = 1; - *end = cdi->tracks_num - 1; - *lead_out = cdi->tracks[*end].start; -} - -int -cdi_get_audio_track_pre(cd_img_t *cdi, int track) -{ - const track_t *trk = &cdi->tracks[track - 1]; - - if ((track < 1) || (track > cdi->tracks_num)) - return 0; - - return trk->pre; -} - -/* This replaces both Info and EndInfo, they are specified by a variable. */ -int -cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) -{ - const track_t *trk = &cdi->tracks[track - 1]; - const int pos = trk->start + 150; - - if ((track < 1) || (track > cdi->tracks_num)) - return 0; - - FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr); - - *track_num = trk->track_number; - *attr = trk->attr; - - return 1; -} - -int -cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, uint32_t *start, uint8_t *attr) -{ - const track_t *trk = &cdi->tracks[track - 1]; - - if ((track < 1) || (track > cdi->tracks_num)) - return 0; - - *start = (uint32_t) trk->start; - - *track_num = trk->track_number; - *attr = trk->attr; - - return 1; -} - -int -cdi_get_track(cd_img_t *cdi, uint32_t sector) -{ - /* There must be at least two tracks - data and lead out. */ - if (cdi->tracks_num < 2) - return -1; - - /* This has a problem - the code skips the last track, which is - lead out - is that correct? */ - for (int i = 0; i < (cdi->tracks_num - 1); i++) { - const track_t *cur = &cdi->tracks[i]; - const track_t *next = &cdi->tracks[i + 1]; - - /* Take into account cue sheets that do not start on sector 0. */ - if ((i == 0) && (sector < cur->start)) - return cur->number; - - if ((cur->start <= sector) && (sector < next->start)) - return cur->number; - } - - return -1; -} - -/* TODO: See if track start is adjusted by 150 or not. */ -int -cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) -{ - const int cur_track = cdi_get_track(cdi, sector); - - if (cur_track < 1) - return 0; - - *track = (uint8_t) cur_track; - const track_t *trk = &cdi->tracks[*track - 1]; - *attr = trk->attr; - *index = 1; - - FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr); - - /* Absolute position should be adjusted by 150, not the relative ones. */ - FRAMES_TO_MSF(sector - trk->start, &rel_pos->min, &rel_pos->sec, &rel_pos->fr); - - return 1; -} - -int -cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector) -{ - const int track = cdi_get_track(cdi, sector) - 1; - const uint64_t sect = (uint64_t) sector; - int raw_size; - int cooked_size; - uint64_t offset; - int m = 0; - int s = 0; - int f = 0; - - if (track < 0) - return 0; - - const track_t *trk = &cdi->tracks[track]; - const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448)); - - const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size); - - if (track_is_raw) - raw_size = trk->sector_size; - else - raw_size = 2448; - - if (trk->mode2 && (trk->form != 1)) { - if (trk->form == 2) - cooked_size = (track_is_raw ? 2328 : trk->sector_size); /* Both 2324 + ECC and 2328 variants are valid. */ - else - cooked_size = 2336; - } else - cooked_size = COOKED_SECTOR_SIZE; - - const size_t length = (raw ? raw_size : cooked_size); - - if (trk->mode2 && (trk->form >= 1)) - offset = 24ULL; - else - offset = 16ULL; - - if (raw && !track_is_raw) { - memset(buffer, 0x00, 2448); - const int ret = trk->file->read(trk->file, buffer + offset, seek, length); - if (!ret) - return 0; - /* Construct the rest of the raw sector. */ - memset(buffer + 1, 0xff, 10); - buffer += 12; - FRAMES_TO_MSF(sector + 150, &m, &s, &f); - /* These have to be BCD. */ - buffer[0] = CDROM_BCD(m & 0xff); - buffer[1] = CDROM_BCD(s & 0xff); - buffer[2] = CDROM_BCD(f & 0xff); - /* Data, should reflect the actual sector type. */ - buffer[3] = trk->mode2 ? 2 : 1; - return 1; - } else if (!raw && track_is_raw) - return trk->file->read(trk->file, buffer, seek + offset, length); - else - return trk->file->read(trk->file, buffer, seek, length); -} - -int -cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num) -{ - int success = 1; - - /* TODO: This fails to account for Mode 2. Shouldn't we have a function - to get sector size? */ - const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - const uint32_t buf_len = num * sector_size; - uint8_t *buf = (uint8_t *) calloc(1, buf_len * sizeof(uint8_t)); - - for (uint32_t i = 0; i < num; i++) { - success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i); - if (!success) - break; - /* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an - audio track. */ - if (raw && (sector < cdi->tracks[0].length) && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[(i * sector_size) + 2068])) - return 0; - } - - memcpy((void *) buffer, buf, buf_len); - free(buf); - buf = NULL; - - return success; -} - -/* TODO: Do CUE+BIN images with a sector size of 2448 even exist? */ -int -cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector) -{ - const int track = cdi_get_track(cdi, sector) - 1; - - if (track < 0) - return 0; - - const track_t *trk = &cdi->tracks[track]; - const uint64_t seek = trk->skip + (((uint64_t) sector - trk->start) * trk->sector_size); - if (trk->sector_size != 2448) - return 0; - - return trk->file->read(trk->file, buffer, seek, 2448); -} - -int -cdi_get_sector_size(cd_img_t *cdi, uint32_t sector) -{ - const int track = cdi_get_track(cdi, sector) - 1; - - if (track < 0) - return 0; - - const track_t *trk = &cdi->tracks[track]; - return trk->sector_size; -} - -int -cdi_is_mode2(cd_img_t *cdi, uint32_t sector) -{ - const int track = cdi_get_track(cdi, sector) - 1; - - if (track < 0) - return 0; - - const track_t *trk = &cdi->tracks[track]; - - return !!(trk->mode2); -} - -int -cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector) -{ - const int track = cdi_get_track(cdi, sector) - 1; - - if (track < 0) - return 0; - - const track_t *trk = &cdi->tracks[track]; - - return trk->form; -} - -static int -cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form) -{ - uint8_t pvd[COOKED_SECTOR_SIZE]; - uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */ - - if (sector_size == RAW_SECTOR_SIZE) { - if (mode2 && (form > 0)) - seek += 24; - else - seek += 16; - } else if (form > 0) - seek += 8; - - file->read(file, pvd, seek, COOKED_SECTOR_SIZE); - - return ((pvd[0] == 1 && !strncmp((char *) (&pvd[1]), "CD001", 5) && pvd[6] == 1) || (pvd[8] == 1 && !strncmp((char *) (&pvd[9]), "CDROM", 5) && pvd[14] == 1)); -} - -/* This reallocates the array and returns the pointer to the last track. */ -static void -cdi_track_push_back(cd_img_t *cdi, track_t *trk) -{ - /* This has to be done so situations in which realloc would misbehave - can be detected and reported to the user. */ - if ((cdi->tracks != NULL) && (cdi->tracks_num == 0)) - fatal("CD-ROM Image: Non-null tracks array at 0 loaded tracks\n"); - if ((cdi->tracks == NULL) && (cdi->tracks_num != 0)) - fatal("CD-ROM Image: Null tracks array at non-zero loaded tracks\n"); - - cdi->tracks = realloc(cdi->tracks, (cdi->tracks_num + 1) * sizeof(track_t)); - memcpy(&(cdi->tracks[cdi->tracks_num]), trk, sizeof(track_t)); - cdi->tracks_num++; -} - -int -cdi_get_iso_track(cd_img_t *cdi, track_t *trk, const char *filename) -{ - int error = 0; - int ret = 2; - memset(trk, 0, sizeof(track_t)); - - /* Data track (shouldn't there be a lead in track?). */ - trk->file = bin_init(filename, &error); - if (error) { - if ((trk->file != NULL) && (trk->file->close != NULL)) - trk->file->close(trk->file); - ret = 3; - trk->file = viso_init(filename, &error); - if (error) { - if ((trk->file != NULL) && (trk->file->close != NULL)) - trk->file->close(trk->file); - return 0; - } - } - trk->number = 1; - trk->track_number = 1; - trk->attr = DATA_TRACK; - - /* Try to detect ISO type. */ - trk->form = 0; - trk->mode2 = 0; - - if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 0, 0)) - trk->sector_size = RAW_SECTOR_SIZE; - else if (cdi_can_read_pvd(trk->file, 2336, 1, 0)) { - trk->sector_size = 2336; - trk->mode2 = 1; - } else if (cdi_can_read_pvd(trk->file, 2324, 1, 2)) { - trk->sector_size = 2324; - trk->mode2 = 1; - trk->form = 2; - trk->noskip = 1; - } else if (cdi_can_read_pvd(trk->file, 2328, 1, 2)) { - trk->sector_size = 2328; - trk->mode2 = 1; - trk->form = 2; - trk->noskip = 1; - } else if (cdi_can_read_pvd(trk->file, 2336, 1, 1)) { - trk->sector_size = 2336; - trk->mode2 = 1; - trk->form = 1; - trk->skip = 8; - } else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 0)) { - trk->sector_size = RAW_SECTOR_SIZE; - trk->mode2 = 1; - } else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 1)) { - trk->sector_size = RAW_SECTOR_SIZE; - trk->mode2 = 1; - trk->form = 1; - } else { - /* We use 2048 mode 1 as the default. */ - trk->sector_size = COOKED_SECTOR_SIZE; - } - - trk->length = trk->file->get_length(trk->file) / trk->sector_size; - cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk->length, trk->sector_size); - return ret; -} - -int -cdi_load_iso(cd_img_t *cdi, const char *filename) -{ - int ret = 2; - track_t trk = { 0 }; - - cdi->tracks = NULL; - cdi->tracks_num = 0; - - ret = cdi_get_iso_track(cdi, &trk, filename); - - if (ret >= 1) { - cdi_track_push_back(cdi, &trk); - - /* Lead out track. */ - trk.number = 2; - trk.track_number = 0xAA; - trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */ - trk.start = trk.length; - trk.length = 0; - trk.file = NULL; - cdi_track_push_back(cdi, &trk); - } - - return ret; -} - -static int -cdi_cue_get_buffer(char *str, char **line, int up) -{ - char *s = *line; - char *p = str; - int quote = 0; - int done = 0; - int space = 1; - - /* Copy to local buffer until we have end of string or whitespace. */ - while (!done) { - switch (*s) { - case '\0': - if (quote) { - /* Ouch, unterminated string.. */ - return 0; - } - done = 1; - break; - - case '\"': - quote ^= 1; - break; - - case ' ': - case '\t': - if (space) - break; - - if (!quote) { - done = 1; - break; - } - fallthrough; - - default: - if (up && islower((int) *s)) - *p++ = toupper((int) *s); - else - *p++ = *s; - space = 0; - break; - } - - if (!done) - s++; - } - *p = '\0'; - - *line = s; - - return 1; -} - -static int -cdi_cue_get_keyword(char **dest, char **line) -{ - int success; - - success = cdi_cue_get_buffer(temp_keyword, line, 1); - if (success) - *dest = temp_keyword; - - return success; -} - -/* Get a string from the input line, handling quotes properly. */ -static uint64_t -cdi_cue_get_number(char **line) -{ - char temp[128]; - uint64_t num; - - if (!cdi_cue_get_buffer(temp, line, 0)) - return 0; - - if (sscanf(temp, "%" PRIu64, &num) != 1) - return 0; - - return num; -} - -static int -cdi_cue_get_frame(uint64_t *frames, char **line) -{ - char temp[128]; - int min = 0; - int sec = 0; - int fr = 0; - int success; - - success = cdi_cue_get_buffer(temp, line, 0); - if (!success) - return 0; - - success = sscanf(temp, "%d:%d:%d", &min, &sec, &fr) == 3; - if (!success) - return 0; - - *frames = MSF_TO_FRAMES(min, sec, fr); - - return 1; -} - -static int -cdi_cue_get_flags(track_t *cur, char **line) -{ - char temp[128]; - char temp2[128]; - int success; - - success = cdi_cue_get_buffer(temp, line, 0); - if (!success) - return 0; - - memset(temp2, 0x00, sizeof(temp2)); - success = sscanf(temp, "%s", temp2) == 1; - if (!success) - return 0; - - cur->pre = (strstr(temp2, "PRE") != NULL); - - return 1; -} - -static int -cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap) -{ - /* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */ - track_t *prev = NULL; - - /* Skip *MUST* be calculated even if prestart is 0. */ - if (prestart > cur->start) - return 0; - const uint64_t skip = cur->start - prestart; - - if ((cdi->tracks != NULL) && (cdi->tracks_num != 0)) - prev = &cdi->tracks[cdi->tracks_num - 1]; - else if ((cdi->tracks == NULL) && (cdi->tracks_num != 0)) { - fatal("NULL cdi->tracks with non-zero cdi->tracks_num\n"); - return 0; - } - - /* First track (track number must be 1). */ - if ((prev == NULL) || (cdi->tracks_num == 0)) { - /* I guess this makes sure the structure is not filled with invalid data. */ - if (cur->number != 1) - return 0; - cur->skip = skip * cur->sector_size; - if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip) - cur->skip += 8; - cur->start += cur_pregap; - *total_pregap = cur_pregap; - cdi_track_push_back(cdi, cur); - return 1; - } - - /* Current track consumes data from the same file as the previous. */ - if (prev->file == cur->file) { - cur->start += *shift; - prev->length = cur->start + *total_pregap - prev->start - skip; - cur->skip += prev->skip + (prev->length * prev->sector_size) + (skip * cur->sector_size); - *total_pregap += cur_pregap; - cur->start += *total_pregap; - } else { - const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip); - prev->length = temp / ((uint64_t) prev->sector_size); - if ((temp % prev->sector_size) != 0) - prev->length++; - /* Padding. */ - - cur->start += prev->start + prev->length + cur_pregap; - cur->skip = skip * cur->sector_size; - if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip) - cur->skip += 8; - *shift += prev->start + prev->length; - *total_pregap = cur_pregap; - } - - /* Error checks. */ - if (cur->number <= 1) - return 0; - if ((prev->number + 1) != cur->number) - return 0; - if (cur->start < (prev->start + prev->length)) - return 0; - - cdi_track_push_back(cdi, cur); - - return 1; -} - -int -cdi_load_cue(cd_img_t *cdi, const char *cuefile) -{ - track_t trk; - char pathname[MAX_FILENAME_LENGTH]; - uint64_t shift = 0ULL; - uint64_t prestart = 0ULL; - uint64_t cur_pregap = 0ULL; - uint64_t total_pregap = 0ULL; - uint64_t frame = 0ULL; - uint64_t index; - int iso_file_used = 0; - int success; - int error; - int can_add_track = 0; - FILE *fp; - char buf[MAX_LINE_LENGTH]; - char *line; - char *command; - char *type; - - cdi->tracks = NULL; - cdi->tracks_num = 0; - - memset(&trk, 0, sizeof(track_t)); - - /* Get a copy of the filename into pathname, we need it later. */ - memset(pathname, 0, MAX_FILENAME_LENGTH * sizeof(char)); - path_get_dirname(pathname, cuefile); - - /* Open the file. */ - fp = plat_fopen(cuefile, "r"); - if (fp == NULL) - return 0; - - success = 0; - - for (;;) { - line = buf; - - /* Read a line from the cuesheet file. */ - if (feof(fp) || fgets(buf, sizeof(buf), fp) == NULL || ferror(fp)) - break; - - /* Do two iterations to make sure to nuke even if it's \r\n or \n\r, - but do checks to make sure we're not nuking other bytes. */ - for (uint8_t i = 0; i < 2; i++) { - if (strlen(buf) > 0) { - if (buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = '\0'; - /* nuke trailing newline */ - else if (buf[strlen(buf) - 1] == '\r') - buf[strlen(buf) - 1] = '\0'; - /* nuke trailing newline */ - } - } - - (void) cdi_cue_get_keyword(&command, &line); - - if (!strcmp(command, "TRACK")) { - if (can_add_track) - success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap); - else - success = 1; - if (!success) - break; - - if (iso_file_used) { - /* We don't alter anything of the detected track type with the one specified in the CUE file, except its numbers. */ - cur_pregap = 0; - prestart = 0; - - trk.number = cdi_cue_get_number(&line); - trk.track_number = trk.number; - success = cdi_cue_get_keyword(&type, &line); - if (!success) - break; - can_add_track = 1; - - iso_file_used = 0; - } else { - trk.start = 0; - trk.skip = 0; - cur_pregap = 0; - prestart = 0; - - trk.number = cdi_cue_get_number(&line); - trk.track_number = trk.number; - success = cdi_cue_get_keyword(&type, &line); - if (!success) - break; - - trk.form = 0; - trk.mode2 = 0; - - trk.pre = 0; - - if (!strcmp(type, "AUDIO")) { - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = AUDIO_TRACK; - } else if (!strcmp(type, "MODE1/2048")) { - trk.sector_size = COOKED_SECTOR_SIZE; - trk.attr = DATA_TRACK; - } else if (!strcmp(type, "MODE1/2352")) { - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = DATA_TRACK; - } else if (!strcmp(type, "MODE1/2448")) { - trk.sector_size = 2448; - trk.attr = DATA_TRACK; - } else if (!strcmp(type, "MODE2/2048")) { - trk.form = 1; - trk.sector_size = COOKED_SECTOR_SIZE; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2324")) { - trk.form = 2; - trk.sector_size = 2324; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2328")) { - trk.form = 2; - trk.sector_size = 2328; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2336")) { - trk.form = 1; - trk.sector_size = 2336; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2352")) { - /* Assume this is XA Mode 2 Form 1. */ - trk.form = 1; - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "MODE2/2448")) { - /* Assume this is XA Mode 2 Form 1. */ - trk.form = 1; - trk.sector_size = 2448; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "CDG/2448")) { - trk.sector_size = 2448; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "CDI/2336")) { - trk.sector_size = 2336; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else if (!strcmp(type, "CDI/2352")) { - trk.sector_size = RAW_SECTOR_SIZE; - trk.attr = DATA_TRACK; - trk.mode2 = 1; - } else - success = 0; - - can_add_track = 1; - } - } else if (!strcmp(command, "INDEX")) { - index = cdi_cue_get_number(&line); - success = cdi_cue_get_frame(&frame, &line); - - switch (index) { - case 0: - prestart = frame; - break; - - case 1: - trk.start = frame; - break; - - default: - /* Ignore other indices. */ - break; - } - } else if (!strcmp(command, "FILE")) { - char filename[MAX_FILENAME_LENGTH]; - char ansi[MAX_FILENAME_LENGTH]; - - if (can_add_track) - success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap); - else - success = 1; - if (!success) - break; - can_add_track = 0; - - memset(ansi, 0, MAX_FILENAME_LENGTH * sizeof(char)); - memset(filename, 0, MAX_FILENAME_LENGTH * sizeof(char)); - - success = cdi_cue_get_buffer(ansi, &line, 0); - if (!success) - break; - success = cdi_cue_get_keyword(&type, &line); - if (!success) - break; - - trk.file = NULL; - error = 1; - - if (!strcmp(type, "BINARY") || !strcmp(type, "MOTOROLA")) { - int fn_len = 0; - if (!path_abs(ansi)) { - path_append_filename(filename, pathname, ansi); - } else { - strcpy(filename, ansi); - } - fn_len = strlen(filename); - if ((tolower((int) filename[fn_len - 1]) == 'o' - && tolower((int) filename[fn_len - 2]) == 's' - && tolower((int) filename[fn_len - 3]) == 'i' - && filename[fn_len - 4] == '.') - || plat_dir_check(filename)) { - error = !cdi_get_iso_track(cdi, &trk, filename); - if (!error) { - iso_file_used = 1; - } - } else - trk.file = track_file_init(filename, &error); - - if (trk.file) { - trk.file->motorola = !strcmp(type, "MOTOROLA"); - } - } else if (!strcmp(type, "WAVE") || !strcmp(type, "AIFF") || !strcmp(type, "MP3")) { - if (!path_abs(ansi)) { - path_append_filename(filename, pathname, ansi); - } else { - strcpy(filename, ansi); - } - trk.file = audio_init(filename, &error); - } - if (error) { - cdrom_image_backend_log("CUE: cannot open file '%s' in cue sheet!\n", - filename); - - if (trk.file != NULL) { - trk.file->close(trk.file); - trk.file = NULL; - } - success = 0; - } - } else if (!strcmp(command, "PREGAP")) - success = cdi_cue_get_frame(&cur_pregap, &line); - else if (!strcmp(command, "FLAGS")) - success = cdi_cue_get_flags(&trk, &line); - else if (!strcmp(command, "CATALOG") || !strcmp(command, "CDTEXTFILE") || !strcmp(command, "ISRC") || !strcmp(command, "PERFORMER") || !strcmp(command, "POSTGAP") || !strcmp(command, "REM") || !strcmp(command, "SONGWRITER") || !strcmp(command, "TITLE") || !strcmp(command, "")) { - /* Ignored commands. */ - success = 1; - } else { - cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", command); - - success = 0; - } - - if (!success) - break; - } - - fclose(fp); - if (!success) - return 0; - - /* Add last track. */ - if (!cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap)) - return 0; - - /* Add lead out track. */ - trk.number++; - trk.track_number = 0xAA; - trk.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - trk.start = 0; - trk.length = 0; - trk.file = NULL; - if (!cdi_add_track(cdi, &trk, &shift, 0, &total_pregap, 0)) - return 0; - - return 1; -} - -int -cdi_has_data_track(cd_img_t *cdi) -{ - if ((cdi == NULL) || (cdi->tracks == NULL)) - return 0; - - /* Data track has attribute 0x14. */ - for (int i = 0; i < cdi->tracks_num; i++) { - if (cdi->tracks[i].attr == DATA_TRACK) - return 1; - } - - return 0; -} - -int -cdi_has_audio_track(cd_img_t *cdi) -{ - if ((cdi == NULL) || (cdi->tracks == NULL)) - return 0; - - /* Audio track has attribute 0x10. */ - for (int i = 0; i < cdi->tracks_num; i++) { - if (cdi->tracks[i].attr == AUDIO_TRACK) - return 1; - } - - return 0; -} diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 90bd83cf7..4bf976794 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -8,9 +8,7 @@ * * Virtual ISO CD-ROM image back-end. * - * - * - * Authors: RichardG + * Authors: RichardG, * * Copyright 2022 RichardG. */ @@ -23,7 +21,9 @@ #define __STDC_FORMAT_MACROS #include #include +#ifdef IMAGE_VISO_LOG #include +#endif #include #include #include @@ -31,15 +31,16 @@ #include #include #include -#define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/bswap.h> -#include <86box/cdrom_image_backend.h> +#include <86box/cdrom.h> +#include <86box/cdrom_image.h> +#include <86box/cdrom_image_viso.h> +#include <86box/log.h> #include <86box/path.h> #include <86box/plat.h> +#include <86box/bswap.h> #include <86box/plat_dir.h> #include <86box/version.h> -#include <86box/timer.h> #include <86box/nvr.h> #ifndef S_ISDIR @@ -138,29 +139,30 @@ static const char rr_eid[] = "RRIP_1991A"; /* identifiers used in ER field for static const char rr_edesc[] = "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS."; static int8_t tz_offset = 0; -#ifdef ENABLE_CDROM_IMAGE_VISO_LOG -int cdrom_image_viso_do_log = ENABLE_CDROM_IMAGE_VISO_LOG; +#ifdef IMAGE_VISO_LOG +int image_viso_do_log = IMAGE_VISO_LOG; void -cdrom_image_viso_log(const char *fmt, ...) +image_viso_log(void *priv, const char *fmt, ...) { va_list ap; - if (cdrom_image_viso_do_log) { + if (image_viso_do_log) { va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define cdrom_image_viso_log(fmt, ...) +# define image_viso_log(priv, fmt, ...) #endif static size_t -viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp) +viso_pread(void *ptr, const uint64_t offset, const size_t size, + const size_t count, FILE *fp) { - uint64_t cur_pos = ftello64(fp); - size_t ret = 0; + const uint64_t cur_pos = ftello64(fp); + size_t ret = 0; if (fseeko64(fp, offset, SEEK_SET) != -1) ret = fread(ptr, size, count, fp); fseeko64(fp, cur_pos, SEEK_SET); @@ -168,10 +170,11 @@ viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp) } static size_t -viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp) +viso_pwrite(const void *ptr, const uint64_t offset, const size_t size, + const size_t count, FILE *fp) { - uint64_t cur_pos = ftello64(fp); - size_t ret = 0; + const uint64_t cur_pos = ftello64(fp); + size_t ret = 0; if (fseeko64(fp, offset, SEEK_SET) != -1) ret = fwrite(ptr, size, count, fp); fseeko64(fp, cur_pos, SEEK_SET); @@ -693,22 +696,22 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) /* Close any existing FIFO entry's file. */ viso_entry_t *other_entry = viso->file_fifo[viso->file_fifo_pos]; if (other_entry && other_entry->file) { - cdrom_image_viso_log("VISO: Closing [%s]", other_entry->path); + image_viso_log(viso->tf.log, "Closing [%s]...\n", other_entry->path); fclose(other_entry->file); other_entry->file = NULL; - cdrom_image_viso_log("\n"); + image_viso_log(viso->tf.log, "Done\n"); } /* Open file. */ - cdrom_image_viso_log("VISO: Opening [%s]", entry->path); + image_viso_log(viso->tf.log, "Opening [%s]...\n", entry->path); if ((entry->file = fopen(entry->path, "rb"))) { - cdrom_image_viso_log("\n"); + image_viso_log(viso->tf.log, "Done\n"); /* Add this entry to the FIFO. */ viso->file_fifo[viso->file_fifo_pos++] = entry; viso->file_fifo_pos &= (sizeof(viso->file_fifo) / sizeof(viso->file_fifo[0])) - 1; } else { - cdrom_image_viso_log(" => failed\n"); + image_viso_log(viso->tf.log, "Failed\n"); /* Clear any existing FIFO entry. */ viso->file_fifo[viso->file_fifo_pos] = NULL; @@ -716,8 +719,11 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count) } /* Read data. */ - if (entry->file && (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) != -1)) - read = fread(buffer, 1, sector_remain, entry->file); + if (!entry->file || (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) == -1)) + return -1; + read = fread(buffer, 1, sector_remain, entry->file); + if (sector_remain && !read) + return -1; } /* Fill remainder with 00 bytes if needed. */ @@ -752,12 +758,12 @@ viso_close(void *priv) if (viso == NULL) return; - cdrom_image_viso_log("VISO: close()\n"); + image_viso_log(viso->tf.log, "close()\n"); /* De-allocate everything. */ if (tf->fp) fclose(tf->fp); -#ifndef ENABLE_CDROM_IMAGE_VISO_LOG +#ifndef ENABLE_IMAGE_VISO_LOG remove(nvr_path(viso->tf.fn)); #endif @@ -776,21 +782,32 @@ viso_close(void *priv) if (viso->entry_map) free(viso->entry_map); + if (tf->log != NULL) { + + } + free(viso); } track_file_t * -viso_init(const char *dirname, int *error) +viso_init(const uint8_t id, const char *dirname, int *error) { - cdrom_image_viso_log("VISO: init()\n"); - /* Initialize our data structure. */ viso_t *viso = (viso_t *) calloc(1, sizeof(viso_t)); uint8_t *data = NULL; uint8_t *p; *error = 1; + if (viso == NULL) goto end; + + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i VISO ", id + 1); + viso->tf.log = log_open(n); + + image_viso_log(viso->tf.log, "init()\n"); + viso->sector_size = VISO_SECTOR_SIZE; viso->format = VISO_FORMAT_ISO | VISO_FORMAT_JOLIET | VISO_FORMAT_RR; viso->use_version_suffix = (viso->format & VISO_FORMAT_ISO); /* cleared later if required */ @@ -801,7 +818,7 @@ viso_init(const char *dirname, int *error) goto end; /* Open temporary file. */ -#ifdef ENABLE_CDROM_IMAGE_VISO_LOG +#ifdef ENABLE_IMAGE_VISO_LOG strcpy(viso->tf.fn, "viso-debug.iso"); #else plat_tempfile(viso->tf.fn, "viso", ".tmp"); @@ -811,7 +828,7 @@ viso_init(const char *dirname, int *error) goto end; /* Set up directory traversal. */ - cdrom_image_viso_log("VISO: Traversing directories:\n"); + image_viso_log(viso->tf.log, "Traversing directories:\n"); viso_entry_t *entry; viso_entry_t *last_entry; viso_entry_t *dir; @@ -838,7 +855,7 @@ viso_init(const char *dirname, int *error) if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */ goto end; dir->parent = dir; /* for the root's path table and .. entries */ - cdrom_image_viso_log("[%08X] %s => [root]\n", dir, dir->path); + image_viso_log(viso->tf.log, "[%08X] %s => [root]\n", dir, dir->path); /* Traverse directories, starting with the root. */ viso_entry_t **dir_entries = NULL; @@ -888,7 +905,8 @@ viso_init(const char *dirname, int *error) /* Set basename. */ strcpy(entry->name_short, children_count ? ".." : "."); - cdrom_image_viso_log("[%08X] %s => %s\n", entry, dir->path, entry->name_short); + image_viso_log(viso->tf.log, "[%08X] %s => %s\n", entry, + dir->path, entry->name_short); } /* Iterate through this directory's children again, making the entries. */ @@ -896,12 +914,16 @@ viso_init(const char *dirname, int *error) rewinddir(dirp); while ((readdir_entry = readdir(dirp))) { /* Ignore . and .. pseudo-directories. */ - if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.'))) + if ((readdir_entry->d_name[0] == '.') && + ((readdir_entry->d_name[1] == '\0') || + (*((uint16_t *) &readdir_entry->d_name[1]) == '.'))) continue; /* Add and fill entry. */ - entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2); - if (!entry) + entry = dir_entries[children_count++] = + (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + + dir_path_len + strlen(readdir_entry->d_name) + 2); + if (entry == NULL) break; entry->parent = dir; strcpy(entry->path, dir->path); @@ -971,10 +993,12 @@ have_eltorito_entry: continue; } - cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename); + image_viso_log(viso->tf.log, "[%08X] %s => [%-12s] %s\n", entry, + dir->path, entry->name_short, entry->basename); } } else { - cdrom_image_viso_log("VISO: Failed to enumerate [%s], will be empty\n", dir->path); + image_viso_log(viso->tf.log, "Failed to enumerate [%s], will be empty\n", + dir->path); } /* Add terminator. */ @@ -1128,13 +1152,17 @@ next_dir: /* Write El Torito boot descriptor. This is an awkward spot for that, but the spec requires it to be the second descriptor. */ if (!i && eltorito_entry) { - cdrom_image_viso_log("VISO: Writing El Torito boot descriptor for entry [%08X]\n", eltorito_entry); + image_viso_log(viso->tf.log, "Writing El Torito boot descriptor for " + "entry [%08X]\n", eltorito_entry); p = data; if (!(viso->format & VISO_FORMAT_ISO)) - VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */ - *p++ = 0; /* type */ - memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */ + /* Sector offset (HSF only). */ + VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); + /* Type. */ + *p++ = 0; + /* Standard ID. */ + memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); p += 5; *p++ = 1; /* version */ @@ -1235,7 +1263,7 @@ next_dir: /* Write each path table. */ for (int i = 0; i <= ((max_vd << 1) | 1); i++) { - cdrom_image_viso_log("VISO: Generating path table #%d:\n", i); + image_viso_log(viso->tf.log, "Generating path table #%d:\n", i); /* Save this path table's start offset. */ uint64_t pt_start = ftello64(viso->tf.fp); @@ -1256,7 +1284,9 @@ next_dir: continue; } - cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename : dir->name_short); + image_viso_log(viso->tf.log, "[%08X] %s => %s\n", dir, + dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename : + dir->name_short); /* Save this directory's path table index and offset. */ dir->pt_idx = pt_idx; @@ -1324,7 +1354,7 @@ next_dir: /* Write directory records for each type. */ int dir_type = VISO_DIR_CURRENT_ROOT; for (int i = 0; i <= max_vd; i++) { - cdrom_image_viso_log("VISO: Generating directory record set #%d:\n", i); + image_viso_log(viso->tf.log, "Generating directory record set #%d:\n", i); /* Go through directories. */ dir = viso->root_dir; @@ -1367,8 +1397,10 @@ next_dir: if ((entry == eltorito_entry) || (entry == eltorito_dir)) goto next_entry; - cdrom_image_viso_log("[%08X] %s => %s\n", entry, dir->path, - ((dir_type == VISO_DIR_PARENT) ? ".." : ((dir_type < VISO_DIR_PARENT) ? "." : (i ? entry->basename : entry->name_short)))); + image_viso_log(viso->tf.log, "[%08X] %s => %s\n", entry, dir->path, + ((dir_type == VISO_DIR_PARENT) ? ".." : + ((dir_type < VISO_DIR_PARENT) ? "." : + (i ? entry->basename : entry->name_short)))); /* Fill directory record. */ viso_fill_dir_record(data, entry, viso, dir_type); @@ -1435,7 +1467,8 @@ next_entry: /* Allocate entry map for sector->file lookups. */ size_t orig_sector_size = viso->sector_size; while (1) { - cdrom_image_viso_log("VISO: Allocating entry map for %zu %zu-byte sectors\n", viso->entry_map_size, viso->sector_size); + image_viso_log(viso->tf.log, "Allocating entry map for %zu %zu-byte sectors\n", + viso->entry_map_size, viso->sector_size); viso->entry_map = (viso_entry_t **) calloc(viso->entry_map_size, sizeof(viso_entry_t *)); if (viso->entry_map) { /* Successfully allocated. */ @@ -1476,7 +1509,7 @@ next_entry: viso->all_sectors = viso->metadata_sectors; /* Go through files, assigning sectors to them. */ - cdrom_image_viso_log("VISO: Assigning sectors to files:\n"); + image_viso_log(viso->tf.log, "Assigning sectors to files:\n"); size_t base_factor = viso->sector_size / orig_sector_size; viso_entry_t *prev_entry = viso->root_dir; viso_entry_t **entry_map_p = viso->entry_map; @@ -1521,7 +1554,8 @@ next_entry: size_t size = entry->stats.st_size / viso->sector_size; if (entry->stats.st_size % viso->sector_size) size++; /* round up to the next sector */ - cdrom_image_viso_log("[%08X] %s => %zu + %zu sectors\n", entry, entry->path, viso->all_sectors, size); + image_viso_log(viso->tf.log, "[%08X] %s => %zu + %zu sectors\n", entry, + entry->path, viso->all_sectors, size); /* Allocate sectors to this file. */ viso->all_sectors += size; @@ -1540,9 +1574,10 @@ next_entry: viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp); /* Metadata processing is finished, read it back to memory. */ - cdrom_image_viso_log("VISO: Reading back %zu %zu-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size); + image_viso_log(viso->tf.log, "Reading back %zu %zu-byte sectors of metadata\n", + viso->metadata_sectors, viso->sector_size); viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size); - if (!viso->metadata) + if (viso->metadata == NULL) goto end; fseeko64(viso->tf.fp, 0, SEEK_SET); size_t metadata_size = viso->metadata_sectors * viso->sector_size; @@ -1553,7 +1588,7 @@ next_entry: /* We no longer need the temporary file; close and delete it. */ fclose(viso->tf.fp); viso->tf.fp = NULL; -#ifndef ENABLE_CDROM_IMAGE_VISO_LOG +#ifndef ENABLE_IMAGE_VISO_LOG remove(nvr_path(viso->tf.fn)); #endif @@ -1564,13 +1599,15 @@ end: /* Set the function pointers. */ viso->tf.priv = viso; if (!*error) { - cdrom_image_viso_log("VISO: Initialized\n"); + image_viso_log(viso->tf.log, "Initialized\n"); + viso->tf.read = viso_read; viso->tf.get_length = viso_get_length; viso->tf.close = viso_close; + return &viso->tf; } else { - cdrom_image_viso_log("VISO: Initialization failed\n"); + image_viso_log(viso->tf.log, "Initialization failed\n"); if (data) free(data); viso_close(&viso->tf); diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c deleted file mode 100644 index 13df2d965..000000000 --- a/src/cdrom/cdrom_ioctl.c +++ /dev/null @@ -1,277 +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. - * - * CD-ROM passthrough support. - * - * - * - * Authors: TheCollector1995, , - * Miran Grca, - * - * Copyright 2023 TheCollector1995. - * Copyright 2023 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/path.h> -#include <86box/plat.h> -#include <86box/plat_cdrom.h> -#include <86box/scsi_device.h> -#include <86box/cdrom.h> - -#ifdef ENABLE_CDROM_IOCTL_LOG -int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG; - -void -cdrom_ioctl_log(const char *fmt, ...) -{ - va_list ap; - - if (cdrom_ioctl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define cdrom_ioctl_log(fmt, ...) -#endif - -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) - -static void -ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) -{ - TMSF tmsf; - - plat_cdrom_get_audio_tracks(first, last, &tmsf); -} - -static void -ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t *ti) -{ - TMSF tmsf; - - plat_cdrom_get_audio_track_info(end, track, &ti->number, &tmsf, &ti->attr); - - ti->m = tmsf.min; - ti->s = tmsf.sec; - ti->f = tmsf.fr; -} - -static void -ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) -{ - TMSF rel_pos; - TMSF abs_pos; - - if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) { - const uint32_t trk = plat_cdrom_get_track_start(lba, &subc->attr, &subc->track); - - FRAMES_TO_MSF(lba + 150, &abs_pos.min, &abs_pos.sec, &abs_pos.fr); - - /* Absolute position should be adjusted by 150, not the relative ones. */ - FRAMES_TO_MSF(lba - trk, &rel_pos.min, &rel_pos.sec, &rel_pos.fr); - - subc->index = 1; - } else - plat_cdrom_get_audio_sub(lba, &subc->attr, &subc->track, &subc->index, - &rel_pos, &abs_pos); - - subc->abs_m = abs_pos.min; - subc->abs_s = abs_pos.sec; - subc->abs_f = abs_pos.fr; - - subc->rel_m = rel_pos.min; - subc->rel_s = rel_pos.sec; - subc->rel_f = rel_pos.fr; - - cdrom_ioctl_log("ioctl_get_subchannel(): %02X, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - subc->attr, subc->track, subc->index, subc->abs_m, subc->abs_s, subc->abs_f, subc->rel_m, subc->rel_s, subc->rel_f); -} - -static int -ioctl_get_capacity(UNUSED(cdrom_t *dev)) -{ - int ret; - - ret = plat_cdrom_get_last_block(); - cdrom_ioctl_log("GetCapacity=%x.\n", ret); - return ret; -} - -static int -ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) -{ - int m; - int s; - int f; - - if (dev->cd_status == CD_STATUS_DATA_ONLY) - return 0; - - if (ismsf) { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f) - 150; - } - - /* GetTrack requires LBA. */ - return plat_cdrom_is_track_audio(pos); -} - -static int -ioctl_is_track_pre(UNUSED(cdrom_t *dev), uint32_t lba) -{ - return plat_cdrom_is_track_pre(lba); -} - -static int -ioctl_sector_size(UNUSED(cdrom_t *dev), uint32_t lba) -{ - cdrom_ioctl_log("LBA=%x.\n", lba); - return plat_cdrom_get_sector_size(lba); -} - -static int -ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba) -{ - switch (type) { - case CD_READ_DATA: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n"); - return plat_cdrom_read_sector(b, 0, lba); - case CD_READ_AUDIO: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n"); - return plat_cdrom_read_sector(b, 1, lba); - case CD_READ_RAW: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n"); - return plat_cdrom_read_sector(b, 1, lba); - default: - cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); - break; - } - return 0; -} - -static int -ioctl_track_type(cdrom_t *dev, uint32_t lba) -{ - int ret = 0; - - if (ioctl_is_track_audio(dev, lba, 0)) - ret = CD_TRACK_AUDIO; - - cdrom_ioctl_log("cdrom_ioctl_track_type(): %i\n", ret); - - return ret; -} - -static int -ioctl_ext_medium_changed(cdrom_t *dev) -{ - int ret; - - if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) - ret = 0; - else - ret = plat_cdrom_ext_medium_changed(); - - if (ret == 1) { - dev->cd_status = CD_STATUS_STOPPED; - dev->cdrom_capacity = ioctl_get_capacity(dev); - } else if (ret == -1) - dev->cd_status = CD_STATUS_EMPTY; - - return ret; -} - -static void -ioctl_exit(cdrom_t *dev) -{ - cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path); - dev->cd_status = CD_STATUS_EMPTY; - - plat_cdrom_close(); - - dev->ops = NULL; -} - -static const cdrom_ops_t cdrom_ioctl_ops = { - ioctl_get_tracks, - ioctl_get_track_info, - ioctl_get_subchannel, - ioctl_is_track_pre, - ioctl_sector_size, - ioctl_read_sector, - ioctl_track_type, - ioctl_ext_medium_changed, - ioctl_exit -}; - -static int -cdrom_ioctl_open_abort(cdrom_t *dev) -{ - cdrom_ioctl_close(dev); - dev->ops = NULL; - dev->image_path[0] = 0; - return 1; -} - -int -cdrom_ioctl_open(cdrom_t *dev, const char *drv) -{ - const char *actual_drv = &(drv[8]); - - /* Make sure to not STRCPY if the two are pointing - at the same place. */ - if (drv != dev->image_path) - strcpy(dev->image_path, drv); - - /* Open the image. */ - if (strstr(drv, "ioctl://") != drv) - return cdrom_ioctl_open_abort(dev); - cdrom_ioctl_log("actual_drv = %s\n", actual_drv); - int i = plat_cdrom_set_drive(actual_drv); - if (!i) - return cdrom_ioctl_open_abort(dev); - - /* All good, reset state. */ - dev->cd_status = CD_STATUS_STOPPED; - dev->seek_pos = 0; - dev->cd_buflen = 0; - dev->cdrom_capacity = ioctl_get_capacity(dev); - cdrom_ioctl_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", - dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); - - /* Attach this handler to the drive. */ - dev->ops = &cdrom_ioctl_ops; - - return 0; -} - -void -cdrom_ioctl_close(cdrom_t *dev) -{ - cdrom_ioctl_log("CDROM: ioctl_close(%s)\n", dev->image_path); - - if (dev && dev->ops && dev->ops->exit) - dev->ops->exit(dev); -} - diff --git a/src/cdrom/cdrom_mitsumi.c b/src/cdrom/cdrom_mitsumi.c index 01a9cf047..e27faab94 100644 --- a/src/cdrom/cdrom_mitsumi.c +++ b/src/cdrom/cdrom_mitsumi.c @@ -118,14 +118,6 @@ typedef struct mcd_t { int newstat; } mcd_t; -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#ifdef MSFtoLBA -#undef MSFtoLBA -#endif -#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) - #define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4)) #define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f)) @@ -156,9 +148,9 @@ mitsumi_cdrom_is_ready(const cdrom_t *dev) static void mitsumi_cdrom_reset(mcd_t *dev) { - cdrom_t cdrom; - - dev->stat = mitsumi_cdrom_is_ready(&cdrom) ? (STAT_READY | STAT_CHANGE) : 0; + cdrom_t *cdrom = calloc(1, sizeof(cdrom_t)); + + dev->stat = mitsumi_cdrom_is_ready(cdrom) ? (STAT_READY | STAT_CHANGE) : 0; dev->cmdrd_count = 0; dev->cmdbuf_count = 0; dev->buf_count = 0; @@ -176,12 +168,12 @@ mitsumi_cdrom_reset(mcd_t *dev) static int mitsumi_cdrom_read_sector(mcd_t *dev, int first) { - cdrom_t cdrom; + cdrom_t *cdrom = calloc(1, sizeof(cdrom_t)); uint8_t status; - int ret; + int ret = 0; if (dev->drvmode == DRV_MODE_CDDA) { - status = cdrom_mitsumi_audio_play(&cdrom, dev->readmsf, dev->readcount); + status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount); if (status == 1) return status; else @@ -195,15 +187,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); - if (!ret) + cdrom_stop(cdrom); + ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->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(cdrom->seek_pos + 1); dev->buf_count = dev->dmalen + 1; dev->buf_idx = 0; dev->data = 1; @@ -224,7 +216,7 @@ static uint8_t mitsumi_cdrom_in(uint16_t port, void *priv) { mcd_t *dev = (mcd_t *) priv; - uint8_t ret; + uint8_t ret = 0xff; pclog("Mitsumi CD-ROM IN=%03x\n", port); switch (port & 1) { @@ -259,14 +251,14 @@ mitsumi_cdrom_in(uint16_t port, void *priv) break; } - return 0xff; + return ret; } static void mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) { mcd_t *dev = (mcd_t *) priv; - cdrom_t cdrom; + cdrom_t *cdrom = calloc(1, sizeof(cdrom_t)); pclog("Mitsumi CD-ROM OUT=%03x, val=%02x\n", port, val); switch (port & 1) { @@ -348,19 +340,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(cdrom) ? (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(cdrom) ? (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(cdrom)) { + cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1])); dev->cmdbuf_count = 10; dev->readcount = 0; } else { @@ -369,8 +361,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) } break; case CMD_GET_Q: - if (mitsumi_cdrom_is_ready(&cdrom)) { - cdrom_get_q(&cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC); + if (mitsumi_cdrom_is_ready(cdrom)) { + cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC); dev->cmdbuf_count = 11; dev->readcount = 0; } else { @@ -386,7 +378,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) break; case CMD_STOPCDDA: case CMD_STOP: - cdrom_stop(&cdrom); + cdrom_stop(cdrom); dev->drvmode = DRV_MODE_STOP; dev->cur_toc_track = 0; break; @@ -395,7 +387,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(cdrom)) { dev->readcount = 0; dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ; dev->cmdrd_count = 6; @@ -411,7 +403,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(cdrom); cdrom_eject(0); dev->readcount = 0; break; @@ -440,10 +432,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv) static void * mitsumi_cdrom_init(UNUSED(const device_t *info)) { - mcd_t *dev; - - dev = malloc(sizeof(mcd_t)); - memset(dev, 0x00, sizeof(mcd_t)); + mcd_t *dev = calloc(1, sizeof(mcd_t)); dev->irq = MCD_DEFAULT_IRQ; dev->dma = MCD_DEFAULT_DMA; @@ -470,12 +459,12 @@ mitsumi_cdrom_close(void *priv) const device_t mitsumi_cdrom_device = { .name = "Mitsumi CD-ROM interface", .internal_name = "mcd", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, + .flags = DEVICE_ISA16, + .local = 0, .init = mitsumi_cdrom_init, .close = mitsumi_cdrom_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/82c100.c b/src/chipset/82c100.c index 689234ebb..a9d61b3b9 100644 --- a/src/chipset/82c100.c +++ b/src/chipset/82c100.c @@ -358,8 +358,7 @@ ct_82c100_init(UNUSED(const device_t *info)) { ct_82c100_t *dev; - dev = (ct_82c100_t *) malloc(sizeof(ct_82c100_t)); - memset(dev, 0x00, sizeof(ct_82c100_t)); + dev = (ct_82c100_t *) calloc(1, sizeof(ct_82c100_t)); ct_82c100_reset(dev); @@ -393,7 +392,7 @@ const device_t ct_82c100_device = { .init = ct_82c100_init, .close = ct_82c100_close, .reset = ct_82c100_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 3f7f6e43d..6018dd045 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -9,20 +9,80 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c - ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c ali1409.c headland.c ims8848.c intel_82335.c - compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c - intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c - opti499.c opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c - sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c - sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c - sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c - via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c - umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c) +add_library(chipset OBJECT + 82c100.c + acc2168.c + cs8230.c + ali1429.c + ali1435.c + ali1489.c + ali1531.c + ali1541.c + ali1543.c + ali1621.c + ali6117.c + ali1409.c + headland.c + ims8848.c + intel_82335.c + compaq_386.c + contaq_82c59x.c + cs4031.c + intel_420ex.c + intel_4x0.c + intel_i450kx.c + intel_sio.c + intel_piix.c + ../ioapic.c + neat.c + opti283.c + opti291.c + opti391.c + opti495.c + opti499.c + opti602.c + opti822.c + opti895.c + opti5x7.c + scamp.c + scat.c + sis_85c310.c + sis_85c4xx.c + sis_85c496.c + sis_85c50x.c + sis_5511.c + sis_5571.c + sis_5581.c + sis_5591.c + sis_5600.c + sis_5511_h2p.c + sis_5571_h2p.c + sis_5581_h2p.c + sis_5591_h2p.c + sis_5600_h2p.c + sis_5513_p2i.c + sis_5513_ide.c + sis_5572_usb.c + sis_5595_pmu.c + sis_55xx.c + via_vt82c49x.c + via_vt82c505.c + gc100.c + stpc.c + umc_8886.c + umc_hb4.c + umc_8890.c + via_apollo.c + via_pipc.c + vl82c480.c + wd76c10.c +) if(OLIVETTI) target_sources(chipset PRIVATE olivetti_eva.c) diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 9ce29bdff..dbbdc99f6 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -184,8 +184,7 @@ acc2168_close(void *priv) static void * acc2168_init(UNUSED(const device_t *info)) { - acc2168_t *dev = (acc2168_t *) malloc(sizeof(acc2168_t)); - memset(dev, 0, sizeof(acc2168_t)); + acc2168_t *dev = (acc2168_t *) calloc(1, sizeof(acc2168_t)); device_add(&port_92_device); io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev); @@ -201,7 +200,7 @@ const device_t acc2168_device = { .init = acc2168_init, .close = acc2168_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1409.c b/src/chipset/ali1409.c index 3e4286f80..5009a6505 100644 --- a/src/chipset/ali1409.c +++ b/src/chipset/ali1409.c @@ -40,9 +40,8 @@ #include <86box/fdc.h> #include <86box/smram.h> #include <86box/chipset.h> - +#include <86box/plat_unused.h> - #ifdef ENABLE_ALI1409_LOG int ali1409_do_log = ENABLE_ALI1409_LOG; @@ -161,10 +160,9 @@ ali1409_close(void *priv) } static void * -ali1409_init(const device_t *info) +ali1409_init(UNUSED(const device_t *info)) { - ali1409_t *dev = (ali1409_t *) malloc(sizeof(ali1409_t)); - memset(dev, 0, sizeof(ali1409_t)); + ali1409_t *dev = (ali1409_t *) calloc(1, sizeof(ali1409_t)); dev->cfg_locked = 1; @@ -173,7 +171,7 @@ ali1409_init(const device_t *info) 23h Data Port */ - ali1409_log ("Bus speed: %i",cpu_busspeed); + ali1409_log ("Bus speed: %i", cpu_busspeed); io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev); @@ -191,7 +189,7 @@ const device_t ali1409_device = { .init = ali1409_init, .close = ali1409_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1429.c b/src/chipset/ali1429.c index 34c3e18c2..e2478078f 100644 --- a/src/chipset/ali1429.c +++ b/src/chipset/ali1429.c @@ -331,8 +331,7 @@ ali1429_defaults(ali1429_t *dev) static void * ali1429_init(const device_t *info) { - ali1429_t *dev = (ali1429_t *) malloc(sizeof(ali1429_t)); - memset(dev, 0, sizeof(ali1429_t)); + ali1429_t *dev = (ali1429_t *) calloc(1, sizeof(ali1429_t)); dev->cfg_locked = 1; GREEN = info->local; @@ -358,7 +357,7 @@ const device_t ali1429_device = { .init = ali1429_init, .close = ali1429_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -372,7 +371,7 @@ const device_t ali1429g_device = { .init = ali1429_init, .close = ali1429_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1435.c b/src/chipset/ali1435.c index 9476d2b45..ff096ac55 100644 --- a/src/chipset/ali1435.c +++ b/src/chipset/ali1435.c @@ -282,8 +282,7 @@ ali1435_close(void *priv) static void * ali1435_init(UNUSED(const device_t *info)) { - ali1435_t *dev = (ali1435_t *) malloc(sizeof(ali1435_t)); - memset(dev, 0, sizeof(ali1435_t)); + ali1435_t *dev = (ali1435_t *) calloc(1, sizeof(ali1435_t)); dev->cfg_locked = 1; @@ -308,7 +307,7 @@ const device_t ali1435_device = { .init = ali1435_init, .close = ali1435_close, .reset = ali1435_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 3550f1da6..fc51bbed2 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -470,8 +470,7 @@ ali1489_close(void *priv) static void * ali1489_init(UNUSED(const device_t *info)) { - ali1489_t *dev = (ali1489_t *) malloc(sizeof(ali1489_t)); - memset(dev, 0, sizeof(ali1489_t)); + ali1489_t *dev = (ali1489_t *) calloc(1, sizeof(ali1489_t)); /* M1487/M1489 22h Index Port @@ -499,7 +498,7 @@ const device_t ali1489_device = { .init = ali1489_init, .close = ali1489_close, .reset = ali1489_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 9eb75f7cd..e765e6d45 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -225,12 +225,8 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) ali1531_shadow_recalc(val, dev); break; - case 0x50: - case 0x51: - case 0x52: - case 0x54: - case 0x55: - case 0x56: + case 0x50 ... 0x52: + case 0x54 ... 0x56: dev->pci_conf[addr] = val; break; @@ -247,8 +243,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x86; break; - case 0x59: - case 0x5a: + case 0x59 ... 0x5a: case 0x5c: dev->pci_conf[addr] = val; break; @@ -270,8 +265,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1); break; - case 0x70: - case 0x71: + case 0x70 ... 0x71: dev->pci_conf[addr] = val; break; @@ -283,8 +277,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0x2b; break; - case 0x76: - case 0x77: + case 0x76 ... 0x77: dev->pci_conf[addr] = val; break; @@ -376,8 +369,7 @@ ali1531_close(void *priv) static void * ali1531_init(UNUSED(const device_t *info)) { - ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t)); - memset(dev, 0, sizeof(ali1531_t)); + ali1531_t *dev = (ali1531_t *) calloc(1, sizeof(ali1531_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot); @@ -396,7 +388,7 @@ const device_t ali1531_device = { .init = ali1531_init, .close = ali1531_close, .reset = ali1531_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c index d57ef51e7..eed6ddbc5 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -643,8 +643,7 @@ ali1541_close(void *priv) static void * ali1541_init(UNUSED(const device_t *info)) { - ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t)); - memset(dev, 0, sizeof(ali1541_t)); + ali1541_t *dev = (ali1541_t *) calloc(1, sizeof(ali1541_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot); @@ -665,7 +664,7 @@ const device_t ali1541_device = { .init = ali1541_init, .close = ali1541_close, .reset = ali1541_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index f35ec7590..69a8990e9 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -1599,8 +1599,7 @@ ali1543_close(void *priv) static void * ali1543_init(const device_t *info) { - ali1543_t *dev = (ali1543_t *) malloc(sizeof(ali1543_t)); - memset(dev, 0, sizeof(ali1543_t)); + ali1543_t *dev = (ali1543_t *) calloc(1, sizeof(ali1543_t)); /* Device 02: M1533 Southbridge */ pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot); @@ -1673,7 +1672,7 @@ const device_t ali1543_device = { .init = ali1543_init, .close = ali1543_close, .reset = ali1543_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1687,7 +1686,7 @@ const device_t ali1543c_device = { .init = ali1543_init, .close = ali1543_close, .reset = ali1543_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index 6194dce19..d44c0f5a9 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -669,8 +669,7 @@ ali1621_close(void *priv) static void * ali1621_init(UNUSED(const device_t *info)) { - ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t)); - memset(dev, 0, sizeof(ali1621_t)); + ali1621_t *dev = (ali1621_t *) calloc(1, sizeof(ali1621_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot); @@ -692,7 +691,7 @@ const device_t ali1621_device = { .init = ali1621_init, .close = ali1621_close, .reset = ali1621_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index cc2e465a2..707b528b2 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -466,8 +466,7 @@ ali6117_init(const device_t *info) ali6117_log("ALI6117: init()\n"); - ali6117_t *dev = (ali6117_t *) malloc(sizeof(ali6117_t)); - memset(dev, 0, sizeof(ali6117_t)); + ali6117_t *dev = (ali6117_t *) calloc(1, sizeof(ali6117_t)); dev->local = info->local; @@ -494,12 +493,12 @@ ali6117_init(const device_t *info) const device_t ali1217_device = { .name = "ALi M1217", .internal_name = "ali1217", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x8, .init = ali6117_init, .close = ali6117_close, .reset = ali6117_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -508,12 +507,12 @@ const device_t ali1217_device = { const device_t ali6117d_device = { .name = "ALi M6117D", .internal_name = "ali6117d", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x2, .init = ali6117_init, .close = ali6117_close, .reset = ali6117_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/compaq_386.c b/src/chipset/compaq_386.c index 8c241e087..bc81c5472 100644 --- a/src/chipset/compaq_386.c +++ b/src/chipset/compaq_386.c @@ -772,7 +772,7 @@ const device_t compaq_386_device = { .init = compaq_386_init, .close = compaq_386_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -786,7 +786,7 @@ const device_t compaq_genoa_device = { .init = compaq_genoa_init, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/contaq_82c59x.c b/src/chipset/contaq_82c59x.c index 5c2910227..1981fd11c 100644 --- a/src/chipset/contaq_82c59x.c +++ b/src/chipset/contaq_82c59x.c @@ -322,8 +322,7 @@ contaq_82c59x_close(void *priv) static void * contaq_82c59x_init(const device_t *info) { - contaq_82c59x_t *dev = (contaq_82c59x_t *) malloc(sizeof(contaq_82c59x_t)); - memset(dev, 0x00, sizeof(contaq_82c59x_t)); + contaq_82c59x_t *dev = (contaq_82c59x_t *) calloc(1, sizeof(contaq_82c59x_t)); dev->green = info->local; @@ -359,7 +358,7 @@ const device_t contaq_82c596a_device = { .init = contaq_82c59x_init, .close = contaq_82c59x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -373,7 +372,7 @@ const device_t contaq_82c597_device = { .init = contaq_82c59x_init, .close = contaq_82c59x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/cs4031.c b/src/chipset/cs4031.c index fb439ec3a..cfec9ad30 100644 --- a/src/chipset/cs4031.c +++ b/src/chipset/cs4031.c @@ -164,8 +164,7 @@ cs4031_close(void *priv) static void * cs4031_init(UNUSED(const device_t *info)) { - cs4031_t *dev = (cs4031_t *) malloc(sizeof(cs4031_t)); - memset(dev, 0, sizeof(cs4031_t)); + cs4031_t *dev = (cs4031_t *) calloc(1, sizeof(cs4031_t)); dev->port_92 = device_add(&port_92_device); @@ -185,7 +184,7 @@ const device_t cs4031_device = { .init = cs4031_init, .close = cs4031_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/cs8230.c b/src/chipset/cs8230.c index 93a7f1bba..0374a44a6 100644 --- a/src/chipset/cs8230.c +++ b/src/chipset/cs8230.c @@ -157,8 +157,7 @@ cs8230_close(void *priv) static void * cs8230_init(UNUSED(const device_t *info)) { - cs8230_t *cs8230 = (cs8230_t *) malloc(sizeof(cs8230_t)); - memset(cs8230, 0, sizeof(cs8230_t)); + cs8230_t *cs8230 = (cs8230_t *) calloc(1, sizeof(cs8230_t)); io_sethandler(0x0022, 0x0002, cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, cs8230); @@ -178,7 +177,7 @@ const device_t cs8230_device = { .init = cs8230_init, .close = cs8230_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/et6000.c b/src/chipset/et6000.c index f2cffd7f7..14ebf852e 100644 --- a/src/chipset/et6000.c +++ b/src/chipset/et6000.c @@ -137,8 +137,7 @@ et6000_close(void *priv) static void * et6000_init(UNUSED(const device_t *info)) { - et6000_t *dev = (et6000_t *) malloc(sizeof(et6000_t)); - memset(dev, 0, sizeof(et6000_t)); + et6000_t *dev = (et6000_t *) calloc(1, sizeof(et6000_t)); /* Port 92h */ device_add(&port_92_device); @@ -162,7 +161,7 @@ const device_t et6000_device = { .init = et6000_init, .close = et6000_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/gc100.c b/src/chipset/gc100.c index 0b4717903..23455b952 100644 --- a/src/chipset/gc100.c +++ b/src/chipset/gc100.c @@ -208,8 +208,7 @@ gc100_close(void *priv) static void * gc100_init(const device_t *info) { - gc100_t *dev = (gc100_t *) malloc(sizeof(gc100_t)); - memset(dev, 0, sizeof(gc100_t)); + gc100_t *dev = (gc100_t *) calloc(1, sizeof(gc100_t)); dev->reg[0x2] = 0xff; dev->reg[0x3] = 0x0; @@ -238,7 +237,7 @@ const device_t gc100_device = { .init = gc100_init, .close = gc100_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -252,7 +251,7 @@ const device_t gc100a_device = { .init = gc100_init, .close = gc100_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/headland.c b/src/chipset/headland.c index db5922470..1172d105d 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -594,8 +594,7 @@ headland_init(const device_t *info) headland_t *dev; int ht386 = 0; - dev = (headland_t *) malloc(sizeof(headland_t)); - memset(dev, 0x00, sizeof(headland_t)); + dev = (headland_t *) calloc(1, sizeof(headland_t)); dev->has_cri = (info->local & HEADLAND_HAS_CRI); dev->has_sleep = (info->local & HEADLAND_HAS_SLEEP); @@ -699,7 +698,7 @@ const device_t headland_gc10x_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -713,7 +712,7 @@ const device_t headland_gc113_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -727,7 +726,7 @@ const device_t headland_ht18a_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -741,7 +740,7 @@ const device_t headland_ht18b_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -755,7 +754,7 @@ const device_t headland_ht18c_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -769,7 +768,7 @@ const device_t headland_ht21c_d_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -783,7 +782,7 @@ const device_t headland_ht21e_device = { .init = headland_init, .close = headland_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index 3e86a44e1..094ee31f8 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -381,8 +381,7 @@ ims8848_close(void *priv) static void * ims8848_init(UNUSED(const device_t *info)) { - ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t)); - memset(dev, 0, sizeof(ims8848_t)); + ims8848_t *dev = (ims8848_t *) calloc(1, sizeof(ims8848_t)); device_add(&port_92_device); @@ -416,7 +415,7 @@ const device_t ims8848_device = { .init = ims8848_init, .close = ims8848_close, .reset = ims8848_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index 34335d53c..662fd0509 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -533,8 +533,7 @@ i420ex_speed_changed(void *priv) static void * i420ex_init(const device_t *info) { - i420ex_t *dev = (i420ex_t *) malloc(sizeof(i420ex_t)); - memset(dev, 0, sizeof(i420ex_t)); + i420ex_t *dev = (i420ex_t *) calloc(1, sizeof(i420ex_t)); dev->smram = smram_add(); @@ -579,7 +578,7 @@ const device_t i420ex_device = { .init = i420ex_init, .close = i420ex_close, .reset = i420ex_reset, - { .available = NULL }, + .available = NULL, .speed_changed = i420ex_speed_changed, .force_redraw = NULL, .config = NULL @@ -593,7 +592,7 @@ const device_t i420ex_ide_device = { .init = i420ex_init, .close = i420ex_close, .reset = i420ex_reset, - { .available = NULL }, + .available = NULL, .speed_changed = i420ex_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 2f6afa940..f9d6af150 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -1608,11 +1608,9 @@ i4x0_close(void *priv) static void * i4x0_init(const device_t *info) { - i4x0_t *dev = (i4x0_t *) malloc(sizeof(i4x0_t)); + i4x0_t *dev = (i4x0_t *) calloc(1, sizeof(i4x0_t)); uint8_t *regs; - memset(dev, 0, sizeof(i4x0_t)); - dev->smram_low = smram_add(); dev->smram_high = smram_add(); @@ -1967,7 +1965,7 @@ const device_t i420tx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1981,7 +1979,7 @@ const device_t i420zx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1995,7 +1993,7 @@ const device_t i430lx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2009,7 +2007,7 @@ const device_t i430nx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2023,7 +2021,7 @@ const device_t i430fx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2037,7 +2035,7 @@ const device_t i430fx_rev02_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2051,7 +2049,7 @@ const device_t i430hx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2065,7 +2063,7 @@ const device_t i430vx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2079,7 +2077,7 @@ const device_t i430tx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2093,7 +2091,7 @@ const device_t i440fx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2107,7 +2105,7 @@ const device_t i440lx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2121,7 +2119,7 @@ const device_t i440ex_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2135,7 +2133,7 @@ const device_t i440bx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2149,7 +2147,7 @@ const device_t i440bx_no_agp_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2163,7 +2161,7 @@ const device_t i440gx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2177,7 +2175,7 @@ const device_t i440zx_device = { .init = i4x0_init, .close = i4x0_close, .reset = i4x0_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/intel_82335.c b/src/chipset/intel_82335.c index da0cc30f6..bd53e0d05 100644 --- a/src/chipset/intel_82335.c +++ b/src/chipset/intel_82335.c @@ -171,8 +171,7 @@ intel_82335_close(void *priv) static void * intel_82335_init(UNUSED(const device_t *info)) { - intel_82335_t *dev = (intel_82335_t *) malloc(sizeof(intel_82335_t)); - memset(dev, 0, sizeof(intel_82335_t)); + intel_82335_t *dev = (intel_82335_t *) calloc(1, sizeof(intel_82335_t)); memset(dev->regs, 0, sizeof(dev->regs)); @@ -209,7 +208,7 @@ const device_t intel_82335_device = { .init = intel_82335_init, .close = intel_82335_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 2f6547309..34cc6a62f 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -799,8 +799,8 @@ i450kx_close(void *priv) static void * i450kx_init(UNUSED(const device_t *info)) { - i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t)); - memset(dev, 0, sizeof(i450kx_t)); + i450kx_t *dev = (i450kx_t *) calloc(1, sizeof(i450kx_t)); + pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */ pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */ @@ -824,7 +824,7 @@ const device_t i450kx_device = { .init = i450kx_init, .close = i450kx_close, .reset = i450kx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 1f95c28b3..6969d3274 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -599,9 +599,9 @@ piix_write(int func, int addr, uint8_t val, void *priv) pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf); if (dev->type == 3) { if (val & 0x20) - sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); - else sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY); + else + sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0); } piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled"); } @@ -1538,8 +1538,7 @@ piix_speed_changed(void *priv) static void * piix_init(const device_t *info) { - piix_t *dev = (piix_t *) malloc(sizeof(piix_t)); - memset(dev, 0, sizeof(piix_t)); + piix_t *dev = (piix_t *) calloc(1, sizeof(piix_t)); dev->type = info->local & 0x0f; /* If (dev->type == 4) and (dev->rev & 0x08), then this is PIIX4E. */ @@ -1674,7 +1673,7 @@ const device_t piix_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1688,7 +1687,7 @@ const device_t piix_no_mirq_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1702,7 +1701,7 @@ const device_t piix_rev02_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1716,7 +1715,7 @@ const device_t piix3_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1730,7 +1729,7 @@ const device_t piix3_ioapic_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1744,7 +1743,7 @@ const device_t piix4_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1758,7 +1757,7 @@ const device_t piix4e_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL @@ -1772,7 +1771,7 @@ const device_t slc90e66_device = { .init = piix_init, .close = piix_close, .reset = piix_reset, - { .available = NULL }, + .available = NULL, .speed_changed = piix_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 03a292da8..9b6d28ab1 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -508,8 +508,7 @@ sio_speed_changed(void *priv) static void * sio_init(const device_t *info) { - sio_t *dev = (sio_t *) malloc(sizeof(sio_t)); - memset(dev, 0, sizeof(sio_t)); + sio_t *dev = (sio_t *) calloc(1, sizeof(sio_t)); pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot); @@ -568,7 +567,7 @@ const device_t sio_device = { .init = sio_init, .close = sio_close, .reset = sio_reset, - { .available = NULL }, + .available = NULL, .speed_changed = sio_speed_changed, .force_redraw = NULL, .config = NULL @@ -582,7 +581,7 @@ const device_t sio_zb_device = { .init = sio_init, .close = sio_close, .reset = sio_reset, - { .available = NULL }, + .available = NULL, .speed_changed = sio_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/neat.c b/src/chipset/neat.c index 97c4b8f1a..069fa87e4 100644 --- a/src/chipset/neat.c +++ b/src/chipset/neat.c @@ -37,6 +37,9 @@ #define EMS_MAXPAGE 4 #define EMS_PGSIZE 16384 +#define EMS_PGMASK 16383 + +#define REG_MASK 0x0f /* CS8221 82C211 controller registers. */ #define REG_RA0 0x60 /* PROCCLK selector */ @@ -194,37 +197,54 @@ #define RB10_P0EXT 0xc0 /* page 0 extension */ #define RB10_P0EXT_SH 6 -#define REG_RB11 0x6f /* Miscellaneous */ -#define RB11_MASK 0xe6 /* 111R R11R */ -#define RB11_GA20 0x02 /* gate for A20 */ -#define RB11_RASTMO 0x04 /* enable RAS timeout counter */ -#define RB11_EMSLEN 0xe0 /* EMS memory chunk size */ -#define RB11_EMSLEN_SH 5 +#define REG_RB12 0x6f /* Miscellaneous */ +#define RB12_MASK 0xe6 /* 111R R11R */ +#define RB12_GA20 0x02 /* gate for A20 */ +#define RB12_RASTMO 0x04 /* enable RAS timeout counter */ +#define RB12_EMSLEN 0xe0 /* EMS memory chunk size */ +#define RB12_EMSLEN_SH 5 -typedef struct emspage_t { - int8_t enabled; /* 1=ENABLED */ +#define MEM_FLAG_REMAP 0x10 +#define MEM_FLAG_EMS 0x08 +#define MEM_FLAG_ROMCS 0x04 +#define MEM_FLAG_READ 0x02 +#define MEM_FLAG_WRITE 0x01 +#define MEM_FMASK_REMAP 0x10 +#define MEM_FMASK_EMS 0x08 +#define MEM_FMASK_SHADOW 0x07 + +typedef struct ram_page_t { + int8_t enabled; /* 1=ENABLED */ char pad; - uint16_t page; /* selected page in EMS block */ - uint32_t start; /* start of EMS in RAM */ - uint8_t *addr; /* start addr in EMS RAM */ - mem_mapping_t mapping; /* mapping entry for page */ -} emspage_t; + uint32_t phys_base; + uint32_t virt_base; + mem_mapping_t mapping; /* mapping entry for page */ +} ram_page_t; typedef struct neat_t { - uint8_t regs[128]; /* all the CS8221 registers */ - uint8_t indx; /* programmed index into registers */ + uint8_t mem_flags[32]; + uint8_t regs[128]; /* all the CS8221 registers */ + uint8_t indx; /* programmed index into registers */ - char pad; + char pad; - uint16_t ems_base; /* configured base address */ - uint16_t ems_oldbase; - uint32_t ems_frame; /* configured frame address */ - uint32_t ems_oldframe; - uint16_t ems_size; /* EMS size in KB */ - uint16_t ems_pages; /* EMS size in pages */ - emspage_t ems[EMS_MAXPAGE]; /* EMS page registers */ + uint16_t ems_base; /* configured base address */ + uint32_t ems_frame; /* configured frame address */ + uint16_t ems_size; /* EMS size in KB */ + uint16_t ems_pages; /* EMS size in pages */ + + uint32_t remap_base; + + ram_page_t ems[EMS_MAXPAGE]; /* EMS page registers */ + ram_page_t shadow[32]; /* Shadow RAM pages */ } neat_t; +static uint8_t defaults[16] = { 0x0a, 0x45, 0xfc, 0x00, 0x00, 0xfe, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x63, 0x10, 0x00, 0x00, 0x12 }; + +static uint8_t masks[4] = { RB10_P0EXT, RB10_P1EXT, RB10_P2EXT, RB10_P3EXT }; +static uint8_t shifts[4] = { RB10_P0EXT_SH, RB10_P1EXT_SH, RB10_P2EXT_SH, RB10_P3EXT_SH }; + #ifdef ENABLE_NEAT_LOG int neat_do_log = ENABLE_NEAT_LOG; @@ -247,12 +267,19 @@ neat_log(const char *fmt, ...) static uint8_t ems_readb(uint32_t addr, void *priv) { - neat_t *dev = (neat_t *) priv; - uint8_t ret = 0xff; + ram_page_t *dev = (ram_page_t *) priv; + uint8_t ret = 0xff; +#ifdef ENABLE_NEAT_LOG + uint32_t old = addr; +#endif /* Grab the data. */ - ret = *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)); + addr = addr - dev->virt_base + dev->phys_base; + if (addr < (mem_size << 10)) + ret = *(uint8_t *) &(ram[addr]); + + neat_log("[R08] %08X -> %08X (%08X): ret = %02X\n", old, addr, (mem_size << 10), ret); return ret; } @@ -260,12 +287,19 @@ ems_readb(uint32_t addr, void *priv) static uint16_t ems_readw(uint32_t addr, void *priv) { - neat_t *dev = (neat_t *) priv; - uint16_t ret = 0xffff; + ram_page_t *dev = (ram_page_t *) priv; + uint16_t ret = 0xffff; +#ifdef ENABLE_NEAT_LOG + uint32_t old = addr; +#endif /* Grab the data. */ - ret = *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)); + addr = addr - dev->virt_base + dev->phys_base; + if (addr < (mem_size << 10)) + ret = *(uint16_t *) &(ram[addr]); + + neat_log("[R16] %08X -> %08X (%08X): ret = %04X\n", old, addr, (mem_size << 10), ret); return ret; } @@ -273,40 +307,144 @@ ems_readw(uint32_t addr, void *priv) static void ems_writeb(uint32_t addr, uint8_t val, void *priv) { - neat_t *dev = (neat_t *) priv; + ram_page_t *dev = (ram_page_t *) priv; +#ifdef ENABLE_NEAT_LOG + uint32_t old = addr; +#endif /* Write the data. */ - *(uint8_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val; + addr = addr - dev->virt_base + dev->phys_base; + neat_log("[W08] %08X -> %08X (%08X): val = %02X\n", old, addr, (mem_size << 10), val); + + if (addr < (mem_size << 10)) + *(uint8_t *) &(ram[addr]) = val; } /* Write one word to paged RAM. */ static void ems_writew(uint32_t addr, uint16_t val, void *priv) { - neat_t *dev = (neat_t *) priv; + ram_page_t *dev = (ram_page_t *) priv; +#ifdef ENABLE_NEAT_LOG + uint32_t old = addr; +#endif /* Write the data. */ - *(uint16_t *) (dev->ems[(addr & 0xffff) >> 14].addr + (addr & 0x3fff)) = val; + addr = addr - dev->virt_base + dev->phys_base; + neat_log("[W16] %08X -> %08X (%08X): val = %04X\n", old, addr, (mem_size << 10), val); + + if (addr < (mem_size << 10)) + *(uint16_t *) &(ram[addr]) = val; +} + +static void +neat_mem_update_state(neat_t *dev, uint32_t addr, uint32_t size, uint8_t new_flags, uint8_t mask) +{ + if ((addr >= 0x00080000) && (addr < 0x00100000) && + ((new_flags ^ dev->mem_flags[(addr - 0x00080000) / EMS_PGSIZE]) & mask)) { + dev->mem_flags[(addr - 0x00080000) / EMS_PGSIZE] &= ~mask; + dev->mem_flags[(addr - 0x00080000) / EMS_PGSIZE] |= new_flags; + + new_flags = dev->mem_flags[(addr - 0x00080000) / EMS_PGSIZE]; + + if (new_flags & MEM_FLAG_ROMCS) { + neat_log("neat_mem_update_state(): %08X-%08X: %02X (ROMCS)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_ROMCS | MEM_WRITE_ROMCS); + } else if (new_flags & MEM_FLAG_REMAP) { + neat_log("neat_mem_update_state(): %08X-%08X: %02X (REMAP)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } else if (new_flags & MEM_FLAG_EMS) { + neat_log("neat_mem_update_state(): %08X-%08X: %02X (EMS)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else switch (new_flags & (MEM_FLAG_READ | MEM_FLAG_WRITE)) { + case 0: + neat_log("neat_mem_update_state(): %08X-%08X: %02X (RE | WE)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + neat_log("neat_mem_update_state(): %08X-%08X: %02X (RE | WI)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + neat_log("neat_mem_update_state(): %08X-%08X: %02X (RI | WE)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + neat_log("neat_mem_update_state(): %08X-%08X: %02X (RI | WI)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + default: + break; + } + } + + flushmmucache_nopc(); +} + +static void +shadow_recalc(neat_t *dev) +{ + for (uint8_t i = 8; i < 32; i++) { + int romcs = 0; + int write = 1; + int shadow_reg = REG_RB3 + ((i - 8) >> 3); + int shadow_bit = i & 7; + int mem_flags; + int read; + + if (i >= 16) { + int rb1_romcs_bit = 7 - (i >> 2); + int rb1_write_bit = rb1_romcs_bit + 4; + + romcs = !(dev->regs[REG_RB1] & (1 << rb1_romcs_bit)); + write = !(dev->regs[REG_RB1] & (1 << rb1_write_bit)); + neat_log("Shadow %08X-%08X: [%02X, %02X] %02X:%02X, %02X, %02X\n", + dev->shadow[i].virt_base, dev->shadow[i].virt_base + EMS_PGSIZE - 1, + dev->regs[REG_RB1], dev->regs[shadow_reg], + shadow_reg, shadow_bit, + rb1_romcs_bit, rb1_write_bit); + } else { + shadow_bit ^= 4; + neat_log("Shadow %08X-%08X: [--, %02X] %02X:%02X, shadow bit ^= 4\n", + dev->shadow[i].virt_base, dev->shadow[i].virt_base + EMS_PGSIZE - 1, + dev->regs[shadow_reg], + shadow_reg, shadow_bit); + } + + read = dev->regs[shadow_reg] & (1 << shadow_bit); + write = write && read; + + mem_flags = romcs ? MEM_FLAG_ROMCS : 0x00; + mem_flags |= read ? MEM_FLAG_READ : 0x00; + mem_flags |= write ? MEM_FLAG_WRITE : 0x00; + + if ((mem_flags > 0x00) && !(mem_flags & MEM_FLAG_ROMCS)) + mem_mapping_set_addr(&(dev->shadow[i].mapping), dev->shadow[i].virt_base, EMS_PGSIZE); + else + mem_mapping_disable(&(dev->shadow[i].mapping)); + + neat_mem_update_state(dev, dev->shadow[i].virt_base, EMS_PGSIZE, mem_flags, MEM_FMASK_SHADOW); + } } /* Re-calculate the active-page physical address. */ static void -ems_recalc(neat_t *dev, emspage_t *ems) +ems_recalc(neat_t *dev, ram_page_t *ems) { - if (ems->page >= dev->ems_pages) { - /* That page does not exist. */ - ems->enabled = 0; - } + uint32_t page = ems->phys_base / EMS_PGSIZE; - /* Pre-calculate the page address in EMS RAM. */ - ems->addr = ram + ems->start + (ems->page * EMS_PGSIZE); + neat_log("ems_recalc(): %08X, %04X, %04X\n", ems->virt_base, page, dev->ems_pages); + + if ((dev->regs[REG_RB7] & RB7_EMSEN) && ems->enabled && (page < dev->ems_pages)) { + neat_log("ems_recalc(): %08X-%08X -> %08X-%08X\n", + ems->virt_base, ems->virt_base + EMS_PGSIZE - 1, + ems->phys_base, ems->phys_base + EMS_PGSIZE - 1); + mem_mapping_set_addr(&ems->mapping, ems->virt_base, EMS_PGSIZE); - if (ems->enabled) { /* Update the EMS RAM address for this page. */ - mem_mapping_set_exec(&ems->mapping, ems->addr); + mem_mapping_set_exec(&ems->mapping, ram + ems->phys_base); - /* Enable this page. */ - mem_mapping_enable(&ems->mapping); + neat_mem_update_state(dev, ems->virt_base, EMS_PGSIZE, MEM_FLAG_EMS, MEM_FMASK_EMS); #if NEAT_DEBUG > 1 neat_log("NEAT EMS: page %d set to %08lx, %sabled)\n", @@ -315,15 +453,21 @@ ems_recalc(neat_t *dev, emspage_t *ems) } else { /* Disable this page. */ mem_mapping_disable(&ems->mapping); + + neat_mem_update_state(dev, ems->virt_base, EMS_PGSIZE, 0x00, MEM_FMASK_EMS); } } static void ems_write(uint16_t port, uint8_t val, void *priv) { - neat_t *dev = (neat_t *) priv; - emspage_t *ems; - int vpage; + neat_t *dev = (neat_t *) priv; + ram_page_t *ems; + int vpage; + int8_t old_enabled; + uint32_t old_phys_base; + int8_t new_enabled; + uint32_t new_phys_base; #if NEAT_DEBUG > 1 neat_log("NEAT: ems_write(%04x, %02x)\n", port, val); @@ -333,13 +477,29 @@ ems_write(uint16_t port, uint8_t val, void *priv) vpage = (port / EMS_PGSIZE); ems = &dev->ems[vpage]; + neat_log("Port: %04X, val: %02X\n", port, val); + switch (port & 0x000f) { case 0x0008: case 0x0009: - ems->enabled = !!(val & 0x80); - ems->page &= 0x0180; /* clear lower bits */ - ems->page |= (val & 0x7f); /* add new bits */ - ems_recalc(dev, ems); + old_enabled = ems->enabled; + old_phys_base = ems->phys_base; + new_enabled = !!(val & 0x80); + new_phys_base = (ems->phys_base & 0xffe00000) | ((val & 0x7f) * EMS_PGSIZE); + + if ((old_enabled != new_enabled) || (old_phys_base != new_phys_base)) { + if (old_enabled && (old_enabled == new_enabled)) { + ems->enabled = 0; + ems_recalc(dev, ems); + } + + ems->enabled = !!(val & 0x80); + + if (old_phys_base != new_phys_base) + ems->phys_base = (ems->phys_base & 0xffe00000) | ((val & 0x7f) * EMS_PGSIZE); + + ems_recalc(dev, ems); + } break; default: break; @@ -358,7 +518,7 @@ ems_read(uint16_t port, void *priv) switch (port & 0x000f) { case 0x0008: /* page number register */ - ret = dev->ems[vpage].page & 0x7f; + ret = (dev->ems[vpage].phys_base / EMS_PGSIZE) & 0x7f; if (dev->ems[vpage].enabled) ret |= 0x80; break; @@ -366,6 +526,8 @@ ems_read(uint16_t port, void *priv) break; } + neat_log("Port: %04X, ret: %02X\n", port, ret); + #if NEAT_DEBUG > 1 neat_log("NEAT: ems_read(%04x) = %02x\n", port, ret); #endif @@ -373,68 +535,85 @@ ems_read(uint16_t port, void *priv) return ret; } -/* Initialize the EMS module. */ static void -ems_init(neat_t *dev, int en) +ems_recalc_all(neat_t *dev) { - uint8_t j; + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) + ems_recalc(dev, &(dev->ems[i])); +} - /* Remove if needed. */ - if (!en) { - if (dev->ems_base > 0) - for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { - /* Disable for now. */ - mem_mapping_disable(&dev->ems[i].mapping); +static void +ems_update_virt_base(neat_t *dev) +{ + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) + dev->ems[i].virt_base = dev->ems_frame + (i * EMS_PGSIZE); +} - /* Remove I/O handler. */ - io_removehandler(dev->ems_base + (i * EMS_PGSIZE), 2, - ems_read, NULL, NULL, ems_write, NULL, NULL, dev); - } - -#ifdef ENABLE_NEAT_LOG - neat_log("NEAT: EMS disabled\n"); -#endif - - return; - } - - /* Get configured I/O address. */ - j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH; - dev->ems_base = 0x0208 + (0x10 * j); - - /* Get configured frame address. */ - j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH; - dev->ems_frame = 0xC0000 + (EMS_PGSIZE * j); - - /* - * For each supported page (we can have a maximum of 4), - * create, initialize and disable the mappings, and set - * up the I/O control handler. - */ +static void +ems_remove_handlers(neat_t *dev) +{ for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { - /* Create and initialize a page mapping. */ - mem_mapping_add(&dev->ems[i].mapping, - dev->ems_frame + (EMS_PGSIZE * i), EMS_PGSIZE, - ems_readb, ems_readw, NULL, - ems_writeb, ems_writew, NULL, - ram, MEM_MAPPING_EXTERNAL, - dev); - - /* Disable for now. */ - mem_mapping_disable(&dev->ems[i].mapping); + neat_log("Removing I/O handler at %04X-%04X\n", + dev->ems_base + (i * EMS_PGSIZE), dev->ems_base + (i * EMS_PGSIZE) + 1); + /* Clean up any previous I/O port handler. */ + io_removehandler(dev->ems_base + (i * EMS_PGSIZE), 2, + ems_read, NULL, NULL, ems_write, NULL, NULL, dev); + } +} +static void +ems_set_handlers(neat_t *dev) +{ + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { + neat_log("Setting up I/O handler at %04X-%04X\n", + dev->ems_base + (i * EMS_PGSIZE), dev->ems_base + (i * EMS_PGSIZE) + 1); /* Set up an I/O port handler. */ io_sethandler(dev->ems_base + (i * EMS_PGSIZE), 2, ems_read, NULL, NULL, ems_write, NULL, NULL, dev); - - /* - * TODO: update the 'high_mem' mapping to reflect that we now - * have NN MB less extended memory available.. - */ } - neat_log("NEAT: EMS enabled, I/O=%04xH, Frame=%05XH\n", - dev->ems_base, dev->ems_frame); + ems_recalc_all(dev); +} + +static void +remap_update_states(neat_t *dev, uint8_t flag) +{ + for (uint8_t i = 0; i < 24; i++) + neat_mem_update_state(dev, 0x000a0000 + (i * EMS_PGSIZE), EMS_PGSIZE, flag, MEM_FMASK_REMAP); +} + +static void +remap_update(neat_t *dev, uint8_t val) +{ + if (dev->regs[REG_RB7] & RB7_UMAREL) { + mem_remap_top_ex_nomid(0, (dev->remap_base >= 1024) ? dev->remap_base : 1024); + + remap_update_states(dev, 0x00); + neat_log("0 kB at %08X\n", ((dev->remap_base >= 1024) ? dev->remap_base : 1024) << 10); + } + + if (val & RB7_EMSEN) + dev->remap_base = mem_size - dev->ems_size; + else + dev->remap_base = mem_size; + neat_log("Total contiguous memory now: %i kB\n", dev->remap_base); + + if (dev->remap_base >= 640) + mem_mapping_set_addr(&ram_low_mapping, 0x00000000, 0x000a0000); + else + mem_mapping_set_addr(&ram_low_mapping, 0x00000000, dev->remap_base << 10); + + if (dev->remap_base > 1024) + mem_mapping_set_addr(&ram_high_mapping, 0x00100000, (dev->remap_base << 10) - 0x00100000); + else + mem_mapping_disable(&ram_high_mapping); + + if (val & RB7_UMAREL) { + mem_remap_top_ex_nomid(384, (dev->remap_base >= 1024) ? dev->remap_base : 1024); + + remap_update_states(dev, MEM_FLAG_REMAP); + neat_log("384 kB at %08X\n", ((dev->remap_base >= 1024) ? dev->remap_base : 1024) << 10); + } } static void @@ -442,6 +621,7 @@ neat_write(uint16_t port, uint8_t val, void *priv) { neat_t *dev = (neat_t *) priv; uint8_t xval; + uint8_t j; uint8_t *reg; int i; @@ -461,6 +641,8 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RA0: val &= RA0_MASK; *reg = (*reg & ~RA0_MASK) | val | (RA0_REV_ID << RA0_REV_SH); + if ((xval & 0x20) && (val & 0x20)) + outb(0x64, 0xfe); #if NEAT_DEBUG > 1 neat_log("NEAT: RA0=%02x(%02x)\n", val, *reg); #endif @@ -493,6 +675,7 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RB1: val &= RB1_MASK; *reg = (*reg & ~RB1_MASK) | val; + shadow_recalc(dev); #if NEAT_DEBUG > 1 neat_log("NEAT: RB1=%02x(%02x)\n", val, *reg); #endif @@ -501,6 +684,10 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RB2: val &= RB2_MASK; *reg = (*reg & ~RB2_MASK) | val; + if (val & RB2_TOP128) + neat_mem_update_state(dev, 0x00080000, 0x00020000, MEM_FLAG_READ | MEM_FLAG_WRITE, MEM_FMASK_SHADOW); + else + neat_mem_update_state(dev, 0x00080000, 0x00020000, 0x00, MEM_FMASK_SHADOW); #if NEAT_DEBUG > 1 neat_log("NEAT: RB2=%02x(%02x)\n", val, *reg); #endif @@ -509,6 +696,7 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RB3: val &= RB3_MASK; *reg = (*reg & ~RB3_MASK) | val; + shadow_recalc(dev); #if NEAT_DEBUG > 1 neat_log("NEAT: RB3=%02x(%02x)\n", val, *reg); #endif @@ -517,6 +705,7 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RB4: val &= RB4_MASK; *reg = (*reg & ~RB4_MASK) | val; + shadow_recalc(dev); #if NEAT_DEBUG > 1 neat_log("NEAT: RB4=%02x(%02x)\n", val, *reg); #endif @@ -525,6 +714,7 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RB5: val &= RB5_MASK; *reg = (*reg & ~RB5_MASK) | val; + shadow_recalc(dev); #if NEAT_DEBUG > 1 neat_log("NEAT: RB5=%02x(%02x)\n", val, *reg); #endif @@ -540,21 +730,21 @@ neat_write(uint16_t port, uint8_t val, void *priv) case REG_RB7: val &= RB7_MASK; - *reg = val; + + if (xval & (RB7_EMSEN | RB7_UMAREL)) + remap_update(dev, val); + + dev->regs[REG_RB7] = val; + + if (xval & RB7_EMSEN) + ems_remove_handlers(dev); + + if ((xval & RB7_EMSEN) && (val & RB7_EMSEN)) + ems_set_handlers(dev); + #if NEAT_DEBUG > 1 neat_log("NEAT: RB7=%02x(%02x)\n", val, *reg); #endif - if (val & RB7_EMSEN) - ems_init(dev, 1); - else if (xval & RB7_EMSEN) - ems_init(dev, 0); - - if (xval & RB7_UMAREL) { - if (val & RB7_UMAREL) - mem_remap_top(384); - else - mem_remap_top(0); - } break; case REG_RB8: @@ -571,10 +761,21 @@ neat_write(uint16_t port, uint8_t val, void *priv) #if NEAT_DEBUG > 1 neat_log("NEAT: RB9=%02x(%02x)\n", val, *reg); #endif - if (dev->regs[REG_RB7] & RB7_EMSEN) { - ems_init(dev, 0); - ems_init(dev, 1); - } + + ems_remove_handlers(dev); + + /* Get configured I/O address. */ + j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH; + dev->ems_base = 0x0208 + (0x10 * j); + + /* Get configured frame address. */ + j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH; + dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j); + + ems_update_virt_base(dev); + + if (dev->regs[REG_RB7] & RB7_EMSEN) + ems_set_handlers(dev); break; case REG_RB10: @@ -584,23 +785,43 @@ neat_write(uint16_t port, uint8_t val, void *priv) neat_log("NEAT: RB10=%02x(%02x)\n", val, *reg); #endif - dev->ems[3].start = ((val & RB10_P3EXT) >> RB10_P3EXT_SH) << 21; - dev->ems[2].start = ((val & RB10_P2EXT) >> RB10_P2EXT_SH) << 21; - dev->ems[1].start = ((val & RB10_P1EXT) >> RB10_P1EXT_SH) << 21; - dev->ems[0].start = ((val & RB10_P0EXT) >> RB10_P0EXT_SH) << 21; - for (i = 0; i < EMS_MAXPAGE; i++) - ems_recalc(dev, &dev->ems[i]); + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { + ram_page_t *ems = &(dev->ems[i]); + + uint32_t old_phys_base = ems->phys_base & 0xffe00000; + uint32_t new_phys_base = (((val & masks[i]) >> shifts[i]) << 21); + + if (new_phys_base != old_phys_base) { + int8_t old_enabled = ems->enabled; + + if ((dev->regs[REG_RB7] & RB7_EMSEN) && old_enabled) { + ems->enabled = 0; + ems_recalc(dev, &(dev->ems[i])); + } + + ems->phys_base = ems->phys_base - old_phys_base + new_phys_base; + + if ((dev->regs[REG_RB7] & RB7_EMSEN) && old_enabled) { + ems->enabled = old_enabled; + ems_recalc(dev, &(dev->ems[i])); + } + } + } + + neat_log("%08X, %08X, %08X, %08X\n", + dev->ems[0].phys_base, dev->ems[1].phys_base, + dev->ems[2].phys_base, dev->ems[3].phys_base); break; - case REG_RB11: - val &= RB11_MASK; - *reg = (*reg & ~RB11_MASK) | val; + case REG_RB12: + val &= RB12_MASK; + *reg = (*reg & ~RB12_MASK) | val; #if NEAT_DEBUG > 1 - neat_log("NEAT: RB11=%02x(%02x)\n", val, *reg); + neat_log("NEAT: RB12=%02x(%02x)\n", val, *reg); #endif - i = (val & RB11_EMSLEN) >> RB11_EMSLEN_SH; + i = (val & RB12_EMSLEN) >> RB12_EMSLEN_SH; switch (i) { - case 0: /* "less than 2MB" */ + case 0: /* "less than 1MB" */ dev->ems_size = 512; break; @@ -616,11 +837,16 @@ neat_write(uint16_t port, uint8_t val, void *priv) default: break; } - dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE; + if (dev->regs[REG_RB7] & RB7_EMSEN) { - neat_log("NEAT: EMS %iKB (%i pages)\n", - dev->ems_size, dev->ems_pages); + remap_update(dev, dev->regs[REG_RB7]); + + neat_log("NEAT: EMS %iKB\n", + dev->ems_size); } + + mem_a20_key = val & RB12_GA20; + mem_a20_recalc(); break; default: @@ -629,6 +855,7 @@ neat_write(uint16_t port, uint8_t val, void *priv) break; } break; + default: break; } @@ -646,8 +873,10 @@ neat_read(uint16_t port, void *priv) break; case 0x23: - if ((dev->indx >= 0x60) && (dev->indx <= 0x6f)) + 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_key & 2); break; default: @@ -674,16 +903,75 @@ neat_init(UNUSED(const device_t *info)) { neat_t *dev; uint8_t dram_mode = 0; - uint8_t i; + uint8_t j; /* Create an instance. */ - dev = (neat_t *) malloc(sizeof(neat_t)); - memset(dev, 0x00, sizeof(neat_t)); + dev = (neat_t *) calloc(1, sizeof(neat_t)); + + /* Get configured I/O address. */ + j = (dev->regs[REG_RB9] & RB9_BASE) >> RB9_BASE_SH; + dev->ems_base = 0x0208 + (0x10 * j); + + /* Get configured frame address. */ + j = (dev->regs[REG_RB9] & RB9_FRAME) >> RB9_FRAME_SH; + dev->ems_frame = 0xc0000 + (EMS_PGSIZE * j); + + ems_update_virt_base(dev); + + dev->ems_pages = (mem_size << 10) / EMS_PGSIZE; + dev->remap_base = mem_size; + + mem_mapping_disable(&ram_mid_mapping); + + for (int i = 0; i < 24; i++) { + if (i >= 20) + neat_mem_update_state(dev, 0x000a0000 + (i * EMS_PGSIZE), EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_SHADOW); + else { + /* This is needed to actually trigger an update. */ + dev->mem_flags[i + 8] = MEM_FLAG_ROMCS; + neat_mem_update_state(dev, 0x000a0000 + (i * EMS_PGSIZE), EMS_PGSIZE, 0x00, MEM_FMASK_SHADOW); + } + } + + /* + * For each supported page (we can have a maximum of 4), + * create, initialize and disable the mappings, and set + * up the I/O control handler. + */ + for (uint8_t i = 0; i < EMS_MAXPAGE; i++) { + /* Create and initialize a page mapping. */ + mem_mapping_add(&dev->ems[i].mapping, + 0x00000000, 0x00000000, + ems_readb, ems_readw, NULL, + ems_writeb, ems_writew, NULL, + ram + dev->ems[i].virt_base, MEM_MAPPING_INTERNAL, + &(dev->ems[i])); + + /* Disable for now. */ + mem_mapping_disable(&dev->ems[i].mapping); + } + + for (uint8_t i = 0; i < 32; i++) { + dev->shadow[i].virt_base = dev->shadow[i].phys_base = + (i * EMS_PGSIZE) + 0x00080000; + dev->shadow[i].enabled = 1; + + /* Create and initialize a page mapping. */ + mem_mapping_add(&dev->shadow[i].mapping, + dev->shadow[i].virt_base, EMS_PGSIZE, + ems_readb, ems_readw, NULL, + ems_writeb, ems_writew, NULL, + ram + dev->shadow[i].virt_base, MEM_MAPPING_INTERNAL, + &(dev->shadow[i])); + + /* Disable for now. */ + mem_mapping_disable(&dev->shadow[i].mapping); + } /* Initialize some of the registers to specific defaults. */ - for (i = REG_RA0; i <= REG_RB11; i++) { + for (uint8_t i = REG_RA0; i <= REG_RB12; i++) { dev->indx = i; - neat_write(0x0023, 0x00, dev); + neat_write(0x0023, defaults[i & REG_MASK], dev); } /* @@ -817,7 +1105,7 @@ neat_init(UNUSED(const device_t *info)) neat_log("NEAT: **INVALID DRAM SIZE %iKB !**\n", mem_size); } if (dram_mode > 0) { - neat_log("NEAT: using DRAM mode #%i (mem=%iKB)\n", i, mem_size); + neat_log("NEAT: using DRAM mode #%i (mem=%iKB)\n", dram_mode, mem_size); } /* Set up an I/O handler for the chipset. */ @@ -835,7 +1123,7 @@ const device_t neat_device = { .init = neat_init, .close = neat_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/olivetti_eva.c b/src/chipset/olivetti_eva.c index 1f5eacc6c..7defac6ae 100644 --- a/src/chipset/olivetti_eva.c +++ b/src/chipset/olivetti_eva.c @@ -134,8 +134,7 @@ olivetti_eva_close(void *priv) static void * olivetti_eva_init(UNUSED(const device_t *info)) { - olivetti_eva_t *dev = (olivetti_eva_t *) malloc(sizeof(olivetti_eva_t)); - memset(dev, 0, sizeof(olivetti_eva_t)); + olivetti_eva_t *dev = (olivetti_eva_t *) calloc(1, sizeof(olivetti_eva_t)); /* GA98 registers */ dev->reg_065 = 0x00; @@ -171,7 +170,7 @@ const device_t olivetti_eva_device = { .init = olivetti_eva_init, .close = olivetti_eva_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti283.c b/src/chipset/opti283.c index 63976985b..395ad4212 100644 --- a/src/chipset/opti283.c +++ b/src/chipset/opti283.c @@ -284,8 +284,7 @@ opti283_close(void *priv) static void * opti283_init(UNUSED(const device_t *info)) { - opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t)); - memset(dev, 0x00, sizeof(opti283_t)); + opti283_t *dev = (opti283_t *) calloc(1, sizeof(opti283_t)); io_sethandler(0x0022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev); io_sethandler(0x0023, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev); @@ -324,7 +323,7 @@ const device_t opti283_device = { .init = opti283_init, .close = opti283_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti291.c b/src/chipset/opti291.c index 6d2256974..91b9010e2 100644 --- a/src/chipset/opti291.c +++ b/src/chipset/opti291.c @@ -138,8 +138,7 @@ opti291_close(void *priv) static void * opti291_init(UNUSED(const device_t *info)) { - opti291_t *dev = (opti291_t *) malloc(sizeof(opti291_t)); - memset(dev, 0, sizeof(opti291_t)); + opti291_t *dev = (opti291_t *) calloc(1, sizeof(opti291_t)); io_sethandler(0x022, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev); io_sethandler(0x024, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev); @@ -161,7 +160,7 @@ const device_t opti291_device = { .init = opti291_init, .close = opti291_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti391.c b/src/chipset/opti391.c index c22c2a04b..7d3c10c98 100644 --- a/src/chipset/opti391.c +++ b/src/chipset/opti391.c @@ -374,7 +374,7 @@ const device_t opti381_device = { .init = opti391_init, .close = opti391_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -388,7 +388,7 @@ const device_t opti481_device = { .init = opti391_init, .close = opti391_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -402,7 +402,7 @@ const device_t opti391_device = { .init = opti391_init, .close = opti391_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti495.c b/src/chipset/opti495.c index 84ef6a202..aa4e4b4c5 100644 --- a/src/chipset/opti495.c +++ b/src/chipset/opti495.c @@ -219,8 +219,7 @@ opti495_close(void *priv) static void * opti495_init(const device_t *info) { - opti495_t *dev = (opti495_t *) malloc(sizeof(opti495_t)); - memset(dev, 0, sizeof(opti495_t)); + opti495_t *dev = (opti495_t *) calloc(1, sizeof(opti495_t)); device_add(&port_92_device); @@ -271,7 +270,7 @@ const device_t opti493_device = { .init = opti495_init, .close = opti495_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -285,7 +284,7 @@ const device_t opti495_device = { .init = opti495_init, .close = opti495_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index ecadd2224..d54e8184e 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -242,8 +242,7 @@ opti499_close(void *priv) static void * opti499_init(UNUSED(const device_t *info)) { - opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t)); - memset(dev, 0, sizeof(opti499_t)); + opti499_t *dev = (opti499_t *) calloc(1, sizeof(opti499_t)); device_add(&port_92_device); @@ -265,7 +264,7 @@ const device_t opti499_device = { .init = opti499_init, .close = opti499_close, .reset = opti499_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index 64adacde4..03fde4173 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -35,7 +35,7 @@ typedef struct opti5x7_t { uint8_t idx; uint8_t is_pci; - uint8_t regs[16]; + uint8_t regs[18]; } opti5x7_t; #ifdef ENABLE_OPTI5X7_LOG @@ -158,7 +158,7 @@ opti5x7_read(uint16_t addr, void *priv) { const opti5x7_t *dev = (opti5x7_t *) priv; - return (addr == 0x24) ? dev->regs[dev->idx] : 0xff; + return ((addr == 0x24) && (dev->idx < sizeof(dev->regs))) ? dev->regs[dev->idx] : 0xff; } static void @@ -172,8 +172,7 @@ opti5x7_close(void *priv) static void * opti5x7_init(const device_t *info) { - opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t)); - memset(dev, 0, sizeof(opti5x7_t)); + opti5x7_t *dev = (opti5x7_t *) calloc(1, sizeof(opti5x7_t)); dev->is_pci = info->local; @@ -193,7 +192,7 @@ const device_t opti5x7_device = { .init = opti5x7_init, .close = opti5x7_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -207,7 +206,7 @@ const device_t opti5x7_pci_device = { .init = opti5x7_init, .close = opti5x7_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti602.c b/src/chipset/opti602.c index 3b5614ff4..7082408c7 100644 --- a/src/chipset/opti602.c +++ b/src/chipset/opti602.c @@ -218,7 +218,7 @@ const device_t opti601_device = { .init = opti602_init, .close = opti602_close, .reset = opti602_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -232,7 +232,7 @@ const device_t opti602_device = { .init = opti602_init, .close = opti602_close, .reset = opti602_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 3e9316f2b..471fbe393 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -394,8 +394,7 @@ opti822_close(void *priv) static void * opti822_init(UNUSED(const device_t *info)) { - opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t)); - memset(dev, 0, sizeof(opti822_t)); + opti822_t *dev = (opti822_t *) calloc(1, sizeof(opti822_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot); @@ -412,7 +411,7 @@ const device_t opti822_device = { .init = opti822_init, .close = opti822_close, .reset = opti822_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/opti895.c b/src/chipset/opti895.c index f1878a51b..cb55ef2a7 100644 --- a/src/chipset/opti895.c +++ b/src/chipset/opti895.c @@ -259,8 +259,7 @@ opti895_close(void *priv) static void * opti895_init(const device_t *info) { - opti895_t *dev = (opti895_t *) malloc(sizeof(opti895_t)); - memset(dev, 0, sizeof(opti895_t)); + opti895_t *dev = (opti895_t *) calloc(1, sizeof(opti895_t)); device_add(&port_92_device); @@ -306,7 +305,7 @@ const device_t opti802g_device = { .init = opti895_init, .close = opti895_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -320,7 +319,7 @@ const device_t opti802g_pci_device = { .init = opti895_init, .close = opti895_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -334,7 +333,7 @@ const device_t opti895_device = { .init = opti895_init, .close = opti895_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 122318862..8e7892c2e 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -47,13 +47,35 @@ #define ID_VL82C311 0xd6 -#define RAMMAP_REMP386 (1 << 4) +#define RAMMAP_ROMMOV 0x60 +#define RAMMAP_ROMMOV1 (1 << 6) +#define RAMMAP_ROMMOV0 (1 << 5) +#define RAMMAP_REMP384 (1 << 4) #define EMSEN1_EMSMAP (1 << 4) +#define EMSEN1_BFENAB (1 << 6) #define EMSEN1_EMSENAB (1 << 7) #define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) +#define EMS_MAXPAGE 4 +#define EMS_PGSIZE 16384 +#define EMS_PGMASK 16383 + +#define MEM_FLAG_SLOTBUS 0x40 +#define MEM_FLAG_REMAP 0x20 +#define MEM_FLAG_MEMCARD 0x10 +#define MEM_FLAG_EMS 0x08 +#define MEM_FLAG_ROMCS 0x04 +#define MEM_FLAG_READ 0x02 +#define MEM_FLAG_WRITE 0x01 +#define MEM_FMASK_SLOTBUS 0x40 +#define MEM_FMASK_REMAP 0x20 +#define MEM_FMASK_MEMCARD 0x10 +#define MEM_FMASK_EMS 0x08 +#define MEM_FMASK_ROMCS 0x04 +#define MEM_FMASK_RW 0x03 + /*Commodore SL386SX requires proper memory slot decoding to detect memory size. Therefore we emulate the SCAMP memory address decoding, and therefore are limited to the DRAM combinations supported by the actual chip*/ @@ -72,36 +94,43 @@ typedef struct ram_struct_t { int bank; } ram_struct_t; -typedef struct ems_struct_t { - void *parent; - int segment; -} ems_struct_t; +typedef struct card_mem_t { + int in_ram; + uint32_t virt_addr; + uint32_t phys_addr; + uint8_t *mem; +} mem_page_t; typedef struct scamp_t { - int cfg_index; - uint8_t cfg_regs[256]; - int cfg_enable; - int ram_config; + int cfg_index; + uint8_t cfg_regs[256]; + int cfg_enable; + int ram_config; int ems_index; int ems_autoinc; - uint16_t ems[0x24]; - mem_mapping_t ems_mappings[20]; /*a0000-effff*/ - uint32_t mappings[20]; + uint16_t ems[64]; mem_mapping_t ram_mapping[2]; ram_struct_t ram_struct[2]; - ems_struct_t ems_struct[20]; - uint32_t ram_virt_base[2]; - uint32_t ram_phys_base[2]; - uint32_t ram_mask[2]; - int row_virt_shift[2]; - int row_phys_shift[2]; - int ram_interleaved[2]; - int ibank_shift[2]; + uint32_t ram_virt_base[2]; + uint32_t ram_phys_base[2]; + uint32_t ram_mask[2]; + int row_virt_shift[2]; + int row_phys_shift[2]; + int ram_interleaved[2]; + int ibank_shift[2]; - port_92_t *port_92; + int mem_flags[64]; + mem_mapping_t mem_mappings[64]; /* The entire first 1 MB of memory space. */ + mem_page_t mem_pages[64]; + + uint32_t card_mem_size; + uint8_t *card_mem; + mem_page_t card_pages[4]; + + port_92_t *port_92; } scamp_t; static const struct { @@ -147,6 +176,70 @@ static const struct { { { BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED }, 0}, /*Undocumented - probably wrong!*/ }; +#ifdef ENABLE_SCAMP_LOG +int scamp_do_log = ENABLE_SCAMP_LOG; + +static void +scamp_log(const char *fmt, ...) +{ + va_list ap; + + if (scamp_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define scamp_log(fmt, ...) +#endif + +/* Read one byte from paged RAM. */ +static uint8_t +scamp_mem_readb(uint32_t addr, void *priv) +{ + mem_page_t *dev = (mem_page_t *) priv; + uint8_t ret = 0xff; + + if (dev->mem != NULL) + ret = *(uint8_t *) &(dev->mem[addr & EMS_PGMASK]); + + return ret; +} + +/* Read one word from paged RAM. */ +static uint16_t +scamp_mem_readw(uint32_t addr, void *priv) +{ + mem_page_t *dev = (mem_page_t *) priv; + uint16_t ret = 0xffff; + + if (dev->mem != NULL) + ret = *(uint16_t *) &(dev->mem[addr & EMS_PGMASK]); + + return ret; +} + +/* Write one byte to paged RAM. */ +static void +scamp_mem_writeb(uint32_t addr, uint8_t val, void *priv) +{ + mem_page_t *dev = (mem_page_t *) priv; + + if (dev->mem != NULL) + *(uint8_t *) &(dev->mem[addr & EMS_PGMASK]) = val; +} + +/* Write one word to paged RAM. */ +static void +scamp_mem_writew(uint32_t addr, uint16_t val, void *priv) +{ + mem_page_t *dev = (mem_page_t *) priv; + + if (dev->mem != NULL) + *(uint16_t *) &(dev->mem[addr & EMS_PGMASK]) = val; +} + /* The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous, so we use separate routines for that special case */ static uint8_t @@ -332,208 +425,193 @@ recalc_mappings(void *priv) /* Once the BIOS programs the correct DRAM configuration, switch to regular linear memory mapping */ if (cur_rammap == ram_configs[dev->ram_config].rammap) { - mem_mapping_set_handler(&ram_low_mapping, - mem_read_ram, mem_read_ramw, mem_read_raml, - mem_write_ram, mem_write_ramw, mem_write_raml); - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_disable(&ram_low_mapping); + + for (uint8_t i = 0; i < 40; i++) + mem_mapping_enable(&(dev->mem_mappings[i])); + if (mem_size > 1024) mem_set_mem_state_both((1 << 20), (mem_size - 1024) << 10, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_mapping_enable(&ram_high_mapping); - return; } else { mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_low_mapping); - } - if (rammap[cur_rammap].bank[0] == BANK_NONE) - bank_nr = 1; + for (uint8_t i = 0; i < 40; i++) + mem_mapping_disable(&(dev->mem_mappings[i])); - for (; bank_nr < 2; bank_nr++) { - old_virt_base = virt_base; - phys_bank = ram_configs[dev->ram_config].bank[bank_nr]; + if (rammap[cur_rammap].bank[0] == BANK_NONE) + bank_nr = 1; - dev->ram_virt_base[bank_nr] = virt_base; + for (; bank_nr < 2; bank_nr++) { + old_virt_base = virt_base; + phys_bank = ram_configs[dev->ram_config].bank[bank_nr]; - if (virt_base == 0) { - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_NONE: - fatal(" Bank %i is empty!\n }\n}\n", bank_nr); - break; + dev->ram_virt_base[bank_nr] = virt_base; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); - } - virt_base += (1 << 19); - dev->row_virt_shift[bank_nr] = 10; - break; + if (virt_base == 0) { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + fatal(" Bank %i is empty!\n }\n}\n", bank_nr); + break; - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); - } - virt_base += (1 << 20); - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_256K: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); + } + virt_base += (1 << 19); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - mem_set_mem_state_both((1 << 20), (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 21); - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); + } + virt_base += (1 << 20); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - mem_set_mem_state_both((1 << 20), (3 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 22); - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 21); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - mem_set_mem_state_both((1 << 20), (7 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 23); - dev->row_virt_shift[bank_nr] = 12; - break; + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (3 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 22); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - mem_set_mem_state_both((1 << 20), (15 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 24); - dev->row_virt_shift[bank_nr] = 12; - break; + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (7 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 23); + dev->row_virt_shift[bank_nr] = 12; + break; - default: - break; + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (15 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 24); + dev->row_virt_shift[bank_nr] = 12; + break; + + default: + break; + } + } else { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + break; + + case BANK_256K: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x80000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 19), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 19); + dev->row_virt_shift[bank_nr] = 10; + break; + + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 20); + dev->row_virt_shift[bank_nr] = 10; + break; + + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 21), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 21); + dev->row_virt_shift[bank_nr] = 11; + break; + + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 22), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 22); + dev->row_virt_shift[bank_nr] = 11; + break; + + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 23), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 23); + dev->row_virt_shift[bank_nr] = 12; + break; + + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 24), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 24); + dev->row_virt_shift[bank_nr] = 12; + break; + + default: + break; + } } - } else { + switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_NONE: - break; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x80000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - mem_set_mem_state_both(virt_base, (1 << 19), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 19); - dev->row_virt_shift[bank_nr] = 10; - break; - - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - mem_set_mem_state_both(virt_base, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 20); - dev->row_virt_shift[bank_nr] = 10; - break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - mem_set_mem_state_both(virt_base, (1 << 21), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 21); - dev->row_virt_shift[bank_nr] = 11; - break; - - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - mem_set_mem_state_both(virt_base, (1 << 22), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 22); - dev->row_virt_shift[bank_nr] = 11; - break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - mem_set_mem_state_both(virt_base, (1 << 23), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 23); - dev->row_virt_shift[bank_nr] = 12; - break; - - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - mem_set_mem_state_both(virt_base, (1 << 24), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } - virt_base += (1 << 24); - dev->row_virt_shift[bank_nr] = 12; - break; - - default: - break; - } - } - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_256K: - case BANK_1M: - case BANK_4M: - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); - break; - - case BANK_256K_INTERLEAVED: - case BANK_1M_INTERLEAVED: - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], - ram_mirrored_interleaved_read, NULL, NULL, - ram_mirrored_interleaved_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_interleaved_read, NULL, NULL, - ram_mirrored_interleaved_write, NULL, NULL); - break; - - case BANK_4M_INTERLEAVED: - if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], - ram_mirrored_256k_in_4mi_read, NULL, NULL, - ram_mirrored_256k_in_4mi_write, NULL, NULL); if (!old_virt_base) mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_256k_in_4mi_read, NULL, NULL, - ram_mirrored_256k_in_4mi_write, NULL, NULL); - } else { + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + break; + + case BANK_256K_INTERLEAVED: + case BANK_1M_INTERLEAVED: mem_mapping_set_handler(&dev->ram_mapping[bank_nr], ram_mirrored_interleaved_read, NULL, NULL, ram_mirrored_interleaved_write, NULL, NULL); @@ -541,13 +619,203 @@ recalc_mappings(void *priv) mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_interleaved_read, NULL, NULL, ram_mirrored_interleaved_write, NULL, NULL); - } - break; + break; + case BANK_4M_INTERLEAVED: + if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + } else { + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + } + break; + + default: + break; + } + } + } +} + +static void +scamp_mem_update_state(scamp_t *dev, uint32_t addr, uint32_t size, uint8_t new_flags, uint8_t mask) +{ + int read_ext = MEM_READ_EXTERNAL; + int write_ext = MEM_WRITE_EXTERNAL; + + if ((addr < 0x00100000) && ((new_flags ^ dev->mem_flags[addr / EMS_PGSIZE]) & mask)) { + dev->mem_flags[addr / EMS_PGSIZE] &= ~mask; + dev->mem_flags[addr / EMS_PGSIZE] |= new_flags; + + new_flags = dev->mem_flags[addr / EMS_PGSIZE]; + + if (new_flags & MEM_FLAG_ROMCS) { + read_ext = MEM_READ_ROMCS; + write_ext = MEM_WRITE_ROMCS; + } + + if (new_flags & (MEM_FLAG_REMAP | MEM_FLAG_SLOTBUS)) { + scamp_log("scamp_mem_update_state(): %08X-%08X: %02X (REMAP)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, read_ext | write_ext); + } else if (new_flags & (MEM_FLAG_EMS | MEM_FLAG_MEMCARD)) { + scamp_log("scamp_mem_update_state(): %08X-%08X: %02X (EMS)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else switch (new_flags & (MEM_FLAG_READ | MEM_FLAG_WRITE)) { + case 0: + scamp_log("scamp_mem_update_state(): %08X-%08X: %02X (RE | WE)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, read_ext | write_ext); + break; + case 1: + scamp_log("scamp_mem_update_state(): %08X-%08X: %02X (RE | WI)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, read_ext | MEM_WRITE_INTERNAL); + break; + case 2: + scamp_log("scamp_mem_update_state(): %08X-%08X: %02X (RI | WE)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | write_ext); + break; + case 3: + scamp_log("scamp_mem_update_state(): %08X-%08X: %02X (RI | WI)\n", addr, addr + size - 1, new_flags); + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; default: break; } } + + flushmmucache_nopc(); +} + +static int +is_seg_in_ram(scamp_t *dev, uint8_t s) +{ + mem_page_t *mp = (mem_page_t *) dev->mem_mappings[s].priv; + const int ret = mp->in_ram; + + return ret; +} + +static void +recalc_ems(scamp_t *dev) +{ + const uint8_t seg_xlat[12] = { 40, 41, 42, 43, 52, 53, 54, 55, 44, 45, 46, 47 }; + const uint16_t seg_enable = dev->cfg_regs[CFG_EMSEN2] | ((dev->cfg_regs[CFG_EMSEN1] & 0xf) << 8); + + for (uint8_t s = 40; s < 60; s++) { + dev->mem_pages[s].phys_addr = dev->mem_pages[s].virt_addr; + dev->mem_pages[s].mem = ram + dev->mem_pages[s].phys_addr; + + if (is_seg_in_ram(dev, s)) + mem_mapping_set_exec(&(dev->mem_mappings[s]), dev->mem_pages[s].mem); + + scamp_mem_update_state(dev, s * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_EMS); + } + + for (uint8_t i = 0; i < 36; i++) { + uint8_t s = (i < 12) ? (i + 48) : (i + 4); + uint8_t on = (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB); + uint32_t phys_addr = dev->ems[i] << 14; + + if (i < 12) { + if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSMAP) + s = seg_xlat[i]; + + on = on && (seg_enable & (1 << i)); + } else + on = on && (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_BFENAB); + + if (on) { + dev->mem_pages[s].phys_addr = phys_addr; + dev->mem_pages[s].mem = ram + dev->mem_pages[s].phys_addr; + + if (is_seg_in_ram(dev, s)) + mem_mapping_set_exec(&(dev->mem_mappings[s]), dev->mem_pages[s].mem); + + scamp_mem_update_state(dev, s * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_EMS, MEM_FMASK_EMS); + } else if (i >= 12) { + dev->mem_pages[s].phys_addr = dev->mem_pages[s].virt_addr; + dev->mem_pages[s].mem = ram + dev->mem_pages[s].phys_addr; + + if (is_seg_in_ram(dev, s)) + mem_mapping_set_exec(&(dev->mem_mappings[s]), dev->mem_pages[s].mem); + + scamp_mem_update_state(dev, s * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_EMS); + } + } + + flushmmucache_nopc(); +} + +static void +shadow_control(scamp_t *dev, uint32_t addr, uint32_t size, int state) +{ + if (size == 0x8000) { + scamp_mem_update_state(dev, addr, EMS_PGSIZE, state, MEM_FMASK_RW); + scamp_mem_update_state(dev, addr + EMS_PGSIZE, EMS_PGSIZE, state, MEM_FMASK_RW); + } else + scamp_mem_update_state(dev, addr, size, state, MEM_FMASK_RW); + + flushmmucache_nopc(); +} + +static void +shadow_recalc(scamp_t *dev) +{ + uint8_t abaxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP384) ? 0 : dev->cfg_regs[CFG_ABAXS]; + uint8_t caxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP384) ? 0 : dev->cfg_regs[CFG_CAXS]; + uint8_t daxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP384) ? 0 : dev->cfg_regs[CFG_DAXS]; + uint8_t feaxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP384) ? 0 : dev->cfg_regs[CFG_FEAXS]; + + /*Enabling remapping will disable all shadowing*/ + if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP384) + mem_remap_top_nomid(384); + else + mem_remap_top_nomid(0); + + for (uint8_t i = 40; i < 64; i++) { + if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP384) + scamp_mem_update_state(dev, (i * EMS_PGSIZE), EMS_PGSIZE, MEM_FLAG_REMAP, MEM_FMASK_REMAP); + else + scamp_mem_update_state(dev, (i * EMS_PGSIZE), EMS_PGSIZE, 0x00, MEM_FMASK_REMAP); + } + + shadow_control(dev, 0xa0000, 0x4000, abaxs & 3); + shadow_control(dev, 0xa0000, 0x4000, abaxs & 3); + shadow_control(dev, 0xa8000, 0x4000, (abaxs >> 2) & 3); + shadow_control(dev, 0xa8000, 0x4000, (abaxs >> 2) & 3); + + shadow_control(dev, 0xb0000, 0x4000, (abaxs >> 4) & 3); + shadow_control(dev, 0xb0000, 0x4000, (abaxs >> 4) & 3); + shadow_control(dev, 0xb8000, 0x4000, (abaxs >> 6) & 3); + shadow_control(dev, 0xb8000, 0x4000, (abaxs >> 6) & 3); + + shadow_control(dev, 0xc0000, 0x4000, caxs & 3); + shadow_control(dev, 0xc4000, 0x4000, (caxs >> 2) & 3); + shadow_control(dev, 0xc8000, 0x4000, (caxs >> 4) & 3); + shadow_control(dev, 0xcc000, 0x4000, (caxs >> 6) & 3); + + shadow_control(dev, 0xd0000, 0x4000, daxs & 3); + shadow_control(dev, 0xd4000, 0x4000, (daxs >> 2) & 3); + shadow_control(dev, 0xd8000, 0x4000, (daxs >> 4) & 3); + shadow_control(dev, 0xdc000, 0x4000, (daxs >> 6) & 3); + + shadow_control(dev, 0xe0000, 0x4000, feaxs & 3); + shadow_control(dev, 0xe4000, 0x4000, feaxs & 3); + shadow_control(dev, 0xe8000, 0x4000, (feaxs >> 2) & 3); + shadow_control(dev, 0xec000, 0x4000, (feaxs >> 2) & 3); + + shadow_control(dev, 0xf0000, 0x8000, (feaxs >> 4) & 3); + shadow_control(dev, 0xf8000, 0x8000, (feaxs >> 6) & 3); } static void @@ -561,155 +829,84 @@ recalc_sltptr(scamp_t *dev) sltptr = 0xfe0000; if (sltptr >= 0xa0000) { - mem_set_mem_state(0, 0xa0000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + for (uint8_t i = 0; i < 40; i++) + scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, 0x00, MEM_FMASK_SLOTBUS); + mem_set_mem_state(0x100000, sltptr - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_set_mem_state(sltptr, 0x1000000 - sltptr, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if ((sltptr >= 0x40000) && (sltptr <= 0x90000)) { + dev->cfg_regs[CFG_EMSEN1] &= ~EMSEN1_BFENAB; + recalc_ems(dev); + } } else { - mem_set_mem_state(0, sltptr, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + for (uint8_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++) + scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_SLOTBUS, MEM_FMASK_SLOTBUS); + mem_set_mem_state(sltptr, 0xa0000 - sltptr, MEM_READ_EXTANY | MEM_WRITE_EXTANY); mem_set_mem_state(0x100000, 0xf00000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); } -} - -static uint8_t -scamp_ems_read(uint32_t addr, void *priv) -{ - const ems_struct_t *ems = (ems_struct_t *) priv; - const scamp_t *dev = ems->parent; - int segment = ems->segment; - - addr = (addr & 0x3fff) | dev->mappings[segment]; - return ram[addr]; -} - -static void -scamp_ems_write(uint32_t addr, uint8_t val, void *priv) -{ - const ems_struct_t *ems = (ems_struct_t *) priv; - const scamp_t *dev = ems->parent; - int segment = ems->segment; - - addr = (addr & 0x3fff) | dev->mappings[segment]; - ram[addr] = val; -} - -static void -recalc_ems(scamp_t *dev) -{ - const uint32_t ems_base[12] = { - 0xc0000, 0xc4000, 0xc8000, 0xcc000, - 0xd0000, 0xd4000, 0xd8000, 0xdc000, - 0xe0000, 0xe4000, 0xe8000, 0xec000 - }; - uint32_t new_mappings[20]; - uint16_t ems_enable; - - for (int segment = 0; segment < 20; segment++) - new_mappings[segment] = 0xa0000 + segment * 0x4000; - - if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) - ems_enable = dev->cfg_regs[CFG_EMSEN2] | ((dev->cfg_regs[CFG_EMSEN1] & 0xf) << 8); - else - ems_enable = 0; - - for (int segment = 0; segment < 12; segment++) { - if (ems_enable & (1 << segment)) { - uint32_t phys_addr = dev->ems[segment] << 14; - - /*If physical address is in remapped memory then adjust down to a0000-fffff range*/ - if ((dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) && phys_addr >= (mem_size * 1024) - && phys_addr < ((mem_size + 384) * 1024)) - phys_addr = (phys_addr - mem_size * 1024) + 0xa0000; - new_mappings[(ems_base[segment] - 0xa0000) >> 14] = phys_addr; - } - } - - for (int segment = 0; segment < 20; segment++) { - if (new_mappings[segment] != dev->mappings[segment]) { - dev->mappings[segment] = new_mappings[segment]; - if (new_mappings[segment] < (mem_size * 1024)) { - mem_mapping_set_exec(&dev->ems_mappings[segment], ram + dev->mappings[segment]); - mem_mapping_enable(&dev->ems_mappings[segment]); - } else - mem_mapping_disable(&dev->ems_mappings[segment]); - } - } -} - -static void -shadow_control(uint32_t addr, uint32_t size, int state, int ems_enable) -{ - if (ems_enable) - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else - switch (state) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - default: - break; - } flushmmucache_nopc(); } static void -shadow_recalc(scamp_t *dev) +recalc_rommov(scamp_t *dev) { - uint8_t abaxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_ABAXS]; - uint8_t caxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_CAXS]; - uint8_t daxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_DAXS]; - uint8_t feaxs = (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : dev->cfg_regs[CFG_FEAXS]; - uint32_t ems_enable; + switch ((dev->cfg_regs[CFG_RAMMAP] & RAMMAP_ROMMOV) >> 5) { + case 0x00: + scamp_mem_update_state(dev, 0x000c0000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c4000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c8000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000cc000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); - if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) { - if (dev->cfg_regs[CFG_EMSEN1] & EMSEN1_EMSMAP) /*Axxx/Bxxx/Dxxx*/ - ems_enable = (dev->cfg_regs[CFG_EMSEN2] & 0xf) | ((dev->cfg_regs[CFG_EMSEN1] & 0xf) << 4) | ((dev->cfg_regs[CFG_EMSEN2] & 0xf0) << 8); - else /*Cxxx/Dxxx/Exxx*/ - ems_enable = (dev->cfg_regs[CFG_EMSEN2] << 8) | ((dev->cfg_regs[CFG_EMSEN1] & 0xf) << 16); - } else - ems_enable = 0; + scamp_mem_update_state(dev, 0x000e0000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e4000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e8000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000ec000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + break; - /*Enabling remapping will disable all shadowing*/ - if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) - mem_remap_top(384); + case 0x01: + scamp_mem_update_state(dev, 0x000c0000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c4000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c8000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000cc000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); - shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00001); - shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00002); - shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00004); - shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00008); + scamp_mem_update_state(dev, 0x000e0000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e4000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e8000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000ec000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + break; - shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00010); - shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00020); - shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00040); - shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00080); + case 0x02: + scamp_mem_update_state(dev, 0x000c0000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c4000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c8000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000cc000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); - shadow_control(0xc0000, 0x4000, caxs & 3, ems_enable & 0x00100); - shadow_control(0xc4000, 0x4000, (caxs >> 2) & 3, ems_enable & 0x00200); - shadow_control(0xc8000, 0x4000, (caxs >> 4) & 3, ems_enable & 0x00400); - shadow_control(0xcc000, 0x4000, (caxs >> 6) & 3, ems_enable & 0x00800); + scamp_mem_update_state(dev, 0x000e0000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e4000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e8000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000ec000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + break; - shadow_control(0xd0000, 0x4000, daxs & 3, ems_enable & 0x01000); - shadow_control(0xd4000, 0x4000, (daxs >> 2) & 3, ems_enable & 0x02000); - shadow_control(0xd8000, 0x4000, (daxs >> 4) & 3, ems_enable & 0x04000); - shadow_control(0xdc000, 0x4000, (daxs >> 6) & 3, ems_enable & 0x08000); + case 0x03: + scamp_mem_update_state(dev, 0x000c0000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c4000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000c8000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000cc000, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); - shadow_control(0xe0000, 0x4000, feaxs & 3, ems_enable & 0x10000); - shadow_control(0xe4000, 0x4000, feaxs & 3, ems_enable & 0x20000); - shadow_control(0xe8000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x40000); - shadow_control(0xec000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x80000); + scamp_mem_update_state(dev, 0x000e0000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e4000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000e8000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + scamp_mem_update_state(dev, 0x000ec000, EMS_PGSIZE, 0x00, MEM_FMASK_ROMCS); + break; + } - shadow_control(0xf0000, 0x8000, (feaxs >> 4) & 3, 0); - shadow_control(0xf8000, 0x8000, (feaxs >> 6) & 3, 0); + flushmmucache_nopc(); } static void @@ -719,7 +916,7 @@ scamp_write(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0xe8: - dev->ems_index = val & 0x1f; + dev->ems_index = val & 0x3f; dev->ems_autoinc = val & 0x40; break; @@ -749,12 +946,14 @@ scamp_write(uint16_t addr, uint8_t val, void *priv) switch (dev->cfg_index) { case CFG_SLTPTR: recalc_sltptr(dev); + recalc_ems(dev); break; case CFG_RAMMAP: recalc_mappings(dev); mem_mapping_disable(&ram_remapped_mapping); shadow_recalc(dev); + recalc_rommov(dev); break; case CFG_EMSEN1: @@ -847,8 +1046,7 @@ static void * scamp_init(UNUSED(const device_t *info)) { uint32_t addr; - scamp_t *dev = (scamp_t *) malloc(sizeof(scamp_t)); - memset(dev, 0x00, sizeof(scamp_t)); + scamp_t *dev = (scamp_t *) calloc(1, sizeof(scamp_t)); dev->cfg_regs[CFG_ID] = ID_VL82C311; dev->cfg_enable = 1; @@ -878,9 +1076,8 @@ scamp_init(UNUSED(const device_t *info)) mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_mid_mapping); mem_mapping_disable(&ram_high_mapping); - mem_mapping_set_addr(&ram_mid_mapping, 0xf0000, 0x10000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0xf0000); addr = 0; for (uint8_t c = 0; c < 2; c++) { @@ -952,15 +1149,45 @@ scamp_init(UNUSED(const device_t *info)) mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - for (uint8_t c = 0; c < 20; c++) { - dev->ems_struct[c].parent = dev; - dev->ems_struct[c].segment = c; - mem_mapping_add(&dev->ems_mappings[c], - 0xa0000 + c * 0x4000, 0x4000, - scamp_ems_read, NULL, NULL, - scamp_ems_write, NULL, NULL, - ram + 0xa0000 + c * 0x4000, MEM_MAPPING_INTERNAL, (void *) &dev->ems_struct[c]); - dev->mappings[c] = 0xa0000 + c * 0x4000; + for (uint8_t i = 0; i < 12; i++) + dev->ems[i] = (0x000c0000 + (i * EMS_PGSIZE)) >> 14; + + for (uint8_t i = 0; i < 24; i++) + dev->ems[i + 12] = (0x00040000 + (i * EMS_PGSIZE)) >> 14; + + for (uint8_t i = 0; i < 64; i++) { + dev->mem_pages[i].in_ram = 1; + dev->mem_pages[i].virt_addr = i * EMS_PGSIZE; + dev->mem_pages[i].phys_addr = dev->mem_pages[i].virt_addr; + dev->mem_pages[i].mem = ram + dev->mem_pages[i].phys_addr; + + mem_mapping_add(&(dev->mem_mappings[i]), + i * EMS_PGSIZE, EMS_PGSIZE, + scamp_mem_readb, scamp_mem_readw, NULL, + scamp_mem_writeb, scamp_mem_writew, NULL, + dev->mem_pages[i].mem, MEM_MAPPING_INTERNAL, + &(dev->mem_pages[i])); + + if (i < 40) { + mem_mapping_disable(&(dev->mem_mappings[i])); + + scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_READ | MEM_FLAG_WRITE, MEM_FMASK_RW); + } else { + /* This is needed to the state update actually occurs. */ + 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) + scamp_mem_update_state(dev, i * EMS_PGSIZE, EMS_PGSIZE, MEM_FLAG_ROMCS, MEM_FMASK_ROMCS); + } + } + + dev->card_mem = NULL; + + for (uint8_t i = 0; i < 4; i++) { + dev->card_pages[i].virt_addr = i * EMS_PGSIZE; + dev->card_pages[i].phys_addr = dev->card_pages[i].virt_addr; + dev->card_pages[i].mem = dev->card_mem + dev->card_pages[i].phys_addr; } dev->port_92 = device_add(&port_92_device); @@ -976,7 +1203,7 @@ const device_t vlsi_scamp_device = { .init = scamp_init, .close = scamp_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/scat.c b/src/chipset/scat.c index 02610efa2..43f93649e 100644 --- a/src/chipset/scat.c +++ b/src/chipset/scat.c @@ -1140,14 +1140,21 @@ scat_out(uint16_t port, uint8_t val, void *priv) if (indx >= 24) base_addr += 0x30000; + if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000)) + mem_set_mem_state(base_addr, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if ((dev->regs[SCAT_EMS_CONTROL] & 0x80) && (dev->page[indx].regs_2x9 & 0x80)) { virt_addr = get_addr(dev, base_addr, &dev->page[indx]); if (virt_addr < ((uint32_t) mem_size << 10)) mem_mapping_set_exec(&dev->ems_mapping[indx], ram + virt_addr); else mem_mapping_set_exec(&dev->ems_mapping[indx], NULL); - flushmmucache(); + + if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000)) + mem_set_mem_state(base_addr, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } + + flushmmucache(); } break; @@ -1163,6 +1170,9 @@ scat_out(uint16_t port, uint8_t val, void *priv) if (indx >= 24) base_addr += 0x30000; + if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000)) + mem_set_mem_state(base_addr, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + if (dev->regs[SCAT_EMS_CONTROL] & 0x80) { if (val & 0x80) { virt_addr = get_addr(dev, base_addr, &dev->page[indx]); @@ -1175,6 +1185,9 @@ scat_out(uint16_t port, uint8_t val, void *priv) else mem_mapping_set_exec(&dev->ems_mapping[indx], NULL); mem_mapping_enable(&dev->ems_mapping[indx]); + + if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000)) + mem_set_mem_state(base_addr, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } else { mem_mapping_set_exec(&dev->ems_mapping[indx], ram + base_addr); mem_mapping_disable(&dev->ems_mapping[indx]); @@ -1390,8 +1403,7 @@ scat_init(const device_t *info) uint32_t k; int sx; - dev = (scat_t *) malloc(sizeof(scat_t)); - memset(dev, 0x00, sizeof(scat_t)); + dev = (scat_t *) calloc(1, sizeof(scat_t)); dev->type = info->local; sx = (dev->type == 32) ? 1 : 0; @@ -1495,7 +1507,7 @@ scat_init(const device_t *info) mem_mapping_add(&dev->ems_mapping[i], (i + 28) << 14, 0x04000, mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, - ram + ((i + 28) << 14), 0, &dev->page[i]); + ram + ((i + 28) << 14), MEM_MAPPING_INTERNAL, &dev->page[i]); mem_mapping_disable(&dev->ems_mapping[i]); } } else { @@ -1508,7 +1520,7 @@ scat_init(const device_t *info) mem_read_scatb, mem_read_scatw, mem_read_scatl, mem_write_scatb, mem_write_scatw, mem_write_scatl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), - 0, &dev->page[i]); + MEM_MAPPING_INTERNAL, &dev->page[i]); } } @@ -1546,7 +1558,7 @@ const device_t scat_device = { .init = scat_init, .close = scat_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1560,7 +1572,7 @@ const device_t scat_4_device = { .init = scat_init, .close = scat_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1574,7 +1586,7 @@ const device_t scat_sx_device = { .init = scat_init, .close = scat_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index aa841ed9c..38fcfe717 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -165,7 +165,7 @@ const device_t sis_5511_device = { .init = sis_5511_init, .close = sis_5511_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5511_h2p.c b/src/chipset/sis_5511_h2p.c index 7916d6ae2..543fcacc5 100644 --- a/src/chipset/sis_5511_h2p.c +++ b/src/chipset/sis_5511_h2p.c @@ -454,7 +454,7 @@ const device_t sis_5511_h2p_device = { .init = sis_5511_host_to_pci_init, .close = sis_5511_host_to_pci_close, .reset = sis_5511_host_to_pci_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5513_ide.c b/src/chipset/sis_5513_ide.c index 5cbfbdea8..9e3a0ad07 100644 --- a/src/chipset/sis_5513_ide.c +++ b/src/chipset/sis_5513_ide.c @@ -456,7 +456,7 @@ const device_t sis_5513_ide_device = { .init = sis_5513_ide_init, .close = sis_5513_ide_close, .reset = sis_5513_ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -470,7 +470,7 @@ const device_t sis_5572_ide_device = { .init = sis_5513_ide_init, .close = sis_5513_ide_close, .reset = sis_5513_ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -484,7 +484,7 @@ const device_t sis_5582_ide_device = { .init = sis_5513_ide_init, .close = sis_5513_ide_close, .reset = sis_5513_ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -498,7 +498,7 @@ const device_t sis_5591_5600_ide_device = { .init = sis_5513_ide_init, .close = sis_5513_ide_close, .reset = sis_5513_ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5513_p2i.c b/src/chipset/sis_5513_p2i.c index ef9a6746d..95a890fcf 100644 --- a/src/chipset/sis_5513_p2i.c +++ b/src/chipset/sis_5513_p2i.c @@ -106,7 +106,7 @@ sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev) { memset(dev->apc_regs, 0x00, sizeof(dev->apc_regs)); - if (dev->rev == 0b0) { + if (dev->rev == 0xb0) { dev->apc_regs[0x03] = 0x80; dev->apc_regs[0x04] = 0x38; dev->apc_regs[0x07] = 0x01; @@ -115,7 +115,7 @@ sis_5513_apc_reset(sis_5513_pci_to_isa_t *dev) } static void -sis_5513_apc_write(uint16_t addr, uint8_t val, void *priv) +sis_5513_apc_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; uint8_t nvr_index = nvr_get_index(dev->nvr, 0); @@ -135,7 +135,7 @@ sis_5513_apc_write(uint16_t addr, uint8_t val, void *priv) } static uint8_t -sis_5513_apc_read(uint16_t addr, void *priv) +sis_5513_apc_read(UNUSED(uint16_t addr), void *priv) { sis_5513_pci_to_isa_t *dev = (sis_5513_pci_to_isa_t *) priv; uint8_t nvr_index = nvr_get_index(dev->nvr, 0); @@ -1287,9 +1287,9 @@ sis_5513_pci_to_isa_init(UNUSED(const device_t *info)) acpi_set_nvr(dev->sis->acpi, dev->nvr); /* Set up the NVR file's name. */ - c = strlen(machine_get_internal_name()) + 9; + c = strlen(machine_get_nvr_name()) + 9; dev->fn = (char *) malloc(c + 1); - sprintf(dev->fn, "%s_apc.nvr", machine_get_internal_name()); + sprintf(dev->fn, "%s_apc.nvr", machine_get_nvr_name()); fp = nvr_fopen(dev->fn, "rb"); @@ -1318,7 +1318,7 @@ const device_t sis_5513_p2i_device = { .init = sis_5513_pci_to_isa_init, .close = sis_5513_pci_to_isa_close, .reset = sis_5513_pci_to_isa_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1332,7 +1332,7 @@ const device_t sis_5572_p2i_device = { .init = sis_5513_pci_to_isa_init, .close = sis_5513_pci_to_isa_close, .reset = sis_5513_pci_to_isa_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1347,7 +1347,7 @@ const device_t sis_5582_p2i_device = { .init = sis_5513_pci_to_isa_init, .close = sis_5513_pci_to_isa_close, .reset = sis_5513_pci_to_isa_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1362,7 +1362,7 @@ const device_t sis_5595_1997_p2i_device = { .init = sis_5513_pci_to_isa_init, .close = sis_5513_pci_to_isa_close, .reset = sis_5513_pci_to_isa_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1376,7 +1376,7 @@ const device_t sis_5595_p2i_device = { .init = sis_5513_pci_to_isa_init, .close = sis_5513_pci_to_isa_close, .reset = sis_5513_pci_to_isa_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 3fb111978..3980704fd 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -177,7 +177,7 @@ const device_t sis_5571_device = { .init = sis_5571_init, .close = sis_5571_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c index 4a4ee9b83..d04964581 100644 --- a/src/chipset/sis_5571_h2p.c +++ b/src/chipset/sis_5571_h2p.c @@ -451,7 +451,7 @@ const device_t sis_5571_h2p_device = { .init = sis_5571_host_to_pci_init, .close = sis_5571_host_to_pci_close, .reset = sis_5571_host_to_pci_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5571_old.c b/src/chipset/sis_5571_old.c index f130ecd8a..495137aed 100644 --- a/src/chipset/sis_5571_old.c +++ b/src/chipset/sis_5571_old.c @@ -732,8 +732,7 @@ sis_5571_close(void *priv) static void * sis_5571_init(UNUSED(const device_t *info)) { - sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t)); - memset(dev, 0x00, sizeof(sis_5571_t)); + sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot); pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot); @@ -765,7 +764,7 @@ const device_t sis_5571_device = { .init = sis_5571_init, .close = sis_5571_close, .reset = sis_5571_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5572_usb.c b/src/chipset/sis_5572_usb.c index 250c32587..bc7dc7d38 100644 --- a/src/chipset/sis_5572_usb.c +++ b/src/chipset/sis_5572_usb.c @@ -288,7 +288,7 @@ const device_t sis_5572_usb_device = { .init = sis_5572_usb_init, .close = sis_5572_usb_close, .reset = sis_5572_usb_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -302,7 +302,7 @@ const device_t sis_5582_usb_device = { .init = sis_5572_usb_init, .close = sis_5572_usb_close, .reset = sis_5572_usb_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -316,7 +316,7 @@ const device_t sis_5595_usb_device = { .init = sis_5572_usb_init, .close = sis_5572_usb_close, .reset = sis_5572_usb_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c index e2308c2d9..998ac5350 100644 --- a/src/chipset/sis_5581.c +++ b/src/chipset/sis_5581.c @@ -177,7 +177,7 @@ const device_t sis_5581_device = { .init = sis_5581_init, .close = sis_5581_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5581_h2p.c b/src/chipset/sis_5581_h2p.c index 30bd70bfe..d01e9dd28 100644 --- a/src/chipset/sis_5581_h2p.c +++ b/src/chipset/sis_5581_h2p.c @@ -545,7 +545,7 @@ const device_t sis_5581_h2p_device = { .init = sis_5581_host_to_pci_init, .close = sis_5581_host_to_pci_close, .reset = sis_5581_host_to_pci_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5591.c b/src/chipset/sis_5591.c index 969fcb8dd..3cb11cb5b 100644 --- a/src/chipset/sis_5591.c +++ b/src/chipset/sis_5591.c @@ -189,7 +189,7 @@ const device_t sis_5591_1997_device = { .init = sis_5591_init, .close = sis_5591_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -203,7 +203,7 @@ const device_t sis_5591_device = { .init = sis_5591_init, .close = sis_5591_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5591_h2p.c b/src/chipset/sis_5591_h2p.c index 8fcbeeb6f..048e7deea 100644 --- a/src/chipset/sis_5591_h2p.c +++ b/src/chipset/sis_5591_h2p.c @@ -486,7 +486,7 @@ const device_t sis_5591_h2p_device = { .init = sis_5591_host_to_pci_init, .close = sis_5591_host_to_pci_close, .reset = sis_5591_host_to_pci_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5595_pmu.c b/src/chipset/sis_5595_pmu.c index de351ad7c..7de9735f1 100644 --- a/src/chipset/sis_5595_pmu.c +++ b/src/chipset/sis_5595_pmu.c @@ -119,7 +119,7 @@ sis_5595_pmu_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, v } static void -sis_5595_pmu_trap_io_ide_bm(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv) +sis_5595_pmu_trap_io_ide_bm(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv) { sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv; sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv; @@ -433,7 +433,7 @@ const device_t sis_5595_1997_pmu_device = { .init = sis_5595_pmu_init, .close = sis_5595_pmu_close, .reset = sis_5595_pmu_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -447,7 +447,7 @@ const device_t sis_5595_pmu_device = { .init = sis_5595_pmu_init, .close = sis_5595_pmu_close, .reset = sis_5595_pmu_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_55xx.c b/src/chipset/sis_55xx.c index 2cad21f22..1cb0744eb 100644 --- a/src/chipset/sis_55xx.c +++ b/src/chipset/sis_55xx.c @@ -89,7 +89,7 @@ const device_t sis_55xx_common_device = { .init = sis_55xx_common_init, .close = sis_55xx_common_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5600.c b/src/chipset/sis_5600.c index ed7384740..1ed7f9ad0 100644 --- a/src/chipset/sis_5600.c +++ b/src/chipset/sis_5600.c @@ -189,7 +189,7 @@ const device_t sis_5600_1997_device = { .init = sis_5600_init, .close = sis_5600_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -203,7 +203,7 @@ const device_t sis_5600_device = { .init = sis_5600_init, .close = sis_5600_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_5600_h2p.c b/src/chipset/sis_5600_h2p.c index f6ee926da..a15c6fff5 100644 --- a/src/chipset/sis_5600_h2p.c +++ b/src/chipset/sis_5600_h2p.c @@ -427,7 +427,7 @@ const device_t sis_5600_h2p_device = { .init = sis_5600_host_to_pci_init, .close = sis_5600_host_to_pci_close, .reset = sis_5600_host_to_pci_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_85c310.c b/src/chipset/sis_85c310.c index 296307fe1..dfbd4b465 100644 --- a/src/chipset/sis_85c310.c +++ b/src/chipset/sis_85c310.c @@ -130,8 +130,7 @@ rabbit_close(void *priv) static void * rabbit_init(UNUSED(const device_t *info)) { - rabbit_t *dev = (rabbit_t *) malloc(sizeof(rabbit_t)); - memset(dev, 0, sizeof(rabbit_t)); + rabbit_t *dev = (rabbit_t *) calloc(1, sizeof(rabbit_t)); io_sethandler(0x0022, 0x0002, rabbit_read, NULL, NULL, rabbit_write, NULL, NULL, dev); @@ -146,7 +145,7 @@ const device_t rabbit_device = { .init = rabbit_init, .close = rabbit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 3c3d5bd8c..10bccc1c8 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -637,8 +637,7 @@ static void * sis_85c496_init(const device_t *info) { - sis_85c496_t *dev = malloc(sizeof(sis_85c496_t)); - memset(dev, 0x00, sizeof(sis_85c496_t)); + sis_85c496_t *dev = calloc(1, sizeof(sis_85c496_t)); dev->smram = smram_add(); @@ -702,7 +701,7 @@ const device_t sis_85c496_device = { .init = sis_85c496_init, .close = sis_85c496_close, .reset = sis_85c496_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -716,7 +715,7 @@ const device_t sis_85c496_ls486e_device = { .init = sis_85c496_init, .close = sis_85c496_close, .reset = sis_85c496_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index f80ecf99e..6e26a4751 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -368,8 +368,7 @@ sis_85c4xx_close(void *priv) static void * sis_85c4xx_init(const device_t *info) { - sis_85c4xx_t *dev = (sis_85c4xx_t *) malloc(sizeof(sis_85c4xx_t)); - memset(dev, 0, sizeof(sis_85c4xx_t)); + sis_85c4xx_t *dev = (sis_85c4xx_t *) calloc(1, sizeof(sis_85c4xx_t)); dev->is_471 = (info->local >> 8) & 0xff; @@ -403,7 +402,7 @@ const device_t sis_85c401_device = { .init = sis_85c4xx_init, .close = sis_85c4xx_close, .reset = sis_85c4xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -417,7 +416,7 @@ const device_t sis_85c460_device = { .init = sis_85c4xx_init, .close = sis_85c4xx_close, .reset = sis_85c4xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -432,7 +431,7 @@ const device_t sis_85c461_device = { .init = sis_85c4xx_init, .close = sis_85c4xx_close, .reset = sis_85c4xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -446,7 +445,7 @@ const device_t sis_85c471_device = { .init = sis_85c4xx_init, .close = sis_85c4xx_close, .reset = sis_85c4xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index 2286105ce..192ae3767 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -684,7 +684,7 @@ const device_t sis_85c50x_device = { .init = sis_85c50x_init, .close = sis_85c50x_close, .reset = sis_85c50x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -698,7 +698,7 @@ const device_t sis_550x_85c503_device = { .init = sis_85c50x_init, .close = sis_85c50x_close, .reset = sis_85c50x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -712,7 +712,7 @@ const device_t sis_85c50x_5503_device = { .init = sis_85c50x_init, .close = sis_85c50x_close, .reset = sis_85c50x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -726,7 +726,7 @@ const device_t sis_550x_device = { .init = sis_85c50x_init, .close = sis_85c50x_close, .reset = sis_85c50x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index dbe39ec5c..13dbd97e9 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -912,8 +912,7 @@ stpc_init(const device_t *info) { stpc_log("STPC: init()\n"); - stpc_t *dev = (stpc_t *) malloc(sizeof(stpc_t)); - memset(dev, 0, sizeof(stpc_t)); + stpc_t *dev = (stpc_t *) calloc(1, sizeof(stpc_t)); dev->local = info->local; @@ -963,8 +962,7 @@ stpc_serial_init(UNUSED(const device_t *info)) { stpc_log("STPC: serial_init()\n"); - stpc_serial_t *dev = (stpc_serial_t *) malloc(sizeof(stpc_serial_t)); - memset(dev, 0, sizeof(stpc_serial_t)); + stpc_serial_t *dev = (stpc_serial_t *) calloc(1, sizeof(stpc_serial_t)); dev->uart[0] = device_add_inst(&ns16550_device, 1); dev->uart[1] = device_add_inst(&ns16550_device, 2); @@ -977,39 +975,24 @@ stpc_serial_init(UNUSED(const device_t *info)) static void stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val) { - uint8_t old_addr = (dev->reg1 & 0x03); - uint8_t new_addr = (val & 0x03); + const uint8_t new_addr = (val & 0x03); - switch (old_addr) { - case 0x1: - lpt3_remove(); - break; - - case 0x2: - lpt1_remove(); - break; - - case 0x3: - lpt2_remove(); - break; - default: - break; - } + lpt1_remove(); switch (new_addr) { case 0x1: stpc_log("STPC: Remapping parallel port to LPT3\n"); - lpt3_init(0x3bc); + lpt1_setup(LPT_MDA_ADDR); break; case 0x2: stpc_log("STPC: Remapping parallel port to LPT1\n"); - lpt1_init(0x378); + lpt1_setup(LPT1_ADDR); break; case 0x3: stpc_log("STPC: Remapping parallel port to LPT2\n"); - lpt2_init(0x278); + lpt1_setup(LPT2_ADDR); break; default: @@ -1017,9 +1000,11 @@ stpc_lpt_handlers(stpc_lpt_t *dev, uint8_t val) break; } - dev->reg1 = (val & 0x08); - dev->reg1 |= new_addr; - dev->reg1 |= 0x84; /* reserved bits that default to 1; hardwired? */ + if (dev != NULL) { + dev->reg1 = (val & 0x08); + dev->reg1 |= new_addr; + dev->reg1 |= 0x84; /* reserved bits that default to 1; hardwired? */ + } } static void @@ -1076,8 +1061,7 @@ stpc_lpt_init(UNUSED(const device_t *info)) { stpc_log("STPC: lpt_init()\n"); - stpc_lpt_t *dev = (stpc_lpt_t *) malloc(sizeof(stpc_lpt_t)); - memset(dev, 0, sizeof(stpc_lpt_t)); + stpc_lpt_t *dev = (stpc_lpt_t *) calloc(1, sizeof(stpc_lpt_t)); stpc_lpt_reset(dev); @@ -1096,7 +1080,7 @@ const device_t stpc_client_device = { .init = stpc_init, .close = stpc_close, .reset = stpc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1110,7 +1094,7 @@ const device_t stpc_consumer2_device = { .init = stpc_init, .close = stpc_close, .reset = stpc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1124,7 +1108,7 @@ const device_t stpc_elite_device = { .init = stpc_init, .close = stpc_close, .reset = stpc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1138,7 +1122,7 @@ const device_t stpc_atlas_device = { .init = stpc_init, .close = stpc_close, .reset = stpc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1153,7 +1137,7 @@ const device_t stpc_serial_device = { .init = stpc_serial_init, .close = stpc_serial_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1167,7 +1151,7 @@ const device_t stpc_lpt_device = { .init = stpc_lpt_init, .close = stpc_lpt_close, .reset = stpc_lpt_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index fb11af0e7..0ed062450 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -82,6 +82,8 @@ #include <86box/hdd.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> +#include <86box/keyboard.h> +#include <86box/machine.h> #include <86box/pic.h> #include <86box/pci.h> #include <86box/port_92.h> @@ -126,10 +128,10 @@ umc_8886_ide_handler(umc_8886_t *dev) ide_sec_disable(); if (dev->pci_conf_sb[1][0x04] & 0x01) { - if (dev->pci_conf_sb[1][0x40] & 0x80) + if (dev->pci_conf_sb[1][0x41] & 0x80) ide_pri_enable(); - if (dev->pci_conf_sb[1][0x40] & 0x40) + if (dev->pci_conf_sb[1][0x41] & 0x40) ide_sec_enable(); } } @@ -164,11 +166,32 @@ umc_8886_bus_recalc(umc_8886_t *dev) } } +static void +umc_8886_irq_recalc(umc_8886_t *dev) +{ + int irq_routing; + uint8_t *conf = dev->pci_conf_sb[0]; + + irq_routing = (conf[0x46] & 0x01) ? (conf[0x43] >> 4) : PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTA, irq_routing); + irq_routing = (conf[0x46] & 0x02) ? (conf[0x43] & 0x0f) : PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTB, irq_routing); + + irq_routing = (conf[0x46] & 0x04) ? (conf[0x44] >> 4) : PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTC, irq_routing); + irq_routing = (conf[0x46] & 0x08) ? (conf[0x44] & 0x0f) : PCI_IRQ_DISABLED; + pci_set_irq_routing(PCI_INTD, irq_routing); + + pci_set_irq_level(PCI_INTA, (conf[0x47] & 0x01)); + pci_set_irq_level(PCI_INTB, (conf[0x47] & 0x02)); + pci_set_irq_level(PCI_INTC, (conf[0x47] & 0x04)); + pci_set_irq_level(PCI_INTD, (conf[0x47] & 0x08)); +} + static void umc_8886_write(int func, int addr, uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *) priv; - int irq_routing; if (func <= dev->max_func) switch (func) { @@ -183,7 +206,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) case 0x50 ... 0x55: case 0x57: case 0x70 ... 0x76: - case 0x80 ... 0x82: + case 0x80 ... 0x83: case 0x90 ... 0x92: case 0xa0 ... 0xa1: case 0xa5 ... 0xa8: @@ -195,28 +218,12 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) break; case 0x43: - dev->pci_conf_sb[func][addr] = val; - irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) : - PCI_IRQ_DISABLED; - pci_set_irq_routing(PCI_INTA, irq_routing); - irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) : - PCI_IRQ_DISABLED; - pci_set_irq_routing(PCI_INTB, irq_routing); - break; case 0x44: - dev->pci_conf_sb[func][addr] = val; - irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) : - PCI_IRQ_DISABLED; - pci_set_irq_routing(PCI_INTC, irq_routing); - irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) : - PCI_IRQ_DISABLED; - pci_set_irq_routing(PCI_INTD, irq_routing); - break; - case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */ case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */ /* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */ dev->pci_conf_sb[func][addr] = val; + umc_8886_irq_recalc(dev); break; case 0x56: @@ -265,13 +272,13 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) break; case 0x3c: - case 0x41 ... 0x4b: - case 0x54 ... 0x59: + case 0x40: + case 0x42 ... 0x59: if (dev->ide_id == 0x673a) dev->pci_conf_sb[func][addr] = val; break; - case 0x40: + case 0x41: if (dev->ide_id == 0x673a) { dev->pci_conf_sb[func][addr] = val; umc_8886_ide_handler(dev); @@ -317,25 +324,17 @@ umc_8886_reset(void *priv) dev->pci_conf_sb[0][0x09] = 0x00; dev->pci_conf_sb[0][0x0a] = 0x01; dev->pci_conf_sb[0][0x0b] = 0x06; + dev->pci_conf_sb[0][0x40] = 0x01; - dev->pci_conf_sb[0][0x41] = 0x06; + dev->pci_conf_sb[0][0x41] = 0x04; dev->pci_conf_sb[0][0x42] = 0x08; - dev->pci_conf_sb[0][0x43] = 0x00; - dev->pci_conf_sb[0][0x44] = 0x00; - dev->pci_conf_sb[0][0x45] = 0x04; - dev->pci_conf_sb[0][0x46] = 0x00; - dev->pci_conf_sb[0][0x47] = 0x40; - dev->pci_conf_sb[0][0x50] = 0x01; - dev->pci_conf_sb[0][0x51] = 0x03; - dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00; - dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00; - dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00; - dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00; - dev->pci_conf_sb[0][0x82] = 0x00; - dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00; - dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00; - dev->pci_conf_sb[0][0xa4] = 0x00; - dev->pci_conf_sb[0][0xa8] = 0x20; + dev->pci_conf_sb[0][0x43] = 0x9a; + dev->pci_conf_sb[0][0x44] = 0xbc; + dev->pci_conf_sb[0][0x45] = 0x00; + dev->pci_conf_sb[0][0x46] = 0x10; + dev->pci_conf_sb[0][0x47] = 0x30; + + dev->pci_conf_sb[0][0x51] = 0x02; if (dev->has_ide) { dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */ @@ -358,13 +357,15 @@ umc_8886_reset(void *priv) dev->pci_conf_sb[1][0x21] = 0x10; if (dev->ide_id == 0x673a) { - dev->pci_conf_sb[1][0x40] = 0xc0; - dev->pci_conf_sb[1][0x41] = 0x00; + dev->pci_conf_sb[1][0x40] = 0x00; + dev->pci_conf_sb[1][0x41] = 0xc0; dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00; dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00; dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00; - dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00; - dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00; + dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x55; + dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x55; + dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x88; + dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0xaa; dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00; dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00; dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00; @@ -393,8 +394,7 @@ umc_8886_close(void *priv) static void * umc_8886_init(const device_t *info) { - umc_8886_t *dev = (umc_8886_t *) malloc(sizeof(umc_8886_t)); - memset(dev, 0, sizeof(umc_8886_t)); + umc_8886_t *dev = (umc_8886_t *) calloc(1, sizeof(umc_8886_t)); /* Device 12: UMC 8886xx */ pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); @@ -432,7 +432,7 @@ const device_t umc_8886f_device = { .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -446,7 +446,7 @@ const device_t umc_8886af_device = { .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -460,7 +460,7 @@ const device_t umc_8886bf_device = { .init = umc_8886_init, .close = umc_8886_close, .reset = umc_8886_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c index 7de2ca1d0..cb69ce6a8 100644 --- a/src/chipset/umc_8890.c +++ b/src/chipset/umc_8890.c @@ -38,6 +38,7 @@ #include <86box/smram.h> #include <86box/chipset.h> +#include <86box/plat_unused.h> #ifdef ENABLE_UMC_8890_LOG int umc_8890_do_log = ENABLE_UMC_8890_LOG; @@ -209,7 +210,7 @@ umc_8890_close(void *priv) static void * -umc_8890_init(const device_t *info) +umc_8890_init(UNUSED(const device_t *info)) { umc_8890_t *dev = (umc_8890_t *) calloc(1, sizeof(umc_8890_t)); @@ -234,7 +235,7 @@ const device_t umc_8890_device = { .init = umc_8890_init, .close = umc_8890_close, .reset = umc_8890_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index a7ed0b880..889691988 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -136,6 +136,9 @@ hb4_log(const char *fmt, ...) #endif typedef struct hb4_t { + uint8_t idx; + uint8_t access_data; + uint8_t pci_slot; uint8_t pci_conf[256]; /* PCI Registers */ @@ -176,7 +179,9 @@ hb4_shadow_bios_low(hb4_t *dev) int state; /* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */ - state = shadow_bios[dev->pci_conf[0x55] >> 6]; + state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[dev->pci_conf[0x54] & 0x01] : + MEM_READ_EXTANY; + state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[7]) { mem_set_mem_state_both(0xe0000, 0x10000, state); @@ -194,8 +199,9 @@ hb4_shadow_main(hb4_t *dev) int n = 0; for (uint8_t i = 0; i < 6; i++) { - state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] | - shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] : + MEM_READ_EXTANY; + state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[i + 1]) { n++; @@ -212,8 +218,9 @@ hb4_shadow_video(hb4_t *dev) { int state; - state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] | - shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; + state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] : + MEM_READ_EXTANY; + state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01]; if (state != dev->mem_state[0]) { mem_set_mem_state_both(0xc0000, 0x8000, state); @@ -302,7 +309,7 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) hb4_shadow(dev); break; - case 0x56 ... 0x5b: + case 0x56 ... 0x5a: case 0x5e ... 0x5f: dev->pci_conf[addr] = val; break; @@ -313,10 +320,14 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) hb4_smram(dev); break; - case 0x61 ... 0x62: + case 0x61: dev->pci_conf[addr] = val; break; + case 0x62: + dev->pci_conf[addr] = val & 0x03; + break; + default: break; } @@ -354,14 +365,16 @@ hb4_reset(void *priv) dev->pci_conf[0x52] = 0x01; dev->pci_conf[0x53] = 0x00; dev->pci_conf[0x54] = 0x00; - dev->pci_conf[0x55] = 0x00; - dev->pci_conf[0x56] = 0x00; - dev->pci_conf[0x57] = 0x00; - dev->pci_conf[0x58] = 0x00; - dev->pci_conf[0x59] = 0x00; - dev->pci_conf[0x5a] = 0x04; + dev->pci_conf[0x55] = 0x40; + dev->pci_conf[0x56] = 0xff; + dev->pci_conf[0x57] = 0x0f; + dev->pci_conf[0x58] = 0xff; + dev->pci_conf[0x59] = 0x0f; + dev->pci_conf[0x5a] = 0x00; + dev->pci_conf[0x5b] = 0x2c; dev->pci_conf[0x5c] = 0x00; - dev->pci_conf[0x5d] = 0x20; + dev->pci_conf[0x5d] = 0x0f; + dev->pci_conf[0x5e] = 0x00; dev->pci_conf[0x5f] = 0xff; dev->pci_conf[0x60] = 0x00; dev->pci_conf[0x61] = 0x00; @@ -385,11 +398,59 @@ 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)) { - hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t)); - memset(dev, 0, sizeof(hb4_t)); + hb4_t *dev = (hb4_t *) calloc(1, sizeof(hb4_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev, &dev->pci_slot); /* Device 10: UMC 8881x */ @@ -402,6 +463,8 @@ 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; } @@ -413,7 +476,7 @@ const device_t umc_hb4_device = { .init = hb4_init, .close = hb4_close, .reset = hb4_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 20e2c7f74..110b1f8e1 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -725,8 +725,7 @@ via_apollo_reset(void *priv) static void * via_apollo_init(const device_t *info) { - via_apollo_t *dev = (via_apollo_t *) malloc(sizeof(via_apollo_t)); - memset(dev, 0, sizeof(via_apollo_t)); + via_apollo_t *dev = (via_apollo_t *) calloc(1, sizeof(via_apollo_t)); dev->smram = smram_add(); if (dev->id != VIA_8601) @@ -793,7 +792,7 @@ const device_t via_vpx_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -807,7 +806,7 @@ const device_t amd640_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -821,7 +820,7 @@ const device_t via_vp3_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -835,7 +834,7 @@ const device_t via_mvp3_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -849,7 +848,7 @@ const device_t via_apro_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -863,7 +862,7 @@ const device_t via_apro133_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -877,7 +876,7 @@ const device_t via_apro133a_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -891,7 +890,7 @@ const device_t via_vt8601_device = { .init = via_apollo_init, .close = via_apollo_close, .reset = via_apollo_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index 1f153092b..dcfe41811 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -1627,8 +1627,7 @@ pipc_reset(void *priv) static void * pipc_init(const device_t *info) { - pipc_t *dev = (pipc_t *) malloc(sizeof(pipc_t)); - memset(dev, 0, sizeof(pipc_t)); + pipc_t *dev = (pipc_t *) calloc(1, sizeof(pipc_t)); pipc_log("PIPC: init()\n"); @@ -1721,7 +1720,7 @@ const device_t via_vt82c586b_device = { .init = pipc_init, .close = pipc_close, .reset = pipc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1735,7 +1734,7 @@ const device_t via_vt82c596a_device = { .init = pipc_init, .close = pipc_close, .reset = pipc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1749,7 +1748,7 @@ const device_t via_vt82c596b_device = { .init = pipc_init, .close = pipc_close, .reset = pipc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1763,7 +1762,7 @@ const device_t via_vt82c686a_device = { .init = pipc_init, .close = pipc_close, .reset = pipc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1777,7 +1776,7 @@ const device_t via_vt82c686b_device = { .init = pipc_init, .close = pipc_close, .reset = pipc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1791,7 +1790,7 @@ const device_t via_vt8231_device = { .init = pipc_init, .close = pipc_close, .reset = pipc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/via_vt82c49x.c b/src/chipset/via_vt82c49x.c index de55f7060..3aaef55a6 100644 --- a/src/chipset/via_vt82c49x.c +++ b/src/chipset/via_vt82c49x.c @@ -342,8 +342,7 @@ vt82c49x_close(void *priv) static void * vt82c49x_init(const device_t *info) { - vt82c49x_t *dev = (vt82c49x_t *) malloc(sizeof(vt82c49x_t)); - memset(dev, 0x00, sizeof(vt82c49x_t)); + vt82c49x_t *dev = (vt82c49x_t *) calloc(1, sizeof(vt82c49x_t)); dev->smram_smm = smram_add(); dev->smram_low = smram_add(); @@ -375,7 +374,7 @@ const device_t via_vt82c49x_device = { .init = vt82c49x_init, .close = vt82c49x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -389,7 +388,7 @@ const device_t via_vt82c49x_pci_device = { .init = vt82c49x_init, .close = vt82c49x_close, .reset = vt82c49x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -403,7 +402,7 @@ const device_t via_vt82c49x_ide_device = { .init = vt82c49x_init, .close = vt82c49x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -417,7 +416,7 @@ const device_t via_vt82c49x_pci_ide_device = { .init = vt82c49x_init, .close = vt82c49x_close, .reset = vt82c49x_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index 34efbead9..dbbb447c7 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -167,7 +167,7 @@ vt82c505_in(uint16_t addr, void *priv) static void vt82c505_reset(void *priv) { - vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t)); + vt82c505_t *dev = (vt82c505_t *) calloc(1, sizeof(vt82c505_t)); dev->pci_conf[0x04] = 0x07; dev->pci_conf[0x07] = 0x00; @@ -204,8 +204,7 @@ vt82c505_close(void *priv) static void * vt82c505_init(UNUSED(const device_t *info)) { - vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t)); - memset(dev, 0, sizeof(vt82c505_t)); + vt82c505_t *dev = (vt82c505_t *) calloc(1, sizeof(vt82c505_t)); pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev, &dev->pci_slot); @@ -232,7 +231,7 @@ const device_t via_vt82c505_device = { .init = vt82c505_init, .close = vt82c505_close, .reset = vt82c505_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index 00adcc2a4..496544c63 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -180,8 +180,7 @@ vl82c480_close(void *priv) static void * vl82c480_init(const device_t *info) { - vl82c480_t *dev = (vl82c480_t *) malloc(sizeof(vl82c480_t)); - memset(dev, 0, sizeof(vl82c480_t)); + vl82c480_t *dev = (vl82c480_t *) calloc(1, sizeof(vl82c480_t)); dev->regs[0x00] = info->local; dev->regs[0x01] = 0xff; @@ -207,7 +206,7 @@ const device_t vl82c480_device = { .init = vl82c480_init, .close = vl82c480_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -221,7 +220,7 @@ const device_t vl82c486_device = { .init = vl82c480_init, .close = vl82c480_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index df8558b05..a375c8eb6 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -37,6 +37,7 @@ #include <86box/port_92.h> #include <86box/serial.h> #include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/chipset.h> /* Lock/Unlock Procedures */ @@ -541,16 +542,16 @@ wd76c10_ser_par_cs_recalc(wd76c10_t *dev) lpt1_remove(); switch ((dev->ser_par_cs >> 9) & 0x03) { case 1: - lpt1_init(0x3bc); - lpt1_irq(7); + lpt1_setup(LPT_MDA_ADDR); + lpt1_irq(LPT1_IRQ); break; case 2: - lpt1_init(0x378); - lpt1_irq(7); + lpt1_setup(LPT1_ADDR); + lpt1_irq(LPT1_IRQ); break; case 3: - lpt1_init(0x278); - lpt1_irq(7); + lpt1_setup(LPT2_ADDR); + lpt1_irq(LPT1_IRQ); break; } } @@ -879,12 +880,12 @@ wd76c10_reset(void *priv) static void * -wd76c10_init(const device_t *info) +wd76c10_init(UNUSED(const device_t *info)) { wd76c10_t *dev = (wd76c10_t *) calloc(1, sizeof(wd76c10_t)); uint32_t total_mem = mem_size << 10; uint32_t accum_mem = 0x00000000; - ram_bank_t *rb; + ram_bank_t *rb = NULL; /* Calculate the physical RAM banks. */ for (uint8_t i = 0; i < 4; i++) { @@ -1022,7 +1023,7 @@ const device_t wd76c10_device = { .init = wd76c10_init, .close = wd76c10_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt index 3cb9de6ca..3d000c98d 100644 --- a/src/codegen/CMakeLists.txt +++ b/src/codegen/CMakeLists.txt @@ -9,19 +9,28 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # if(DYNAREC) - add_library(dynarec OBJECT codegen.c codegen_ops.c) + add_library(dynarec OBJECT + codegen.c + codegen_ops.c + ) if(ARCH STREQUAL "i386") - target_sources(dynarec PRIVATE codegen_x86.c - codegen_accumulate_x86.c) + target_sources(dynarec PRIVATE + codegen_x86.c + codegen_accumulate_x86.c + ) elseif(ARCH STREQUAL "x86_64") - target_sources(dynarec PRIVATE codegen_x86-64.c - codegen_accumulate_x86-64.c) + target_sources(dynarec PRIVATE + codegen_x86-64.c + codegen_accumulate_x86-64.c + ) else() message(SEND_ERROR "Dynarec is incompatible with target platform ${ARCH}") diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index 6d30211a6..d020fc57f 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -311,6 +311,7 @@ extern codegen_timing_t codegen_timing_686; extern codegen_timing_t codegen_timing_486; extern codegen_timing_t codegen_timing_winchip; extern codegen_timing_t codegen_timing_winchip2; +extern codegen_timing_t codegen_timing_k5; extern codegen_timing_t codegen_timing_k6; extern codegen_timing_t codegen_timing_p6; diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index 28ee6d06c..50ef4310f 100644 --- a/src/codegen/codegen_ops_arith.h +++ b/src/codegen/codegen_ops_arith.h @@ -1,5 +1,5 @@ static uint32_t -ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropINC_rw(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -22,7 +22,7 @@ ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } static uint32_t -ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropINC_rl(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -45,7 +45,7 @@ ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } static uint32_t -ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropDEC_rw(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -68,7 +68,7 @@ ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } static uint32_t -ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropDEC_rl(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -93,7 +93,7 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod #define ROP_ARITH_RMW(name, op, writeback) \ static uint32_t \ - rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_b_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -129,7 +129,7 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc + 1; \ } \ static uint32_t \ - rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_w_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -165,7 +165,7 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc + 1; \ } \ static uint32_t \ - rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_l_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -203,7 +203,7 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod #define ROP_ARITH_RM(name, op, writeback) \ static uint32_t \ - rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_b_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -233,7 +233,7 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc + 1; \ } \ static uint32_t \ - rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_w_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -263,7 +263,7 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc + 1; \ } \ static uint32_t \ - rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_l_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -299,7 +299,7 @@ ROP_ARITH_RM(ADD, ADD, 1) ROP_ARITH_RM(SUB, SUB, 1) static uint32_t -ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_b_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -326,7 +326,7 @@ ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc + 1; } static uint32_t -ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_w_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -353,7 +353,7 @@ ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc + 1; } static uint32_t -ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_l_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -381,7 +381,7 @@ ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c } static uint32_t -ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_b_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -408,7 +408,7 @@ ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_w_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -435,7 +435,7 @@ ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_l_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -463,7 +463,7 @@ ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropADD_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -478,7 +478,7 @@ ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropADD_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -493,7 +493,7 @@ ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropADD_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -510,7 +510,7 @@ ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc } static uint32_t -ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -525,7 +525,7 @@ ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -540,7 +540,7 @@ ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCMP_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -557,7 +557,7 @@ ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc } static uint32_t -ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropSUB_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -572,7 +572,7 @@ ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropSUB_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -587,7 +587,7 @@ ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropSUB_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -604,7 +604,7 @@ ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc } static uint32_t -rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +rop80(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; uint32_t imm; @@ -679,7 +679,7 @@ rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblo } static uint32_t -rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +rop81_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; uint32_t imm; @@ -753,7 +753,7 @@ rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc + 3; } static uint32_t -rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +rop81_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; uint32_t imm; @@ -827,7 +827,7 @@ rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb } static uint32_t -rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +rop83_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; uint32_t imm; @@ -904,7 +904,7 @@ rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc + 2; } static uint32_t -rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +rop83_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; uint32_t imm; diff --git a/src/codegen/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h index 242743dee..a82b10d82 100644 --- a/src/codegen/codegen_ops_fpu.h +++ b/src/codegen/codegen_ops_fpu.h @@ -1,5 +1,5 @@ static uint32_t -ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFXCH(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); @@ -9,7 +9,7 @@ ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb } static uint32_t -ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFLD(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); @@ -19,7 +19,7 @@ ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codebl } static uint32_t -ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFST(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); @@ -28,7 +28,7 @@ ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codebl return op_pc; } static uint32_t -ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSTP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); @@ -39,7 +39,7 @@ ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb } static uint32_t -ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFLDs(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; @@ -57,7 +57,7 @@ ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc + 1; } static uint32_t -ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFLDd(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; @@ -76,7 +76,7 @@ ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb } static uint32_t -ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFILDw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; @@ -94,7 +94,7 @@ ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc + 1; } static uint32_t -ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFILDl(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; @@ -112,7 +112,7 @@ ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc + 1; } static uint32_t -ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFILDq(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; @@ -133,7 +133,7 @@ ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code } static uint32_t -ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSTs(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg; @@ -153,7 +153,7 @@ ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc + 1; } static uint32_t -ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSTd(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg1; @@ -194,24 +194,28 @@ ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return new_pc; } -#define ropFarith(name, size, load, op) \ - static uint32_t \ - ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(FPU_##name); \ - \ - return op_pc + 1; \ +#define ropFarith(name, size, load, op) \ + static uint32_t \ + ropF##name##size(UNUSED(uint8_t opcode), \ + uint32_t fetchdat, \ + uint32_t op_32, \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(FPU_##name); \ + \ + return op_pc + 1; \ } ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); @@ -239,32 +243,40 @@ ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -#define ropFcompare(name, size, load, op) \ - static uint32_t \ - ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(); \ - \ - return op_pc + 1; \ - } \ - static uint32_t ropF##name##P##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - uint32_t new_pc = ropF##name##size(opcode, fetchdat, op_32, op_pc, block); \ - \ - FP_POP(); \ - \ - return new_pc; \ +#define ropFcompare(name, size, load, op) \ + static uint32_t \ + ropF##name##size(UNUSED(uint8_t opcode), \ + uint32_t fetchdat, \ + uint32_t op_32, \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(); \ + \ + return op_pc + 1; \ + } \ + static uint32_t ropF##name##P##size(uint8_t opcode, \ + uint32_t fetchdat, \ + uint32_t op_32, \ + uint32_t op_pc, \ + codeblock_t *block) \ + { \ + uint32_t new_pc = ropF##name##size(opcode, fetchdat, op_32, op_pc, block); \ + \ + FP_POP(); \ + \ + return new_pc; \ } ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); @@ -348,7 +360,7 @@ ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code #endif static uint32_t -ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFADD(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_ADD, 0, opcode & 7); @@ -356,7 +368,7 @@ ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } static uint32_t -ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFCOM(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_COMPARE_REG(0, opcode & 7); @@ -364,7 +376,7 @@ ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } static uint32_t -ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFDIV(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_DIV, 0, opcode & 7); @@ -372,7 +384,7 @@ ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } static uint32_t -ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFDIVR(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_DIVR, 0, opcode & 7); @@ -380,7 +392,7 @@ ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFMUL(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_MUL, 0, opcode & 7); @@ -388,7 +400,7 @@ ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } static uint32_t -ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSUB(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_SUB, 0, opcode & 7); @@ -396,7 +408,7 @@ ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } static uint32_t -ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSUBR(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_SUBR, 0, opcode & 7); @@ -405,7 +417,7 @@ ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code } static uint32_t -ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFADDr(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_ADD, opcode & 7, 0); @@ -413,7 +425,7 @@ ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFDIVr(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_DIV, opcode & 7, 0); @@ -421,7 +433,7 @@ ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFDIVRr(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_DIVR, opcode & 7, 0); @@ -429,7 +441,7 @@ ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } static uint32_t -ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFMULr(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_MUL, opcode & 7, 0); @@ -437,7 +449,7 @@ ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSUBr(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_SUB, opcode & 7, 0); @@ -445,7 +457,7 @@ ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSUBRr(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_SUBR, opcode & 7, 0); @@ -454,7 +466,7 @@ ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFADDP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_ADD, opcode & 7, 0); @@ -463,7 +475,7 @@ ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFCOMP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_COMPARE_REG(0, opcode & 7); @@ -472,7 +484,7 @@ ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFDIVP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_DIV, opcode & 7, 0); @@ -481,7 +493,7 @@ ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFDIVRP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_DIVR, opcode & 7, 0); @@ -490,7 +502,7 @@ ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } static uint32_t -ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFMULP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_MUL, opcode & 7, 0); @@ -499,7 +511,7 @@ ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSUBP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_SUB, opcode & 7, 0); @@ -508,7 +520,7 @@ ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc; } static uint32_t -ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSUBRP(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_OP_REG(FPU_SUBR, opcode & 7, 0); @@ -518,7 +530,7 @@ ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFCOMPP(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_COMPARE_REG(0, 1); @@ -528,7 +540,7 @@ ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSTSW_AX(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -540,7 +552,7 @@ ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c } static uint32_t -ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFISTw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg; @@ -560,7 +572,7 @@ ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc + 1; } static uint32_t -ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFISTl(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg; @@ -599,7 +611,7 @@ ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return new_pc; } static uint32_t -ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFISTPq(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg1; @@ -623,7 +635,7 @@ ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFLDCW(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; @@ -640,7 +652,7 @@ ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc + 1; } static uint32_t -ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFSTCW(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; x86seg *target_seg; @@ -658,7 +670,7 @@ ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code } static uint32_t -ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFCHS(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_FCHS(); @@ -666,17 +678,21 @@ ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc; } -#define opFLDimm(name, v) \ - static uint32_t \ - ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - static double fp_imm = v; \ - static uint64_t *fptr = (uint64_t *) &fp_imm; \ - \ - FP_ENTER(); \ - FP_LOAD_IMM_Q(*fptr); \ - \ - return op_pc; \ +#define opFLDimm(name, v) \ + static uint32_t \ + ropFLD##name(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + static double fp_imm = v; \ + static uint64_t *fptr = (uint64_t *) &fp_imm; \ + \ + FP_ENTER(); \ + FP_LOAD_IMM_Q(*fptr); \ + \ + return op_pc; \ } // clang-format off @@ -689,7 +705,7 @@ opFLDimm(Z, 0.0) // clang-format on static uint32_t -ropFLDLN2(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) +ropFLDLN2(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { FP_ENTER(); FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ULL); diff --git a/src/codegen/codegen_ops_jump.h b/src/codegen/codegen_ops_jump.h index da16ce03e..4572b623b 100644 --- a/src/codegen/codegen_ops_jump.h +++ b/src/codegen/codegen_ops_jump.h @@ -1,5 +1,5 @@ static uint32_t -ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropJMP_r8(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t offset = fetchdat & 0xff; @@ -12,7 +12,7 @@ ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropJMP_r16(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint16_t offset = fetchdat & 0xffff; @@ -22,7 +22,7 @@ ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co } static uint32_t -ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropJMP_r32(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t offset = fastreadl(cs + op_pc); @@ -32,7 +32,7 @@ ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co } static uint32_t -ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropJCXZ(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t offset = fetchdat & 0xff; @@ -51,7 +51,7 @@ ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb } static uint32_t -ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropLOOP(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t offset = fetchdat & 0xff; @@ -214,45 +214,51 @@ BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) } } -#define ropBRANCH(name, func, not ) \ - static uint32_t \ - rop##name(uint8_t opcode, uint32_t fetchdat, \ - uint32_t op_32, uint32_t op_pc, \ - codeblock_t *block) \ - { \ - uint32_t offset = fetchdat & 0xff; \ - \ - if (offset & 0x80) \ - offset |= 0xffffff00; \ - \ - func(1, op_pc, offset, not ); \ - \ - return op_pc + 1; \ - } \ - static uint32_t \ - rop##name##_w(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ - { \ - uint32_t offset = fetchdat & 0xffff; \ - \ - if (offset & 0x8000) \ - offset |= 0xffff0000; \ - \ - func(2, op_pc, offset, not ); \ - \ - return op_pc + 2; \ - } \ - static uint32_t \ - rop##name##_l(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ - { \ - uint32_t offset = fastreadl(cs + op_pc); \ - \ - func(4, op_pc, offset, not ); \ - \ - return op_pc + 4; \ +#define ropBRANCH(name, func, not ) \ + static uint32_t \ + rop##name(UNUSED(uint8_t opcode), \ + uint32_t fetchdat, \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + uint32_t offset = fetchdat & 0xff; \ + \ + if (offset & 0x80) \ + offset |= 0xffffff00; \ + \ + func(1, op_pc, offset, not ); \ + \ + return op_pc + 1; \ + } \ + static uint32_t \ + rop##name##_w(UNUSED(uint8_t opcode), \ + uint32_t fetchdat, \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + uint32_t offset = fetchdat & 0xffff; \ + \ + if (offset & 0x8000) \ + offset |= 0xffff0000; \ + \ + func(2, op_pc, offset, not ); \ + \ + return op_pc + 2; \ + } \ + static uint32_t \ + rop##name##_l(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + \ + func(4, op_pc, offset, not ); \ + \ + return op_pc + 4; \ } // clang-format off diff --git a/src/codegen/codegen_ops_logic.h b/src/codegen/codegen_ops_logic.h index 9f23723e2..2c79c4a2d 100644 --- a/src/codegen/codegen_ops_logic.h +++ b/src/codegen/codegen_ops_logic.h @@ -1,6 +1,6 @@ #define ROP_LOGIC(name, op, writeback) \ static uint32_t \ - rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_b_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -33,7 +33,7 @@ return op_pc + 1; \ } \ static uint32_t \ - rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_w_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -66,7 +66,7 @@ return op_pc + 1; \ } \ static uint32_t \ - rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_l_rmw(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -99,7 +99,7 @@ return op_pc + 1; \ } \ static uint32_t \ - rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_b_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -126,7 +126,7 @@ return op_pc + 1; \ } \ static uint32_t \ - rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_w_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -153,7 +153,7 @@ return op_pc + 1; \ } \ static uint32_t \ - rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + rop##name##_l_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int src_reg; \ int dst_reg; \ @@ -185,7 +185,7 @@ ROP_LOGIC(OR, OR, 1) ROP_LOGIC(XOR, XOR, 1) static uint32_t -ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropTEST_b_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -209,7 +209,7 @@ ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropTEST_w_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -233,7 +233,7 @@ ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropTEST_l_rm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -258,7 +258,7 @@ ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropAND_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -270,7 +270,7 @@ ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropAND_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -282,7 +282,7 @@ ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropAND_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -296,7 +296,7 @@ ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc } static uint32_t -ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropOR_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -308,7 +308,7 @@ ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropOR_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -320,7 +320,7 @@ ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropOR_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -334,7 +334,7 @@ ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropTEST_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -346,7 +346,7 @@ ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc return op_pc + 1; } static uint32_t -ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropTEST_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -358,7 +358,7 @@ ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc return op_pc + 2; } static uint32_t -ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropTEST_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -372,7 +372,7 @@ ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_p } static uint32_t -ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropXOR_AL_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B(REG_AL); @@ -384,7 +384,7 @@ ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropXOR_AX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W(REG_AX); @@ -396,7 +396,7 @@ ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropXOR_EAX_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_L(REG_EAX); @@ -410,7 +410,7 @@ ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc } static uint32_t -ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropF6(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg; @@ -458,7 +458,7 @@ ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblo return 0; } static uint32_t -ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropF7_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg; @@ -506,7 +506,7 @@ ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return 0; } static uint32_t -ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropF7_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg; int host_reg; diff --git a/src/codegen/codegen_ops_misc.h b/src/codegen/codegen_ops_misc.h index 61854ab37..db16dc09e 100644 --- a/src/codegen/codegen_ops_misc.h +++ b/src/codegen/codegen_ops_misc.h @@ -1,24 +1,24 @@ static uint32_t -ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropNOP(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { return op_pc; } static uint32_t -ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCLD(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { CLEAR_BITS((uintptr_t) &cpu_state.flags, D_FLAG); return op_pc; } static uint32_t -ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropSTD(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { SET_BITS((uintptr_t) &cpu_state.flags, D_FLAG); return op_pc; } static uint32_t -ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCLI(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) return 0; @@ -29,7 +29,7 @@ ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codebl return op_pc; } static uint32_t -ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropSTI(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) return 0; @@ -38,7 +38,7 @@ ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codebl } static uint32_t -ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFE(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int host_reg; @@ -88,7 +88,7 @@ ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblo } static uint32_t codegen_temp; static uint32_t -ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFF_16(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int host_reg; @@ -175,7 +175,7 @@ ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return 0; } static uint32_t -ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropFF_32(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int host_reg; diff --git a/src/codegen/codegen_ops_mmx.h b/src/codegen/codegen_ops_mmx.h index 4c5a92c8f..2e07bde77 100644 --- a/src/codegen/codegen_ops_mmx.h +++ b/src/codegen/codegen_ops_mmx.h @@ -1,5 +1,5 @@ static uint32_t -ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVQ_q_mm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg1; int host_reg2 = 0; @@ -25,7 +25,7 @@ ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVQ_mm_q(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { MMX_ENTER(); @@ -50,7 +50,7 @@ ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVD_l_mm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -74,7 +74,7 @@ ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVD_mm_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { MMX_ENTER(); @@ -95,36 +95,40 @@ ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } -#define MMX_OP(name, func) \ - static uint32_t \ - name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg1; \ - int src_reg2; \ - int xmm_src; \ - int xmm_dst; \ - \ - MMX_ENTER(); \ - \ - if ((fetchdat & 0xc0) == 0xc0) { \ - xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ - } else { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - \ - MEM_LOAD_ADDR_EA_Q(target_seg); \ - src_reg1 = LOAD_Q_REG_1; \ - src_reg2 = LOAD_Q_REG_2; \ - xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ - } \ - xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ - func(xmm_dst, xmm_src); \ - STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ - \ - return op_pc + 1; \ +#define MMX_OP(name, func) \ + static uint32_t \ + name(UNUSED(uint8_t opcode), \ + uint32_t fetchdat, \ + uint32_t op_32, \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + int src_reg1; \ + int src_reg2; \ + int xmm_src; \ + int xmm_dst; \ + \ + MMX_ENTER(); \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + \ + MEM_LOAD_ADDR_EA_Q(target_seg); \ + src_reg1 = LOAD_Q_REG_1; \ + src_reg2 = LOAD_Q_REG_2; \ + xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ + } \ + xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ + func(xmm_dst, xmm_src); \ + STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ + \ + return op_pc + 1; \ } MMX_OP(ropPAND, MMX_AND) @@ -179,7 +183,7 @@ MMX_OP(ropPMULHW, MMX_PMULHW); MMX_OP(ropPMADDWD, MMX_PMADDWD); static uint32_t -ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPSxxW_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int xmm_dst; @@ -207,7 +211,7 @@ ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPSxxD_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int xmm_dst; @@ -235,7 +239,7 @@ ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPSxxQ_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int xmm_dst; @@ -264,7 +268,7 @@ ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropEMMS(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc), UNUSED(codeblock_t *block)) { codegen_mmx_entered = 0; diff --git a/src/codegen/codegen_ops_mov.h b/src/codegen/codegen_ops_mov.h index 04c4bf2bc..039489035 100644 --- a/src/codegen/codegen_ops_mov.h +++ b/src/codegen/codegen_ops_mov.h @@ -1,19 +1,19 @@ static uint32_t -ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); return op_pc + 1; } static uint32_t -ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); return op_pc + 2; } static uint32_t -ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { fetchdat = fastreadl(cs + op_pc); @@ -23,7 +23,7 @@ ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_b_r(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); @@ -44,7 +44,7 @@ ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co return op_pc + 1; } static uint32_t -ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_w_r(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); @@ -66,7 +66,7 @@ ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co } static uint32_t -ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_l_r(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -90,7 +90,7 @@ ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co } static uint32_t -ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_r_b(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_B(fetchdat & 7); @@ -109,7 +109,7 @@ ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co return op_pc + 1; } static uint32_t -ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_r_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_W(fetchdat & 7); @@ -128,7 +128,7 @@ ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co return op_pc + 1; } static uint32_t -ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_r_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_L(fetchdat & 7); @@ -148,7 +148,7 @@ ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co } static uint32_t -ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_b_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); @@ -167,7 +167,7 @@ ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 2; } static uint32_t -ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_w_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); @@ -186,7 +186,7 @@ ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 3; } static uint32_t -ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_l_imm(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { uint32_t imm = fastreadl(cs + op_pc + 1); @@ -208,7 +208,7 @@ ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_AL_a(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t addr; @@ -226,7 +226,7 @@ ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc + ((op_32 & 0x200) ? 4 : 2); } static uint32_t -ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_AX_a(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t addr; @@ -244,7 +244,7 @@ ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc + ((op_32 & 0x200) ? 4 : 2); } static uint32_t -ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_EAX_a(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t addr; @@ -263,7 +263,7 @@ ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_a_AL(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t addr; int host_reg; @@ -284,7 +284,7 @@ ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc + ((op_32 & 0x200) ? 4 : 2); } static uint32_t -ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_a_AX(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t addr; int host_reg; @@ -305,7 +305,7 @@ ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc + ((op_32 & 0x200) ? 4 : 2); } static uint32_t -ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_a_EAX(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t addr; int host_reg; @@ -327,7 +327,7 @@ ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropLEA_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int dest_reg = (fetchdat >> 3) & 7; @@ -341,7 +341,7 @@ ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code return op_pc + 1; } static uint32_t -ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropLEA_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int dest_reg = (fetchdat >> 3) & 7; @@ -356,7 +356,7 @@ ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code } static uint32_t -ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVZX_w_b(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_B(fetchdat & 7); @@ -377,7 +377,7 @@ ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVZX_l_b(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_B(fetchdat & 7); @@ -398,7 +398,7 @@ ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVZX_l_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_W(fetchdat & 7); @@ -420,7 +420,7 @@ ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVSX_w_b(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_B(fetchdat & 7); @@ -441,7 +441,7 @@ ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVSX_l_b(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_B(fetchdat & 7); @@ -462,7 +462,7 @@ ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOVSX_l_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { if ((fetchdat & 0xc0) == 0xc0) { int host_reg = LOAD_REG_W(fetchdat & 7); @@ -484,7 +484,7 @@ ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_w_seg(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -531,7 +531,7 @@ ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; } static uint32_t -ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropMOV_seg_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -578,7 +578,7 @@ ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } #define ropLseg(seg, rseg) \ - static uint32_t ropL##seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + static uint32_t ropL##seg(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) \ { \ int dest_reg = (fetchdat >> 3) & 7; \ x86seg *target_seg; \ diff --git a/src/codegen/codegen_ops_shift.h b/src/codegen/codegen_ops_shift.h index d750bfcad..a36fb3fdc 100644 --- a/src/codegen/codegen_ops_shift.h +++ b/src/codegen/codegen_ops_shift.h @@ -43,7 +43,7 @@ } static uint32_t -ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropC0(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int count; @@ -57,7 +57,7 @@ ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblo return op_pc + 2; } static uint32_t -ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropC1_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int count; @@ -71,7 +71,7 @@ ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc + 2; } static uint32_t -ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropC1_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int count; @@ -86,7 +86,7 @@ ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb } static uint32_t -ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropD0(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int count = 1; @@ -100,7 +100,7 @@ ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblo return op_pc + 1; } static uint32_t -ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropD1_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int count = 1; @@ -114,7 +114,7 @@ ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb return op_pc + 1; } static uint32_t -ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropD1_l(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, UNUSED(codeblock_t *block)) { x86seg *target_seg = NULL; int count = 1; diff --git a/src/codegen/codegen_ops_stack.h b/src/codegen/codegen_ops_stack.h index 342ddedd4..b7e3d66fe 100644 --- a/src/codegen/codegen_ops_stack.h +++ b/src/codegen/codegen_ops_stack.h @@ -1,5 +1,5 @@ static uint32_t -ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPUSH_16(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -12,7 +12,7 @@ ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co return op_pc; } static uint32_t -ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPUSH_32(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -26,7 +26,7 @@ ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, co } static uint32_t -ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPUSH_imm_16(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint16_t imm = fetchdat & 0xffff; int host_reg; @@ -40,7 +40,7 @@ ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc return op_pc + 2; } static uint32_t -ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPUSH_imm_32(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t imm = fastreadl(cs + op_pc); int host_reg; @@ -55,7 +55,7 @@ ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc } static uint32_t -ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPUSH_imm_b16(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint16_t imm = fetchdat & 0xff; int host_reg; @@ -72,7 +72,7 @@ ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_p return op_pc + 1; } static uint32_t -ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPUSH_imm_b32(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t imm = fetchdat & 0xff; int host_reg; @@ -90,7 +90,7 @@ ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_p } static uint32_t -ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPOP_16(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -101,7 +101,7 @@ ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc; } static uint32_t -ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropPOP_32(uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -113,7 +113,7 @@ ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropRET_16(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc), UNUSED(codeblock_t *block)) { STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -124,7 +124,7 @@ ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return -1; } static uint32_t -ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropRET_32(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc), UNUSED(codeblock_t *block)) { STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -136,7 +136,7 @@ ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod } static uint32_t -ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropRET_imm_16(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc), UNUSED(codeblock_t *block)) { uint16_t offset = fetchdat & 0xffff; @@ -149,7 +149,7 @@ ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return -1; } static uint32_t -ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropRET_imm_32(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc), UNUSED(codeblock_t *block)) { uint16_t offset = fetchdat & 0xffff; @@ -163,7 +163,7 @@ ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, } static uint32_t -ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCALL_r16(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint16_t offset = fetchdat & 0xffff; int host_reg; @@ -178,7 +178,7 @@ ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return -1; } static uint32_t -ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropCALL_r32(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { uint32_t offset = fastreadl(cs + op_pc); int host_reg; @@ -194,7 +194,7 @@ ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c } static uint32_t -ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropLEAVE_16(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -209,7 +209,7 @@ ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc; } static uint32_t -ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropLEAVE_32(UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int host_reg; @@ -224,32 +224,40 @@ ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c return op_pc; } -#define ROP_PUSH_SEG(seg) \ - static uint32_t \ - ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-2); \ - host_reg = LOAD_VAR_W((uintptr_t) &seg); \ - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-2); \ - \ - return op_pc; \ - } \ - static uint32_t \ - ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-4); \ - host_reg = LOAD_VAR_W((uintptr_t) &seg); \ - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-4); \ - \ - return op_pc; \ +#define ROP_PUSH_SEG(seg) \ + static uint32_t \ + ropPUSH_##seg##_16(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-2); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-2); \ + \ + return op_pc; \ + } \ + static uint32_t \ + ropPUSH_##seg##_32(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-4); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-4); \ + \ + return op_pc; \ } ROP_PUSH_SEG(CS) @@ -259,28 +267,36 @@ ROP_PUSH_SEG(FS) ROP_PUSH_SEG(GS) ROP_PUSH_SEG(SS) -#define ROP_POP_SEG(seg, rseg) \ - static uint32_t \ - ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(2); \ - \ - return op_pc; \ - } \ - static uint32_t \ - ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(4); \ - \ - return op_pc; \ +#define ROP_POP_SEG(seg, rseg) \ + static uint32_t \ + ropPOP_##seg##_16(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(2); \ + \ + return op_pc; \ + } \ + static uint32_t \ + ropPOP_##seg##_32(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(4); \ + \ + return op_pc; \ } ROP_POP_SEG(DS, cpu_state.seg_ds) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 08b9ee5f2..e46f55a05 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -55,7 +55,7 @@ call_long(uintptr_t func) } static __inline void -load_param_1_32(codeblock_t *block, uint32_t param) +load_param_1_32(UNUSED(codeblock_t *block), uint32_t param) { #if _WIN64 addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ @@ -93,7 +93,7 @@ static __inline void load_param_1_64(codeblock_t *block, uint64_t param) #endif static __inline void -load_param_2_32(codeblock_t *block, uint32_t param) +load_param_2_32(UNUSED(codeblock_t *block), uint32_t param) { #if _WIN64 addbyte(0xba); /*MOVL $fetchdat,%edx*/ @@ -118,7 +118,7 @@ load_param_2_reg_32(int reg) #endif } static __inline void -load_param_2_64(codeblock_t *block, uint64_t param) +load_param_2_64(UNUSED(codeblock_t *block), uint64_t param) { addbyte(0x48); #if _WIN64 @@ -1492,7 +1492,7 @@ MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) /*done:*/ } static __inline void -MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, UNUSED(int host_reg2)) { if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR ECX, ECX*/ @@ -3926,7 +3926,7 @@ FP_LOAD_REG(int reg) return REG_EBX; } static __inline void -FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +FP_LOAD_REG_D(int reg, int *host_reg1, UNUSED(int *host_reg2)) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); @@ -4086,7 +4086,7 @@ FP_LOAD_REG_INT(int reg) return REG_EBX; } static __inline void -FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +FP_LOAD_REG_INT_Q(int reg, int *host_reg1, UNUSED(int *host_reg2)) { addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); @@ -4693,7 +4693,7 @@ LOAD_MMX_D(int guest_reg) return host_reg; } static __inline void -LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +LOAD_MMX_Q(int guest_reg, int *host_reg1, UNUSED(int *host_reg2)) { int host_reg = REG_EBX; @@ -4725,7 +4725,7 @@ LOAD_MMX_Q_MMX(int guest_reg) } static __inline int -LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +LOAD_INT_TO_MMX(int src_reg1, UNUSED(int src_reg2)) { int dst_reg = find_host_xmm_reg(); host_reg_xmm_mapping[dst_reg] = 100; @@ -4758,7 +4758,7 @@ STORE_MMX_LQ(int guest_reg, int host_reg1) addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } static __inline void -STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +STORE_MMX_Q(int guest_reg, int host_reg1, UNUSED(int host_reg2)) { if (host_reg1 & 8) addbyte(0x4c); diff --git a/src/codegen/codegen_ops_xchg.h b/src/codegen/codegen_ops_xchg.h index 28a558078..467f711e4 100644 --- a/src/codegen/codegen_ops_xchg.h +++ b/src/codegen/codegen_ops_xchg.h @@ -1,16 +1,20 @@ -#define OP_XCHG_AX_(reg) \ - static uint32_t \ - ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int ax_reg, host_reg, temp_reg; \ - \ - ax_reg = LOAD_REG_W(REG_AX); \ - host_reg = LOAD_REG_W(REG_##reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \ - STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ - \ - return op_pc; \ +#define OP_XCHG_AX_(reg) \ + static uint32_t \ + ropXCHG_AX_##reg(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + int ax_reg, host_reg, temp_reg; \ + \ + ax_reg = LOAD_REG_W(REG_AX); \ + host_reg = LOAD_REG_W(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \ + STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ + \ + return op_pc; \ } OP_XCHG_AX_(BX) @@ -21,19 +25,23 @@ OP_XCHG_AX_(DI) OP_XCHG_AX_(SP) OP_XCHG_AX_(BP) -#define OP_XCHG_EAX_(reg) \ - static uint32_t \ - ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int eax_reg, host_reg, temp_reg; \ - \ - eax_reg = LOAD_REG_L(REG_EAX); \ - host_reg = LOAD_REG_L(REG_##reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \ - STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ - \ - return op_pc; \ +#define OP_XCHG_EAX_(reg) \ + static uint32_t \ + ropXCHG_EAX_##reg(UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc, \ + UNUSED(codeblock_t *block)) \ + { \ + int eax_reg, host_reg, temp_reg; \ + \ + eax_reg = LOAD_REG_L(REG_EAX); \ + host_reg = LOAD_REG_L(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \ + STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ + \ + return op_pc; \ } OP_XCHG_EAX_(EBX) @@ -45,7 +53,7 @@ OP_XCHG_EAX_(ESP) OP_XCHG_EAX_(EBP) static uint32_t -ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropXCHG_b(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -63,7 +71,7 @@ ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc + 1; } static uint32_t -ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropXCHG_w(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; @@ -81,7 +89,7 @@ ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod return op_pc + 1; } static uint32_t -ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +ropXCHG_l(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block)) { int src_reg; int dst_reg; diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index 958872162..04c2136ff 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -7,6 +7,7 @@ # include # define HAVE_STDARG_H # include <86box/86box.h> +# include <86box/plat.h> # include "cpu.h" # include "x86.h" # include "x86_flags.h" @@ -25,14 +26,6 @@ # include "codegen_ops.h" # include "codegen_ops_x86-64.h" -# if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) -# include -# include -# endif -# if _WIN64 -# include -# endif - int codegen_flat_ds; int codegen_flat_ss; int codegen_flags_changed = 0; @@ -68,13 +61,7 @@ static int last_ssegs; void codegen_init(void) { -# if _WIN64 - codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -# elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) - codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); -# else - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); -# endif + codeblock = plat_mmap(BLOCK_SIZE * sizeof(codeblock_t), 1); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); @@ -138,7 +125,7 @@ add_to_block_list(codeblock_t *block) } static void -remove_from_block_list(codeblock_t *block, uint32_t pc) +remove_from_block_list(codeblock_t *block, UNUSED(uint32_t pc)) { if (!block->page_mask) return; diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index 74c209001..df0ed3bfd 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -44,6 +44,7 @@ # include # include # include <86box/86box.h> +# include <86box/plat.h> # include "cpu.h" # include <86box/mem.h> # include "x86.h" @@ -64,14 +65,6 @@ # include "codegen_ops.h" # include "codegen_ops_x86.h" -# ifdef __unix__ -# include -# include -# endif -# if defined _WIN32 -# include -# endif - int codegen_flat_ds; int codegen_flat_ss; int mmx_ebx_ecx_loaded; @@ -1194,13 +1187,7 @@ gen_MEM_CHECK_WRITE_L(void) void codegen_init(void) { -# ifdef _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -# elif defined __unix__ - codeblock = mmap(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); -# else - codeblock = malloc((BLOCK_SIZE + 1) * sizeof(codeblock_t)); -# endif + codeblock = plat_mmap((BLOCK_SIZE + 1) * sizeof(codeblock_t), 1); codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); memset(codeblock, 0, (BLOCK_SIZE + 1) * sizeof(codeblock_t)); diff --git a/src/codegen_new/CMakeLists.txt b/src/codegen_new/CMakeLists.txt index 038f1edd1..cee7d5cb9 100644 --- a/src/codegen_new/CMakeLists.txt +++ b/src/codegen_new/CMakeLists.txt @@ -9,39 +9,71 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # if(DYNAREC) - add_library(dynarec OBJECT codegen.c codegen_accumulate.c - codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c - codegen_ops_3dnow.c codegen_ops_branch.c codegen_ops_arith.c - codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c - codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c - codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c - codegen_ops_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c - codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c - codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_mov.c - codegen_ops_shift.c codegen_ops_stack.c codegen_reg.c) + add_library(dynarec OBJECT + codegen.c + codegen_accumulate.c + codegen_allocator.c + codegen_block.c + codegen_ir.c + codegen_ops.c + codegen_ops_3dnow.c + codegen_ops_branch.c + codegen_ops_arith.c + codegen_ops_fpu_arith.c + codegen_ops_fpu_constant.c + codegen_ops_fpu_loadstore.c + codegen_ops_fpu_misc.c + codegen_ops_helpers.c + codegen_ops_jump.c + codegen_ops_logic.c + codegen_ops_misc.c + codegen_ops_mmx_arith.c + codegen_ops_mmx_cmp.c + codegen_ops_mmx_loadstore.c + codegen_ops_mmx_logic.c + codegen_ops_mmx_pack.c + codegen_ops_mmx_shift.c + codegen_ops_mov.c + codegen_ops_shift.c + codegen_ops_stack.c + codegen_reg.c + ) if(ARCH STREQUAL "i386") - target_sources(dynarec PRIVATE codegen_backend_x86.c - codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c + target_sources(dynarec PRIVATE + codegen_backend_x86.c + codegen_backend_x86_ops.c + codegen_backend_x86_ops_fpu.c codegen_backend_x86_ops_sse.c - codegen_backend_x86_uops.c) + codegen_backend_x86_uops.c + ) elseif(ARCH STREQUAL "x86_64") - target_sources(dynarec PRIVATE codegen_backend_x86-64.c + target_sources(dynarec PRIVATE + codegen_backend_x86-64.c codegen_backend_x86-64_ops.c codegen_backend_x86-64_ops_sse.c - codegen_backend_x86-64_uops.c) + codegen_backend_x86-64_uops.c + ) elseif(ARCH STREQUAL "arm64") - target_sources(dynarec PRIVATE codegen_backend_arm64.c - codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c - codegen_backend_arm64_imm.c) + target_sources(dynarec PRIVATE + codegen_backend_arm64.c + codegen_backend_arm64_ops.c + codegen_backend_arm64_uops.c + codegen_backend_arm64_imm.c + ) elseif(ARCH STREQUAL "arm") - target_sources(dynarec PRIVATE codegen_backend_arm.c - codegen_backend_arm_ops.c codegen_backend_arm_uops.c) + target_sources(dynarec PRIVATE + codegen_backend_arm.c + codegen_backend_arm_ops.c + codegen_backend_arm_uops.c + ) else() message(SEND_ERROR "Dynarec is incompatible with target platform ${ARCH}") diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index a3f4ede8f..39ab69b3d 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -21,8 +21,7 @@ #define MAX_INSTRUCTION_COUNT 50 -static struct -{ +static struct { uint32_t pc; int op_ssegs; x86seg *op_ea_seg; diff --git a/src/codegen_new/codegen.h b/src/codegen_new/codegen.h index deeeb899c..eecfa249b 100644 --- a/src/codegen_new/codegen.h +++ b/src/codegen_new/codegen.h @@ -341,6 +341,7 @@ extern codegen_timing_t codegen_timing_686; extern codegen_timing_t codegen_timing_486; extern codegen_timing_t codegen_timing_winchip; extern codegen_timing_t codegen_timing_winchip2; +extern codegen_timing_t codegen_timing_k5; extern codegen_timing_t codegen_timing_k6; extern codegen_timing_t codegen_timing_p6; diff --git a/src/codegen_new/codegen_accumulate.c b/src/codegen_new/codegen_accumulate.c index 29b05ad77..087d9c797 100644 --- a/src/codegen_new/codegen_accumulate.c +++ b/src/codegen_new/codegen_accumulate.c @@ -8,8 +8,7 @@ #include "codegen_accumulate.h" #include "codegen_ir.h" -static struct -{ +static struct { int count; int dest_reg; } acc_regs[] = { diff --git a/src/codegen_new/codegen_allocator.c b/src/codegen_new/codegen_allocator.c index 90e619d70..3cdb731b9 100644 --- a/src/codegen_new/codegen_allocator.c +++ b/src/codegen_new/codegen_allocator.c @@ -13,6 +13,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat.h> #include <86box/plat_unused.h> #include "codegen.h" @@ -33,15 +34,7 @@ int codegen_allocator_usage = 0; void codegen_allocator_init(void) { -#if defined WIN32 || defined _WIN32 || defined _WIN32 - mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - /* TODO: check deployment target: older Intel-based versions of macOS don't play - nice with MAP_JIT. */ -#elif defined(__APPLE__) && defined(MAP_JIT) - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0); -#else - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); -#endif + mem_block_alloc = plat_mmap(MEM_BLOCK_NR * MEM_BLOCK_SIZE, 1); for (uint32_t c = 0; c < MEM_BLOCK_NR; c++) { mem_blocks[c].offset = c * MEM_BLOCK_SIZE; diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index 6345bbe86..ed8ae051f 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "codegen.h" #include "codegen_allocator.h" diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 26a1c3cb4..9bd2f9afe 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -410,7 +410,7 @@ uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) } static inline void -uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) +uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, UNUSED(int arg), int src_reg_a) { uop_t *uop = uop_alloc(ir, uop_type); diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 59e148659..bb7d1f3ee 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "codegen.h" #include "codegen_ir.h" diff --git a/src/codegen_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c index 8b4d471ba..e827d0d27 100644 --- a/src/codegen_new/codegen_ops_3dnow.c +++ b/src/codegen_new/codegen_ops_3dnow.c @@ -16,28 +16,29 @@ #include "codegen_ops_3dnow.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ - uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) { \ - int src_reg = fetchdat & 7; \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } else { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - codegen_mark_code_present(block, cs + op_pc + 1, 1); \ - return op_pc + 2; \ +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + codegen_mark_code_present(block, cs + op_pc + 1, 1); \ + return op_pc + 2; \ } // clang-format off @@ -192,7 +193,7 @@ ropPFRSQRT(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f } uint32_t -ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MMX_ENTER(ir); diff --git a/src/codegen_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c index 9e136ace5..c899c13d8 100644 --- a/src/codegen_new/codegen_ops_arith.c +++ b/src/codegen_new/codegen_ops_arith.c @@ -22,7 +22,7 @@ get_cf(ir_data_t *ir, int dest_reg) } uint32_t -ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -39,7 +39,7 @@ ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -274,7 +274,7 @@ ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -289,7 +289,7 @@ ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -511,7 +511,7 @@ ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -526,7 +526,7 @@ ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -734,7 +734,7 @@ ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -751,7 +751,7 @@ ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -988,7 +988,7 @@ ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -1003,7 +1003,7 @@ ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -2293,7 +2293,7 @@ rebuild_c(ir_data_t *ir) } uint32_t -ropINC_r16(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropINC_r16(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2307,7 +2307,7 @@ ropINC_r16(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opc return op_pc; } uint32_t -ropINC_r32(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropINC_r32(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2322,7 +2322,7 @@ ropINC_r32(UNUSED(UNUSED(codeblock_t *block)), ir_data_t *ir, UNUSED(uint8_t opc } uint32_t -ropDEC_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropDEC_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); @@ -2336,7 +2336,7 @@ ropDEC_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } uint32_t -ropDEC_r32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropDEC_r32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { rebuild_c(ir); diff --git a/src/codegen_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c index cedb54177..2039b6d79 100644 --- a/src/codegen_new/codegen_ops_branch.c +++ b/src/codegen_new/codegen_ops_branch.c @@ -815,43 +815,59 @@ ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t n } } -#define ropJ(cond) \ - uint32_t ropJ##cond##_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); \ - uint32_t dest_addr = op_pc + 1 + offset; \ - int ret; \ - \ - if (!(op_32 & 0x100)) \ - dest_addr &= 0xffff; \ - ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 1); \ - \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - return ret ? dest_addr : (op_pc + 1); \ - } \ - uint32_t ropJ##cond##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); \ - uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ - int ret; \ - \ - ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 2); \ - \ - codegen_mark_code_present(block, cs + op_pc, 2); \ - return ret ? dest_addr : (op_pc + 2); \ - } \ - uint32_t ropJ##cond##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - uint32_t offset = fastreadl(cs + op_pc); \ - uint32_t dest_addr = op_pc + 4 + offset; \ - int ret; \ - \ - ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 4); \ - \ - codegen_mark_code_present(block, cs + op_pc, 4); \ - return ret ? dest_addr : (op_pc + 4); \ +#define ropJ(cond) \ + uint32_t ropJ##cond##_8(codeblock_t *block, \ + ir_data_t *ir, \ + UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + uint32_t op_32, \ + uint32_t op_pc) \ + { \ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); \ + uint32_t dest_addr = op_pc + 1 + offset; \ + int ret; \ + \ + if (!(op_32 & 0x100)) \ + dest_addr &= 0xffff; \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 1); \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + return ret ? dest_addr : (op_pc + 1); \ + } \ + uint32_t ropJ##cond##_16(codeblock_t *block, \ + ir_data_t *ir, \ + UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc) \ + { \ + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); \ + uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 2); \ + \ + codegen_mark_code_present(block, cs + op_pc, 2); \ + return ret ? dest_addr : (op_pc + 2); \ + } \ + uint32_t ropJ##cond##_32(codeblock_t *block, \ + ir_data_t *ir, \ + UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), \ + UNUSED(uint32_t op_32), \ + uint32_t op_pc) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + uint32_t dest_addr = op_pc + 4 + offset; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 4); \ + \ + codegen_mark_code_present(block, cs + op_pc, 4); \ + return ret ? dest_addr : (op_pc + 4); \ } +// clang-format off ropJ(O) ropJ(NO) ropJ(B) @@ -868,9 +884,10 @@ ropJ(L) ropJ(NL) ropJ(LE) ropJ(NLE) +// clang-format on uint32_t -ropJCXZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJCXZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -892,7 +909,7 @@ ropJCXZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc } uint32_t -ropLOOP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLOOP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -932,7 +949,7 @@ ropLOOP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc } uint32_t -ropLOOPE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLOOPE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -965,7 +982,7 @@ ropLOOPE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet return op_pc + 1; } uint32_t -ropLOOPNE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropLOOPNE(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index a7b5290f4..1568852df 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -79,7 +79,7 @@ ropFCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet return op_pc; } uint32_t -ropFCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); @@ -289,7 +289,7 @@ ropFUCOMP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe return op_pc; } uint32_t -ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); @@ -300,131 +300,139 @@ ropFUCOMPP(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f return op_pc; } -#define ropF_arith_mem(name, load_uop) \ - uint32_t ropFADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - if ((cpu_state.npxc >> 10) & 3) \ - return 0; \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFCOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFCOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFSUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFSUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ +#define ropF_arith_mem(name, load_uop) \ + uint32_t ropFADD##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + if ((cpu_state.npxc >> 10) & 3) \ + return 0; \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOM##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOMP##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIV##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIVR##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFMUL##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUB##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUBR##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ } // clang-format off @@ -432,144 +440,154 @@ ropF_arith_mem(s, uop_MEM_LOAD_SINGLE) ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) // clang-format on -#define ropFI_arith_mem(name, temp_reg) \ - uint32_t ropFIADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFICOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFICOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFIDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFIDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFIMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFISUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ - } \ - uint32_t ropFISUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc + 1; \ +#define ropFI_arith_mem(name, temp_reg) \ + uint32_t ropFIADD##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOM##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOMP##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIV##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIVR##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIMUL##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUB##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUBR##name(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ } +// clang-format off ropFI_arith_mem(l, IREG_temp0) ropFI_arith_mem(w, IREG_temp0_W) +// clang-format on uint32_t -ropFABS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFABS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FABS(ir, IREG_ST(0), IREG_ST(0)); @@ -579,7 +597,7 @@ ropFABS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3 } uint32_t -ropFCHS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFCHS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); @@ -588,7 +606,7 @@ ropFCHS(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint3 return op_pc; } uint32_t -ropFSQRT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFSQRT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); @@ -597,7 +615,7 @@ ropFSQRT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint return op_pc; } uint32_t -ropFTST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFTST(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index a91d675c5..6ec2f6888 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -19,7 +19,7 @@ #include "codegen_ops_helpers.h" uint32_t -ropFLD1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFLD1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_MOV_IMM(ir, IREG_temp0, 1); @@ -30,7 +30,7 @@ ropFLD1(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc return op_pc; } uint32_t -ropFLDZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFLDZ(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_MOV_IMM(ir, IREG_temp0, 0); diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index 31b668488..938204a70 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -98,7 +98,7 @@ ropFSTSW(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet return op_pc + 1; } uint32_t -ropFSTSW_AX(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropFSTSW_AX(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_FP_ENTER(ir); uop_MOV(ir, IREG_AX, IREG_NPXS); diff --git a/src/codegen_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c index f2a4ce41a..037d91469 100644 --- a/src/codegen_new/codegen_ops_helpers.c +++ b/src/codegen_new/codegen_ops_helpers.c @@ -18,8 +18,8 @@ void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(UNUSED(codeblock_t *block), ir_data_t *ir, int dest_reg, uint32_t addr) { /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); - uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr + 1)); + uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr + 1)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); } diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 5a8f1e1c7..92b721099 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -71,7 +71,7 @@ fpu_PUSH(codeblock_t *block, ir_data_t *ir) } static inline void -CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) +CHECK_SEG_LIMITS(UNUSED(codeblock_t *block), ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) { if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) return; @@ -85,7 +85,7 @@ CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, i } static inline void -LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +LOAD_IMMEDIATE_FROM_RAM_8(UNUSED(codeblock_t *block), ir_data_t *ir, int dest_reg, uint32_t addr) { uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); } diff --git a/src/codegen_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c index fb2f1e5ba..430b16b2b 100644 --- a/src/codegen_new/codegen_ops_jump.c +++ b/src/codegen_new/codegen_ops_jump.c @@ -15,7 +15,7 @@ #include "codegen_ops_mov.h" uint32_t -ropJMP_r8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropJMP_r8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); uint32_t dest_addr = op_pc + 1 + offset; @@ -29,7 +29,7 @@ ropJMP_r8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fe return dest_addr; } uint32_t -ropJMP_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropJMP_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); uint32_t dest_addr = op_pc + 2 + offset; @@ -42,7 +42,7 @@ ropJMP_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f return dest_addr; } uint32_t -ropJMP_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropJMP_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = fastreadl(cs + op_pc); uint32_t dest_addr = op_pc + 4 + offset; @@ -54,7 +54,7 @@ ropJMP_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f } uint32_t -ropJMP_far_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropJMP_far_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t new_pc = fastreadw(cs + op_pc); uint16_t new_cs = fastreadw(cs + op_pc + 2); @@ -69,7 +69,7 @@ ropJMP_far_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return -1; } uint32_t -ropJMP_far_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropJMP_far_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t new_pc = fastreadl(cs + op_pc); uint16_t new_cs = fastreadw(cs + op_pc + 4); @@ -85,7 +85,7 @@ ropJMP_far_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ } uint32_t -ropCALL_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCALL_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); uint16_t ret_addr = op_pc + 2; @@ -104,7 +104,7 @@ ropCALL_r16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return -1; } uint32_t -ropCALL_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCALL_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t offset = fastreadl(cs + op_pc); uint32_t ret_addr = op_pc + 4; @@ -122,7 +122,7 @@ ropCALL_r32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropRET_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) +ropRET_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -138,7 +138,7 @@ ropRET_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uin return -1; } uint32_t -ropRET_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) +ropRET_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -154,7 +154,7 @@ ropRET_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uin } uint32_t -ropRET_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropRET_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset = fastreadw(cs + op_pc); @@ -173,7 +173,7 @@ ropRET_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return -1; } uint32_t -ropRET_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropRET_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset = fastreadw(cs + op_pc); @@ -192,7 +192,7 @@ ropRET_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ } uint32_t -ropRETF_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) +ropRETF_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) return 0; @@ -215,7 +215,7 @@ ropRETF_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), ui return -1; } uint32_t -ropRETF_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) +ropRETF_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), UNUSED(uint32_t op_pc)) { if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) return 0; @@ -239,7 +239,7 @@ ropRETF_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), ui } uint32_t -ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset; @@ -266,7 +266,7 @@ ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32 return -1; } uint32_t -ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t offset; diff --git a/src/codegen_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c index 684052fea..f289f1cba 100644 --- a/src/codegen_new/codegen_ops_logic.c +++ b/src/codegen_new/codegen_ops_logic.c @@ -16,7 +16,7 @@ #include "codegen_ops_logic.h" uint32_t -ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -29,7 +29,7 @@ ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -226,7 +226,7 @@ ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -239,7 +239,7 @@ ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return op_pc + 1; } uint32_t -ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -437,7 +437,7 @@ ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -449,7 +449,7 @@ ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32 return op_pc + 1; } uint32_t -ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); @@ -557,7 +557,7 @@ ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uint32_t -ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm_data = fastreadb(cs + op_pc); @@ -570,7 +570,7 @@ ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + 1; } uint32_t -ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm_data = fastreadw(cs + op_pc); diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index 545634672..91e0f5d63 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -485,108 +485,112 @@ ropFF_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet } uint32_t -ropNOP(UNUSED(codeblock_t *block), UNUSED(ir_data_t *ir), UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropNOP(UNUSED(codeblock_t *block), UNUSED(ir_data_t *ir), UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { return op_pc; } uint32_t -ropCBW(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCBW(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOVSX(ir, IREG_AX, IREG_AL); return op_pc; } uint32_t -ropCDQ(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCDQ(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); return op_pc; } uint32_t -ropCWD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCWD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); return op_pc; } uint32_t -ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOVSX(ir, IREG_EAX, IREG_AX); return op_pc; } -#define ropLxS(name, seg) \ - uint32_t rop##name##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ - } \ - uint32_t rop##name##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ +#define ropLxS(name, seg) \ + uint32_t rop##name##_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } \ + uint32_t rop##name##_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ } +// clang-format off ropLxS(LDS, &cpu_state.seg_ds) ropLxS(LES, &cpu_state.seg_es) ropLxS(LFS, &cpu_state.seg_fs) ropLxS(LGS, &cpu_state.seg_gs) ropLxS(LSS, &cpu_state.seg_ss) +// clang-format on uint32_t -ropCLC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCLC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_CALL_FUNC(ir, flags_rebuild); uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); return op_pc; } uint32_t -ropCMC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCMC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_CALL_FUNC(ir, flags_rebuild); uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); return op_pc; } uint32_t -ropSTC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSTC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_CALL_FUNC(ir, flags_rebuild); uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); @@ -594,20 +598,20 @@ ropSTC(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32 } uint32_t -ropCLD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCLD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); return op_pc; } uint32_t -ropSTD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSTD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); return op_pc; } uint32_t -ropCLI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropCLI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) return 0; @@ -616,7 +620,7 @@ ropCLI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32 return op_pc; } uint32_t -ropSTI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropSTI(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) return 0; diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index e99b4c56d..f01d64273 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" @@ -15,27 +16,28 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ - uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) { \ - int src_reg = fetchdat & 7; \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } else { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ } // clang-format off @@ -58,4 +60,4 @@ ropParith(PSUBUSW) ropParith(PMADDWD) ropParith(PMULHW) ropParith(PMULLW) - // clang-format on +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index 6f38cba67..cf0cededb 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" @@ -15,27 +16,28 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -#define ropPcmp(func) \ - uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) { \ - int src_reg = fetchdat & 7; \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } else { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ +#define ropPcmp(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ } // clang-format off @@ -45,4 +47,4 @@ ropPcmp(PCMPEQD) ropPcmp(PCMPGTB) ropPcmp(PCMPGTW) ropPcmp(PCMPGTD) - // clang-format on +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index d25edd52e..c62aa10d0 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -2,6 +2,7 @@ #include <86box/86box.h> #include "cpu.h" #include <86box/mem.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_flags.h" @@ -15,27 +16,28 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -#define ropPpack(func) \ - uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs + op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) { \ - int src_reg = fetchdat & 7; \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } else { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ +#define ropPpack(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ + uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ } // clang-format off @@ -48,4 +50,4 @@ ropPpack(PUNPCKLDQ) ropPpack(PUNPCKHBW) ropPpack(PUNPCKHWD) ropPpack(PUNPCKHDQ) - // clang-format on +// clang-format on diff --git a/src/codegen_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c index eae7045a8..031d2ea05 100644 --- a/src/codegen_new/codegen_ops_mov.c +++ b/src/codegen_new/codegen_ops_mov.c @@ -15,7 +15,7 @@ #include "codegen_ops_mov.h" uint32_t -ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint8_t imm = fastreadb(cs + op_pc); @@ -25,7 +25,7 @@ ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchd return op_pc + 1; } uint32_t -ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm = fastreadw(cs + op_pc); @@ -172,7 +172,7 @@ ropMOV_r_l(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f } uint32_t -ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -189,7 +189,7 @@ ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -206,7 +206,7 @@ ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t addr = 0; @@ -233,7 +233,7 @@ ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32 } uint32_t -ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -250,7 +250,7 @@ ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -267,7 +267,7 @@ ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_ return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t -ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uint32_t addr; @@ -614,7 +614,7 @@ ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32 } uint32_t -ropXCHG_AX(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropXCHG_AX(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int reg2 = IREG_16(opcode & 7); @@ -625,7 +625,7 @@ ropXCHG_AX(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } uint32_t -ropXCHG_EAX(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropXCHG_EAX(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int reg2 = IREG_32(opcode & 7); @@ -716,7 +716,7 @@ ropXCHG_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t f } uint32_t -ropXLAT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +ropXLAT(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), uint32_t op_32, uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index 92ad9509d..fca9c9efa 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -16,7 +16,7 @@ #include "codegen_ops_misc.h" uint32_t -ropPUSH_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSH_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -28,7 +28,7 @@ ropPUSH_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t return op_pc; } uint32_t -ropPUSH_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSH_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -41,7 +41,7 @@ ropPUSH_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t } uint32_t -ropPOP_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPOP_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -57,7 +57,7 @@ ropPOP_r16(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t f return op_pc; } uint32_t -ropPOP_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPOP_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -74,7 +74,7 @@ ropPOP_r32(UNUSED(codeblock_t *block), ir_data_t *ir, uint8_t opcode, uint32_t f } uint32_t -ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm = fastreadw(cs + op_pc); int sp_reg; @@ -88,7 +88,7 @@ ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32 return op_pc + 2; } uint32_t -ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t imm = fastreadl(cs + op_pc); int sp_reg; @@ -103,7 +103,7 @@ ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32 } uint32_t -ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint16_t imm = (int16_t) (int8_t) fastreadb(cs + op_pc); int sp_reg; @@ -117,7 +117,7 @@ ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint return op_pc + 1; } uint32_t -ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uint32_t imm = (int32_t) (int8_t) fastreadb(cs + op_pc); int sp_reg; @@ -196,63 +196,68 @@ ropPOP_L(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet return op_pc + 1; } -#define ROP_PUSH_SEG(seg) \ - uint32_t ropPUSH_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_##seg##_seg_W); \ - SUB_SP(ir, 2); \ - \ - return op_pc; \ - } \ - uint32_t ropPUSH_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ - uop_MOVZX(ir, IREG_temp0, IREG_##seg##_seg_W); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ - SUB_SP(ir, 4); \ - \ - return op_pc; \ +#define ROP_PUSH_SEG(seg) \ + uint32_t ropPUSH_##seg##_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) \ + { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_##seg##_seg_W); \ + SUB_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPUSH_##seg##_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) \ + { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ + uop_MOVZX(ir, IREG_temp0, IREG_##seg##_seg_W); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ + SUB_SP(ir, 4); \ + \ + return op_pc; \ } -#define ROP_POP_SEG(seg, rseg) \ - uint32_t ropPOP_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 2); \ - \ - return op_pc; \ - } \ - uint32_t ropPOP_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ - { \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 4); \ - \ - return op_pc; \ +#define ROP_POP_SEG(seg, rseg) \ + uint32_t ropPOP_##seg##_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) \ + { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPOP_##seg##_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), \ + UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) \ + { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 4); \ + \ + return op_pc; \ } +// clang-format off ROP_PUSH_SEG(CS) ROP_PUSH_SEG(DS) ROP_PUSH_SEG(ES) @@ -263,9 +268,10 @@ ROP_POP_SEG(DS, cpu_state.seg_ds) ROP_POP_SEG(ES, cpu_state.seg_es) ROP_POP_SEG(FS, cpu_state.seg_fs) ROP_POP_SEG(GS, cpu_state.seg_gs) +// clang-format on uint32_t -ropLEAVE_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropLEAVE_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -281,7 +287,7 @@ ropLEAVE_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), u return op_pc; } uint32_t -ropLEAVE_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropLEAVE_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); @@ -298,7 +304,7 @@ ropLEAVE_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), u } uint32_t -ropPUSHA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSHA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -317,7 +323,7 @@ ropPUSHA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), u return op_pc; } uint32_t -ropPUSHA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSHA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -337,7 +343,7 @@ ropPUSHA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), u } uint32_t -ropPOPA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPOPA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -355,7 +361,7 @@ ropPOPA_16(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), ui return op_pc; } uint32_t -ropPOPA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPOPA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -374,7 +380,7 @@ ropPOPA_32(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), ui } uint32_t -ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; @@ -390,7 +396,7 @@ ropPUSHF(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint return op_pc; } uint32_t -ropPUSHFD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) +ropPUSHFD(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSED(uint32_t fetchdat), UNUSED(uint32_t op_32), uint32_t op_pc) { int sp_reg; diff --git a/src/config.c b/src/config.c index 7a5d76465..6c34c4790 100644 --- a/src/config.c +++ b/src/config.c @@ -8,20 +8,19 @@ * * Configuration file handler. * - * - * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * Overdoze, * David Hrdlička, + * Jasmine Iwanek, * * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2018-2019 David Hrdlička. * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. * * NOTE: Forcing config files to be in Unicode encoding breaks * it on Windows XP, and possibly also Vista. Use the @@ -29,12 +28,13 @@ */ #include +#ifdef ENABLE_CONFIG_LOG #include +#endif #include #include #include #include -#include #define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" @@ -53,10 +53,8 @@ #include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/fdd.h> -#include <86box/fdc.h> #include <86box/fdc_ext.h> #include <86box/gameport.h> -#include <86box/serial.h> #include <86box/serial_passthrough.h> #include <86box/machine.h> #include <86box/mouse.h> @@ -118,7 +116,8 @@ load_general(void) memset(temp, '\0', sizeof(temp)); p = ini_section_get_string(cat, "vid_renderer", "default"); vid_api = plat_vidapi(p); - ini_section_delete_var(cat, "vid_api"); + if (!strcmp(p, "default")) + ini_section_delete_var(cat, "vid_api"); video_fullscreen_scale = ini_section_get_int(cat, "video_fullscreen_scale", 1); @@ -202,12 +201,12 @@ load_general(void) if (window_remember) { p = ini_section_get_string(cat, "window_coordinates", NULL); if (p == NULL) - p = "0, 0, 0, 0"; + p = "640, 480, 0, 0"; sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy); - } else + } else { cw = ch = cx = cy = 0; - - ini_section_delete_var(cat, "window_coordinates"); + ini_section_delete_var(cat, "window_coordinates"); + } do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0); @@ -299,7 +298,7 @@ load_machine(void) /* Only copy if a file with the new name doesn't already exist. */ FILE *g = nvr_fopen(new_fn, "rb"); - if (!g) { + if (g == NULL) { FILE *f = nvr_fopen(entry->d_name, "rb"); g = nvr_fopen(new_fn, "wb"); @@ -360,7 +359,7 @@ load_machine(void) while (!cpu_family_is_eligible(&cpu_families[c], machine)) { if (cpu_families[c++].package == 0) { /* End of list. */ - fatal("No eligible CPU families for the selected machine\n"); + fatal("Configuration: No eligible CPU families for the selected machine\n"); return; } } @@ -404,7 +403,7 @@ load_machine(void) else time_sync = TIME_SYNC_ENABLED; } else - time_sync = !!ini_section_get_int(cat, "enable_sync", 1); + time_sync = TIME_SYNC_ENABLED; pit_mode = ini_section_get_int(cat, "pit_mode", -1); } @@ -440,7 +439,6 @@ load_video(void) if (free_p) { free(p); p = NULL; - free_p = 0; } } @@ -475,8 +473,6 @@ load_input_devices(void) { ini_section_t cat = ini_find_section(config, "Input devices"); char temp[512]; - int c; - int d; char *p; p = ini_section_get_string(cat, "mouse_type", NULL); @@ -495,8 +491,8 @@ load_input_devices(void) /* Workaround for ini_section_get_int returning 0 on non-integer data */ joystick_type = joystick_get_from_internal_name("2axis_2button"); else { - c = ini_section_get_int(cat, "joystick_type", 8); - switch (c) { + int js = ini_section_get_int(cat, "joystick_type", 8); + switch (js) { case JS_TYPE_2AXIS_4BUTTON: joystick_type = joystick_get_from_internal_name("2axis_4button"); break; @@ -527,25 +523,25 @@ load_input_devices(void) } else joystick_type = JS_TYPE_NONE; - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - sprintf(temp, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = ini_section_get_int(cat, temp, 0); + for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { + sprintf(temp, "joystick_%i_nr", js); + joystick_state[0][js].plat_joystick_nr = ini_section_get_int(cat, temp, 0); - if (joystick_state[c].plat_joystick_nr) { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { - sprintf(temp, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = ini_section_get_int(cat, temp, d); + if (joystick_state[0][js].plat_joystick_nr) { + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) { + sprintf(temp, "joystick_%i_axis_%i", js, axis_nr); + joystick_state[0][js].axis_mapping[axis_nr] = ini_section_get_int(cat, temp, axis_nr); } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) { - sprintf(temp, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = ini_section_get_int(cat, temp, d); + for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) { + sprintf(temp, "joystick_%i_button_%i", js, button_nr); + joystick_state[0][js].button_mapping[button_nr] = ini_section_get_int(cat, temp, button_nr); } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(temp, "joystick_%i_pov_%i", c, d); + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { + sprintf(temp, "joystick_%i_pov_%i", js, pov_nr); p = ini_section_get_string(cat, temp, "0, 0"); - joystick_state[c].pov_mapping[d][0] = joystick_state[c].pov_mapping[d][1] = 0; - sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0], - &joystick_state[c].pov_mapping[d][1]); + joystick_state[0][js].pov_mapping[pov_nr][0] = joystick_state[0][js].pov_mapping[pov_nr][1] = 0; + sscanf(p, "%i, %i", &joystick_state[0][js].pov_mapping[pov_nr][0], + &joystick_state[0][js].pov_mapping[pov_nr][1]); } } } @@ -620,7 +616,7 @@ load_sound(void) memset(temp, '\0', sizeof(temp)); p = ini_section_get_string(cat, "sound_type", "float"); if (strlen(p) > 511) - fatal("load_sound(): strlen(p) > 511\n"); + fatal("Configuration: Length of sound_type is more than 511\n"); else strncpy(temp, p, 511); if (!strcmp(temp, "float") || !strcmp(temp, "1")) @@ -743,11 +739,9 @@ load_ports(void) ini_section_t cat = ini_find_section(config, "Ports (COM & LPT)"); char *p; char temp[512]; - int c; - memset(temp, 0, sizeof(temp)); - for (c = 0; c < SERIAL_MAX; c++) { + for (int c = 0; c < SERIAL_MAX; c++) { sprintf(temp, "serial%d_enabled", c + 1); com_ports[c].enabled = !!ini_section_get_int(cat, temp, (c >= 2) ? 0 : 1); @@ -758,7 +752,7 @@ load_ports(void) config_log("Serial Port %d: passthrough enabled.\n\n", c + 1); } - for (c = 0; c < PARALLEL_MAX; c++) { + for (int c = 0; c < PARALLEL_MAX; c++) { sprintf(temp, "lpt%d_enabled", c + 1); lpt_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0); @@ -766,6 +760,28 @@ load_ports(void) p = ini_section_get_string(cat, temp, "none"); lpt_ports[c].device = lpt_device_get_from_internal_name(p); } + +#if 0 +// TODO: Load + for (c = 0; c < GAMEPORT_MAX; c++) { + sprintf(temp, "gameport%d_enabled", c + 1); + game_ports[c].enabled = !!ini_section_get_int(cat, temp, (c == 0) ? 1 : 0); + + sprintf(temp, "gameport%d_device", c + 1); + p = ini_section_get_string(cat, temp, "none"); + game_ports[c].device = gameport_get_from_internal_name(p); + } + + for (uint8_t c = 0; c < GAMEPORT_MAX; c++) { + sprintf(temp, "gameport%d_type", c); + + p = ini_section_get_string(cat, temp, "none"); + gameport_type[c] = gameport_get_from_internal_name(p); + + if (!strcmp(p, "none")) + ini_section_delete_var(cat, temp); + } +#endif } /* Load "Storage Controllers" section. */ @@ -776,11 +792,10 @@ load_storage_controllers(void) ini_section_t migration_cat; char *p; char temp[512]; - int c; int min = 0; int free_p = 0; - for (c = min; c < SCSI_CARD_MAX; c++) { + for (int c = min; c < SCSI_CARD_MAX; c++) { sprintf(temp, "scsicard_%d", c + 1); p = ini_section_get_string(cat, temp, NULL); @@ -852,7 +867,6 @@ load_storage_controllers(void) if (free_p) { free(p); p = NULL; - free_p = 0; } ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0); @@ -862,23 +876,77 @@ load_storage_controllers(void) cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0); else cassette_enable = 0; + 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); + } + + p = ini_section_get_string(cat, "cassette_mode", "load"); if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); - else - strncpy(cassette_fname, p, 511); - p = ini_section_get_string(cat, "cassette_mode", ""); - if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); + fatal("Configuration: Length of cassette_mode is more than 511\n"); else strncpy(cassette_mode, p, 511); - cassette_pos = ini_section_get_int(cat, "cassette_position", 0); - cassette_srate = ini_section_get_int(cat, "cassette_srate", 44100); - cassette_append = !!ini_section_get_int(cat, "cassette_append", 0); - cassette_pcm = ini_section_get_int(cat, "cassette_pcm", 0); - cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0); - for (c = 0; c < 2; c++) { + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + cassette_image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); + 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]); + } + } + cassette_pos = ini_section_get_int(cat, "cassette_position", 0); + if (!cassette_pos) + ini_section_delete_var(cat, "cassette_position"); + cassette_srate = ini_section_get_int(cat, "cassette_srate", 44100); + if (cassette_srate == 44100) + ini_section_delete_var(cat, "cassette_srate"); + cassette_append = !!ini_section_get_int(cat, "cassette_append", 0); + if (!cassette_append) + ini_section_delete_var(cat, "cassette_append"); + 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"); + ini_section_delete_var(cat, "cassette_mode"); + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "cassette_image_history_%02i", i + 1); + ini_section_delete_var(cat, temp); + } + ini_section_delete_var(cat, "cassette_position"); + ini_section_delete_var(cat, "cassette_srate"); + ini_section_delete_var(cat, "cassette_append"); + ini_section_delete_var(cat, "cassette_pcm"); + ini_section_delete_var(cat, "cassette_ui_writeprot"); + } + + for (int c = 0; c < 2; c++) { sprintf(temp, "cartridge_%02i_fn", c + 1); p = ini_section_get_string(cat, temp, ""); @@ -888,16 +956,38 @@ load_storage_controllers(void) if (p[0] != 0x00) { if (path_abs(p)) { if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511 (cart_fns[%i])\n", c); + fatal("Configuration: Length of cartridge_%02i_fn is more than 511\n", + c + 1); else strncpy(cart_fns[c], p, 511); } else path_append_filename(cart_fns[c], usr_path, p); path_normalize(cart_fns[c]); } + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + cart_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); + sprintf(temp, "cartridge_%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 cartridge_%02i_image_history_%02i " + "is more than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); + else + snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p); + } else + snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, + path_get_slash(usr_path), p); + path_normalize(cart_image_history[c][i]); + } + } } 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. */ @@ -922,8 +1012,8 @@ load_hard_disks(void) sscanf(p, "%u, %u, %u, %i, %s", &hdd[c].spt, &hdd[c].hpc, &hdd[c].tracks, (int *) &hdd[c].wp, s); - hdd[c].bus = hdd_string_to_bus(s, 0); - switch (hdd[c].bus) { + hdd[c].bus_type = hdd_string_to_bus(s, 0); + switch (hdd[c].bus_type) { default: case HDD_BUS_DISABLED: max_spt = max_hpc = max_tracks = 0; @@ -969,7 +1059,7 @@ load_hard_disks(void) hdd[c].tracks = max_tracks; sprintf(temp, "hdd_%02i_speed", c + 1); - switch (hdd[c].bus) { + switch (hdd[c].bus_type) { case HDD_BUS_IDE: case HDD_BUS_ESDI: case HDD_BUS_ATAPI: @@ -985,28 +1075,28 @@ load_hard_disks(void) /* MFM/RLL */ sprintf(temp, "hdd_%02i_mfm_channel", c + 1); - if (hdd[c].bus == HDD_BUS_MFM) + if (hdd[c].bus_type == HDD_BUS_MFM) hdd[c].mfm_channel = !!ini_section_get_int(cat, temp, c & 1); else ini_section_delete_var(cat, temp); /* XTA */ sprintf(temp, "hdd_%02i_xta_channel", c + 1); - if (hdd[c].bus == HDD_BUS_XTA) + if (hdd[c].bus_type == HDD_BUS_XTA) hdd[c].xta_channel = !!ini_section_get_int(cat, temp, c & 1); else ini_section_delete_var(cat, temp); /* ESDI */ sprintf(temp, "hdd_%02i_esdi_channel", c + 1); - if (hdd[c].bus == HDD_BUS_ESDI) + if (hdd[c].bus_type == HDD_BUS_ESDI) hdd[c].esdi_channel = !!ini_section_get_int(cat, temp, c & 1); else ini_section_delete_var(cat, temp); /* IDE */ sprintf(temp, "hdd_%02i_ide_channel", c + 1); - if ((hdd[c].bus == HDD_BUS_IDE) || (hdd[c].bus == HDD_BUS_ATAPI)) { + if ((hdd[c].bus_type == HDD_BUS_IDE) || (hdd[c].bus_type == HDD_BUS_ATAPI)) { sprintf(tmp2, "%01u:%01u", c >> 1, c & 1); p = ini_section_get_string(cat, temp, tmp2); sscanf(p, "%01u:%01u", &board, &dev); @@ -1016,12 +1106,11 @@ load_hard_disks(void) if (hdd[c].ide_channel > 7) hdd[c].ide_channel = 7; - } else { + } else ini_section_delete_var(cat, temp); - } /* SCSI */ - if (hdd[c].bus == HDD_BUS_SCSI) { + if (hdd[c].bus_type == HDD_BUS_SCSI) { sprintf(temp, "hdd_%02i_scsi_location", c + 1); sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); p = ini_section_get_string(cat, temp, tmp2); @@ -1061,7 +1150,8 @@ load_hard_disks(void) if (p[0] != 0x00) { if (path_abs(p)) { if (strlen(p) > 511) - fatal("load_hard_disks(): strlen(p) > 511 (hdd[%i].fn)\n", c); + fatal("Configuration: Length of hdd_%02i_fn is more " + "than 511\n", c + 1); else strncpy(hdd[c].fn, p, 511); } else @@ -1081,24 +1171,24 @@ load_hard_disks(void) sprintf(temp, "hdd_%02i_parameters", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_preide_channels", c + 1); + sprintf(temp, "hdd_%02i_mfm_channel", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_ide_channels", c + 1); + sprintf(temp, "hdd_%02i_xta_channel", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_scsi_id", c + 1); + sprintf(temp, "hdd_%02i_esdi_channel", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "hdd_%02i_ide_channel", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "hdd_%02i_scsi_location", c + 1); ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_fn", c + 1); ini_section_delete_var(cat, temp); } - - sprintf(temp, "hdd_%02i_mfm_channel", c + 1); - ini_section_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_ide_channel", c + 1); - ini_section_delete_var(cat, temp); } } @@ -1115,6 +1205,7 @@ load_floppy_and_cdrom_drives(void) unsigned int dev = 0; int c; int d = 0; + int count = cdrom_get_type_count(); memset(temp, 0x00, sizeof(temp)); for (c = 0; c < FDD_NUM; c++) { @@ -1133,7 +1224,7 @@ load_floppy_and_cdrom_drives(void) if (p[0] != 0x00) { if (path_abs(p)) { if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (floppyfns[%i])\n", c); + fatal("Configuration: Length of fdd_%02i_fn is more than 511\n", c + 1); else strncpy(floppyfns[c], p, 511); } else @@ -1181,12 +1272,12 @@ load_floppy_and_cdrom_drives(void) if (p) { if (path_abs(p)) { if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " - "(fdd_image_history[%i][%i])\n", c, i); + 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 - 1), "%s", p); + snprintf(fdd_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p); } else - snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + 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]); } @@ -1214,11 +1305,21 @@ 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, (c == 1) ? "86BOX_CD-ROM_1.00" : "none"); - cdrom_set_type(c, cdrom_get_from_internal_name(p)); - if (cdrom_get_type(c) > KNOWN_CDROM_DRIVE_TYPES) - cdrom_set_type(c, KNOWN_CDROM_DRIVE_TYPES); - ini_section_delete_var(cat, temp); + p = ini_section_get_string(cat, temp, "86cd"); + /* TODO: Configuration migration, remove when no longer needed. */ + int cdrom_type = cdrom_get_from_internal_name(p); + if (cdrom_type == -1) { + cdrom_type = cdrom_get_from_name(p); + if (cdrom_type == -1) + cdrom_set_type(c, cdrom_get_from_internal_name("86cd")); + else + cdrom_set_type(c, cdrom_type); + } else + cdrom_set_type(c, cdrom_type); + if (cdrom_get_type(c) >= count) + cdrom_set_type(c, count - 1); + if (!strcmp(p, "86cd")) + 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; @@ -1275,7 +1376,7 @@ load_floppy_and_cdrom_drives(void) if (p[0] != 0x00) { if (path_abs(p)) { if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 (cdrom[%i].image_path)\n", c); + fatal("Configuration: Length of cdrom_%02i_image_path is more than 511\n", c + 1); else strncpy(cdrom[c].image_path, p, 511); } else @@ -1290,12 +1391,12 @@ load_floppy_and_cdrom_drives(void) if (p) { if (path_abs(p)) { if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " - "(cdrom[%i].image_history[%i])\n", c, i); + fatal("Configuration: Length of cdrom_%02i_image_history_%02i is more " + "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); else - snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); + snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); } else - snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(cdrom[c].image_history[i]); } @@ -1306,10 +1407,16 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_parameters", c + 1); ini_section_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_speed", c + 1); + ini_section_delete_var(cat, temp); + + sprintf(temp, "cdrom_%02i_type", c + 1); + ini_section_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_scsi_id", c + 1); + sprintf(temp, "cdrom_%02i_scsi_location", c + 1); ini_section_delete_var(cat, temp); sprintf(temp, "cdrom_%02i_image_path", c + 1); @@ -1404,8 +1511,7 @@ load_other_removable_devices(void) if (p[0] != 0x00) { if (path_abs(p)) { if (strlen(p) > 511) - fatal("load_other_removable_devices(): strlen(p) > 511 (zip_drives[%i].image_path)\n", - c); + 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 @@ -1420,12 +1526,12 @@ load_other_removable_devices(void) if (p) { if (path_abs(p)) { if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("load_other_removable_devices(): strlen(p) > 2047 " - "(zip_drives[%i].image_history[%i])\n", c, i); + 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 - 1), "%s", p); + 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 - 1), "%s%s%s", usr_path, + 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]); } @@ -1439,7 +1545,7 @@ load_other_removable_devices(void) sprintf(temp, "zip_%02i_ide_channel", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "zip_%02i_scsi_id", c + 1); + sprintf(temp, "zip_%02i_scsi_location", c + 1); ini_section_delete_var(cat, temp); sprintf(temp, "zip_%02i_image_path", c + 1); @@ -1517,8 +1623,7 @@ load_other_removable_devices(void) if (p[0] != 0x00) { if (path_abs(p)) { if (strlen(p) > 511) - fatal("load_other_removable_devices(): strlen(p) > 511 (mo_drives[%i].image_path)\n", - c); + 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 @@ -1533,12 +1638,12 @@ load_other_removable_devices(void) if (p) { if (path_abs(p)) { if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("load_other_removable_devices(): strlen(p) > 2047 " - "(mo_drives[%i].image_history[%i])\n", c, i); + 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 - 1), "%s", p); + 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 - 1), "%s%s%s", usr_path, + 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]); } @@ -1552,7 +1657,7 @@ load_other_removable_devices(void) sprintf(temp, "mo_%02i_ide_channel", c + 1); ini_section_delete_var(cat, temp); - sprintf(temp, "mo_%02i_scsi_id", c + 1); + sprintf(temp, "mo_%02i_scsi_location", c + 1); ini_section_delete_var(cat, temp); sprintf(temp, "mo_%02i_image_path", c + 1); @@ -1579,15 +1684,33 @@ load_other_peripherals(void) unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0); novell_keycard_enabled = !!ini_section_get_int(cat, "novell_keycard_enabled", 0); + if (!bugger_enabled) + ini_section_delete_var(cat, "bugger_enabled"); + + if (!postcard_enabled) + ini_section_delete_var(cat, "postcard_enabled"); + + if (!unittester_enabled) + ini_section_delete_var(cat, "unittester_enabled"); + + if (!novell_keycard_enabled) + ini_section_delete_var(cat, "novell_keycard_enabled"); + for (uint8_t c = 0; c < ISAMEM_MAX; c++) { sprintf(temp, "isamem%d_type", c); p = ini_section_get_string(cat, temp, "none"); isamem_type[c] = isamem_get_from_internal_name(p); + + if (!strcmp(p, "none")) + ini_section_delete_var(cat, temp); } p = ini_section_get_string(cat, "isartc_type", "none"); isartc_type = isartc_get_from_internal_name(p); + + if (!strcmp(p, "none")) + ini_section_delete_var(cat, temp); } /* Load the specified or a default configuration file. */ @@ -1608,7 +1731,7 @@ config_load(void) config = ini_read(cfg_path); - if (!config) { + if (config == NULL) { config = ini_new(); config_changed = 1; @@ -1968,17 +2091,20 @@ save_machine(void) /* Write the mem_size explicitly to the setttings in order to help managers to display it without having the actual machine table. */ - ini_section_delete_var(cat, "mem_size"); ini_section_set_int(cat, "mem_size", mem_size); ini_section_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); - ini_section_set_int(cat, "fpu_softfloat", fpu_softfloat); + + if (fpu_softfloat == 0) + ini_section_delete_var(cat, "fpu_softfloat"); + else + ini_section_set_int(cat, "fpu_softfloat", fpu_softfloat); if (time_sync & TIME_SYNC_ENABLED) if (time_sync & TIME_SYNC_UTC) ini_section_set_string(cat, "time_sync", "utc"); else - ini_section_set_string(cat, "time_sync", "local"); + ini_section_delete_var(cat, "time_sync"); else ini_section_set_string(cat, "time_sync", "disabled"); @@ -2047,50 +2173,49 @@ save_input_devices(void) ini_section_t cat = ini_find_or_create_section(config, "Input devices"); char temp[512]; char tmp2[512]; - int c; - int d; ini_section_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); if (!joystick_type) { ini_section_delete_var(cat, "joystick_type"); - for (c = 0; c < 16; c++) { - sprintf(tmp2, "joystick_%i_nr", c); + for (int js = 0; js < MAX_PLAT_JOYSTICKS; js++) { + sprintf(tmp2, "joystick_%i_nr", js); ini_section_delete_var(cat, tmp2); - for (d = 0; d < 16; d++) { - sprintf(tmp2, "joystick_%i_axis_%i", c, d); + for (int axis_nr = 0; axis_nr < MAX_JOY_AXES; axis_nr++) { + sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr); ini_section_delete_var(cat, tmp2); } - for (d = 0; d < 16; d++) { - sprintf(tmp2, "joystick_%i_button_%i", c, d); + for (int button_nr = 0; button_nr < MAX_JOY_BUTTONS; button_nr++) { + sprintf(tmp2, "joystick_%i_button_%i", js, button_nr); ini_section_delete_var(cat, tmp2); } - for (d = 0; d < 16; d++) { - sprintf(tmp2, "joystick_%i_pov_%i", c, d); + for (int pov_nr = 0; pov_nr < MAX_JOY_POVS; pov_nr++) { + sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr); ini_section_delete_var(cat, tmp2); } } } else { ini_section_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type)); - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - sprintf(tmp2, "joystick_%i_nr", c); - ini_section_set_int(cat, tmp2, joystick_state[c].plat_joystick_nr); + for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { + sprintf(tmp2, "joystick_%i_nr", js); + ini_section_set_int(cat, tmp2, joystick_state[0][js].plat_joystick_nr); - if (joystick_state[c].plat_joystick_nr) { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { - sprintf(tmp2, "joystick_%i_axis_%i", c, d); - ini_section_set_int(cat, tmp2, joystick_state[c].axis_mapping[d]); + if (joystick_state[0][js].plat_joystick_nr) { + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) { + sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr); + ini_section_set_int(cat, tmp2, joystick_state[0][js].axis_mapping[axis_nr]); } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) { - sprintf(tmp2, "joystick_%i_button_%i", c, d); - ini_section_set_int(cat, tmp2, joystick_state[c].button_mapping[d]); + for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) { + sprintf(tmp2, "joystick_%i_button_%i", js, button_nr); + ini_section_set_int(cat, tmp2, joystick_state[0][js].button_mapping[button_nr]); } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(tmp2, "joystick_%i_pov_%i", c, d); - sprintf(temp, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { + sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr); + sprintf(temp, "%i, %i", joystick_state[0][js].pov_mapping[pov_nr][0], + joystick_state[0][js].pov_mapping[pov_nr][1]); ini_section_set_string(cat, tmp2, temp); } } @@ -2173,7 +2298,10 @@ save_sound(void) else ini_section_set_string(cat, "sound_type", (sound_is_float == 1) ? "float" : "int16"); - ini_section_set_string(cat, "fm_driver", (fm_driver == FM_DRV_NUKED) ? "nuked" : "ymfm"); + if (fm_driver == FM_DRV_NUKED) + ini_section_delete_var(cat, "fm_driver"); + else + ini_section_set_string(cat, "fm_driver", "ymfm"); ini_delete_section_if_empty(config, cat); } @@ -2245,10 +2373,8 @@ save_ports(void) { ini_section_t cat = ini_find_or_create_section(config, "Ports (COM & LPT)"); char temp[512]; - int c; - int d; - for (c = 0; c < SERIAL_MAX; c++) { + for (int c = 0; c < SERIAL_MAX; c++) { sprintf(temp, "serial%d_enabled", c + 1); if (((c < 2) && com_ports[c].enabled) || ((c >= 2) && !com_ports[c].enabled)) ini_section_delete_var(cat, temp); @@ -2256,16 +2382,15 @@ save_ports(void) ini_section_set_int(cat, temp, com_ports[c].enabled); sprintf(temp, "serial%d_passthrough_enabled", c + 1); - if (serial_passthrough_enabled[c]) { + if (serial_passthrough_enabled[c]) ini_section_set_int(cat, temp, 1); - } else { + else ini_section_delete_var(cat, temp); - } } - for (c = 0; c < PARALLEL_MAX; c++) { + for (int c = 0; c < PARALLEL_MAX; c++) { sprintf(temp, "lpt%d_enabled", c + 1); - d = (c == 0) ? 1 : 0; + int d = (c == 0) ? 1 : 0; if (lpt_ports[c].enabled == d) ini_section_delete_var(cat, temp); else @@ -2279,6 +2404,34 @@ save_ports(void) lpt_device_get_internal_name(lpt_ports[c].device)); } +#if 0 +// TODO: Save + for (c = 0; c < GAMEPORT_MAX; c++) { + sprintf(temp, "gameport%d_enabled", c + 1); + d = (c == 0) ? 1 : 0; + if (game_ports[c].enabled == d) + ini_section_delete_var(cat, temp); + else + ini_section_set_int(cat, temp, game_ports[c].enabled); + + sprintf(temp, "gameport%d_device", c + 1); + if (game_ports[c].device == 0) + ini_section_delete_var(cat, temp); + else + ini_section_set_string(cat, temp, + gameport_get_internal_name(game_ports[c].device)); + } + + for (uint8_t c = 0; c < GAMEPORT_MAX; c++) { + sprintf(temp, "gameport%d_enabled", c); + if (gameport_type[c] == 0) + ini_section_delete_var(cat, temp); + else + ini_section_set_string(cat, temp, + gameport_get_internal_name(gameport_type[c])); + } +#endif + ini_delete_section_if_empty(config, cat); } @@ -2289,6 +2442,7 @@ save_storage_controllers(void) ini_section_t cat = ini_find_or_create_section(config, "Storage controllers"); char temp[512]; int c; + char *def_hdc; ini_section_delete_var(cat, "scsicard"); @@ -2308,8 +2462,16 @@ save_storage_controllers(void) ini_section_set_string(cat, "fdc", fdc_card_get_internal_name(fdc_current[0])); - ini_section_set_string(cat, "hdc", - hdc_get_internal_name(hdc_current[0])); + if (machine_has_flags(machine, MACHINE_HDC)) + def_hdc = "internal"; + else + def_hdc = "none"; + + 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])); if (cdrom_interface_current == 0) ini_section_delete_var(cat, "cdrom_interface"); @@ -2327,8 +2489,6 @@ save_storage_controllers(void) else ini_section_set_int(cat, "ide_qua", ide_qua_enabled); - ini_delete_section_if_empty(config, cat); - if (cassette_enable == 0) ini_section_delete_var(cat, "cassette_enabled"); else @@ -2336,14 +2496,32 @@ save_storage_controllers(void) if (strlen(cassette_fname) == 0) ini_section_delete_var(cat, "cassette_file"); - else - ini_section_set_string(cat, "cassette_file", cassette_fname); + 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); + } - if (strlen(cassette_mode) == 0) + if (!strcmp(cassette_mode, "load")) ini_section_delete_var(cat, "cassette_mode"); else ini_section_set_string(cat, "cassette_mode", cassette_mode); + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + 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]); + } + } + if (cassette_pos == 0) ini_section_delete_var(cat, "cassette_position"); else @@ -2371,16 +2549,37 @@ save_storage_controllers(void) for (c = 0; c < 2; c++) { sprintf(temp, "cartridge_%02i_fn", c + 1); + if (strlen(cart_fns[c]) == 0) ini_section_delete_var(cat, temp); - else - ini_section_set_string(cat, temp, cart_fns[c]); + else { + path_normalize(cart_fns[c]); + if (!strnicmp(cart_fns[c], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &cart_fns[c][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, cart_fns[c]); + } + + for (int i = 0; i < MAX_PREV_IMAGES; i++) { + sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1); + if ((cart_image_history[c][i] == 0) || strlen(cart_image_history[c][i]) == 0) + ini_section_delete_var(cat, temp); + else { + path_normalize(cart_image_history[c][i]); + if (!strnicmp(cart_image_history[c][i], usr_path, strlen(usr_path))) + ini_section_set_string(cat, temp, &cart_image_history[c][i][strlen(usr_path)]); + else + ini_section_set_string(cat, temp, cart_image_history[c][i]); + } + } } if (lba_enhancer_enabled == 0) 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); } /* Save "Other Peripherals" section. */ @@ -2441,34 +2640,34 @@ save_hard_disks(void) for (uint8_t c = 0; c < HDD_NUM; c++) { sprintf(temp, "hdd_%02i_parameters", c + 1); if (hdd_is_valid(c)) { - p = hdd_bus_to_string(hdd[c].bus, 0); + p = hdd_bus_to_string(hdd[c].bus_type, 0); sprintf(tmp2, "%u, %u, %u, %i, %s", hdd[c].spt, hdd[c].hpc, hdd[c].tracks, hdd[c].wp, p); ini_section_set_string(cat, temp, tmp2); - } else { + } else ini_section_delete_var(cat, temp); - } sprintf(temp, "hdd_%02i_mfm_channel", c + 1); - if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_MFM)) + if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_MFM)) ini_section_set_int(cat, temp, hdd[c].mfm_channel); else ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_xta_channel", c + 1); - if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_XTA)) + if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_XTA)) ini_section_set_int(cat, temp, hdd[c].xta_channel); else ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_esdi_channel", c + 1); - if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_ESDI)) + if (hdd_is_valid(c) && (hdd[c].bus_type == HDD_BUS_ESDI)) ini_section_set_int(cat, temp, hdd[c].esdi_channel); else ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_ide_channel", c + 1); - if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_IDE) && (hdd[c].bus != HDD_BUS_ATAPI))) + if (!hdd_is_valid(c) || ((hdd[c].bus_type != HDD_BUS_IDE) && + (hdd[c].bus_type != HDD_BUS_ATAPI))) ini_section_delete_var(cat, temp); else { sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1); @@ -2479,7 +2678,7 @@ save_hard_disks(void) ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_scsi_location", c + 1); - if (hdd[c].bus != HDD_BUS_SCSI) + if (hdd[c].bus_type != HDD_BUS_SCSI) ini_section_delete_var(cat, temp); else { sprintf(tmp2, "%01u:%02u", hdd[c].scsi_id >> 4, @@ -2511,8 +2710,9 @@ save_hard_disks(void) ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_speed", c + 1); - if (!hdd_is_valid(c) || ((hdd[c].bus != HDD_BUS_ESDI) && (hdd[c].bus != HDD_BUS_IDE) && - (hdd[c].bus != HDD_BUS_SCSI) && (hdd[c].bus != HDD_BUS_ATAPI))) + if (!hdd_is_valid(c) || + ((hdd[c].bus_type != HDD_BUS_ESDI) && (hdd[c].bus_type != HDD_BUS_IDE) && + (hdd[c].bus_type != HDD_BUS_SCSI) && (hdd[c].bus_type != HDD_BUS_ATAPI))) ini_section_delete_var(cat, temp); else ini_section_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset)); @@ -2597,11 +2797,12 @@ save_floppy_and_cdrom_drives(void) ini_section_set_int(cat, temp, cdrom[c].speed); sprintf(temp, "cdrom_%02i_type", c + 1); - if ((cdrom[c].bus_type == 0) || (cdrom[c].bus_type == CDROM_BUS_MITSUMI)) + 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")) ini_section_delete_var(cat, temp); else - ini_section_set_string(cat, temp, - cdrom_get_internal_name(cdrom_get_type(c))); + ini_section_set_string(cat, temp, tn); sprintf(temp, "cdrom_%02i_parameters", c + 1); if (cdrom[c].bus_type == 0) diff --git a/src/cpu/386.c b/src/cpu/386.c index 3524e0d1e..caa5f84a2 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -27,6 +27,7 @@ #include <86box/fdc.h> #include <86box/machine.h> #include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/gdbstub.h> #ifndef OPS_286_386 # define OPS_286_386 @@ -268,7 +269,8 @@ exec386_2386(int32_t cycs) } else { CHECK_READ_CS(MIN(ol, 4)); } - ins_fetch_fault = cpu_386_check_instruction_fault(); + if (is386) + ins_fetch_fault = cpu_386_check_instruction_fault(); /* Breakpoint fault has priority over other faults. */ if (ins_fetch_fault) { @@ -304,6 +306,13 @@ exec386_2386(int32_t cycs) cpu_state.pc &= 0xffff; #endif + if (cpu_flush_pending == 1) + cpu_flush_pending++; + else if (cpu_flush_pending == 2) { + cpu_flush_pending = 0; + flushmmucache_pc(); + } + if (cpu_end_block_after_ins) cpu_end_block_after_ins--; @@ -329,6 +338,14 @@ exec386_2386(int32_t cycs) #endif } } + } else if (new_ne) { + flags_rebuild(); + new_ne = 0; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + cpu_state.oldpc = cpu_state.pc; + x86_int(16); } else if (trap) { flags_rebuild(); if (trap & 2) dr[6] |= 0x8000; diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 1d130cd8a..8a2bb4ab8 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -72,6 +72,7 @@ extern uint8_t *pccache2; extern int optype; extern uint32_t pccache; +int new_ne = 0; int in_sys = 0; int unmask_a20_in_smm = 0; uint32_t old_rammask = 0xffffffff; @@ -1016,9 +1017,14 @@ smram_restore_state_p6(uint32_t *saved_state) cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_gs); - mem_a20_alt = 0x00; - mem_a20_key = saved_state[SMRAM_FIELD_P6_A20M] ? 0x00 : 0x02; - mem_a20_recalc(); + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x3000000; + + if (saved_state[SMRAM_FIELD_P6_A20M] & 0x01) + rammask &= 0xffefffff; + + flushmmucache(); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; @@ -1819,7 +1825,7 @@ cpu_386_check_instruction_fault(void) } int -sysenter(uint32_t fetchdat) +sysenter(UNUSED(uint32_t fetchdat)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSENTER called\n"); @@ -1901,7 +1907,7 @@ sysenter(uint32_t fetchdat) } int -sysexit(uint32_t fetchdat) +sysexit(UNUSED(uint32_t fetchdat)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSEXIT called\n"); @@ -1988,7 +1994,7 @@ sysexit(uint32_t fetchdat) } int -syscall_op(uint32_t fetchdat) +syscall_op(UNUSED(uint32_t fetchdat)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSCALL called\n"); @@ -2040,7 +2046,7 @@ syscall_op(uint32_t fetchdat) } int -sysret(uint32_t fetchdat) +sysret(UNUSED(uint32_t fetchdat)) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSRET called\n"); diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 8ca89181c..ec40612ee 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -458,6 +458,7 @@ fastreadw_fetch(uint32_t a) { uint16_t ret; + cpu_old_paging = (cpu_flush_pending == 2); if ((a & 0xFFF) > 0xFFE) { ret = fastreadb(a); if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1)) @@ -469,6 +470,7 @@ fastreadw_fetch(uint32_t a) ret = readmemwl_2386(a); read_type = 4; } + cpu_old_paging = 0; return ret; } @@ -486,7 +488,9 @@ fastreadl_fetch(uint32_t a) ret = 0; else { read_type = 1; + cpu_old_paging = (cpu_flush_pending == 2); ret = readmemll_2386(a); + cpu_old_paging = 0; read_type = 4; } @@ -563,35 +567,52 @@ fastreadl_fetch(uint32_t a) } #endif +#ifdef OPS_286_386 static __inline uint8_t getbyte(void) { + uint8_t ret; cpu_state.pc++; - return fastreadb(cs + (cpu_state.pc - 1)); + cpu_old_paging = (cpu_flush_pending == 2); + ret = fastreadb(cs + (cpu_state.pc - 1)); + cpu_old_paging = 0; + return ret; + } static __inline uint16_t getword(void) { + uint16_t ret; cpu_state.pc += 2; - return fastreadw(cs + (cpu_state.pc - 2)); + cpu_old_paging = (cpu_flush_pending == 2); + ret = fastreadw(cs + (cpu_state.pc - 2)); + cpu_old_paging = 0; + return ret; } static __inline uint32_t getlong(void) { + uint32_t ret; cpu_state.pc += 4; - return fastreadl(cs + (cpu_state.pc - 4)); + cpu_old_paging = (cpu_flush_pending == 2); + ret = fastreadl(cs + (cpu_state.pc - 4)); + cpu_old_paging = 0; + return ret; } static __inline uint64_t getquad(void) { + uint64_t ret; cpu_state.pc += 8; - return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); + cpu_old_paging = (cpu_flush_pending == 2); + ret = fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); + cpu_old_paging = 0; + return ret; } -#ifdef OPS_286_386 static __inline uint8_t geteab(void) { @@ -678,6 +699,34 @@ seteaq(uint64_t v) # define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v); # define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v); #else +static __inline uint8_t +getbyte(void) +{ + cpu_state.pc++; + return fastreadb(cs + (cpu_state.pc - 1)); +} + +static __inline uint16_t +getword(void) +{ + cpu_state.pc += 2; + return fastreadw(cs + (cpu_state.pc - 2)); +} + +static __inline uint32_t +getlong(void) +{ + cpu_state.pc += 4; + return fastreadl(cs + (cpu_state.pc - 4)); +} + +static __inline uint64_t +getquad(void) +{ + cpu_state.pc += 8; + return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); +} + static __inline uint8_t geteab(void) { diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index d8a33a624..5f41c416a 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -30,6 +30,7 @@ #include <86box/fdc.h> #include <86box/machine.h> #include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC # include "codegen.h" @@ -357,6 +358,8 @@ exec386_dynarec_int(void) CPU_BLOCK_END(); if (smi_line) CPU_BLOCK_END(); + else if (new_ne) + CPU_BLOCK_END(); else if (trap) CPU_BLOCK_END(); else if (nmi && nmi_enable && nmi_mask) @@ -366,7 +369,7 @@ exec386_dynarec_int(void) } block_ended: - if (!cpu_state.abrt && trap) { + if (!cpu_state.abrt && !new_ne && trap) { # ifdef USE_DEBUG_REGS_486 //pclog("Debug trap 0x%X\n", trap); if (trap & 2) dr[6] |= 0x8000; @@ -386,7 +389,11 @@ block_ended: cpu_end_block_after_ins = 0; } +#if defined(__linux__) && !defined(__clang__) && defined(USE_NEW_DYNAREC) +static inline void __attribute__((optimize("O2"))) +#else static __inline void +#endif exec386_dynarec_dyn(void) { uint32_t start_pc = 0; @@ -598,6 +605,8 @@ exec386_dynarec_dyn(void) if (cpu_init) CPU_BLOCK_END(); + if (new_ne) + CPU_BLOCK_END(); if ((cpu_state.flags & T_FLAG) || (trap == 2)) CPU_BLOCK_END(); if (smi_line) @@ -622,7 +631,7 @@ exec386_dynarec_dyn(void) cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !new_ne && !x86_was_reset) codegen_block_end_recompile(block); if (x86_was_reset) @@ -698,6 +707,8 @@ exec386_dynarec_dyn(void) if (cpu_init) CPU_BLOCK_END(); + if (new_ne) + CPU_BLOCK_END(); if (cpu_state.flags & T_FLAG) CPU_BLOCK_END(); if (smi_line) @@ -722,7 +733,7 @@ exec386_dynarec_dyn(void) cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !new_ne && !x86_was_reset) codegen_block_end(); if (x86_was_reset) @@ -805,6 +816,15 @@ exec386_dynarec(int32_t cycs) } } + if (new_ne) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + new_ne = 0; + x86_int(16); + } + if (smi_line) enter_smm_check(0); else if (nmi && nmi_enable && nmi_mask) { @@ -933,6 +953,13 @@ exec386(int32_t cycs) x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc); #endif + if (cpu_flush_pending == 1) + cpu_flush_pending++; + else if (cpu_flush_pending == 2) { + cpu_flush_pending = 0; + flushmmucache_pc(); + } + #ifndef USE_NEW_DYNAREC if (!use32) cpu_state.pc &= 0xffff; @@ -966,6 +993,15 @@ block_ended: #endif } } + } else if (new_ne) { + flags_rebuild(); + + new_ne = 0; +#ifndef USE_NEW_DYNAREC + oldcs = CS; +#endif + cpu_state.oldpc = cpu_state.pc; + x86_int(16); } else if (trap) { flags_rebuild(); #ifdef USE_DEBUG_REGS_486 diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 3e0d191f2..b8ef9edda 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -649,7 +649,7 @@ const OpFn OP_TABLE(386_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -671,7 +671,7 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -693,7 +693,7 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -715,7 +715,7 @@ const OpFn OP_TABLE(386_0f)[1024] = { /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1384,7 +1384,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = { // clang-format on }; -# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# ifdef USE_CYRIX_6X86 const OpFn OP_TABLE(c6x86_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1476,7 +1476,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = { /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, // clang-format on }; -# endif +# endif /* USE_CYRIX_6X86 */ const OpFn OP_TABLE(pentiummmx_0f)[1024] = { // clang-format off @@ -1754,7 +1754,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = { // clang-format on }; -# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# ifdef USE_CYRIX_6X86 const OpFn OP_TABLE(c6x86mx_0f)[1024] = { // clang-format off /*16-bit data, 16-bit addr*/ @@ -1846,7 +1846,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = { /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, // clang-format on }; -# endif +# endif /* USE_CYRIX_6X86 */ const OpFn OP_TABLE(pentiumpro_0f)[1024] = { // clang-format off diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 990f9ae87..e3a326503 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -35,6 +35,7 @@ #include <86box/ppi.h> #include <86box/timer.h> #include <86box/gdbstub.h> +#include <86box/plat_unused.h> /* Is the CPU 8088 or 8086. */ int is8086 = 0; @@ -153,6 +154,48 @@ x808x_log(const char *fmt, ...) static void pfq_add(int c, int add); static void set_pzs(int bits); +void +prefetch_queue_set_pos(int pos) +{ + pfq_pos = pos; +} + +void +prefetch_queue_set_ip(uint16_t ip) +{ + pfq_ip = ip; +} + +void +prefetch_queue_set_prefetching(int p) +{ + prefetching = p; +} + +int +prefetch_queue_get_pos(void) +{ + return pfq_pos; +} + +uint16_t +prefetch_queue_get_ip(void) +{ + return pfq_ip; +} + +int +prefetch_queue_get_prefetching(void) +{ + return prefetching; +} + +int +prefetch_queue_get_size(void) +{ + return pfq_size; +} + uint16_t get_last_addr(void) { @@ -240,13 +283,13 @@ cpu_io(int bits, int out, uint16_t port) int old_cycles = cycles; if (out) { - wait(4, 1); + wait(is_mazovia ? 5 : 4, 1); if (bits == 16) { if (is8086 && !(port & 1)) { old_cycles = cycles; outw(port, AX); } else { - wait(4, 1); + wait(is_mazovia ? 5 : 4, 1); old_cycles = cycles; outb(port++, AL); outb(port, AH); @@ -256,13 +299,13 @@ cpu_io(int bits, int out, uint16_t port) outb(port, AL); } } else { - wait(4, 1); + wait(is_mazovia ? 5 : 4, 1); if (bits == 16) { if (is8086 && !(port & 1)) { old_cycles = cycles; AX = inw(port); } else { - wait(4, 1); + wait(is_mazovia ? 5 : 4, 1); old_cycles = cycles; AL = inb(port++); AH = inb(port); @@ -815,7 +858,7 @@ pop(void) } static void -access(int num, int bits) +access(int num, UNUSED(int bits)) { switch (num) { case 0: @@ -1419,7 +1462,7 @@ set_pzs(int bits) } static void -set_co_mul(int bits, int carry) +set_co_mul(UNUSED(int bits), int carry) { set_cf(carry); set_of(carry); @@ -1634,28 +1677,75 @@ cpu_data_opff_rm(void) } } +uint8_t +cpu_inb(uint16_t port) +{ + int old_cycles = cycles; + uint8_t ret; + + wait(is_mazovia ? 5 : 4, 1); + old_cycles = cycles; + + ret = inb(port); + + resub_cycles(old_cycles); + + return ret; +} + uint16_t cpu_inw(uint16_t port) { + int old_cycles = cycles; + uint16_t ret; + + wait(is_mazovia ? 5 : 4, 1); if (is8086 && !(port & 1)) { - wait(4, 0); + old_cycles = cycles; + ret = inw(port); } else { - wait(8, 0); + wait(is_mazovia ? 5 : 4, 1); + old_cycles = cycles; + ret = inb(port++); + ret |= (inb(port) << 8); } - return inw(port); + resub_cycles(old_cycles); + + return ret; +} + +void +cpu_outb(uint16_t port, uint16_t val) +{ + int old_cycles = cycles; + + wait(is_mazovia ? 5 : 4, 1); + old_cycles = cycles; + + outb(port, val); + + resub_cycles(old_cycles); } void cpu_outw(uint16_t port, uint16_t val) { + int old_cycles = cycles; + + wait(is_mazovia ? 5 : 4, 1); + if (is8086 && !(port & 1)) { - wait(4, 0); + old_cycles = cycles; + outw(port, val); } else { - wait(8, 0); + wait(is_mazovia ? 5 : 4, 1); + old_cycles = cycles; + outb(port++, val); + outb(port, val >> 8); } - return outw(port, val); + resub_cycles(old_cycles); } /* Executes instructions up to the specified number of cycles. */ @@ -1804,8 +1894,7 @@ execx86(int cycs) writememw(es, DI, cpu_inw(DX)); DI += (cpu_state.flags & D_FLAG) ? -2 : 2; } else { - wait(4, 0); - writememb(es, DI, inb(DX)); + writememb(es, DI, cpu_inb(DX)); DI += (cpu_state.flags & D_FLAG) ? -1 : 1; } @@ -1833,8 +1922,7 @@ execx86(int cycs) cpu_outw(DX, readmemw(dest_seg, SI)); SI += (cpu_state.flags & D_FLAG) ? -2 : 2; } else { - wait(4, 0); - outb(DX, readmemb(dest_seg + SI)); + cpu_outb(DX, readmemb(dest_seg + SI)); SI += (cpu_state.flags & D_FLAG) ? -1 : 1; } if (in_rep == 0) @@ -3154,8 +3242,10 @@ execx86(int cycs) #else cpu_src = pfq_fetchb(); #endif - if (x86_div(AL, 0)) - set_pzs(16); + if (x86_div(AL, 0)) { + cpu_data = AL; + set_pzs(8); + } break; case 0xD5: /*AAD*/ wait(1, 0); @@ -3169,6 +3259,7 @@ execx86(int cycs) add(8); AL = cpu_data; AH = 0x00; + set_pzs(8); break; case 0xD6: /*SALC*/ wait(1, 0); diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index a3677767d..890d02e3e 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -9,32 +9,60 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c - 386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c - x87_timings.c 8080.c) +add_library(cpu OBJECT + cpu.c + cpu_table.c + fpu.c x86.c + 808x.c + 386.c + 386_common.c + 386_dynarec.c + x86_ops_mmx.c + x86seg_common.c + x86seg.c + x86seg_2386.c + x87.c + x87_timings.c + 8080.c +) if(AMD_K5) target_compile_definitions(cpu PRIVATE USE_AMD_K5) + +if(DYNAREC) + add_library(ctk5 OBJECT codegen_timing_k5.c) + target_link_libraries(86Box ctk5) +endif() + endif() if(CYRIX_6X86) target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86) +if(DYNAREC) add_library(ct686 OBJECT codegen_timing_686.c) target_link_libraries(86Box ct686) endif() +endif() if(DYNAREC) target_sources(cpu PRIVATE 386_dynarec_ops.c) - add_library(cgt OBJECT codegen_timing_486.c - codegen_timing_common.c codegen_timing_k6.c - codegen_timing_pentium.c codegen_timing_p6.c - codegen_timing_winchip.c codegen_timing_winchip2.c) + add_library(cgt OBJECT + codegen_timing_486.c + codegen_timing_common.c + codegen_timing_k6.c + codegen_timing_pentium.c + codegen_timing_p6.c + codegen_timing_winchip.c + codegen_timing_winchip2.c + ) endif() add_subdirectory(softfloat3e) diff --git a/src/cpu/codegen_timing_486.c b/src/cpu/codegen_timing_486.c index 548a9ec28..d8f05cfd3 100644 --- a/src/cpu/codegen_timing_486.c +++ b/src/cpu/codegen_timing_486.c @@ -18,7 +18,7 @@ #define CYCLES(c) (int *) c #define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = { +static int *opcode_timings_486[256] = { // clang-format off /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), @@ -42,7 +42,7 @@ static int *opcode_timings[256] = { // clang-format on }; -static int *opcode_timings_mod3[256] = { +static int *opcode_timings_486_mod3[256] = { // clang-format off /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), @@ -66,7 +66,7 @@ static int *opcode_timings_mod3[256] = { // clang-format on }; -static int *opcode_timings_0f[256] = { +static int *opcode_timings_486_0f[256] = { // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -89,7 +89,7 @@ static int *opcode_timings_0f[256] = { /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, // clang-format on }; -static int *opcode_timings_0f_mod3[256] = { +static int *opcode_timings_486_0f_mod3[256] = { // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -113,65 +113,65 @@ static int *opcode_timings_0f_mod3[256] = { // clang-format on }; -static int *opcode_timings_shift[8] = { +static int *opcode_timings_486_shift[8] = { // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) }; -static int *opcode_timings_shift_mod3[8] = { +static int *opcode_timings_486_shift_mod3[8] = { // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) // clang-format on }; -static int *opcode_timings_f6[8] = { +static int *opcode_timings_486_f6[8] = { // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) // clang-format on }; -static int *opcode_timings_f6_mod3[8] = { +static int *opcode_timings_486_f6_mod3[8] = { // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) // clang-format on }; -static int *opcode_timings_f7[8] = { +static int *opcode_timings_486_f7[8] = { // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) // clang-format on }; -static int *opcode_timings_f7_mod3[8] = { +static int *opcode_timings_486_f7_mod3[8] = { // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) }; -static int *opcode_timings_ff[8] = { +static int *opcode_timings_486_ff[8] = { // clang-format off &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL }; -static int *opcode_timings_ff_mod3[8] = { +static int *opcode_timings_486_ff_mod3[8] = { // clang-format off &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL // clang-format on }; -static int *opcode_timings_d8[8] = { +static int *opcode_timings_486_d8[8] = { // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_d8_mod3[8] = { +static int *opcode_timings_486_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_d9[8] = { +static int *opcode_timings_486_d9[8] = { // clang-format off /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) // clang-format on }; -static int *opcode_timings_d9_mod3[64] = { +static int *opcode_timings_486_d9_mod3[64] = { // clang-format off /*FLD*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), @@ -192,25 +192,25 @@ static int *opcode_timings_d9_mod3[64] = { // clang-format on }; -static int *opcode_timings_da[8] = { +static int *opcode_timings_486_da[8] = { // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_da_mod3[8] = { +static int *opcode_timings_486_da_mod3[8] = { // clang-format off NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL // clang-format on }; -static int *opcode_timings_db[8] = { +static int *opcode_timings_486_db[8] = { // clang-format off /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6) // clang-format on }; -static int *opcode_timings_db_mod3[64] = { +static int *opcode_timings_486_db_mod3[64] = { // clang-format off NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -224,74 +224,74 @@ static int *opcode_timings_db_mod3[64] = { // clang-format on }; -static int *opcode_timings_dc[8] = { +static int *opcode_timings_486_dc[8] = { // clang-format off /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_dc_mod3[8] = { +static int *opcode_timings_486_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_dd[8] = { +static int *opcode_timings_486_dd[8] = { // clang-format off /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3) // clang-format on }; -static int *opcode_timings_dd_mod3[8] = { +static int *opcode_timings_486_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL // clang-format on }; -static int *opcode_timings_de[8] = { +static int *opcode_timings_486_de[8] = { // clang-format off /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_de_mod3[8] = { +static int *opcode_timings_486_de_mod3[8] = { // clang-format off /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73) // clang-format on }; -static int *opcode_timings_df[8] = { +static int *opcode_timings_486_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28) // clang-format on }; -static int *opcode_timings_df_mod3[8] = { +static int *opcode_timings_486_df_mod3[8] = { // clang-format off /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL // clang-format on }; -static int *opcode_timings_8x[8] = { +static int *opcode_timings_486_8x[8] = { // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm // clang-format on }; -static int *opcode_timings_8x_mod3[8] = { +static int *opcode_timings_486_8x_mod3[8] = { // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm // clang-format on }; -static int *opcode_timings_81[8] = { +static int *opcode_timings_486_81[8] = { // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm // clang-format on }; -static int *opcode_timings_81_mod3[8] = { +static int *opcode_timings_486_81_mod3[8] = { // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm // clang-format on @@ -328,9 +328,9 @@ codegen_timing_486_start(void) } void -codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat) +codegen_timing_486_prefix(uint8_t prefix, UNUSED(uint32_t fetchdat)) { - timing_count += COUNT(opcode_timings[prefix], 0); + timing_count += COUNT(opcode_timings_486[prefix], 0); last_prefix = prefix; } @@ -344,47 +344,47 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u switch (last_prefix) { case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + timings = mod3 ? opcode_timings_486_0f_mod3 : opcode_timings_486_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; break; case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + timings = mod3 ? opcode_timings_486_d8_mod3 : opcode_timings_486_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + timings = mod3 ? opcode_timings_486_d9_mod3 : opcode_timings_486_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + timings = mod3 ? opcode_timings_486_da_mod3 : opcode_timings_486_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + timings = mod3 ? opcode_timings_486_db_mod3 : opcode_timings_486_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + timings = mod3 ? opcode_timings_486_dc_mod3 : opcode_timings_486_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + timings = mod3 ? opcode_timings_486_dd_mod3 : opcode_timings_486_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + timings = mod3 ? opcode_timings_486_de_mod3 : opcode_timings_486_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + timings = mod3 ? opcode_timings_486_df_mod3 : opcode_timings_486_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -394,12 +394,12 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + timings = mod3 ? opcode_timings_486_8x_mod3 : opcode_timings_486_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + timings = mod3 ? opcode_timings_486_81_mod3 : opcode_timings_486_81; deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; opcode = (fetchdat >> 3) & 7; break; @@ -410,29 +410,29 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + timings = mod3 ? opcode_timings_486_shift_mod3 : opcode_timings_486_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + timings = mod3 ? opcode_timings_486_f6_mod3 : opcode_timings_486_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + timings = mod3 ? opcode_timings_486_f7_mod3 : opcode_timings_486_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + timings = mod3 ? opcode_timings_486_ff_mod3 : opcode_timings_486_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; + timings = mod3 ? opcode_timings_486_mod3 : opcode_timings_486; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } diff --git a/src/cpu/codegen_timing_686.c b/src/cpu/codegen_timing_686.c index 6ea5ac543..285881956 100644 --- a/src/cpu/codegen_timing_686.c +++ b/src/cpu/codegen_timing_686.c @@ -65,7 +65,7 @@ static uint32_t prev_fetchdat; static uint32_t last_regmask_modified; static uint32_t regmask_modified; -static uint32_t opcode_timings[256] = { +static uint32_t opcode_timings_686[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, @@ -202,7 +202,7 @@ static uint32_t opcode_timings[256] = { // clang-format on }; -static uint32_t opcode_timings_mod3[256] = { +static uint32_t opcode_timings_686_mod3[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, @@ -340,7 +340,7 @@ static uint32_t opcode_timings_mod3[256] = { // clang-format on }; -static uint32_t opcode_timings_0f[256] = { +static uint32_t opcode_timings_686_0f[256] = { // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, @@ -423,7 +423,7 @@ static uint32_t opcode_timings_0f[256] = { PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, // clang-format on }; -static uint32_t opcode_timings_0f_mod3[256] = { +static uint32_t opcode_timings_686_0f_mod3[256] = { // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, @@ -506,44 +506,44 @@ static uint32_t opcode_timings_0f_mod3[256] = { // clang-format on }; -static uint32_t opcode_timings_shift[8] = { +static uint32_t opcode_timings_686_shift[8] = { // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, // clang-format on }; -static uint32_t opcode_timings_shift_mod3[8] = { +static uint32_t opcode_timings_686_shift_mod3[8] = { // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, // clang-format on }; -static uint32_t opcode_timings_shift_imm[8] = { +static uint32_t opcode_timings_686_shift_imm[8] = { // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, // clang-format on }; -static uint32_t opcode_timings_shift_imm_mod3[8] = { +static uint32_t opcode_timings_686_shift_imm_mod3[8] = { // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, // clang-format on }; -static uint32_t opcode_timings_shift_cl[8] = { +static uint32_t opcode_timings_686_shift_cl[8] = { // clang-format off PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), // clang-format on }; -static uint32_t opcode_timings_shift_cl_mod3[8] = { +static uint32_t opcode_timings_686_shift_cl_mod3[8] = { // clang-format off PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), // clang-format on }; -static uint32_t opcode_timings_f6[8] = { +static uint32_t opcode_timings_686_f6[8] = { // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), @@ -551,7 +551,7 @@ static uint32_t opcode_timings_f6[8] = { PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) // clang-format on }; -static uint32_t opcode_timings_f6_mod3[8] = { +static uint32_t opcode_timings_686_f6_mod3[8] = { // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), @@ -559,7 +559,7 @@ static uint32_t opcode_timings_f6_mod3[8] = { PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18) // clang-format on }; -static uint32_t opcode_timings_f7[8] = { +static uint32_t opcode_timings_686_f7[8] = { // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), @@ -567,7 +567,7 @@ static uint32_t opcode_timings_f7[8] = { PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) // clang-format on }; -static uint32_t opcode_timings_f7_mod3[8] = { +static uint32_t opcode_timings_686_f7_mod3[8] = { // clang-format off /* TST NOT NEG*/ PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1), @@ -575,7 +575,7 @@ static uint32_t opcode_timings_f7_mod3[8] = { PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30) // clang-format on }; -static uint32_t opcode_timings_ff[8] = { +static uint32_t opcode_timings_686_ff[8] = { // clang-format off /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), @@ -583,7 +583,7 @@ static uint32_t opcode_timings_ff[8] = { PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID // clang-format on }; -static uint32_t opcode_timings_ff_mod3[8] = { +static uint32_t opcode_timings_686_ff_mod3[8] = { // clang-format off /* INC DEC CALL CALL far*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), @@ -592,7 +592,7 @@ static uint32_t opcode_timings_ff_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_d8[8] = { +static uint32_t opcode_timings_686_d8[8] = { // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), @@ -600,7 +600,7 @@ static uint32_t opcode_timings_d8[8] = { PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) // clang-format on }; -static uint32_t opcode_timings_d8_mod3[8] = { +static uint32_t opcode_timings_686_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), @@ -609,7 +609,7 @@ static uint32_t opcode_timings_d8_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_d9[8] = { +static uint32_t opcode_timings_686_d9[8] = { // clang-format off /* FLDs FSTs FSTPs*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -617,7 +617,7 @@ static uint32_t opcode_timings_d9[8] = { PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5) // clang-format on }; -static uint32_t opcode_timings_d9_mod3[64] = { +static uint32_t opcode_timings_686_d9_mod3[64] = { // clang-format off /*FLD*/ PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -650,7 +650,7 @@ static uint32_t opcode_timings_d9_mod3[64] = { // clang-format on }; -static uint32_t opcode_timings_da[8] = { +static uint32_t opcode_timings_686_da[8] = { // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), @@ -658,14 +658,14 @@ static uint32_t opcode_timings_da[8] = { PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48) // clang-format on }; -static uint32_t opcode_timings_da_mod3[8] = { +static uint32_t opcode_timings_686_da_mod3[8] = { // clang-format off PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), INVALID, PAIR_X | CYCLES(5), INVALID, INVALID // clang-format on }; -static uint32_t opcode_timings_db[8] = { +static uint32_t opcode_timings_686_db[8] = { // clang-format off /* FLDil FSTil FSTPil*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -673,7 +673,7 @@ static uint32_t opcode_timings_db[8] = { INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2) // clang-format on }; -static uint32_t opcode_timings_db_mod3[64] = { +static uint32_t opcode_timings_686_db_mod3[64] = { // clang-format off PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), @@ -703,7 +703,7 @@ static uint32_t opcode_timings_db_mod3[64] = { // clang-format on }; -static uint32_t opcode_timings_dc[8] = { +static uint32_t opcode_timings_686_dc[8] = { // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), @@ -711,7 +711,7 @@ static uint32_t opcode_timings_dc[8] = { PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34) // clang-format on }; -static uint32_t opcode_timings_dc_mod3[8] = { +static uint32_t opcode_timings_686_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID, @@ -720,7 +720,7 @@ static uint32_t opcode_timings_dc_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_dd[8] = { +static uint32_t opcode_timings_686_dd[8] = { // clang-format off /* FLDd FSTd FSTPd*/ PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -728,7 +728,7 @@ static uint32_t opcode_timings_dd[8] = { PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2) // clang-format on }; -static uint32_t opcode_timings_dd_mod3[8] = { +static uint32_t opcode_timings_686_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP*/ PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), @@ -737,14 +737,14 @@ static uint32_t opcode_timings_dd_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_de[8] = { +static uint32_t opcode_timings_686_de[8] = { // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10), /* FISUBw FISUBRw FIDIVw FIDIVRw*/ PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38) }; -static uint32_t opcode_timings_de_mod3[8] = { +static uint32_t opcode_timings_686_de_mod3[8] = { // clang-format off /* FADD FMUL FCOMPP*/ PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7), @@ -753,7 +753,7 @@ static uint32_t opcode_timings_de_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_df[8] = { +static uint32_t opcode_timings_686_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw*/ PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13), @@ -761,7 +761,7 @@ static uint32_t opcode_timings_df[8] = { INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13) // clang-format on }; -static uint32_t opcode_timings_df_mod3[8] = { +static uint32_t opcode_timings_686_df_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -769,25 +769,25 @@ static uint32_t opcode_timings_df_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_8x[8] = { +static uint32_t opcode_timings_686_8x[8] = { // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM // clang-format on }; -static uint32_t opcode_timings_8x_mod3[8] = { +static uint32_t opcode_timings_686_8x_mod3[8] = { // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG // clang-format on }; -static uint32_t opcode_timings_81[8] = { +static uint32_t opcode_timings_686_81[8] = { // clang-format off PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM // clang-format on }; -static uint32_t opcode_timings_81_mod3[8] = { +static uint32_t opcode_timings_686_81_mod3[8] = { // clang-format off PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG @@ -874,47 +874,47 @@ codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u switch (last_prefix) { case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + timings = mod3 ? opcode_timings_686_0f_mod3 : opcode_timings_686_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; break; case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + timings = mod3 ? opcode_timings_686_d8_mod3 : opcode_timings_686_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + timings = mod3 ? opcode_timings_686_d9_mod3 : opcode_timings_686_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + timings = mod3 ? opcode_timings_686_da_mod3 : opcode_timings_686_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + timings = mod3 ? opcode_timings_686_db_mod3 : opcode_timings_686_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + timings = mod3 ? opcode_timings_686_dc_mod3 : opcode_timings_686_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + timings = mod3 ? opcode_timings_686_dd_mod3 : opcode_timings_686_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + timings = mod3 ? opcode_timings_686_de_mod3 : opcode_timings_686_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + timings = mod3 ? opcode_timings_686_df_mod3 : opcode_timings_686_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -924,55 +924,55 @@ codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + timings = mod3 ? opcode_timings_686_8x_mod3 : opcode_timings_686_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + timings = mod3 ? opcode_timings_686_81_mod3 : opcode_timings_686_81; deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; opcode = (fetchdat >> 3) & 7; break; case 0xc0: case 0xc1: - timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm; + timings = mod3 ? opcode_timings_686_shift_imm_mod3 : opcode_timings_686_shift_imm; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + timings = mod3 ? opcode_timings_686_shift_mod3 : opcode_timings_686_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl; + timings = mod3 ? opcode_timings_686_shift_cl_mod3 : opcode_timings_686_shift_cl; deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + timings = mod3 ? opcode_timings_686_f6_mod3 : opcode_timings_686_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + timings = mod3 ? opcode_timings_686_f7_mod3 : opcode_timings_686_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + timings = mod3 ? opcode_timings_686_ff_mod3 : opcode_timings_686_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; + timings = mod3 ? opcode_timings_686_mod3 : opcode_timings_686; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } diff --git a/src/cpu/codegen_timing_k5.c b/src/cpu/codegen_timing_k5.c new file mode 100644 index 000000000..8ce2f4cea --- /dev/null +++ b/src/cpu/codegen_timing_k5.c @@ -0,0 +1,2233 @@ +/*Most of the vector instructions here are a total guess. + Some of the timings are based on https://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000502_k5_InstLatX86.txt*/ +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/mem.h> +#include "cpu.h" +#include <86box/machine.h> +#include <86box/plat_unused.h> + +#include "x86.h" +#include "x86_ops.h" +#include "x86seg_common.h" +#include "x87_sf.h" +#include "x87.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ops.h" +#include "codegen_timing_common.h" + +typedef enum uop_type_t { + UOP_ALU = 0, /*Executes in Integer X or Y units*/ + UOP_ALUX, /*Executes in Integer X unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORE, /*Executes in Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORE, /*Executes in Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORE, /*Executes in Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MEU, /*Executes in Multimedia unit*/ + UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ + UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ + UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_LIMM /*Does not require an execution unit*/ +} uop_type_t; + +typedef enum decode_type_t { + DECODE_SHORT, + DECODE_LONG, + DECODE_VECTOR +} decode_type_t; + +#define MAX_UOPS 10 + +typedef struct risc86_uop_t { + uop_type_t type; + int throughput; + int latency; +} risc86_uop_t; + +typedef struct risc86_instruction_t { + int nr_uops; + decode_type_t decode_type; + risc86_uop_t uop[MAX_UOPS]; +} risc86_instruction_t; + +static const risc86_instruction_t alu_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alux_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_alux_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alu_store_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t alux_store_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t branch_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t limm_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t load_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t store_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t bswap_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t leave_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t lods_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t loop_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mov_reg_seg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t movs_op = { + .nr_uops = 4, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pop_reg_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pop_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t push_imm_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t push_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t push_seg_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t stos_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_reg_b_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_mem_imm_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t test_mem_imm_b_op = { + .nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t xchg_op = { + .nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t m3dn_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mmx_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mmx_mul_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t mmx_shift_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_3dn_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_3DN, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_mmx_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t load_mmx_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t load_mmx_shift_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t mload_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t mstore_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t pmul_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t pmul_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_MEU_MUL, .throughput = 1, .latency = 2} +}; + +static const risc86_instruction_t float_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t load_float_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t fstore_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t fdiv_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} +}; +static const risc86_instruction_t fdiv_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_FLOAT, .throughput = 40, .latency = 40} +}; +static const risc86_instruction_t fsin_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} +}; +static const risc86_instruction_t fsqrt_op = { + .nr_uops = 1, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} +}; + +static const risc86_instruction_t vector_fldcw_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} +}; +static const risc86_instruction_t vector_float_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t vector_float_l_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} +}; +static const risc86_instruction_t vector_flde_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_FLOAT, .throughput = 2, .latency = 2} +}; +static const risc86_instruction_t vector_fste_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, + .uop[1] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; + +static const risc86_instruction_t vector_alu1_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu2_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu3_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu6_op = { + .nr_uops = 6, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux1_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux3_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux6_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alu_store_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_alux_store_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_arpl_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_bound_op = { + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_bsx_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_call_far_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cli_sti_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} +}; +static const risc86_instruction_t vector_cmps_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cmpsb_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_cmpxchg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cmpxchg_b_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cpuid_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} +}; +static const risc86_instruction_t vector_div16_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_div16_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_div32_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} +}; +static const risc86_instruction_t vector_div32_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 18, .latency = 18} +}; +static const risc86_instruction_t vector_emms_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} +}; +static const risc86_instruction_t vector_enter_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALU, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_femms_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} +}; +static const risc86_instruction_t vector_in_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} +}; +static const risc86_instruction_t vector_ins_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_int_op = { + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1 }, + .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_iret_op = { + .nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[3] = { .type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[4] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_invd_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} +}; +static const risc86_instruction_t vector_jmp_far_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_load_alu_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_load_alux_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_loop_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_lss_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = { .type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mov_mem_seg_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mov_seg_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mov_seg_reg_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} +}; +static const risc86_instruction_t vector_mul_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul64_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_mul64_mem_op = { + .nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_out_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} +}; +static const risc86_instruction_t vector_outs_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1 }, + .uop[1] = { .type = UOP_STORE, .throughput = 10, .latency = 10}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1 } +}; +static const risc86_instruction_t vector_pusha_op = { + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[6] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[7] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_popa_op = { + .nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = { .type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = { .type = UOP_LOAD, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_popf_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2 }, + .uop[1] = { .type = UOP_ALUX, .throughput = 17, .latency = 17} +}; +static const risc86_instruction_t vector_push_mem_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_pushf_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_ret_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_retf_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[2] = { .type = UOP_BRANCH, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_scas_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_scasb_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_setcc_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_FSTORE, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_setcc_reg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_test_mem_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_test_mem_b_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = { .type = UOP_ALUX, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_xchg_mem_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = { .type = UOP_ALU, .throughput = 1, .latency = 1} +}; +static const risc86_instruction_t vector_xlat_op = { + .nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = { .type = UOP_LOAD, .throughput = 1, .latency = 2} +}; +static const risc86_instruction_t vector_wbinvd_op = { + .nr_uops = 1, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} +}; + +#define INVALID NULL + +static const risc86_instruction_t *opcode_timings_k5[256] = { + // clang-format off +/* ADD ADD ADD ADD*/ +/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* ADD ADD PUSH ES POP ES*/ + &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, +/* OR OR OR OR*/ + &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* OR OR PUSH CS */ + &alux_op, &alu_op, &push_seg_op, INVALID, + +/* ADC ADC ADC ADC*/ +/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, +/* ADC ADC PUSH SS POP SS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, +/* SBB SBB SBB SBB*/ +/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, +/* SBB SBB PUSH DS POP DS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + +/* AND AND AND AND*/ +/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* AND AND DAA*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, +/* SUB SUB SUB SUB*/ + &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* SUB SUB DAS*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + +/* XOR XOR XOR XOR*/ +/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, +/* XOR XOR AAA*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, +/* CMP CMP CMP CMP*/ + &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, +/* CMP CMP AAS*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ &store_op, &store_op, &store_op, &store_op, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, +/* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, +/* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, +/* INSB INSW OUTSB OUTSW*/ + &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, + +/* Jxx*/ +/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + &vector_test_mem_b_op, &vector_test_mem_op, &vector_xchg_mem_op, &vector_xchg_mem_op, +/* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, +/* MOV from seg LEA MOV to seg POP*/ + &vector_mov_mem_seg_op, &store_op, &vector_mov_seg_mem_op, &pop_mem_op, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, +/* CBW CWD CALL far WAIT*/ + &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, +/* PUSHF POPF SAHF LAHF*/ + &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, + +/* MOV MOV MOV MOV*/ +/*a0*/ &load_op, &load_op, &store_op, &store_op, +/* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, +/* TEST TEST STOSB STOSW*/ + &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, +/* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, + +/* MOV*/ +/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + +/* RET imm RET*/ +/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, +/* LES LDS MOV MOV*/ + &vector_lss_op, &vector_lss_op, &store_op, &store_op, +/* ENTER LEAVE RETF RETF*/ + &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, +/* INT3 INT INTO IRET*/ + &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, + + +/*d0*/ INVALID, INVALID, INVALID, INVALID, +/* AAM AAD SETALC XLAT*/ + &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, +/* CALL JMP JMP JMP*/ + &store_op, &branch_op, &vector_jmp_far_op, &branch_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + +/* REPNE REPE*/ +/*f0*/ INVALID, INVALID, INVALID, INVALID, +/* HLT CMC*/ + &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, +/* CLC STC CLI STI*/ + &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, +/* CLD STD INCDEC*/ + &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_mod3[256] = { + // clang-format off +/* ADD ADD ADD ADD*/ +/*00*/ &alux_op, &alu_op, &alux_op, &alu_op, +/* ADD ADD PUSH ES POP ES*/ + &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, +/* OR OR OR OR*/ + &alux_op, &alu_op, &alux_op, &alu_op, +/* OR OR PUSH CS */ + &alux_op, &alu_op, &push_seg_op, INVALID, + +/* ADC ADC ADC ADC*/ +/*10*/ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, +/* ADC ADC PUSH SS POP SS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, +/* SBB SBB SBB SBB*/ + &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, +/* SBB SBB PUSH DS POP DS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + +/* AND AND AND AND*/ +/*20*/ &alux_op, &alu_op, &alux_op, &alu_op, +/* AND AND DAA*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, +/* SUB SUB SUB SUB*/ + &alux_op, &alu_op, &alux_op, &alu_op, +/* SUB SUB DAS*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + +/* XOR XOR XOR XOR*/ +/*30*/ &alux_op, &alu_op, &alux_op, &alu_op, +/* XOR XOR AAA*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, +/* CMP CMP CMP CMP*/ + &alux_op, &alu_op, &alux_op, &alu_op, +/* CMP CMP AAS*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + +/* INC EAX INC ECX INC EDX INC EBX*/ +/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, +/* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, +/* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + +/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ +/*50*/ &store_op, &store_op, &store_op, &store_op, +/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, +/* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, +/* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + +/* PUSHA POPA BOUND ARPL*/ +/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, + INVALID, INVALID, INVALID, INVALID, +/* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, +/* INSB INSW OUTSB OUTSW*/ + &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, + +/* Jxx*/ +/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*80*/ INVALID, INVALID, INVALID, INVALID, +/* TEST TEST XCHG XCHG*/ + &vector_alu1_op, &vector_alu1_op, &vector_alu3_op, &vector_alu3_op, +/* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, +/* MOV from seg LEA MOV to seg POP*/ + &mov_reg_seg_op, &store_op, &vector_mov_seg_reg_op, &pop_reg_op, + +/* NOP XCHG XCHG XCHG*/ +/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, +/* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, +/* CBW CWD CALL far WAIT*/ + &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, +/* PUSHF POPF SAHF LAHF*/ + &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, + +/* MOV MOV MOV MOV*/ +/*a0*/ &load_op, &load_op, &store_op, &store_op, +/* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, +/* TEST TEST STOSB STOSW*/ + &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, +/* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, + +/* MOV*/ +/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, + +/* RET imm RET*/ +/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, +/* LES LDS MOV MOV*/ + &vector_lss_op, &vector_lss_op, &store_op, &store_op, +/* ENTER LEAVE RETF RETF*/ + &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, +/* INT3 INT INTO IRET*/ + &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, + + +/*d0*/ INVALID, INVALID, INVALID, INVALID, +/* AAM AAD SETALC XLAT*/ + &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, +/* LOOPNE LOOPE LOOP JCXZ*/ +/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, +/* CALL JMP JMP JMP*/ + &store_op, &branch_op, &vector_jmp_far_op, &branch_op, +/* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + +/* REPNE REPE*/ +/*f0*/ INVALID, INVALID, INVALID, INVALID, +/* HLT CMC*/ + &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, +/* CLC STC CLI STI*/ + &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, +/* CLD STD INCDEC*/ + &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_0f[256] = { + // clang-format off +/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, + &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, + INVALID, &load_op, &vector_femms_op, &load_3dn_op, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, + INVALID, INVALID, &mload_op, &mload_op, + +/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + &load_mmx_op, &load_mmx_op, &load_mmx_op, &vector_emms_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, &mstore_op, &mstore_op, + +/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*90*/ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, + +/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_load_alu_op, + &vector_alu_store_op, &vector_alu_store_op, INVALID, INVALID, + &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_load_alu_op, + &vector_alu_store_op, &vector_alu_store_op, INVALID, &vector_mul_op, + +/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_load_alu_op, + &vector_lss_op, &vector_lss_op, &load_alux_op, &load_alu_op, + INVALID, INVALID, &vector_load_alu_op, &vector_load_alu_op, + &vector_bsx_op, &vector_bsx_op, &load_alux_op, &load_alu_op, + +/*c0*/ &vector_alux_store_op, &vector_alu_store_op, INVALID, INVALID, + INVALID, INVALID, INVALID, &vector_cmpxchg_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + +/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + INVALID, &load_mmx_mul_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + +/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, + INVALID, &pmul_mem_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, + +/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, + INVALID, &pmul_mem_op, INVALID, INVALID, + &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_0f_mod3[256] = { + // clang-format off +/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, + &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, + INVALID, INVALID, &vector_femms_op, &m3dn_op, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, + &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, + &mmx_op, &mmx_op, &mmx_op, &mmx_op, + &mmx_op, &mmx_op, &mmx_op, &mmx_op, + INVALID, INVALID, &mmx_op, &mmx_op, + +/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + &mmx_op, &mmx_op, &mmx_op, &vector_emms_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, &mmx_op, &mmx_op, + +/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, + +/*90*/ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, + +/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_alu1_op, + &vector_alu1_op, &vector_alu1_op, INVALID, INVALID, + &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_alu1_op, + &vector_alu1_op, &vector_alu1_op, INVALID, &vector_mul_op, + +/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_alu1_op, + &vector_lss_op, &vector_lss_op, &alux_op, &alu_op, + INVALID, INVALID, &vector_alu1_op, &vector_alu1_op, + &vector_bsx_op, &vector_bsx_op, &alux_op, &alu_op, + +/*c0*/ &vector_alux1_op, &vector_alu1_op, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + &bswap_op, &bswap_op, &bswap_op, &bswap_op, + +/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + INVALID, &mmx_mul_op, INVALID, INVALID, + &mmx_op, &mmx_op, INVALID, &mmx_op, + &mmx_op, &mmx_op, INVALID, &mmx_op, + +/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, + INVALID, &pmul_op, INVALID, INVALID, + &mmx_op, &mmx_op, INVALID, &mmx_op, + &mmx_op, &mmx_op, INVALID, &mmx_op, + +/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, + INVALID, &pmul_op, INVALID, INVALID, + &mmx_op, &mmx_op, &mmx_op, INVALID, + &mmx_op, &mmx_op, &mmx_op, INVALID, + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_0f0f[256] = { + // clang-format off +/*00*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &load_3dn_op, INVALID, INVALID, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &load_3dn_op, INVALID, INVALID, + +/*20*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*70*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*80*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*90*/ &load_3dn_op, INVALID, INVALID, INVALID, + &load_3dn_op, INVALID, &load_3dn_op, &load_3dn_op, + INVALID, INVALID, &load_3dn_op, INVALID, + INVALID, INVALID, &load_3dn_op, INVALID, + +/*a0*/ &load_3dn_op, INVALID, INVALID, INVALID, + &load_3dn_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, + INVALID, INVALID, &load_3dn_op, INVALID, + INVALID, INVALID, &load_3dn_op, INVALID, + +/*b0*/ &load_3dn_op, INVALID, INVALID, INVALID, + &load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, &load_mmx_op, + +/*c0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*d0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*e0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*f0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_0f0f_mod3[256] = { + // clang-format off +/*00*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &m3dn_op, INVALID, INVALID, + +/*10*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, &m3dn_op, INVALID, INVALID, + +/*20*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*30*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*40*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*50*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*60*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*70*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*80*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*90*/ &m3dn_op, INVALID, INVALID, INVALID, + &m3dn_op, INVALID, &m3dn_op, &m3dn_op, + INVALID, INVALID, &m3dn_op, INVALID, + INVALID, INVALID, &m3dn_op, INVALID, + +/*a0*/ &m3dn_op, INVALID, INVALID, INVALID, + &m3dn_op, INVALID, &mmx_mul_op, &mmx_mul_op, + INVALID, INVALID, &m3dn_op, INVALID, + INVALID, INVALID, &m3dn_op, INVALID, + +/*b0*/ &m3dn_op, INVALID, INVALID, INVALID, + &mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, &mmx_op, + +/*c0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*d0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*e0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/*f0*/ INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_shift[8] = { + // clang-format off + &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_shift_b[8] = { + // clang-format off + &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, + &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_shift_mod3[8] = { + // clang-format off + &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, + &alu_op, &alu_op, &alu_op, &alu_op + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_shift_b_mod3[8] = { + // clang-format off + &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, + &alux_op, &alux_op, &alux_op, &alux_op + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_80[8] = { + // clang-format off + &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, + &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_80_mod3[8] = { + // clang-format off + &alux_op, &alux_op, &alux_store_op, &alux_store_op, + &alux_op, &alux_op, &alux_op, &alux_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_8x[8] = { + // clang-format off + &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_8x_mod3[8] = { + // clang-format off + &alu_op, &alu_op, &alu_store_op, &alu_store_op, + &alu_op, &alu_op, &alu_op, &alu_op, + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_f6[8] = { + // clang-format off +/* TST NOT NEG*/ + &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_f6_mod3[8] = { + // clang-format off +/* TST NOT NEG*/ + &test_reg_b_op, INVALID, &alux_op, &alux_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_f7[8] = { + // clang-format off +/* TST NOT NEG*/ + &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_f7_mod3[8] = { + // clang-format off +/* TST NOT NEG*/ + &test_reg_op, INVALID, &alu_op, &alu_op, +/* MUL IMUL DIV IDIV*/ + &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_ff[8] = { + // clang-format off +/* INC DEC CALL CALL far*/ + &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, +/* JMP JMP far PUSH*/ + &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_ff_mod3[8] = { + // clang-format off +/* INC DEC CALL CALL far*/ + &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, +/* JMP JMP far PUSH*/ + &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_d8[8] = { + // clang-format off +/* FADDs FMULs FCOMs FCOMPs*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FSUBs FSUBRs FDIVs FDIVRs*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_d8_mod3[8] = { + // clang-format off +/* FADD FMUL FCOM FCOMP*/ + &float_op, &float_op, &float_op, &float_op, +/* FSUB FSUBR FDIV FDIVR*/ + &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_d9[8] = { + // clang-format off +/* FLDs FSTs FSTPs*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FLDENV FLDCW FSTENV FSTCW*/ + &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_d9_mod3[64] = { + // clang-format off + /*FLD*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, + /*FXCH*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, + /*FNOP*/ + &float_op, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + &float_op, &float_op, &float_op, &float_op, + &float_op, &float_op, &float_op, &float_op, +/* opFCHS opFABS*/ + &float_op, &float_op, INVALID, INVALID, +/* opFTST opFXAM*/ + &float_op, &float_op, INVALID, INVALID, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + &float_op, &float_op, &float_op, &float_op, +/* opFLDEG2 opFLDLN2 opFLDZ*/ + &float_op, &float_op, &float_op, INVALID, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + &fsin_op, &fsin_op, &fsin_op, &fsin_op, +/* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, &float_op, &float_op, +/* opFPREM opFSQRT opFSINCOS*/ + &fdiv_op, INVALID, &fsqrt_op, &fsin_op, +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + &float_op, &fdiv_op, &fsin_op, &fsin_op + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_da[8] = { + // clang-format off +/* FIADDl FIMULl FICOMl FICOMPl*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_da_mod3[8] = { + // clang-format off + INVALID, INVALID, INVALID, INVALID, +/* FCOMPP*/ + INVALID, &float_op, INVALID, INVALID + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_db[8] = { + // clang-format off +/* FLDil FSTil FSTPil*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FLDe FSTPe*/ + INVALID, &vector_flde_op, INVALID, &vector_fste_op + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_db_mod3[64] = { + // clang-format off + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + +/* opFNOP opFCLEX opFINIT*/ + INVALID, &float_op, &float_op, &float_op, +/* opFNOP opFNOP*/ + &float_op, &float_op, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + + INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_dc[8] = { + // clang-format off +/* FADDd FMULd FCOMd FCOMPd*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FSUBd FSUBRd FDIVd FDIVRd*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_dc_mod3[8] = { + // clang-format off +/* opFADDr opFMULr*/ + &float_op, &float_op, INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + &float_op, &float_op, &fdiv_op, &fdiv_op + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_dd[8] = { + // clang-format off +/* FLDd FSTd FSTPd*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FRSTOR FSAVE FSTSW*/ + &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_dd_mod3[8] = { + // clang-format off +/* FFFREE FST FSTP*/ + &float_op, INVALID, &float_op, &float_op, +/* FUCOM FUCOMP*/ + &float_op, &float_op, INVALID, INVALID + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_de[8] = { + // clang-format off +/* FIADDw FIMULw FICOMw FICOMPw*/ + &load_float_op, &load_float_op, &load_float_op, &load_float_op, +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_de_mod3[8] = { + // clang-format off +/* FADDP FMULP FCOMPP*/ + &float_op, &float_op, INVALID, &float_op, +/* FSUBP FSUBRP FDIVP FDIVRP*/ + &float_op, &float_op, &fdiv_op, &fdiv_op, + // clang-format on +}; + +static const risc86_instruction_t *opcode_timings_k5_df[8] = { + // clang-format off +/* FILDiw FISTiw FISTPiw*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, +/* FILDiq FBSTP FISTPiq*/ + INVALID, &load_float_op, &vector_float_l_op, &fstore_op, + // clang-format on +}; +static const risc86_instruction_t *opcode_timings_k5_df_mod3[8] = { + // clang-format off + INVALID, INVALID, INVALID, INVALID, +/* FSTSW AX*/ + &float_op, INVALID, INVALID, INVALID + // clang-format on +}; + +static uint8_t last_prefix; +static int prefixes; + +static int decode_timestamp; +static int last_complete_timestamp; + +typedef struct k5_unit_t { + uint32_t uop_mask; + int first_available_cycle; +} k5_unit_t; + +static int nr_units; +static k5_unit_t *units; + +/*k5 has dedicated MMX unit*/ +static k5_unit_t k5_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) }, /*Integer X*/ + { .uop_mask = (1 << UOP_ALU) }, /*Integer Y*/ + { .uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) }, /*Multimedia*/ + { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/ + { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/ + { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/ +}; +#define NR_k5_UNITS (sizeof(k5_units) / sizeof(k5_unit_t)) + +/*k5-2 and later integrate MMX into ALU X & Y, sharing multiplier, shifter and + 3DNow ALU between two execution units*/ +static k5_unit_t k5_2_units[] = { + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) }, + { .uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN) }, + { .uop_mask = (1 << UOP_FLOAT) }, /*Floating point*/ + { .uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD) }, /*Load*/ + { .uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE) }, /*Store*/ + { .uop_mask = (1 << UOP_BRANCH) } /*Branch*/ +}; +#define NR_k5_2_UNITS (sizeof(k5_2_units) / sizeof(k5_unit_t)) + +/*First available cycles of shared execution units. Each of these can be submitted + to by ALU X and Y*/ +static int mul_first_available_cycle; +static int shift_first_available_cycle; +static int m3dnow_first_available_cycle; + +static int +uop_run(const risc86_uop_t *uop, int decode_time) +{ + k5_unit_t *best_unit = NULL; + int best_start_cycle = 99999; + + /*UOP_LIMM does not require execution*/ + if (uop->type == UOP_LIMM) + return decode_time; + + /*Handle shared units on k5-2 and later*/ + if (units == k5_2_units) { + if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) + decode_time = mul_first_available_cycle; + else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) + decode_time = shift_first_available_cycle; + else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) + decode_time = m3dnow_first_available_cycle; + } + + /*Find execution unit for this uOP*/ + for (int c = 0; c < nr_units; c++) { + if (units[c].uop_mask & (1 << uop->type)) { + if (units[c].first_available_cycle < best_start_cycle) { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } + } + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); + + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; + + if (units == k5_2_units) { + if (uop->type == UOP_MEU_MUL) + mul_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_SHIFT) + shift_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_3DN) + m3dnow_first_available_cycle = best_start_cycle + uop->throughput; + } + + return best_start_cycle + uop->throughput; +} + +/*The k5 decoder can decode, per clock : + - 1 or 2 'short' instructions, each up to 2 uOPs and 7 bytes long + - 1 'long' instruction, up to 4 uOPs + - 1 'vector' instruction, up to 4 uOPs per cycle, plus (I think) 1 cycle startup delay) +*/ +static struct { + int nr_uops; + const risc86_uop_t *uops[4]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[4]; +} decode_buffer; + +#define NR_OPQUADS 6 +/*Timestamps of when the last six opquads completed. The k5 scheduler retires + opquads in order, so this is needed to determine when the next can be scheduled*/ +static int opquad_completion_timestamp[NR_OPQUADS]; +static int next_opquad = 0; + +#define NR_REGS 8 +/*Timestamp of when last operation on an integer register completed*/ +static int reg_available_timestamp[NR_REGS]; +/*Timestamp of when last operation on an FPU register completed*/ +static int fpu_st_timestamp[8]; +/*Completion time of the last uop to be processed. Used to calculate timing of + dependent uop chains*/ +static int last_uop_timestamp = 0; + +void +decode_flush_k5(void) +{ + int uop_timestamp = 0; + + /*Decoded opquad can not be submitted if there are no free spaces in the + opquad buffer*/ + if (decode_timestamp < opquad_completion_timestamp[next_opquad]) + decode_timestamp = opquad_completion_timestamp[next_opquad]; + + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; + + /*Submit uops to execution units, and determine the latest completion time*/ + for (int c = 0; c < decode_buffer.nr_uops; c++) { + int start_timestamp; + + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; + else + start_timestamp = decode_buffer.earliest_start[c]; + + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } + + /*Calculate opquad completion time. Since opquads complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; + + /*Advance to next opquad in buffer*/ + opquad_completion_timestamp[next_opquad] = last_complete_timestamp; + next_opquad++; + if (next_opquad == NR_OPQUADS) + next_opquad = 0; + + decode_timestamp++; + decode_buffer.nr_uops = 0; +} + +/*The instruction is only of interest here if it's longer than 7 bytes, as that's the + limit on k5 short decoding*/ +static int +codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) +{ + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; + + if (op_32 & 0x200) { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } else { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; + } + } + + return len; +} + +static void +decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) +{ + uint32_t regmask_required; + uint32_t regmask_modified; + int c; + int d; + int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; + } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if (deps & FPU_RW_STREG) { + int reg = fetchdat & 7; + + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } + + /*Short decoders are limited to 7 bytes*/ + if (decode_type == DECODE_SHORT && instr_length > 7) + decode_type = DECODE_LONG; + /*Long decoder is limited to 11 bytes*/ + else if (instr_length > 11) + decode_type = DECODE_VECTOR; + + switch (decode_type) { + case DECODE_SHORT: + if (decode_buffer.nr_uops) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[decode_buffer.nr_uops + 1] = &ins->uop[1]; + decode_buffer.earliest_start[decode_buffer.nr_uops + 1] = -1; + } + decode_buffer.nr_uops += ins->nr_uops; + + decode_flush_k5(); + } else { + decode_buffer.nr_uops = ins->nr_uops; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[1] = &ins->uop[1]; + decode_buffer.earliest_start[1] = -1; + } + } + break; + + case DECODE_LONG: + if (decode_buffer.nr_uops) + decode_flush_k5(); + + decode_buffer.nr_uops = ins->nr_uops; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; + else + decode_buffer.earliest_start[c] = -1; + } + decode_flush_k5(); + break; + + case DECODE_VECTOR: + if (decode_buffer.nr_uops) + decode_flush_k5(); + + decode_timestamp++; + d = 0; + + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; + + if (d == 4) { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush_k5(); + } + } + if (d) { + decode_buffer.nr_uops = d; + decode_flush_k5(); + } + break; + } + + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; + if (deps & FPU_POP) + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } +} + +void +codegen_timing_k5_block_start(void) +{ + int c; + + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; + + mul_first_available_cycle = 0; + shift_first_available_cycle = 0; + m3dnow_first_available_cycle = 0; + + decode_timestamp = 0; + last_complete_timestamp = 0; + + for (c = 0; c < NR_OPQUADS; c++) + opquad_completion_timestamp[c] = 0; + next_opquad = 0; + + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; +} + +void +codegen_timing_k5_start(void) +{ + if (cpu_s->cpu_type == CPU_K5) { + units = k5_units; + nr_units = NR_k5_UNITS; + } else { + units = k5_2_units; + nr_units = NR_k5_2_UNITS; + } + last_prefix = 0; + prefixes = 0; +} + +void +codegen_timing_k5_prefix(uint8_t prefix, UNUSED(uint32_t fetchdat)) +{ + if (prefix != 0x0f) + decode_timestamp++; + + last_prefix = prefix; + prefixes++; +} + +void +codegen_timing_k5_opcode(uint8_t opcode, UNUSED(uint32_t fetchdat), int op_32, uint32_t op_pc) +{ + const risc86_instruction_t **ins_table; + const uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); + + switch (last_prefix) { + case 0x0f: + if (opcode == 0x0f) { + /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ + uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } + + opcode = fastreadb(cs + opcode_pc); + + ins_table = mod3 ? opcode_timings_k5_0f0f_mod3 : opcode_timings_k5_0f0f; + deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; + } else { + ins_table = mod3 ? opcode_timings_k5_0f_mod3 : opcode_timings_k5_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + } + break; + + case 0xd8: + ins_table = mod3 ? opcode_timings_k5_d8_mod3 : opcode_timings_k5_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_k5_d9_mod3 : opcode_timings_k5_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xda: + ins_table = mod3 ? opcode_timings_k5_da_mod3 : opcode_timings_k5_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_k5_db_mod3 : opcode_timings_k5_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_k5_dc_mod3 : opcode_timings_k5_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_k5_dd_mod3 : opcode_timings_k5_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + break; + case 0xde: + ins_table = mod3 ? opcode_timings_k5_de_mod3 : opcode_timings_k5_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_k5_df_mod3 : opcode_timings_k5_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + break; + + default: + switch (opcode) { + case 0x80: + case 0x82: + ins_table = mod3 ? opcode_timings_k5_80_mod3 : opcode_timings_k5_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + case 0x81: + case 0x83: + ins_table = mod3 ? opcode_timings_k5_8x_mod3 : opcode_timings_k5_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc0: + case 0xd0: + case 0xd2: + ins_table = mod3 ? opcode_timings_k5_shift_b_mod3 : opcode_timings_k5_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_k5_shift_mod3 : opcode_timings_k5_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + break; + + case 0xf6: + ins_table = mod3 ? opcode_timings_k5_f6_mod3 : opcode_timings_k5_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_k5_f7_mod3 : opcode_timings_k5_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + break; + case 0xff: + ins_table = mod3 ? opcode_timings_k5_ff_mod3 : opcode_timings_k5_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + break; + + default: + ins_table = mod3 ? opcode_timings_k5_mod3 : opcode_timings_k5; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + break; + } + } + + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); +} + +void +codegen_timing_k5_block_end(void) +{ + if (decode_buffer.nr_uops) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush_k5(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } +} + +int +codegen_timing_k5_jump_cycles(void) +{ + if (decode_buffer.nr_uops) + return 1; + return 0; +} + +codegen_timing_t codegen_timing_k5 = { + codegen_timing_k5_start, + codegen_timing_k5_prefix, + codegen_timing_k5_opcode, + codegen_timing_k5_block_start, + codegen_timing_k5_block_end, + codegen_timing_k5_jump_cycles +}; diff --git a/src/cpu/codegen_timing_k6.c b/src/cpu/codegen_timing_k6.c index 6a2871884..34297211b 100644 --- a/src/cpu/codegen_timing_k6.c +++ b/src/cpu/codegen_timing_k6.c @@ -1,5 +1,5 @@ /*Most of the vector instructions here are a total guess. - Some of the timings are based on http://http://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/ + Some of the timings are based on https://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/ #include #include #include @@ -8,6 +8,7 @@ #include <86box/mem.h> #include "cpu.h" #include <86box/machine.h> +#include <86box/plat_unused.h> #include "x86.h" #include "x86_ops.h" @@ -759,7 +760,7 @@ static const risc86_instruction_t vector_wbinvd_op = { #define INVALID NULL -static const risc86_instruction_t *opcode_timings[256] = { +static const risc86_instruction_t *opcode_timings_k6[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, @@ -896,7 +897,7 @@ static const risc86_instruction_t *opcode_timings[256] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_mod3[256] = { +static const risc86_instruction_t *opcode_timings_k6_mod3[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alux_op, &alu_op, &alux_op, &alu_op, @@ -1033,7 +1034,7 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f[256] = { +static const risc86_instruction_t *opcode_timings_k6_0f[256] = { // clang-format off /*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, @@ -1116,7 +1117,7 @@ static const risc86_instruction_t *opcode_timings_0f[256] = { &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f_mod3[256] = { +static const risc86_instruction_t *opcode_timings_k6_0f_mod3[256] = { // clang-format off /*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, @@ -1200,7 +1201,7 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f0f[256] = { +static const risc86_instruction_t *opcode_timings_k6_0f0f[256] = { // clang-format off /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1283,7 +1284,7 @@ static const risc86_instruction_t *opcode_timings_0f0f[256] = { INVALID, INVALID, INVALID, INVALID, // clang-format on }; -static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = { +static const risc86_instruction_t *opcode_timings_k6_0f0f_mod3[256] = { // clang-format off /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1367,57 +1368,57 @@ static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift[8] = { +static const risc86_instruction_t *opcode_timings_k6_shift[8] = { // clang-format off &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_b[8] = { +static const risc86_instruction_t *opcode_timings_k6_shift_b[8] = { // clang-format off &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_shift_mod3[8] = { // clang-format off &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_shift_b_mod3[8] = { // clang-format off &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &alux_op, &alux_op, &alux_op, &alux_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_80[8] = { +static const risc86_instruction_t *opcode_timings_k6_80[8] = { // clang-format off &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_80_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_80_mod3[8] = { // clang-format off &alux_op, &alux_op, &alux_store_op, &alux_store_op, &alux_op, &alux_op, &alux_op, &alux_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_8x[8] = { +static const risc86_instruction_t *opcode_timings_k6_8x[8] = { // clang-format off &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_8x_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_8x_mod3[8] = { // clang-format off &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_f6[8] = { +static const risc86_instruction_t *opcode_timings_k6_f6[8] = { // clang-format off /* TST NOT NEG*/ &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op, @@ -1425,7 +1426,7 @@ static const risc86_instruction_t *opcode_timings_f6[8] = { &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_f6_mod3[8] = { // clang-format off /* TST NOT NEG*/ &test_reg_b_op, INVALID, &alux_op, &alux_op, @@ -1433,7 +1434,7 @@ static const risc86_instruction_t *opcode_timings_f6_mod3[8] = { &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_f7[8] = { +static const risc86_instruction_t *opcode_timings_k6_f7[8] = { // clang-format off /* TST NOT NEG*/ &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op, @@ -1441,7 +1442,7 @@ static const risc86_instruction_t *opcode_timings_f7[8] = { &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_f7_mod3[8] = { // clang-format off /* TST NOT NEG*/ &test_reg_op, INVALID, &alu_op, &alu_op, @@ -1449,7 +1450,7 @@ static const risc86_instruction_t *opcode_timings_f7_mod3[8] = { &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_ff[8] = { +static const risc86_instruction_t *opcode_timings_k6_ff[8] = { // clang-format off /* INC DEC CALL CALL far*/ &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, @@ -1457,7 +1458,7 @@ static const risc86_instruction_t *opcode_timings_ff[8] = { &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID // clang-format on }; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_ff_mod3[8] = { // clang-format off /* INC DEC CALL CALL far*/ &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, @@ -1466,7 +1467,7 @@ static const risc86_instruction_t *opcode_timings_ff_mod3[8] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_d8[8] = { +static const risc86_instruction_t *opcode_timings_k6_d8[8] = { // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, @@ -1474,7 +1475,7 @@ static const risc86_instruction_t *opcode_timings_d8[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_d8_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP*/ &float_op, &float_op, &float_op, &float_op, @@ -1483,7 +1484,7 @@ static const risc86_instruction_t *opcode_timings_d8_mod3[8] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_d9[8] = { +static const risc86_instruction_t *opcode_timings_k6_d9[8] = { // clang-format off /* FLDs FSTs FSTPs*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1491,7 +1492,7 @@ static const risc86_instruction_t *opcode_timings_d9[8] = { &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = { +static const risc86_instruction_t *opcode_timings_k6_d9_mod3[64] = { // clang-format off /*FLD*/ &float_op, &float_op, &float_op, &float_op, @@ -1524,7 +1525,7 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_da[8] = { +static const risc86_instruction_t *opcode_timings_k6_da[8] = { // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, @@ -1532,7 +1533,7 @@ static const risc86_instruction_t *opcode_timings_da[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_da_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_da_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ @@ -1540,7 +1541,7 @@ static const risc86_instruction_t *opcode_timings_da_mod3[8] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_db[8] = { +static const risc86_instruction_t *opcode_timings_k6_db[8] = { // clang-format off /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1548,7 +1549,7 @@ static const risc86_instruction_t *opcode_timings_db[8] = { INVALID, &vector_flde_op, INVALID, &vector_fste_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_db_mod3[64] = { +static const risc86_instruction_t *opcode_timings_k6_db_mod3[64] = { // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1578,7 +1579,7 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_dc[8] = { +static const risc86_instruction_t *opcode_timings_k6_dc[8] = { // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, @@ -1586,7 +1587,7 @@ static const risc86_instruction_t *opcode_timings_dc[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_dc_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr*/ &float_op, &float_op, INVALID, INVALID, @@ -1595,7 +1596,7 @@ static const risc86_instruction_t *opcode_timings_dc_mod3[8] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_dd[8] = { +static const risc86_instruction_t *opcode_timings_k6_dd[8] = { // clang-format off /* FLDd FSTd FSTPd*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1603,7 +1604,7 @@ static const risc86_instruction_t *opcode_timings_dd[8] = { &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op // clang-format on }; -static const risc86_instruction_t *opcode_timings_dd_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, @@ -1612,7 +1613,7 @@ static const risc86_instruction_t *opcode_timings_dd_mod3[8] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_de[8] = { +static const risc86_instruction_t *opcode_timings_k6_de[8] = { // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ &load_float_op, &load_float_op, &load_float_op, &load_float_op, @@ -1620,7 +1621,7 @@ static const risc86_instruction_t *opcode_timings_de[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_de_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_de_mod3[8] = { // clang-format off /* FADDP FMULP FCOMPP*/ &float_op, &float_op, INVALID, &float_op, @@ -1629,7 +1630,7 @@ static const risc86_instruction_t *opcode_timings_de_mod3[8] = { // clang-format on }; -static const risc86_instruction_t *opcode_timings_df[8] = { +static const risc86_instruction_t *opcode_timings_k6_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1637,7 +1638,7 @@ static const risc86_instruction_t *opcode_timings_df[8] = { INVALID, &load_float_op, &vector_float_l_op, &fstore_op, // clang-format on }; -static const risc86_instruction_t *opcode_timings_df_mod3[8] = { +static const risc86_instruction_t *opcode_timings_k6_df_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -1769,7 +1770,7 @@ static int fpu_st_timestamp[8]; static int last_uop_timestamp = 0; void -decode_flush(void) +decode_flush_k6(void) { int uop_timestamp = 0; @@ -1908,7 +1909,7 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc } decode_buffer.nr_uops += ins->nr_uops; - decode_flush(); + decode_flush_k6(); } else { decode_buffer.nr_uops = ins->nr_uops; decode_buffer.uops[0] = &ins->uop[0]; @@ -1922,7 +1923,7 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc case DECODE_LONG: if (decode_buffer.nr_uops) - decode_flush(); + decode_flush_k6(); decode_buffer.nr_uops = ins->nr_uops; for (c = 0; c < ins->nr_uops; c++) { @@ -1932,12 +1933,12 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc else decode_buffer.earliest_start[c] = -1; } - decode_flush(); + decode_flush_k6(); break; case DECODE_VECTOR: if (decode_buffer.nr_uops) - decode_flush(); + decode_flush_k6(); decode_timestamp++; d = 0; @@ -1953,12 +1954,12 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc if (d == 4) { d = 0; decode_buffer.nr_uops = 4; - decode_flush(); + decode_flush_k6(); } } if (d) { decode_buffer.nr_uops = d; - decode_flush(); + decode_flush_k6(); } break; } @@ -2037,7 +2038,7 @@ codegen_timing_k6_start(void) } void -codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) +codegen_timing_k6_prefix(uint8_t prefix, UNUSED(uint32_t fetchdat)) { if (prefix != 0x0f) decode_timestamp++; @@ -2047,7 +2048,7 @@ codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) } void -codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) +codegen_timing_k6_opcode(uint8_t opcode, UNUSED(uint32_t fetchdat), int op_32, uint32_t op_pc) { const risc86_instruction_t **ins_table; const uint64_t *deps; @@ -2094,51 +2095,51 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t opcode = fastreadb(cs + opcode_pc); - ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; + ins_table = mod3 ? opcode_timings_k6_0f0f_mod3 : opcode_timings_k6_0f0f; deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; } else { - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + ins_table = mod3 ? opcode_timings_k6_0f_mod3 : opcode_timings_k6_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; } break; case 0xd8: - ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + ins_table = mod3 ? opcode_timings_k6_d8_mod3 : opcode_timings_k6_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + ins_table = mod3 ? opcode_timings_k6_d9_mod3 : opcode_timings_k6_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + ins_table = mod3 ? opcode_timings_k6_da_mod3 : opcode_timings_k6_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + ins_table = mod3 ? opcode_timings_k6_db_mod3 : opcode_timings_k6_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + ins_table = mod3 ? opcode_timings_k6_dc_mod3 : opcode_timings_k6_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + ins_table = mod3 ? opcode_timings_k6_dd_mod3 : opcode_timings_k6_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + ins_table = mod3 ? opcode_timings_k6_de_mod3 : opcode_timings_k6_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + ins_table = mod3 ? opcode_timings_k6_df_mod3 : opcode_timings_k6_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -2147,13 +2148,13 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t switch (opcode) { case 0x80: case 0x82: - ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + ins_table = mod3 ? opcode_timings_k6_80_mod3 : opcode_timings_k6_80; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: case 0x83: - ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + ins_table = mod3 ? opcode_timings_k6_8x_mod3 : opcode_timings_k6_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; @@ -2161,7 +2162,7 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t case 0xc0: case 0xd0: case 0xd2: - ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + ins_table = mod3 ? opcode_timings_k6_shift_b_mod3 : opcode_timings_k6_shift_b; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; @@ -2169,29 +2170,29 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t case 0xc1: case 0xd1: case 0xd3: - ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + ins_table = mod3 ? opcode_timings_k6_shift_mod3 : opcode_timings_k6_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + ins_table = mod3 ? opcode_timings_k6_f6_mod3 : opcode_timings_k6_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + ins_table = mod3 ? opcode_timings_k6_f7_mod3 : opcode_timings_k6_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + ins_table = mod3 ? opcode_timings_k6_ff_mod3 : opcode_timings_k6_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + ins_table = mod3 ? opcode_timings_k6_mod3 : opcode_timings_k6; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } @@ -2209,7 +2210,7 @@ codegen_timing_k6_block_end(void) { if (decode_buffer.nr_uops) { int old_last_complete_timestamp = last_complete_timestamp; - decode_flush(); + decode_flush_k6(); codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } } diff --git a/src/cpu/codegen_timing_p6.c b/src/cpu/codegen_timing_p6.c index 25c098ca4..42db319c3 100644 --- a/src/cpu/codegen_timing_p6.c +++ b/src/cpu/codegen_timing_p6.c @@ -787,7 +787,7 @@ static const macro_op_t wbinvd_op = { }; #define INVALID NULL -static const macro_op_t *opcode_timings[256] = { +static const macro_op_t *opcode_timings_p6[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op, @@ -924,7 +924,7 @@ static const macro_op_t *opcode_timings[256] = { // clang-format on }; -static const macro_op_t *opcode_timings_mod3[256] = { +static const macro_op_t *opcode_timings_p6_mod3[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op, @@ -1062,7 +1062,7 @@ static const macro_op_t *opcode_timings_mod3[256] = { // clang-format on }; -static const macro_op_t *opcode_timings_0f[256] = { +static const macro_op_t *opcode_timings_p6_0f[256] = { // clang-format off /*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, INVALID, &alu6_op, &alu6_op, INVALID, @@ -1145,7 +1145,7 @@ static const macro_op_t *opcode_timings_0f[256] = { &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, // clang-format on }; -static const macro_op_t *opcode_timings_0f_mod3[256] = { +static const macro_op_t *opcode_timings_p6_0f_mod3[256] = { // clang-format off /*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, INVALID, &alu6_op, &alu6_op, INVALID, @@ -1228,58 +1228,58 @@ static const macro_op_t *opcode_timings_0f_mod3[256] = { &mmx_op, &mmx_op, &mmx_op, INVALID, }; -static const macro_op_t *opcode_timings_shift[8] = +static const macro_op_t *opcode_timings_p6_shift[8] = { // clang-format off &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op // clang-format on }; -static const macro_op_t *opcode_timings_shift_b[8] = { +static const macro_op_t *opcode_timings_p6_shift_b[8] = { // clang-format off &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op // clang-format on }; -static const macro_op_t *opcode_timings_shift_mod3[8] = { +static const macro_op_t *opcode_timings_p6_shift_mod3[8] = { // clang-format off &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op // clang-format on }; -static const macro_op_t *opcode_timings_shift_b_mod3[8] = { +static const macro_op_t *opcode_timings_p6_shift_b_mod3[8] = { // clang-format off &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &alup0_op, &alup0_op, &alup0_op, &alup0_op // clang-format on }; -static const macro_op_t *opcode_timings_80[8] = { +static const macro_op_t *opcode_timings_p6_80[8] = { // clang-format off &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op, // clang-format on }; -static const macro_op_t *opcode_timings_80_mod3[8] = { +static const macro_op_t *opcode_timings_p6_80_mod3[8] = { // clang-format off &alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op, &alup0_op, &alup0_op, &alup0_op, &alup0_op, // clang-format on }; -static const macro_op_t *opcode_timings_8x[8] = { +static const macro_op_t *opcode_timings_p6_8x[8] = { // clang-format off &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, // clang-format on }; -static const macro_op_t *opcode_timings_8x_mod3[8] = { +static const macro_op_t *opcode_timings_p6_8x_mod3[8] = { // clang-format off &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, // clang-format on }; -static const macro_op_t *opcode_timings_f6[8] = { +static const macro_op_t *opcode_timings_p6_f6[8] = { // clang-format off /* TST NOT NEG*/ &test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op, @@ -1287,7 +1287,7 @@ static const macro_op_t *opcode_timings_f6[8] = { &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, // clang-format on }; -static const macro_op_t *opcode_timings_f6_mod3[8] = { +static const macro_op_t *opcode_timings_p6_f6_mod3[8] = { // clang-format off /* TST NOT NEG*/ &test_reg_b_op, INVALID, &alup0_op, &alup0_op, @@ -1295,7 +1295,7 @@ static const macro_op_t *opcode_timings_f6_mod3[8] = { &mul_op, &mul_op, &div16_op, &div16_op, // clang-format on }; -static const macro_op_t *opcode_timings_f7[8] = { +static const macro_op_t *opcode_timings_p6_f7[8] = { // clang-format off /* TST NOT NEG*/ &test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op, @@ -1303,7 +1303,7 @@ static const macro_op_t *opcode_timings_f7[8] = { &mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op, // clang-format on }; -static const macro_op_t *opcode_timings_f7_mod3[8] = { +static const macro_op_t *opcode_timings_p6_f7_mod3[8] = { // clang-format off /* TST NOT NEG*/ &test_reg_op, INVALID, &alu_op, &alu_op, @@ -1311,7 +1311,7 @@ static const macro_op_t *opcode_timings_f7_mod3[8] = { &mul64_op, &mul64_op, &div32_op, &div32_op, // clang-format on }; -static const macro_op_t *opcode_timings_ff[8] = { +static const macro_op_t *opcode_timings_p6_ff[8] = { // clang-format off /* INC DEC CALL CALL far*/ &alu_store_op, &alu_store_op, &store_op, &call_far_op, @@ -1319,7 +1319,7 @@ static const macro_op_t *opcode_timings_ff[8] = { &branch_op, &jmp_far_op, &push_mem_op, INVALID // clang-format on }; -static const macro_op_t *opcode_timings_ff_mod3[8] = { +static const macro_op_t *opcode_timings_p6_ff_mod3[8] = { // clang-format off /* INC DEC CALL CALL far*/ &complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op, @@ -1328,7 +1328,7 @@ static const macro_op_t *opcode_timings_ff_mod3[8] = { // clang-format on }; -static const macro_op_t *opcode_timings_d8[8] = { +static const macro_op_t *opcode_timings_p6_d8[8] = { // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, @@ -1336,7 +1336,7 @@ static const macro_op_t *opcode_timings_d8[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const macro_op_t *opcode_timings_d8_mod3[8] = { +static const macro_op_t *opcode_timings_p6_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP*/ &fadd_op, &fmul_op, &float_op, &float_op, @@ -1345,7 +1345,7 @@ static const macro_op_t *opcode_timings_d8_mod3[8] = { // clang-format on }; -static const macro_op_t *opcode_timings_d9[8] = { +static const macro_op_t *opcode_timings_p6_d9[8] = { // clang-format off /* FLDs FSTs FSTPs*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1353,7 +1353,7 @@ static const macro_op_t *opcode_timings_d9[8] = { &complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op // clang-format on }; -static const macro_op_t *opcode_timings_d9_mod3[64] = { +static const macro_op_t *opcode_timings_p6_d9_mod3[64] = { // clang-format off /*FLD*/ &float_op, &float_op, &float_op, &float_op, @@ -1386,7 +1386,7 @@ static const macro_op_t *opcode_timings_d9_mod3[64] = { // clang-format on }; -static const macro_op_t *opcode_timings_da[8] = { +static const macro_op_t *opcode_timings_p6_da[8] = { // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, @@ -1394,7 +1394,7 @@ static const macro_op_t *opcode_timings_da[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const macro_op_t *opcode_timings_da_mod3[8] = { +static const macro_op_t *opcode_timings_p6_da_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ @@ -1402,7 +1402,7 @@ static const macro_op_t *opcode_timings_da_mod3[8] = { // clang-format on }; -static const macro_op_t *opcode_timings_db[8] = { +static const macro_op_t *opcode_timings_p6_db[8] = { // clang-format off /* FLDil FSTil FSTPil*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1410,7 +1410,7 @@ static const macro_op_t *opcode_timings_db[8] = { INVALID, &flde_op, INVALID, &fste_op // clang-format on }; -static const macro_op_t *opcode_timings_db_mod3[64] = { +static const macro_op_t *opcode_timings_p6_db_mod3[64] = { // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -1440,7 +1440,7 @@ static const macro_op_t *opcode_timings_db_mod3[64] = { // clang-format on }; -static const macro_op_t *opcode_timings_dc[8] = { +static const macro_op_t *opcode_timings_p6_dc[8] = { // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ &load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op, @@ -1448,7 +1448,7 @@ static const macro_op_t *opcode_timings_dc[8] = { &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, // clang-format on }; -static const macro_op_t *opcode_timings_dc_mod3[8] = { +static const macro_op_t *opcode_timings_p6_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr*/ &fadd_op, &fmul_op, INVALID, INVALID, @@ -1457,7 +1457,7 @@ static const macro_op_t *opcode_timings_dc_mod3[8] = { // clang-format on }; -static const macro_op_t *opcode_timings_dd[8] = { +static const macro_op_t *opcode_timings_p6_dd[8] = { // clang-format off /* FLDd FSTd FSTPd*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1465,7 +1465,7 @@ static const macro_op_t *opcode_timings_dd[8] = { &complex_float_l_op, INVALID, &complex_float_l_op, &complex_float_l_op // clang-format on }; -static const macro_op_t *opcode_timings_dd_mod3[8] = { +static const macro_op_t *opcode_timings_p6_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP*/ &float_op, INVALID, &float_op, &float_op, @@ -1474,7 +1474,7 @@ static const macro_op_t *opcode_timings_dd_mod3[8] = { // clang-format on }; -static const macro_op_t *opcode_timings_de[8] = { +static const macro_op_t *opcode_timings_p6_de[8] = { // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, @@ -1482,7 +1482,7 @@ static const macro_op_t *opcode_timings_de[8] = { &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op, // clang-format on }; -static const macro_op_t *opcode_timings_de_mod3[8] = { +static const macro_op_t *opcode_timings_p6_de_mod3[8] = { // clang-format off /* FADDP FMULP FCOMPP*/ &fadd_op, &fmul_op, INVALID, &float_op, @@ -1491,7 +1491,7 @@ static const macro_op_t *opcode_timings_de_mod3[8] = { // clang-format on }; -static const macro_op_t *opcode_timings_df[8] = { +static const macro_op_t *opcode_timings_p6_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw*/ &load_float_op, INVALID, &fstore_op, &fstore_op, @@ -1499,7 +1499,7 @@ static const macro_op_t *opcode_timings_df[8] = { INVALID, &load_float_op, &complex_float_l_op, &fstore_op, // clang-format on }; -static const macro_op_t *opcode_timings_df_mod3[8] = { +static const macro_op_t *opcode_timings_p6_df_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -1845,7 +1845,7 @@ codegen_timing_p6_start(void) } void -codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) +codegen_timing_p6_prefix(uint8_t prefix, UNUSED(uint32_t fetchdat)) { if (prefix != 0x0f) decode_timestamp++; @@ -1855,7 +1855,7 @@ codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) } void -codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(uint32_t op_pc)) +codegen_timing_p6_opcode(uint8_t opcode, UNUSED(uint32_t fetchdat), int op_32, UNUSED(uint32_t op_pc)) { const macro_op_t **ins_table; const uint64_t *deps; @@ -1865,47 +1865,47 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui switch (last_prefix) { case 0x0f: - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + ins_table = mod3 ? opcode_timings_p6_0f_mod3 : opcode_timings_p6_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; break; case 0xd8: - ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + ins_table = mod3 ? opcode_timings_p6_d8_mod3 : opcode_timings_p6_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + ins_table = mod3 ? opcode_timings_p6_d9_mod3 : opcode_timings_p6_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + ins_table = mod3 ? opcode_timings_p6_da_mod3 : opcode_timings_p6_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + ins_table = mod3 ? opcode_timings_p6_db_mod3 : opcode_timings_p6_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + ins_table = mod3 ? opcode_timings_p6_dc_mod3 : opcode_timings_p6_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + ins_table = mod3 ? opcode_timings_p6_dd_mod3 : opcode_timings_p6_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + ins_table = mod3 ? opcode_timings_p6_de_mod3 : opcode_timings_p6_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + ins_table = mod3 ? opcode_timings_p6_df_mod3 : opcode_timings_p6_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -1914,13 +1914,13 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui switch (opcode) { case 0x80: case 0x82: - ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + ins_table = mod3 ? opcode_timings_p6_80_mod3 : opcode_timings_p6_80; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: case 0x83: - ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + ins_table = mod3 ? opcode_timings_p6_8x_mod3 : opcode_timings_p6_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; @@ -1928,7 +1928,7 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui case 0xc0: case 0xd0: case 0xd2: - ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + ins_table = mod3 ? opcode_timings_p6_shift_b_mod3 : opcode_timings_p6_shift_b; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; @@ -1936,29 +1936,29 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui case 0xc1: case 0xd1: case 0xd3: - ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + ins_table = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + ins_table = mod3 ? opcode_timings_p6_f6_mod3 : opcode_timings_p6_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + ins_table = mod3 ? opcode_timings_p6_f7_mod3 : opcode_timings_p6_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + ins_table = mod3 ? opcode_timings_p6_ff_mod3 : opcode_timings_p6_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + ins_table = mod3 ? opcode_timings_p6_mod3 : opcode_timings_p6; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } diff --git a/src/cpu/codegen_timing_pentium.c b/src/cpu/codegen_timing_pentium.c index af344307f..aa78ee1c9 100644 --- a/src/cpu/codegen_timing_pentium.c +++ b/src/cpu/codegen_timing_pentium.c @@ -110,7 +110,7 @@ static uint32_t addr_regmask; static int fpu_latency; static int fpu_st_latency[8]; -static uint64_t opcode_timings[256] = { +static uint64_t opcode_timings_p6[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM, @@ -247,7 +247,7 @@ static uint64_t opcode_timings[256] = { // clang-format on }; -static uint64_t opcode_timings_mod3[256] = { +static uint64_t opcode_timings_p6_mod3[256] = { // clang-format off /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, @@ -385,7 +385,7 @@ static uint64_t opcode_timings_mod3[256] = { // clang-format on }; -static uint64_t opcode_timings_0f[256] = { +static uint64_t opcode_timings_p6_0f[256] = { // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, @@ -468,7 +468,7 @@ static uint64_t opcode_timings_0f[256] = { PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, // clang-format on }; -static uint64_t opcode_timings_0f_mod3[256] = { +static uint64_t opcode_timings_p6_0f_mod3[256] = { // clang-format off /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, @@ -552,20 +552,20 @@ static uint64_t opcode_timings_0f_mod3[256] = { // clang-format on }; -static uint64_t opcode_timings_shift[8] = { +static uint64_t opcode_timings_p6_shift[8] = { // clang-format off PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, // clang-format on }; -static uint64_t opcode_timings_shift_mod3[8] = { +static uint64_t opcode_timings_p6_shift_mod3[8] = { // clang-format off PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, // clang-format on }; -static uint64_t opcode_timings_f6[8] = { +static uint64_t opcode_timings_p6_f6[8] = { // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), @@ -573,7 +573,7 @@ static uint64_t opcode_timings_f6[8] = { PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) // clang-format on }; -static uint64_t opcode_timings_f6_mod3[8] = { +static uint64_t opcode_timings_p6_f6_mod3[8] = { // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), @@ -581,7 +581,7 @@ static uint64_t opcode_timings_f6_mod3[8] = { PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) // clang-format on }; -static uint64_t opcode_timings_f7[8] = { +static uint64_t opcode_timings_p6_f7[8] = { // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), @@ -589,7 +589,7 @@ static uint64_t opcode_timings_f7[8] = { PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) // clang-format on }; -static uint64_t opcode_timings_f7_mod3[8] = { +static uint64_t opcode_timings_p6_f7_mod3[8] = { // clang-format off /* TST NOT NEG*/ PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), @@ -597,7 +597,7 @@ static uint64_t opcode_timings_f7_mod3[8] = { PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) // clang-format on }; -static uint64_t opcode_timings_ff[8] = { +static uint64_t opcode_timings_p6_ff[8] = { // clang-format off /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), @@ -605,7 +605,7 @@ static uint64_t opcode_timings_ff[8] = { PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID // clang-format on }; -static uint64_t opcode_timings_ff_mod3[8] = { +static uint64_t opcode_timings_p6_ff_mod3[8] = { // clang-format off /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), @@ -614,7 +614,7 @@ static uint64_t opcode_timings_ff_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_d8[8] = { +static uint64_t opcode_timings_p6_d8[8] = { // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), @@ -622,7 +622,7 @@ static uint64_t opcode_timings_d8[8] = { PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) // clang-format on }; -static uint64_t opcode_timings_d8_mod3[8] = { +static uint64_t opcode_timings_p6_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), @@ -631,7 +631,7 @@ static uint64_t opcode_timings_d8_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_d9[8] = { +static uint64_t opcode_timings_p6_d9[8] = { // clang-format off /* FLDs FSTs FSTPs*/ PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), @@ -639,7 +639,7 @@ static uint64_t opcode_timings_d9[8] = { PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0) // clang-format on }; -static uint64_t opcode_timings_d9_mod3[64] = { +static uint64_t opcode_timings_p6_d9_mod3[64] = { // clang-format off /*FLD*/ PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), @@ -672,7 +672,7 @@ static uint64_t opcode_timings_d9_mod3[64] = { // clang-format on }; -static uint64_t opcode_timings_da[8] = { +static uint64_t opcode_timings_p6_da[8] = { // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), @@ -680,7 +680,7 @@ static uint64_t opcode_timings_da[8] = { PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) // clang-format on }; -static uint64_t opcode_timings_da_mod3[8] = { +static uint64_t opcode_timings_p6_da_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ @@ -688,7 +688,7 @@ static uint64_t opcode_timings_da_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_db[8] = { +static uint64_t opcode_timings_p6_db[8] = { // clang-format off /* FLDil FSTil FSTPil*/ PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), @@ -696,7 +696,7 @@ static uint64_t opcode_timings_db[8] = { INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0) // clang-format on }; -static uint64_t opcode_timings_db_mod3[64] = { +static uint64_t opcode_timings_p6_db_mod3[64] = { // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -726,7 +726,7 @@ static uint64_t opcode_timings_db_mod3[64] = { // clang-format on }; -static uint64_t opcode_timings_dc[8] = { +static uint64_t opcode_timings_p6_dc[8] = { // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), @@ -734,7 +734,7 @@ static uint64_t opcode_timings_dc[8] = { PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2) // clang-format on }; -static uint64_t opcode_timings_dc_mod3[8] = { +static uint64_t opcode_timings_p6_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID, @@ -743,7 +743,7 @@ static uint64_t opcode_timings_dc_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_dd[8] = { +static uint64_t opcode_timings_p6_dd[8] = { // clang-format off /* FLDd FSTd FSTPd*/ PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), @@ -751,7 +751,7 @@ static uint64_t opcode_timings_dd[8] = { PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0) // clang-format on }; -static uint64_t opcode_timings_dd_mod3[8] = { +static uint64_t opcode_timings_p6_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP*/ PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), @@ -760,7 +760,7 @@ static uint64_t opcode_timings_dd_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_de[8] = { +static uint64_t opcode_timings_p6_de[8] = { // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0), @@ -768,7 +768,7 @@ static uint64_t opcode_timings_de[8] = { PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2) // clang-format on }; -static uint64_t opcode_timings_de_mod3[8] = { +static uint64_t opcode_timings_p6_de_mod3[8] = { // clang-format off /* FADDP FMULP FCOMPP*/ PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0), @@ -777,7 +777,7 @@ static uint64_t opcode_timings_de_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_df[8] = { +static uint64_t opcode_timings_p6_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw*/ PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0), @@ -785,7 +785,7 @@ static uint64_t opcode_timings_df[8] = { INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0) // clang-format on }; -static uint64_t opcode_timings_df_mod3[8] = { +static uint64_t opcode_timings_p6_df_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -793,25 +793,25 @@ static uint64_t opcode_timings_df_mod3[8] = { // clang-format on }; -static uint64_t opcode_timings_81[8] = { +static uint64_t opcode_timings_p6_81[8] = { // clang-format off PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632 // clang-format on }; -static uint64_t opcode_timings_81_mod3[8] = { +static uint64_t opcode_timings_p6_81_mod3[8] = { // clang-format off PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG // clang-format on }; -static uint64_t opcode_timings_8x[8] = { +static uint64_t opcode_timings_p6_8x[8] = { // clang-format off PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8 // clang-format on }; -static uint64_t opcode_timings_8x_mod3[8] = { +static uint64_t opcode_timings_p6_8x_mod3[8] = { // clang-format off PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG @@ -1097,47 +1097,47 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS switch (last_prefix) { case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + timings = mod3 ? opcode_timings_p6_0f_mod3 : opcode_timings_p6_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; break; case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + timings = mod3 ? opcode_timings_p6_d8_mod3 : opcode_timings_p6_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + timings = mod3 ? opcode_timings_p6_d9_mod3 : opcode_timings_p6_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + timings = mod3 ? opcode_timings_p6_da_mod3 : opcode_timings_p6_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + timings = mod3 ? opcode_timings_p6_db_mod3 : opcode_timings_p6_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + timings = mod3 ? opcode_timings_p6_dc_mod3 : opcode_timings_p6_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + timings = mod3 ? opcode_timings_p6_dd_mod3 : opcode_timings_p6_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + timings = mod3 ? opcode_timings_p6_de_mod3 : opcode_timings_p6_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + timings = mod3 ? opcode_timings_p6_df_mod3 : opcode_timings_p6_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -1147,12 +1147,12 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + timings = mod3 ? opcode_timings_p6_8x_mod3 : opcode_timings_p6_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + timings = mod3 ? opcode_timings_p6_81_mod3 : opcode_timings_p6_81; deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; opcode = (fetchdat >> 3) & 7; break; @@ -1161,36 +1161,36 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS case 0xc1: case 0xd0: case 0xd1: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + timings = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + timings = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift; deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + timings = mod3 ? opcode_timings_p6_f6_mod3 : opcode_timings_p6_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + timings = mod3 ? opcode_timings_p6_f7_mod3 : opcode_timings_p6_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + timings = mod3 ? opcode_timings_p6_ff_mod3 : opcode_timings_p6_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; + timings = mod3 ? opcode_timings_p6_mod3 : opcode_timings_p6; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } diff --git a/src/cpu/codegen_timing_winchip.c b/src/cpu/codegen_timing_winchip.c index 76ea8b954..0d39f4151 100644 --- a/src/cpu/codegen_timing_winchip.c +++ b/src/cpu/codegen_timing_winchip.c @@ -18,7 +18,7 @@ #define CYCLES(c) (int *) c #define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8)) -static int *opcode_timings[256] = { +static int *opcode_timings_winchip[256] = { // clang-format off /*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), @@ -42,7 +42,7 @@ static int *opcode_timings[256] = { // clang-format on }; -static int *opcode_timings_mod3[256] = { +static int *opcode_timings_winchip_mod3[256] = { // clang-format off /*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL, /*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), @@ -66,7 +66,7 @@ static int *opcode_timings_mod3[256] = { // clang-format on }; -static int *opcode_timings_0f[256] = { +static int *opcode_timings_winchip_0f[256] = { // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -89,7 +89,7 @@ static int *opcode_timings_0f[256] = { /*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, // clang-format on }; -static int *opcode_timings_0f_mod3[256] = { +static int *opcode_timings_winchip_0f_mod3[256] = { // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -113,68 +113,68 @@ static int *opcode_timings_0f_mod3[256] = { // clang-format on }; -static int *opcode_timings_shift[8] = { +static int *opcode_timings_winchip_shift[8] = { // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) // clang-format on }; -static int *opcode_timings_shift_mod3[8] = { +static int *opcode_timings_winchip_shift_mod3[8] = { // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) // clang-format on }; -static int *opcode_timings_f6[8] = { +static int *opcode_timings_winchip_f6[8] = { // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) // clang-format on }; -static int *opcode_timings_f6_mod3[8] = { +static int *opcode_timings_winchip_f6_mod3[8] = { // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) // clang-format on }; -static int *opcode_timings_f7[8] = { +static int *opcode_timings_winchip_f7[8] = { // clang-format off &timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) // clang-format on }; -static int *opcode_timings_f7_mod3[8] = { +static int *opcode_timings_winchip_f7_mod3[8] = { // clang-format off &timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) // clang-format on }; -static int *opcode_timings_ff[8] = { +static int *opcode_timings_winchip_ff[8] = { // clang-format off &timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL // clang-format on }; -static int *opcode_timings_ff_mod3[8] = { +static int *opcode_timings_winchip_ff_mod3[8] = { // clang-format off &timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL // clang-format on }; -static int *opcode_timings_d8[8] = { +static int *opcode_timings_winchip_d8[8] = { // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) // clang-format on }; -static int *opcode_timings_d8_mod3[8] = { +static int *opcode_timings_winchip_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) // clang-format on }; -static int *opcode_timings_d9[8] = { +static int *opcode_timings_winchip_d9[8] = { // clang-format off /* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/ CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3) // clang-format on }; -static int *opcode_timings_d9_mod3[64] = { +static int *opcode_timings_winchip_d9_mod3[64] = { // clang-format off /*FLD*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), @@ -195,25 +195,25 @@ static int *opcode_timings_d9_mod3[64] = { // clang-format on }; -static int *opcode_timings_da[8] = { +static int *opcode_timings_winchip_da[8] = { // clang-format off /* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) // clang-format on }; -static int *opcode_timings_da_mod3[8] = { +static int *opcode_timings_winchip_da_mod3[8] = { // clang-format off NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL // clang-format on }; -static int *opcode_timings_db[8] = { +static int *opcode_timings_winchip_db[8] = { // clang-format off /* FLDil FSTil FSTPil FLDe FSTPe*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8) // clang-format on }; -static int *opcode_timings_db_mod3[64] = { +static int *opcode_timings_winchip_db_mod3[64] = { // clang-format off NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -227,71 +227,71 @@ static int *opcode_timings_db_mod3[64] = { // clang-format on }; -static int *opcode_timings_dc[8] = { +static int *opcode_timings_winchip_dc[8] = { // clang-format off /* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/ CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74) // clang-format on }; -static int *opcode_timings_dc_mod3[8] = { +static int *opcode_timings_winchip_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/ CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) // clang-format on }; -static int *opcode_timings_dd[8] = { +static int *opcode_timings_winchip_dd[8] = { // clang-format off /* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/ CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5) // clang-format on }; -static int *opcode_timings_dd_mod3[8] = { +static int *opcode_timings_winchip_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL // clang-format on }; -static int *opcode_timings_de[8] = { +static int *opcode_timings_winchip_de[8] = { // clang-format off /* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/ CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78) // clang-format on }; -static int *opcode_timings_de_mod3[8] = { +static int *opcode_timings_winchip_de_mod3[8] = { // clang-format off /* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/ CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72) // clang-format on }; -static int *opcode_timings_df[8] = { +static int *opcode_timings_winchip_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/ CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8) // clang-format on }; -static int *opcode_timings_df_mod3[8] = { +static int *opcode_timings_winchip_df_mod3[8] = { // clang-format off /* FFREE FST FSTP FUCOM FUCOMP*/ CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL // clang-format on }; -static int *opcode_timings_8x[8] = { +static int *opcode_timings_winchip_8x[8] = { // clang-format off &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; -static int *opcode_timings_8x_mod3[8] = +static int *opcode_timings_winchip_8x_mod3[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; -static int *opcode_timings_81[8] = +static int *opcode_timings_winchip_81[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm }; -static int *opcode_timings_81_mod3[8] = +static int *opcode_timings_winchip_81_mod3[8] = { &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm // clang-format on @@ -328,9 +328,9 @@ codegen_timing_winchip_start(void) } void -codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat) +codegen_timing_winchip_prefix(uint8_t prefix, UNUSED(uint32_t fetchdat)) { - timing_count += COUNT(opcode_timings[prefix], 0); + timing_count += COUNT(opcode_timings_winchip[prefix], 0); last_prefix = prefix; } @@ -344,47 +344,47 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS switch (last_prefix) { case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + timings = mod3 ? opcode_timings_winchip_0f_mod3 : opcode_timings_winchip_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; break; case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + timings = mod3 ? opcode_timings_winchip_d8_mod3 : opcode_timings_winchip_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + timings = mod3 ? opcode_timings_winchip_d9_mod3 : opcode_timings_winchip_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + timings = mod3 ? opcode_timings_winchip_da_mod3 : opcode_timings_winchip_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + timings = mod3 ? opcode_timings_winchip_db_mod3 : opcode_timings_winchip_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + timings = mod3 ? opcode_timings_winchip_dc_mod3 : opcode_timings_winchip_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + timings = mod3 ? opcode_timings_winchip_dd_mod3 : opcode_timings_winchip_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + timings = mod3 ? opcode_timings_winchip_de_mod3 : opcode_timings_winchip_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + timings = mod3 ? opcode_timings_winchip_df_mod3 : opcode_timings_winchip_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -394,12 +394,12 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + timings = mod3 ? opcode_timings_winchip_8x_mod3 : opcode_timings_winchip_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + timings = mod3 ? opcode_timings_winchip_81_mod3 : opcode_timings_winchip_81; deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; opcode = (fetchdat >> 3) & 7; break; @@ -410,29 +410,29 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + timings = mod3 ? opcode_timings_winchip_shift_mod3 : opcode_timings_winchip_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + timings = mod3 ? opcode_timings_winchip_f6_mod3 : opcode_timings_winchip_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + timings = mod3 ? opcode_timings_winchip_f7_mod3 : opcode_timings_winchip_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + timings = mod3 ? opcode_timings_winchip_ff_mod3 : opcode_timings_winchip_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; + timings = mod3 ? opcode_timings_winchip_mod3 : opcode_timings_winchip; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } diff --git a/src/cpu/codegen_timing_winchip2.c b/src/cpu/codegen_timing_winchip2.c index ea206f068..696a059cf 100644 --- a/src/cpu/codegen_timing_winchip2.c +++ b/src/cpu/codegen_timing_winchip2.c @@ -63,7 +63,7 @@ #define INVALID 0 -static uint32_t opcode_timings[256] = { +static uint32_t opcode_timings_winchip2[256] = { // clang-format off /*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, /*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), @@ -87,7 +87,7 @@ static uint32_t opcode_timings[256] = { // clang-format on }; -static uint32_t opcode_timings_mod3[256] = { +static uint32_t opcode_timings_winchip2_mod3[256] = { // clang-format off /*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, /*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), @@ -111,7 +111,7 @@ static uint32_t opcode_timings_mod3[256] = { // clang-format on }; -static uint32_t opcode_timings_0f[256] = { +static uint32_t opcode_timings_winchip2_0f[256] = { // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -134,7 +134,7 @@ static uint32_t opcode_timings_0f[256] = { /*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, // clang-format on }; -static uint32_t opcode_timings_0f_mod3[256] = { +static uint32_t opcode_timings_winchip2_0f_mod3[256] = { // clang-format off /*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -158,49 +158,49 @@ static uint32_t opcode_timings_0f_mod3[256] = { // clang-format on }; -static uint32_t opcode_timings_shift[8] = { +static uint32_t opcode_timings_winchip2_shift[8] = { // clang-format off CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) // clang-format on }; -static uint32_t opcode_timings_shift_mod3[8] = { +static uint32_t opcode_timings_winchip2_shift_mod3[8] = { // clang-format off CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) // clang-format on }; -static uint32_t opcode_timings_f6[8] = { +static uint32_t opcode_timings_winchip2_f6[8] = { // clang-format off CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) // clang-format on }; -static uint32_t opcode_timings_f6_mod3[8] = { +static uint32_t opcode_timings_winchip2_f6_mod3[8] = { // clang-format off CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) // clang-format on }; -static uint32_t opcode_timings_f7[8] = { +static uint32_t opcode_timings_winchip2_f7[8] = { // clang-format off CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) // clang-format on }; -static uint32_t opcode_timings_f7_mod3[8] = { +static uint32_t opcode_timings_winchip2_f7_mod3[8] = { // clang-format off CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43) // clang-format on }; -static uint32_t opcode_timings_ff[8] = { +static uint32_t opcode_timings_winchip2_ff[8] = { // clang-format off CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID // clang-format on }; -static uint32_t opcode_timings_ff_mod3[8] = { +static uint32_t opcode_timings_winchip2_ff_mod3[8] = { // clang-format off CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID // clang-format on }; -static uint32_t opcode_timings_d8[8] = { +static uint32_t opcode_timings_winchip2_d8[8] = { // clang-format off /* FADDs FMULs FCOMs FCOMPs*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -208,7 +208,7 @@ static uint32_t opcode_timings_d8[8] = { FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) // clang-format on }; -static uint32_t opcode_timings_d8_mod3[8] = { +static uint32_t opcode_timings_winchip2_d8_mod3[8] = { // clang-format off /* FADD FMUL FCOM FCOMP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -217,7 +217,7 @@ static uint32_t opcode_timings_d8_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_d9[8] = { +static uint32_t opcode_timings_winchip2_d9[8] = { // clang-format off /* FLDs FSTs FSTPs*/ FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), @@ -225,7 +225,7 @@ static uint32_t opcode_timings_d9[8] = { FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0) // clang-format on }; -static uint32_t opcode_timings_d9_mod3[64] = { +static uint32_t opcode_timings_winchip2_d9_mod3[64] = { // clang-format off /*FLD*/ FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -258,7 +258,7 @@ static uint32_t opcode_timings_d9_mod3[64] = { // clang-format on }; -static uint32_t opcode_timings_da[8] = { +static uint32_t opcode_timings_winchip2_da[8] = { // clang-format off /* FIADDl FIMULl FICOMl FICOMPl*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), @@ -266,7 +266,7 @@ static uint32_t opcode_timings_da[8] = { FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) // clang-format on }; -static uint32_t opcode_timings_da_mod3[8] = { +static uint32_t opcode_timings_winchip2_da_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FCOMPP*/ @@ -274,7 +274,7 @@ static uint32_t opcode_timings_da_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_db[8] = { +static uint32_t opcode_timings_winchip2_db[8] = { // clang-format off /* FLDil FSTil FSTPil*/ FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), @@ -282,7 +282,7 @@ static uint32_t opcode_timings_db[8] = { INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0) // clang-format on }; -static uint32_t opcode_timings_db_mod3[64] = { +static uint32_t opcode_timings_winchip2_db_mod3[64] = { // clang-format off INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -312,7 +312,7 @@ static uint32_t opcode_timings_db_mod3[64] = { // clang-format on }; -static uint32_t opcode_timings_dc[8] = { +static uint32_t opcode_timings_winchip2_dc[8] = { // clang-format off /* FADDd FMULd FCOMd FCOMPd*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -320,7 +320,7 @@ static uint32_t opcode_timings_dc[8] = { FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2) // clang-format on }; -static uint32_t opcode_timings_dc_mod3[8] = { +static uint32_t opcode_timings_winchip2_dc_mod3[8] = { // clang-format off /* opFADDr opFMULr*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID, @@ -329,7 +329,7 @@ static uint32_t opcode_timings_dc_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_dd[8] = { +static uint32_t opcode_timings_winchip2_dd[8] = { // clang-format off /* FLDd FSTd FSTPd*/ FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0), @@ -337,7 +337,7 @@ static uint32_t opcode_timings_dd[8] = { FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0) // clang-format on }; -static uint32_t opcode_timings_dd_mod3[8] = { +static uint32_t opcode_timings_winchip2_dd_mod3[8] = { // clang-format off /* FFFREE FST FSTP*/ FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), @@ -346,7 +346,7 @@ static uint32_t opcode_timings_dd_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_de[8] = { +static uint32_t opcode_timings_winchip2_de[8] = { // clang-format off /* FIADDw FIMULw FICOMw FICOMPw*/ FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0), @@ -354,7 +354,7 @@ static uint32_t opcode_timings_de[8] = { FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2) // clang-format on }; -static uint32_t opcode_timings_de_mod3[8] = { +static uint32_t opcode_timings_winchip2_de_mod3[8] = { // clang-format off /* FADDP FMULP FCOMPP*/ FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0), @@ -363,7 +363,7 @@ static uint32_t opcode_timings_de_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_df[8] = { +static uint32_t opcode_timings_winchip2_df[8] = { // clang-format off /* FILDiw FISTiw FISTPiw*/ FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0), @@ -371,7 +371,7 @@ static uint32_t opcode_timings_df[8] = { INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0) // clang-format on }; -static uint32_t opcode_timings_df_mod3[8] = { +static uint32_t opcode_timings_winchip2_df_mod3[8] = { // clang-format off INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ @@ -379,22 +379,22 @@ static uint32_t opcode_timings_df_mod3[8] = { // clang-format on }; -static uint32_t opcode_timings_8x[8] = { +static uint32_t opcode_timings_winchip2_8x[8] = { // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) // clang-format on }; -static uint32_t opcode_timings_8x_mod3[8] = { +static uint32_t opcode_timings_winchip2_8x_mod3[8] = { // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) // clang-format on }; -static uint32_t opcode_timings_81[8] = { +static uint32_t opcode_timings_winchip2_81[8] = { // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) // clang-format on }; -static uint32_t opcode_timings_81_mod3[8] = { +static uint32_t opcode_timings_winchip2_81_mod3[8] = { // clang-format off CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) // clang-format on @@ -589,7 +589,7 @@ codegen_timing_winchip2_start(void) } static void -codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) +codegen_timing_winchip2_prefix(uint8_t prefix, UNUSED(uint32_t fetchdat)) { if (prefix == 0x0f) { /*0fh prefix is 'free'*/ @@ -613,47 +613,47 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU switch (last_prefix) { case 0x0f: - timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + timings = mod3 ? opcode_timings_winchip2_0f_mod3 : opcode_timings_winchip2_0f; deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; break; case 0xd8: - timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + timings = mod3 ? opcode_timings_winchip2_d8_mod3 : opcode_timings_winchip2_d8; deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; opcode = (opcode >> 3) & 7; break; case 0xd9: - timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + timings = mod3 ? opcode_timings_winchip2_d9_mod3 : opcode_timings_winchip2_d9; deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xda: - timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + timings = mod3 ? opcode_timings_winchip2_da_mod3 : opcode_timings_winchip2_da; deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; opcode = (opcode >> 3) & 7; break; case 0xdb: - timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + timings = mod3 ? opcode_timings_winchip2_db_mod3 : opcode_timings_winchip2_db; deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; break; case 0xdc: - timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + timings = mod3 ? opcode_timings_winchip2_dc_mod3 : opcode_timings_winchip2_dc; deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; opcode = (opcode >> 3) & 7; break; case 0xdd: - timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + timings = mod3 ? opcode_timings_winchip2_dd_mod3 : opcode_timings_winchip2_dd; deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; opcode = (opcode >> 3) & 7; break; case 0xde: - timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + timings = mod3 ? opcode_timings_winchip2_de_mod3 : opcode_timings_winchip2_de; deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; opcode = (opcode >> 3) & 7; break; case 0xdf: - timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + timings = mod3 ? opcode_timings_winchip2_df_mod3 : opcode_timings_winchip2_df; deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; opcode = (opcode >> 3) & 7; break; @@ -663,12 +663,12 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU case 0x80: case 0x82: case 0x83: - timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + timings = mod3 ? opcode_timings_winchip2_8x_mod3 : opcode_timings_winchip2_8x; deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; opcode = (fetchdat >> 3) & 7; break; case 0x81: - timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81; + timings = mod3 ? opcode_timings_winchip2_81_mod3 : opcode_timings_winchip2_81; deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81; opcode = (fetchdat >> 3) & 7; break; @@ -679,29 +679,29 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU case 0xd1: case 0xd2: case 0xd3: - timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + timings = mod3 ? opcode_timings_winchip2_shift_mod3 : opcode_timings_winchip2_shift; deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; opcode = (fetchdat >> 3) & 7; break; case 0xf6: - timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + timings = mod3 ? opcode_timings_winchip2_f6_mod3 : opcode_timings_winchip2_f6; deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; opcode = (fetchdat >> 3) & 7; break; case 0xf7: - timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + timings = mod3 ? opcode_timings_winchip2_f7_mod3 : opcode_timings_winchip2_f7; deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; opcode = (fetchdat >> 3) & 7; break; case 0xff: - timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + timings = mod3 ? opcode_timings_winchip2_ff_mod3 : opcode_timings_winchip2_ff; deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; opcode = (fetchdat >> 3) & 7; break; default: - timings = mod3 ? opcode_timings_mod3 : opcode_timings; + timings = mod3 ? opcode_timings_winchip2_mod3 : opcode_timings_winchip2; deps = mod3 ? opcode_deps_mod3 : opcode_deps; break; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 0ff54f61c..0802fa3ac 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -47,7 +47,7 @@ #ifdef USE_DYNAREC # include "codegen.h" -#endif +#endif /* USE_DYNAREC */ #include "x87_timings.h" #define CCR1_USE_SMI (1 << 1) @@ -76,6 +76,7 @@ enum { CPUID_MCA = (1 << 14), /* Machine Check Architecture */ CPUID_CMOV = (1 << 15), /* Conditional move instructions */ CPUID_PAT = (1 << 16), /* Page Attribute Table */ + CPUID_PSE36 = (1 << 17), /* 36-bit Page Size Extension */ CPUID_MMX = (1 << 23), /* MMX technology */ CPUID_FXSR = (1 << 24) /* FXSAVE and FXRSTOR instructions */ }; @@ -119,7 +120,7 @@ const OpFn *x86_dynarec_opcodes_df_a32; const OpFn *x86_dynarec_opcodes_REPE; const OpFn *x86_dynarec_opcodes_REPNE; const OpFn *x86_dynarec_opcodes_3DNOW; -#endif +#endif /* USE_DYNAREC */ const OpFn *x86_opcodes; const OpFn *x86_opcodes_0f; @@ -182,6 +183,8 @@ int cpu_rom_prefetch_cycles; int cpu_waitstates; int cpu_cache_int_enabled; int cpu_cache_ext_enabled; +int cpu_flush_pending; +int cpu_old_paging; int cpu_isa_speed; int cpu_pci_speed; int cpu_isa_pci_div; @@ -200,6 +203,7 @@ int cpu_override_interpreter; int CPUID; int is186; +int is_mazovia; int is_nec; int is286; int is386; @@ -504,7 +508,7 @@ cpu_set(void) #ifdef USE_ACYCS acycs = 0; -#endif +#endif /* USE_ACYCS */ soft_reset_pci = 0; cpu_init = 0; @@ -514,6 +518,7 @@ cpu_set(void) CPUID = cpu_s->cpuid_model; is8086 = (cpu_s->cpu_type > CPU_8088) && (cpu_s->cpu_type != CPU_V20) && (cpu_s->cpu_type != CPU_188); + is_mazovia = (cpu_s->cpu_type == CPU_8086_MAZOVIA); is_nec = (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30); is186 = (cpu_s->cpu_type == CPU_186) || (cpu_s->cpu_type == CPU_188) || (cpu_s->cpu_type == CPU_V20) || (cpu_s->cpu_type == CPU_V30); is286 = (cpu_s->cpu_type >= CPU_286); @@ -576,7 +581,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); #else x86_setopcodes(ops_386, ops_386_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f); x86_opcodes_REPE = ops_REPE; x86_opcodes_REPNE = ops_REPNE; @@ -587,7 +592,7 @@ cpu_set(void) x86_dynarec_opcodes_REPE = dynarec_ops_REPE; x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; -#endif +#endif /* USE_DYNAREC */ if (hasfpu) { #ifdef USE_DYNAREC @@ -626,7 +631,7 @@ cpu_set(void) x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16; x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32; } -#endif +#endif /* USE_DYNAREC */ if (fpu_softfloat) { x86_opcodes_d8_a16 = ops_sf_fpu_d8_a16; x86_opcodes_d8_a32 = ops_sf_fpu_d8_a32; @@ -714,7 +719,7 @@ cpu_set(void) x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32; x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16; x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32; -#endif +#endif /* USE_DYNAREC */ x86_opcodes_d8_a16 = ops_nofpu_a16; x86_opcodes_d8_a32 = ops_nofpu_a32; x86_opcodes_d9_a16 = ops_nofpu_a16; @@ -752,7 +757,7 @@ cpu_set(void) #ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_486); -#endif +#endif /* USE_DYNAREC */ memset(&msr, 0, sizeof(msr)); @@ -764,6 +769,7 @@ cpu_set(void) switch (cpu_s->cpu_type) { case CPU_8088: case CPU_8086: + case CPU_8086_MAZOVIA: break; case CPU_V20: @@ -774,7 +780,7 @@ cpu_set(void) x86_setopcodes(ops_186, ops_186_0f, dynarec_ops_186, dynarec_ops_186_0f); #else x86_setopcodes(ops_186, ops_186_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f); break; @@ -783,7 +789,7 @@ cpu_set(void) x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); #else x86_setopcodes(ops_286, ops_286_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f); if (fpu_type == FPU_287) { @@ -819,7 +825,7 @@ cpu_set(void) x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; } -#endif +#endif /* USE_DYNAREC */ if (fpu_softfloat) { x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32; @@ -921,7 +927,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f); #else x86_setopcodes(ops_386, ops_ibm486_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f); cpu_features = CPU_FEATURE_MSR; fallthrough; @@ -961,7 +967,7 @@ cpu_set(void) x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; } -#endif +#endif /* USE_DYNAREC */ if (fpu_softfloat) { x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16; x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32; @@ -1067,7 +1073,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else x86_setopcodes(ops_386, ops_486_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ @@ -1107,7 +1113,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else x86_setopcodes(ops_386, ops_486_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ @@ -1160,7 +1166,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f); #else x86_setopcodes(ops_386, ops_486_0f); -#endif +#endif /* USE_DYNAREC */ x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f); timing_rr = 1; /* register dest - register src */ @@ -1209,7 +1215,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_stpc_0f); else x86_setopcodes(ops_386, ops_c486_0f); -#endif +#endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ timing_rm = 3; /* register dest - memory src */ @@ -1252,7 +1258,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f); #else x86_setopcodes(ops_386, ops_c486_0f); -#endif +#endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ timing_rm = 1; /* register dest - memory src */ @@ -1301,7 +1307,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_winchip2_0f); else x86_setopcodes(ops_386, ops_winchip_0f); -#endif +#endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ timing_rm = 2; /* register dest - memory src */ @@ -1350,7 +1356,7 @@ cpu_set(void) codegen_timing_set(&codegen_timing_winchip2); else codegen_timing_set(&codegen_timing_winchip); -#endif +#endif /* USE_DYNAREC */ break; case CPU_P24T: @@ -1366,7 +1372,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_pentiummmx_0f); else x86_setopcodes(ops_386, ops_pentium_0f); -#endif +#endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ timing_rm = 2; /* register dest - memory src */ @@ -1409,10 +1415,10 @@ cpu_set(void) cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; #ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_pentium); -#endif +#endif /* USE_DYNAREC */ break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -1434,7 +1440,7 @@ cpu_set(void) x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16; x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32; } -# endif +# endif /* USE_DYNAREC */ if (fpu_softfloat) { x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16; x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32; @@ -1472,7 +1478,7 @@ cpu_set(void) # if 0 x86_setopcodes(ops_386, ops_c6x86_0f); # endif -# endif +# endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ timing_rm = 1; /* register dest - memory src */ @@ -1524,19 +1530,65 @@ cpu_set(void) # ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_686); -# endif +# endif /* USE_DYNAREC */ if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX)) ccr4 = 0x80; else if (CPU_Cx6x86) CPUID = 0; /* Disabled on powerup by default */ break; -#endif +#endif /* USE_CYRIX_6X86 */ -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +#ifdef USE_AMD_K5 case CPU_K5: case CPU_5K86: -#endif +#ifdef USE_DYNAREC + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); +#else + x86_setopcodes(ops_386, ops_pentiummmx_0f); +#endif /* USE_DYNAREC */ + + timing_rr = 1; /* register dest - register src */ + timing_rm = 2; /* register dest - memory src */ + timing_mr = 3; /* memory dest - register src */ + timing_mm = 3; + timing_rml = 2; /* register dest - memory src long */ + timing_mrl = 3; /* memory dest - register src long */ + timing_mml = 3; + timing_bt = 0; /* branch taken */ + timing_bnt = 1; /* branch not taken */ + + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /* unknown */ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + + timing_misaligned = 3; + + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PGE; + +#ifdef USE_DYNAREC + codegen_timing_set(&codegen_timing_k5); +#endif /* USE_DYNAREC */ + break; + +#endif /* USE_AMD_K5 */ case CPU_K6: case CPU_K6_2: case CPU_K6_2C: @@ -1546,34 +1598,20 @@ cpu_set(void) #ifdef USE_DYNAREC if (cpu_s->cpu_type >= CPU_K6_2) x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f); -# if defined(DEV_BRANCH) && defined(USE_AMD_K5) - else if (cpu_s->cpu_type == CPU_K6) - x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); - else - x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); -# else else x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f); -# endif #else if (cpu_s->cpu_type >= CPU_K6_2) x86_setopcodes(ops_386, ops_k62_0f); -# if defined(DEV_BRANCH) && defined(USE_AMD_K5) - else if (cpu_s->cpu_type == CPU_K6) - x86_setopcodes(ops_386, ops_k6_0f); - else - x86_setopcodes(ops_386, ops_pentiummmx_0f); -# else else x86_setopcodes(ops_386, ops_k6_0f); -# endif -#endif +#endif /* USE_DYNAREC */ if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) { x86_opcodes_3DNOW = ops_3DNOWE; #ifdef USE_DYNAREC x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE; -#endif +#endif /* USE_DYNAREC */ } timing_rr = 1; /* register dest - register src */ @@ -1613,27 +1651,15 @@ cpu_set(void) cpu_features |= CPU_FEATURE_3DNOW; if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) cpu_features |= CPU_FEATURE_3DNOWE; -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE; - if (cpu_s->cpu_type >= CPU_K6) { - cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE); - if (cpu_s->cpu_type <= CPU_K6) - cpu_CR4_mask |= CR4_PCE; - else if (cpu_s->cpu_type >= CPU_K6_2C) - cpu_CR4_mask |= CR4_PGE; - } else - cpu_CR4_mask |= CR4_PGE; -#else cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; if (cpu_s->cpu_type == CPU_K6) cpu_CR4_mask |= CR4_PCE; else if (cpu_s->cpu_type >= CPU_K6_2C) cpu_CR4_mask |= CR4_PGE; -#endif #ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_k6); -#endif +#endif /* USE_DYNAREC */ break; case CPU_PENTIUMPRO: @@ -1668,7 +1694,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_pentium2d_0f); else x86_setopcodes(ops_386, ops_pentium2_0f); -#endif +#endif /* USE_DYNAREC */ if (fpu_softfloat) { x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16; x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32; @@ -1721,12 +1747,14 @@ cpu_set(void) if (cpu_s->cpu_type >= CPU_PENTIUM2) cpu_features |= CPU_FEATURE_MMX; cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PAE | CR4_PCE | CR4_PGE; - if (cpu_s->cpu_type == CPU_PENTIUM2D) + if (cpu_s->cpu_type == CPU_PENTIUM2D) { cpu_CR4_mask |= CR4_OSFXSR; + cpu_features |= CPU_FEATURE_PSE36; + } #ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_p6); -#endif +#endif /* USE_DYNAREC */ break; case CPU_CYRIX3S: @@ -1734,7 +1762,7 @@ cpu_set(void) x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); #else x86_setopcodes(ops_386, ops_winchip2_0f); -#endif +#endif /* USE_DYNAREC */ timing_rr = 1; /* register dest - register src */ timing_rm = 2; /* register dest - memory src */ timing_mr = 2; /* memory dest - register src */ @@ -1774,7 +1802,7 @@ cpu_set(void) #ifdef USE_DYNAREC codegen_timing_set(&codegen_timing_winchip); -#endif +#endif /* USE_DYNAREC */ break; default: @@ -1812,7 +1840,7 @@ cpu_set(void) cpu_exec = exec386_dynarec; cpu_use_exec = 1; } else -#endif +#endif /* defined(USE_DYNAREC) && !defined(USE_GDBSTUB) */ /* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */ if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) || cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC) || cpu_override_interpreter) { @@ -2065,7 +2093,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +#ifdef USE_AMD_K5 case CPU_K5: if (!EAX) { EAX = 0x00000001; @@ -2123,7 +2151,7 @@ cpu_CPUID(void) break; } break; -#endif +#endif /* USE_AMD_K5 */ case CPU_K6: switch (EAX) { @@ -2354,7 +2382,7 @@ cpu_CPUID(void) EAX = EBX = ECX = EDX = 0; break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 case CPU_Cx6x86: if (!EAX) { EAX = 0x00000001; @@ -2407,10 +2435,15 @@ cpu_CPUID(void) EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_DE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX; + /* + Return anything non-zero in bits 32-63 of the BIOS signature MSR + to indicate there has been an update. + */ + msr.bbl_cr_dx[3] = 0xffffffff00000000ULL; } else EAX = EBX = ECX = EDX = 0; break; -#endif +#endif /* USE_CYRIX_6X86 */ case CPU_PENTIUMPRO: if (!EAX) { @@ -2445,6 +2478,11 @@ cpu_CPUID(void) EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_CMOV; + /* + Return anything non-zero in bits 32-63 of the BIOS signature MSR + to indicate there has been an update. + */ + msr.bbl_cr_dx[3] = 0xffffffff00000000ULL; } else if (EAX == 2) { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries @@ -2467,7 +2505,12 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV | CPUID_PSE36; + /* + Return anything non-zero in bits 32-63 of the BIOS signature MSR + to indicate there has been an update. + */ + msr.bbl_cr_dx[3] = 0xffffffff00000000ULL; } else if (EAX == 2) { EAX = 0x03020101; /* Instruction TLB: 4 KB pages, 4-way set associative, 32 entries Instruction TLB: 4 MB pages, fully associative, 2 entries @@ -2565,10 +2608,10 @@ cpu_ven_reset(void) msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL; fallthrough; case CPU_K6_2: -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +#ifdef USE_AMD_K5 case CPU_K5: case CPU_5K86: -#endif +#endif /* USE_AMD_K5 */ case CPU_K6: msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL; break; @@ -2589,7 +2632,9 @@ cpu_ven_reset(void) void cpu_RDMSR(void) { - switch (cpu_s->cpu_type) { + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) + x86gpf(NULL, 0); + else switch (cpu_s->cpu_type) { case CPU_IBM386SLC: case CPU_IBM486SLC: case CPU_IBM486BL: @@ -2789,10 +2834,10 @@ cpu_RDMSR(void) } break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +#ifdef USE_AMD_K5 case CPU_K5: case CPU_5K86: -#endif +#endif /* USE_AMD_K5 */ case CPU_K6: case CPU_K6_2: case CPU_K6_2C: @@ -3075,7 +3120,7 @@ pentium_invalid_rdmsr: cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -3115,7 +3160,7 @@ pentium_invalid_rdmsr: } cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); break; -#endif +#endif /* USE_CYRIX_6X86 */ case CPU_PENTIUMPRO: case CPU_PENTIUM2: @@ -3223,6 +3268,7 @@ pentium_invalid_rdmsr: case 0x88 ... 0x8b: EAX = msr.bbl_cr_dx[ECX - 0x88] & 0xffffffff; EDX = msr.bbl_cr_dx[ECX - 0x88] >> 32; + // EDX |= 0xffffffff; break; /* Unknown */ case 0xae: @@ -3278,26 +3324,17 @@ pentium_invalid_rdmsr: break; /* SYSENTER_CS - SYSENTER target CS */ case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_rdmsr; - EAX &= 0xffff0000; EAX |= msr.sysenter_cs; EDX = 0x00000000; break; /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_rdmsr; - EAX = msr.sysenter_esp; EDX = 0x00000000; break; /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_rdmsr; - EAX = msr.sysenter_eip; EDX = 0x00000000; break; @@ -3453,7 +3490,9 @@ cpu_WRMSR(void) cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX); - switch (cpu_s->cpu_type) { + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) + x86gpf(NULL, 0); + else switch (cpu_s->cpu_type) { case CPU_IBM386SLC: case CPU_IBM486SLC: case CPU_IBM486BL: @@ -3638,10 +3677,10 @@ cpu_WRMSR(void) } break; -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +#ifdef USE_AMD_K5 case CPU_K5: case CPU_5K86: -#endif +#endif /* USE_AMD_K5 */ case CPU_K6: case CPU_K6_2: case CPU_K6_2C: @@ -3692,7 +3731,7 @@ cpu_WRMSR(void) /* Extended Feature Enable Register */ case 0xc0000080: temp = EAX | ((uint64_t) EDX << 32); - if (temp & ~1ULL) + if (temp & ~0x1fULL) x86gpf(NULL, 0); else msr.amd_efer = temp; @@ -3902,7 +3941,7 @@ pentium_invalid_wrmsr: } break; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 case CPU_Cx6x86: case CPU_Cx6x86L: case CPU_CxGX1: @@ -3936,7 +3975,7 @@ pentium_invalid_wrmsr: break; } break; -#endif +#endif /* USE_CYRIX_6X86 */ case CPU_PENTIUMPRO: case CPU_PENTIUM2: @@ -4047,23 +4086,14 @@ pentium_invalid_wrmsr: break; /* SYSENTER_CS - SYSENTER target CS */ case 0x174: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_wrmsr; - msr.sysenter_cs = EAX & 0xFFFF; break; /* SYSENTER_ESP - SYSENTER target ESP */ case 0x175: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_wrmsr; - msr.sysenter_esp = EAX; break; /* SYSENTER_EIP - SYSENTER target EIP */ case 0x176: - if (cpu_s->cpu_type == CPU_PENTIUMPRO) - goto i686_invalid_wrmsr; - msr.sysenter_eip = EAX; break; /* MCG_CAP - Machine Check Global Capability */ @@ -4249,14 +4279,14 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) case 0xe8: /* CCR4 */ if ((ccr3 & 0xf0) == 0x10) { ccr4 = val; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 if (cpu_s->cpu_type >= CPU_Cx6x86) { if (val & 0x80) CPUID = cpu_s->cpuid_model; else CPUID = 0; } -#endif +#endif /* USE_CYRIX_6X86 */ } break; case 0xe9: /* CCR5 */ @@ -4330,7 +4360,7 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f) x86_opcodes = opcodes; x86_opcodes_0f = opcodes_0f; } -#endif +#endif /* USE_DYNAREC */ void x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f) diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9b154cd0d..1d003ddc9 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -35,6 +35,7 @@ enum { enum { CPU_8088 = 1, /* 808x class CPUs */ CPU_8086, + CPU_8086_MAZOVIA, CPU_V20, /* NEC 808x class CPUs */ CPU_V30, CPU_188, /* 18x class CPUs */ @@ -87,28 +88,29 @@ enum { CPU_PKG_8088 = (1 << 0), CPU_PKG_8088_EUROPC = (1 << 1), CPU_PKG_8086 = (1 << 2), - CPU_PKG_188 = (1 << 3), - CPU_PKG_186 = (1 << 4), - CPU_PKG_286 = (1 << 5), - CPU_PKG_386SX = (1 << 6), - CPU_PKG_386DX = (1 << 7), - CPU_PKG_386DX_DESKPRO386 = (1 << 8), - CPU_PKG_M6117 = (1 << 9), - CPU_PKG_386SLC_IBM = (1 << 10), - CPU_PKG_486SLC = (1 << 11), - CPU_PKG_486SLC_IBM = (1 << 12), - CPU_PKG_486BL = (1 << 13), - CPU_PKG_486DLC = (1 << 14), - CPU_PKG_SOCKET1 = (1 << 15), - CPU_PKG_SOCKET3 = (1 << 16), - CPU_PKG_SOCKET3_PC330 = (1 << 17), - CPU_PKG_STPC = (1 << 18), - CPU_PKG_SOCKET4 = (1 << 19), - CPU_PKG_SOCKET5_7 = (1 << 20), - CPU_PKG_SOCKET8 = (1 << 21), - CPU_PKG_SLOT1 = (1 << 22), - CPU_PKG_SLOT2 = (1 << 23), - CPU_PKG_SOCKET370 = (1 << 24) + CPU_PKG_8086_MAZOVIA = (1 << 3), + CPU_PKG_188 = (1 << 4), + CPU_PKG_186 = (1 << 5), + CPU_PKG_286 = (1 << 6), + CPU_PKG_386SX = (1 << 7), + CPU_PKG_386DX = (1 << 8), + CPU_PKG_386DX_DESKPRO386 = (1 << 9), + CPU_PKG_M6117 = (1 << 10), + CPU_PKG_386SLC_IBM = (1 << 11), + CPU_PKG_486SLC = (1 << 12), + CPU_PKG_486SLC_IBM = (1 << 13), + CPU_PKG_486BL = (1 << 14), + CPU_PKG_486DLC = (1 << 15), + CPU_PKG_SOCKET1 = (1 << 16), + CPU_PKG_SOCKET3 = (1 << 17), + CPU_PKG_SOCKET3_PC330 = (1 << 18), + CPU_PKG_STPC = (1 << 19), + CPU_PKG_SOCKET4 = (1 << 20), + CPU_PKG_SOCKET5_7 = (1 << 21), + CPU_PKG_SOCKET8 = (1 << 22), + CPU_PKG_SLOT1 = (1 << 23), + CPU_PKG_SLOT2 = (1 << 24), + CPU_PKG_SOCKET370 = (1 << 25) }; #define CPU_SUPPORTS_DYNAREC 1 @@ -518,6 +520,7 @@ extern int is_p6; extern int is_cxsmm; extern int hascache; extern int isibm486; +extern int is_mazovia; extern int is_nec; extern int is_rapidcad; extern int hasfpu; @@ -530,6 +533,7 @@ extern int hasfpu; #define CPU_FEATURE_3DNOW (1 << 6) #define CPU_FEATURE_SYSCALL (1 << 7) #define CPU_FEATURE_3DNOWE (1 << 8) +#define CPU_FEATURE_PSE36 (1 << 9) extern uint32_t cpu_features; @@ -616,6 +620,8 @@ extern int cpu_prefetch_width; extern int cpu_mem_prefetch_cycles; extern int cpu_rom_prefetch_cycles; extern int cpu_waitstates; +extern int cpu_flush_pending; +extern int cpu_old_paging; extern int cpu_cache_int_enabled; extern int cpu_cache_ext_enabled; extern int cpu_isa_speed; @@ -808,9 +814,22 @@ extern int lock_legal_80[8]; extern int lock_legal_f6[8]; extern int lock_legal_fe[8]; +extern int new_ne; + extern int in_lock; extern int cpu_override_interpreter; extern int is_lock_legal(uint32_t fetchdat); +extern void prefetch_queue_set_pos(int pos); +extern void prefetch_queue_set_ip(uint16_t ip); +extern void prefetch_queue_set_prefetching(int p); +extern int prefetch_queue_get_pos(void); +extern uint16_t prefetch_queue_get_ip(void); +extern int prefetch_queue_get_prefetching(void); +extern int prefetch_queue_get_size(void); + +#define prefetch_queue_set_suspended(s) prefetch_queue_set_prefetching(!s) +#define prefetch_queue_get_suspended !prefetch_queue_get_prefetching + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index ace51eed8..b2ef71075 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -373,6 +373,32 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, + { + .package = CPU_PKG_8086_MAZOVIA, + .manufacturer = "Kyiv Research Institute of Microdevices", + .name = "K1810VM86", + .internal_name = "8086_mazovia", + .cpus = (const CPU[]) { + { + .name = "4.77", + .cpu_type = CPU_8086_MAZOVIA, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } + } + }, { .package = CPU_PKG_188, .manufacturer = "Intel", @@ -2508,7 +2534,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 75000000, .multi = 3.0, - .voltage = 3300, + .voltage = 5000, .edx_reset = 0x480, .cpuid_model = 0x480, .cyrix_id = 0x0000, @@ -2525,7 +2551,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 100000000, .multi = 3.0, - .voltage = 3300, + .voltage = 5000, .edx_reset = 0x483, .cpuid_model = 0x483, .cyrix_id = 0x0000, @@ -3066,7 +3092,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 133333333, .multi = 4.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x4e0, .cpuid_model = 0x4e0, .cyrix_id = 0, @@ -3083,7 +3109,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 150000000, .multi = 3.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x482, .cpuid_model = 0x482, .cyrix_id = 0, @@ -3100,7 +3126,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 160000000, .multi = 4.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x4e0, .cpuid_model = 0x4e0, .cyrix_id = 0, @@ -3332,7 +3358,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 80000000, .multi = 2.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x480, .cpuid_model = 0, .cyrix_id = 0x002f, @@ -3349,7 +3375,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 100000000, .multi = 3.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x480, .cpuid_model = 0, .cyrix_id = 0x002f, @@ -3366,7 +3392,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 120000000, .multi = 3.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x480, .cpuid_model = 0, .cyrix_id = 0x002f, @@ -3383,7 +3409,7 @@ const cpu_family_t cpu_families[] = { .fpus = fpus_internal, .rspeed = 133333333, .multi = 4.0, - .voltage = 3450, + .voltage = 5000, .edx_reset = 0x480, .cpuid_model = 0, .cyrix_id = 0x002f, @@ -4474,7 +4500,7 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, -#if defined(DEV_BRANCH) && defined(USE_AMD_K5) +#ifdef USE_AMD_K5 { .package = CPU_PKG_SOCKET5_7, .manufacturer = "AMD", @@ -4629,7 +4655,7 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, -#endif +#endif /* USE_AMD_K5 */ { .package = CPU_PKG_SOCKET5_7, .manufacturer = "AMD", @@ -5982,7 +6008,7 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 { .package = CPU_PKG_SOCKET5_7, .manufacturer = "Cyrix", @@ -6342,7 +6368,7 @@ const cpu_family_t cpu_families[] = { { .name = "", 0 } } }, -#endif +#endif /* USE_CYRIX_6X86 */ { .package = CPU_PKG_SOCKET8, .manufacturer = "Intel", diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 4bf381ee4..6f15560f3 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -271,13 +271,14 @@ reset_common(int hard) stack32 = 0; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); msw = 0; + new_ne = 0; if (hascache) cr0 = 1 << 30; else cr0 = 0; if (is386 && !is486 && (fpu_type == FPU_387)) cr0 |= 0x10; - cpu_cache_int_enabled = 0; + cpu_cache_int_enabled = 0; cpu_update_waitstates(); cr4 = 0; cpu_state.eflags = 0; @@ -325,6 +326,8 @@ reset_common(int hard) if (hard) codegen_reset(); #endif + cpu_flush_pending = 0; + cpu_old_paging = 0; if (!hard) flushmmucache(); x86_was_reset = 1; @@ -382,9 +385,6 @@ softresetx86(void) if (soft_reset_mask) return; - if (ibm8514_active || xga_active) - vga_on = 1; - reset_common(0); } diff --git a/src/cpu/x86_flags.h b/src/cpu/x86_flags.h index e82041783..7d5c41ca8 100644 --- a/src/cpu/x86_flags.h +++ b/src/cpu/x86_flags.h @@ -741,7 +741,7 @@ setadc8(uint8_t a, uint8_t b) cpu_state.flags |= C_FLAG; if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) + if (((a & 0xF) + (b & 0xF) + tempc) & 0x10) cpu_state.flags |= A_FLAG; } static __inline void @@ -755,7 +755,7 @@ setadc16(uint16_t a, uint16_t b) cpu_state.flags |= C_FLAG; if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) + if (((a & 0xF) + (b & 0xF) + tempc) & 0x10) cpu_state.flags |= A_FLAG; } static __inline void @@ -785,7 +785,7 @@ setsbc8(uint8_t a, uint8_t b) cpu_state.flags |= C_FLAG; if ((a ^ b) & (a ^ c) & 0x80) cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) + if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) cpu_state.flags |= A_FLAG; } static __inline void @@ -800,7 +800,7 @@ setsbc16(uint16_t a, uint16_t b) cpu_state.flags |= C_FLAG; if ((a ^ b) & (a ^ c) & 0x8000) cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) + if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) cpu_state.flags |= A_FLAG; } diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index 86f54ee3b..3dfb3f917 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -90,10 +90,10 @@ extern const OpFn dynarec_ops_winchip2_0f[1024]; extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# ifdef USE_CYRIX_6X86 extern const OpFn dynarec_ops_c6x86_0f[1024]; extern const OpFn dynarec_ops_c6x86mx_0f[1024]; -# endif +# endif /* USE_CYRIX_6X86 */ extern const OpFn dynarec_ops_k6_0f[1024]; extern const OpFn dynarec_ops_k62_0f[1024]; @@ -232,10 +232,10 @@ extern const OpFn ops_winchip2_0f[1024]; extern const OpFn ops_pentium_0f[1024]; extern const OpFn ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 extern const OpFn ops_c6x86_0f[1024]; extern const OpFn ops_c6x86mx_0f[1024]; -#endif +#endif /* USE_CYRIX_6X86 */ extern const OpFn ops_k6_0f[1024]; extern const OpFn ops_k62_0f[1024]; diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index b72cbc06c..2b4ed1a6d 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -20,7 +20,7 @@ opPREFETCH_a32(uint32_t fetchdat) } static int -opFEMMS(uint32_t fetchdat) +opFEMMS(UNUSED(uint32_t fetchdat)) { ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); if (cr0 & 0xc) { @@ -33,7 +33,7 @@ opFEMMS(uint32_t fetchdat) } static int -opPAVGUSB(uint32_t fetchdat) +opPAVGUSB(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -54,7 +54,7 @@ opPAVGUSB(uint32_t fetchdat) return 0; } static int -opPF2ID(uint32_t fetchdat) +opPF2ID(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -69,7 +69,7 @@ opPF2ID(uint32_t fetchdat) return 0; } static int -opPF2IW(uint32_t fetchdat) +opPF2IW(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -84,7 +84,7 @@ opPF2IW(uint32_t fetchdat) return 0; } static int -opPFACC(uint32_t fetchdat) +opPFACC(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -101,7 +101,7 @@ opPFACC(uint32_t fetchdat) return 0; } static int -opPFNACC(uint32_t fetchdat) +opPFNACC(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -118,7 +118,7 @@ opPFNACC(uint32_t fetchdat) return 0; } static int -opPFPNACC(uint32_t fetchdat) +opPFPNACC(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -135,7 +135,7 @@ opPFPNACC(uint32_t fetchdat) return 0; } static int -opPSWAPD(uint32_t fetchdat) +opPSWAPD(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -155,7 +155,7 @@ opPSWAPD(uint32_t fetchdat) return 0; } static int -opPFADD(uint32_t fetchdat) +opPFADD(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -170,7 +170,7 @@ opPFADD(uint32_t fetchdat) return 0; } static int -opPFCMPEQ(uint32_t fetchdat) +opPFCMPEQ(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -185,7 +185,7 @@ opPFCMPEQ(uint32_t fetchdat) return 0; } static int -opPFCMPGE(uint32_t fetchdat) +opPFCMPGE(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -200,7 +200,7 @@ opPFCMPGE(uint32_t fetchdat) return 0; } static int -opPFCMPGT(uint32_t fetchdat) +opPFCMPGT(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -215,7 +215,7 @@ opPFCMPGT(uint32_t fetchdat) return 0; } static int -opPFMAX(uint32_t fetchdat) +opPFMAX(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -232,7 +232,7 @@ opPFMAX(uint32_t fetchdat) return 0; } static int -opPFMIN(uint32_t fetchdat) +opPFMIN(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -249,7 +249,7 @@ opPFMIN(uint32_t fetchdat) return 0; } static int -opPFMUL(uint32_t fetchdat) +opPFMUL(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -264,7 +264,7 @@ opPFMUL(uint32_t fetchdat) return 0; } static int -opPFRCP(uint32_t fetchdat) +opPFRCP(UNUSED(uint32_t fetchdat)) { MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -293,7 +293,7 @@ opPFRCP(uint32_t fetchdat) } /*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ static int -opPFRCPIT1(uint32_t fetchdat) +opPFRCPIT1(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -308,7 +308,7 @@ opPFRCPIT1(uint32_t fetchdat) return 0; } static int -opPFRCPIT2(uint32_t fetchdat) +opPFRCPIT2(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -323,7 +323,7 @@ opPFRCPIT2(uint32_t fetchdat) return 0; } static int -opPFRSQRT(uint32_t fetchdat) +opPFRSQRT(UNUSED(uint32_t fetchdat)) { MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -352,7 +352,7 @@ opPFRSQRT(uint32_t fetchdat) } /*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ static int -opPFRSQIT1(uint32_t fetchdat) +opPFRSQIT1(UNUSED(uint32_t fetchdat)) { MMX_REG src; @@ -362,7 +362,7 @@ opPFRSQIT1(uint32_t fetchdat) return 0; } static int -opPFSUB(uint32_t fetchdat) +opPFSUB(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -377,7 +377,7 @@ opPFSUB(uint32_t fetchdat) return 0; } static int -opPFSUBR(uint32_t fetchdat) +opPFSUBR(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -392,7 +392,7 @@ opPFSUBR(uint32_t fetchdat) return 0; } static int -opPI2FD(uint32_t fetchdat) +opPI2FD(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -407,7 +407,7 @@ opPI2FD(uint32_t fetchdat) return 0; } static int -opPI2FW(uint32_t fetchdat) +opPI2FW(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); @@ -422,7 +422,7 @@ opPI2FW(uint32_t fetchdat) return 0; } static int -opPMULHRW(uint32_t fetchdat) +opPMULHRW(UNUSED(uint32_t fetchdat)) { MMX_REG src; MMX_REG *dst = MMX_GETREGP(cpu_reg); diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index 9e6bcce55..54da4a79d 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -22,12 +22,8 @@ opSYSCALL(uint32_t fetchdat) ret = syscall_op(fetchdat); - if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); + if (ret <= 1) CPU_BLOCK_END(); - } return ret; } @@ -41,12 +37,8 @@ opSYSRET(uint32_t fetchdat) ret = sysret(fetchdat); - if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); + if (ret <= 1) CPU_BLOCK_END(); - } return ret; } diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index 4e3f74e36..0764877a4 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -313,7 +313,7 @@ return 0; \ } \ \ - static int op##name##_EAX_imm(uint32_t fetchdat) \ + static int op##name##_EAX_imm(UNUSED(uint32_t fetchdat)) \ { \ uint32_t dst = EAX; \ uint32_t src = getlong(); \ @@ -581,7 +581,7 @@ opCMP_AX_imm(uint32_t fetchdat) } static int -opCMP_EAX_imm(uint32_t fetchdat) +opCMP_EAX_imm(UNUSED(uint32_t fetchdat)) { uint32_t src = getlong(); @@ -747,7 +747,7 @@ opTEST_AX(uint32_t fetchdat) return 0; } static int -opTEST_EAX(uint32_t fetchdat) +opTEST_EAX(UNUSED(uint32_t fetchdat)) { uint32_t temp = getlong(); if (cpu_state.abrt) diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index b4779ab3e..a0d18875d 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -1,5 +1,5 @@ static int -opAAA(uint32_t fetchdat) +opAAA(UNUSED(uint32_t fetchdat)) { flags_rebuild(); if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { @@ -24,7 +24,7 @@ opAAD(uint32_t fetchdat) base = 10; AL = (AH * base) + AL; AH = 0; - setznp16(AX); + setznp8(AL); CLOCK_CYCLES((is486) ? 14 : 19); PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0); return 0; @@ -39,14 +39,14 @@ opAAM(uint32_t fetchdat) base = 10; AH = AL / base; AL %= base; - setznp16(AX); + setznp8(AL); CLOCK_CYCLES((is486) ? 15 : 17); PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0); return 0; } static int -opAAS(uint32_t fetchdat) +opAAS(UNUSED(uint32_t fetchdat)) { flags_rebuild(); if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { @@ -63,7 +63,7 @@ opAAS(uint32_t fetchdat) } static int -opDAA(uint32_t fetchdat) +opDAA(UNUSED(uint32_t fetchdat)) { uint16_t tempw; uint16_t old_AL; @@ -100,7 +100,7 @@ opDAA(uint32_t fetchdat) } static int -opDAS(uint32_t fetchdat) +opDAS(UNUSED(uint32_t fetchdat)) { uint16_t tempw; uint16_t old_AL; diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index 9d52a2764..ee54dceff 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -209,7 +209,7 @@ opCALL_far_w(uint32_t fetchdat) return 0; } static int -opCALL_far_l(uint32_t fetchdat) +opCALL_far_l(UNUSED(uint32_t fetchdat)) { uint32_t old_cs; uint32_t old_pc; diff --git a/src/cpu/x86_ops_cyrix.h b/src/cpu/x86_ops_cyrix.h index 672ebd08e..8c3d6e155 100644 --- a/src/cpu/x86_ops_cyrix.h +++ b/src/cpu/x86_ops_cyrix.h @@ -212,7 +212,7 @@ opRSTS_a32(uint32_t fetchdat) } static int -opSMINT(uint32_t fetchdat) +opSMINT(UNUSED(uint32_t fetchdat)) { if (in_smm) fatal("opSMINT\n"); @@ -223,7 +223,7 @@ opSMINT(uint32_t fetchdat) } static int -opRDSHR_a16(uint32_t fetchdat) +opRDSHR_a16(UNUSED(uint32_t fetchdat)) { if (in_smm) fatal("opRDSHR_a16\n"); @@ -233,7 +233,7 @@ opRDSHR_a16(uint32_t fetchdat) return 1; } static int -opRDSHR_a32(uint32_t fetchdat) +opRDSHR_a32(UNUSED(uint32_t fetchdat)) { if (in_smm) fatal("opRDSHR_a32\n"); @@ -244,7 +244,7 @@ opRDSHR_a32(uint32_t fetchdat) } static int -opWRSHR_a16(uint32_t fetchdat) +opWRSHR_a16(UNUSED(uint32_t fetchdat)) { if (in_smm) fatal("opWRSHR_a16\n"); @@ -254,7 +254,7 @@ opWRSHR_a16(uint32_t fetchdat) return 1; } static int -opWRSHR_a32(uint32_t fetchdat) +opWRSHR_a32(UNUSED(uint32_t fetchdat)) { if (in_smm) fatal("opWRSHR_a32\n"); diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 019472aa0..a0fa612a8 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -1,5 +1,5 @@ static int -opCMC(uint32_t fetchdat) +opCMC(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags ^= C_FLAG; @@ -9,7 +9,7 @@ opCMC(uint32_t fetchdat) } static int -opCLC(uint32_t fetchdat) +opCLC(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags &= ~C_FLAG; @@ -18,7 +18,7 @@ opCLC(uint32_t fetchdat) return 0; } static int -opCLD(uint32_t fetchdat) +opCLD(UNUSED(uint32_t fetchdat)) { cpu_state.flags &= ~D_FLAG; CLOCK_CYCLES(2); @@ -26,7 +26,7 @@ opCLD(uint32_t fetchdat) return 0; } static int -opCLI(uint32_t fetchdat) +opCLI(UNUSED(uint32_t fetchdat)) { if (!IOPLp) { if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { @@ -44,7 +44,7 @@ opCLI(uint32_t fetchdat) } static int -opSTC(uint32_t fetchdat) +opSTC(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags |= C_FLAG; @@ -53,7 +53,7 @@ opSTC(uint32_t fetchdat) return 0; } static int -opSTD(uint32_t fetchdat) +opSTD(UNUSED(uint32_t fetchdat)) { cpu_state.flags |= D_FLAG; CLOCK_CYCLES(2); @@ -61,7 +61,7 @@ opSTD(uint32_t fetchdat) return 0; } static int -opSTI(uint32_t fetchdat) +opSTI(UNUSED(uint32_t fetchdat)) { if (!IOPLp) { if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { @@ -87,7 +87,7 @@ opSTI(uint32_t fetchdat) } static int -opSAHF(uint32_t fetchdat) +opSAHF(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; @@ -101,7 +101,7 @@ opSAHF(uint32_t fetchdat) return 0; } static int -opLAHF(uint32_t fetchdat) +opLAHF(UNUSED(uint32_t fetchdat)) { flags_rebuild(); AH = cpu_state.flags & 0xff; @@ -111,7 +111,7 @@ opLAHF(uint32_t fetchdat) } static int -opPUSHF(uint32_t fetchdat) +opPUSHF(UNUSED(uint32_t fetchdat)) { if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { if (cr4 & CR4_VME) { @@ -135,7 +135,7 @@ opPUSHF(uint32_t fetchdat) return cpu_state.abrt; } static int -opPUSHFD(uint32_t fetchdat) +opPUSHFD(UNUSED(uint32_t fetchdat)) { uint16_t tempw; if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { @@ -156,7 +156,7 @@ opPUSHFD(uint32_t fetchdat) } static int -opPOPF_186(uint32_t fetchdat) +opPOPF_186(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -192,7 +192,7 @@ opPOPF_186(uint32_t fetchdat) return 0; } static int -opPOPF_286(uint32_t fetchdat) +opPOPF_286(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -228,7 +228,7 @@ opPOPF_286(uint32_t fetchdat) return 0; } static int -opPOPF(uint32_t fetchdat) +opPOPF(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -284,7 +284,7 @@ opPOPF(uint32_t fetchdat) return 0; } static int -opPOPFD(uint32_t fetchdat) +opPOPFD(UNUSED(uint32_t fetchdat)) { uint32_t templ; diff --git a/src/cpu/x86_ops_flag_2386.h b/src/cpu/x86_ops_flag_2386.h index ba34ae5e7..c9a2d5ab2 100644 --- a/src/cpu/x86_ops_flag_2386.h +++ b/src/cpu/x86_ops_flag_2386.h @@ -1,5 +1,5 @@ static int -opCMC(uint32_t fetchdat) +opCMC(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags ^= C_FLAG; @@ -9,7 +9,7 @@ opCMC(uint32_t fetchdat) } static int -opCLC(uint32_t fetchdat) +opCLC(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags &= ~C_FLAG; @@ -18,7 +18,7 @@ opCLC(uint32_t fetchdat) return 0; } static int -opCLD(uint32_t fetchdat) +opCLD(UNUSED(uint32_t fetchdat)) { cpu_state.flags &= ~D_FLAG; CLOCK_CYCLES(2); @@ -26,7 +26,7 @@ opCLD(uint32_t fetchdat) return 0; } static int -opCLI(uint32_t fetchdat) +opCLI(UNUSED(uint32_t fetchdat)) { if (!IOPLp) { if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { @@ -44,7 +44,7 @@ opCLI(uint32_t fetchdat) } static int -opSTC(uint32_t fetchdat) +opSTC(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags |= C_FLAG; @@ -53,7 +53,7 @@ opSTC(uint32_t fetchdat) return 0; } static int -opSTD(uint32_t fetchdat) +opSTD(UNUSED(uint32_t fetchdat)) { cpu_state.flags |= D_FLAG; CLOCK_CYCLES(2); @@ -61,7 +61,7 @@ opSTD(uint32_t fetchdat) return 0; } static int -opSTI(uint32_t fetchdat) +opSTI(UNUSED(uint32_t fetchdat)) { if (!IOPLp) { if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { @@ -87,7 +87,7 @@ opSTI(uint32_t fetchdat) } static int -opSAHF(uint32_t fetchdat) +opSAHF(UNUSED(uint32_t fetchdat)) { flags_rebuild(); cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; @@ -101,7 +101,7 @@ opSAHF(uint32_t fetchdat) return 0; } static int -opLAHF(uint32_t fetchdat) +opLAHF(UNUSED(uint32_t fetchdat)) { flags_rebuild(); AH = cpu_state.flags & 0xff; @@ -111,7 +111,7 @@ opLAHF(uint32_t fetchdat) } static int -opPUSHF(uint32_t fetchdat) +opPUSHF(UNUSED(uint32_t fetchdat)) { if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { if (cr4 & CR4_VME) { @@ -135,7 +135,7 @@ opPUSHF(uint32_t fetchdat) return cpu_state.abrt; } static int -opPUSHFD(uint32_t fetchdat) +opPUSHFD(UNUSED(uint32_t fetchdat)) { uint16_t tempw; if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { @@ -156,7 +156,7 @@ opPUSHFD(uint32_t fetchdat) } static int -opPOPF_186(uint32_t fetchdat) +opPOPF_186(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -190,7 +190,7 @@ opPOPF_186(uint32_t fetchdat) return 0; } static int -opPOPF_286(uint32_t fetchdat) +opPOPF_286(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -224,7 +224,7 @@ opPOPF_286(uint32_t fetchdat) return 0; } static int -opPOPF(uint32_t fetchdat) +opPOPF(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -278,7 +278,7 @@ opPOPF(uint32_t fetchdat) return 0; } static int -opPOPFD(uint32_t fetchdat) +opPOPFD(UNUSED(uint32_t fetchdat)) { uint32_t templ; diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index 9ea04b447..3434c4a73 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -4,7 +4,6 @@ static int opESCAPE_d8_a16(uint32_t fetchdat) { - //pclog("D8 A16: fetchdat=%02x.\n", (fetchdat >> 3) & 0x1f); return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int @@ -16,7 +15,6 @@ opESCAPE_d8_a32(uint32_t fetchdat) static int opESCAPE_d9_a16(uint32_t fetchdat) { - //pclog("D9 A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } static int @@ -28,7 +26,6 @@ opESCAPE_d9_a32(uint32_t fetchdat) static int opESCAPE_da_a16(uint32_t fetchdat) { - //pclog("DA A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } static int @@ -40,7 +37,6 @@ opESCAPE_da_a32(uint32_t fetchdat) static int opESCAPE_db_a16(uint32_t fetchdat) { - //pclog("DB A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } static int @@ -52,7 +48,6 @@ opESCAPE_db_a32(uint32_t fetchdat) static int opESCAPE_dc_a16(uint32_t fetchdat) { - //pclog("DC A16: fetchdat=%02x.\n", (fetchdat >> 3) & 0x1f); return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int @@ -64,7 +59,6 @@ opESCAPE_dc_a32(uint32_t fetchdat) static int opESCAPE_dd_a16(uint32_t fetchdat) { - //pclog("DD A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } static int @@ -76,7 +70,6 @@ opESCAPE_dd_a32(uint32_t fetchdat) static int opESCAPE_de_a16(uint32_t fetchdat) { - //pclog("DE A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } static int @@ -88,7 +81,6 @@ opESCAPE_de_a32(uint32_t fetchdat) static int opESCAPE_df_a16(uint32_t fetchdat) { - //pclog("DF A16: fetchdat=%02x.\n", fetchdat & 0xff); return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } static int @@ -98,22 +90,20 @@ opESCAPE_df_a32(uint32_t fetchdat) } static int -opWAIT(uint32_t fetchdat) +opWAIT(UNUSED(uint32_t fetchdat)) { if ((cr0 & 0xa) == 0xa) { x86_int(7); return 1; } -#if 0 - if (!cpu_use_dynarec && fpu_softfloat) { -#endif if (fpu_softfloat) { if (fpu_state.swd & FPU_SW_Summary) { - if (cr0 & 0x20) { - x86_int(16); - return 1; - } + if (cr0 & 0x20) + new_ne = 1; + else + picint(1 << 13); + return 1; } } CLOCK_CYCLES(4); diff --git a/src/cpu/x86_ops_fpu_2386.h b/src/cpu/x86_ops_fpu_2386.h index 52c24d995..c2252af12 100644 --- a/src/cpu/x86_ops_fpu_2386.h +++ b/src/cpu/x86_ops_fpu_2386.h @@ -90,22 +90,20 @@ opESCAPE_df_a32(uint32_t fetchdat) } static int -opWAIT(uint32_t fetchdat) +opWAIT(UNUSED(uint32_t fetchdat)) { if ((cr0 & 0xa) == 0xa) { x86_int(7); return 1; } -#if 0 - if (!cpu_use_dynarec && fpu_softfloat) { -#endif if (fpu_softfloat) { if (fpu_state.swd & FPU_SW_Summary) { - if (cr0 & 0x20) { - x86_int(16); - return 1; - } + if (cr0 & 0x20) + new_ne = 1; + else + picint(1 << 13); + return 1; } } CLOCK_CYCLES(4); diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index 5e5dc3c7c..a67571875 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -18,12 +18,8 @@ opSYSENTER(uint32_t fetchdat) { int ret = sysenter(fetchdat); - if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); + if (ret <= 1) CPU_BLOCK_END(); - } return ret; } @@ -33,12 +29,8 @@ opSYSEXIT(uint32_t fetchdat) { int ret = sysexit(fetchdat); - if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); + if (ret <= 1) CPU_BLOCK_END(); - } return ret; } @@ -118,7 +110,8 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward); } - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + // CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES(1); } else { /* FXSAVE */ writememw(easeg, cpu_state.eaaddr, i387_get_control_word()); @@ -163,7 +156,7 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits) writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.signExp); } - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES(1); } return cpu_state.abrt; @@ -327,7 +320,8 @@ fx_save_stor_common(uint32_t fetchdat, int bits) } } - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + // CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES(1); } else { /* FXSAVE */ if ((twd & 0x0003) != 0x0003) @@ -372,7 +366,7 @@ fx_save_stor_common(uint32_t fetchdat, int bits) cpu_state.eaaddr = old_eaaddr; - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES(1); } return cpu_state.abrt; @@ -400,8 +394,7 @@ static int opHINT_NOP_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + CLOCK_CYCLES(1); return 0; } @@ -409,7 +402,6 @@ static int opHINT_NOP_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + CLOCK_CYCLES(1); return 0; } diff --git a/src/cpu/x86_ops_inc_dec.h b/src/cpu/x86_ops_inc_dec.h index 3eb908c57..b33d02f45 100644 --- a/src/cpu/x86_ops_inc_dec.h +++ b/src/cpu/x86_ops_inc_dec.h @@ -1,5 +1,5 @@ #define INC_DEC_OP(name, reg, inc, setflags) \ - static int op##name(uint32_t fetchdat) \ + static int op##name(UNUSED(uint32_t fetchdat)) \ { \ setflags(reg, 1); \ reg += inc; \ diff --git a/src/cpu/x86_ops_int.h b/src/cpu/x86_ops_int.h index a73ed62e0..1ed5e6c2f 100644 --- a/src/cpu/x86_ops_int.h +++ b/src/cpu/x86_ops_int.h @@ -1,5 +1,5 @@ static int -opINT3(uint32_t fetchdat) +opINT3(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -18,7 +18,7 @@ opINT3(uint32_t fetchdat) } static int -opINT1(uint32_t fetchdat) +opINT1(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -75,7 +75,7 @@ opINT(uint32_t fetchdat) } static int -opINTO(uint32_t fetchdat) +opINTO(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); diff --git a/src/cpu/x86_ops_io.h b/src/cpu/x86_ops_io.h index 8a99b8668..36bf05cd3 100644 --- a/src/cpu/x86_ops_io.h +++ b/src/cpu/x86_ops_io.h @@ -75,7 +75,7 @@ opOUT_EAX_imm(uint32_t fetchdat) } static int -opIN_AL_DX(uint32_t fetchdat) +opIN_AL_DX(UNUSED(uint32_t fetchdat)) { check_io_perm(DX, 1); AL = inb(DX); @@ -86,7 +86,7 @@ opIN_AL_DX(uint32_t fetchdat) return 0; } static int -opIN_AX_DX(uint32_t fetchdat) +opIN_AX_DX(UNUSED(uint32_t fetchdat)) { check_io_perm(DX, 2); AX = inw(DX); @@ -97,7 +97,7 @@ opIN_AX_DX(uint32_t fetchdat) return 0; } static int -opIN_EAX_DX(uint32_t fetchdat) +opIN_EAX_DX(UNUSED(uint32_t fetchdat)) { check_io_perm(DX, 4); EAX = inl(DX); @@ -109,7 +109,7 @@ opIN_EAX_DX(uint32_t fetchdat) } static int -opOUT_AL_DX(uint32_t fetchdat) +opOUT_AL_DX(UNUSED(uint32_t fetchdat)) { check_io_perm(DX, 1); outb(DX, AL); @@ -120,7 +120,7 @@ opOUT_AL_DX(uint32_t fetchdat) return x86_was_reset; } static int -opOUT_AX_DX(uint32_t fetchdat) +opOUT_AX_DX(UNUSED(uint32_t fetchdat)) { check_io_perm(DX, 2); outw(DX, AX); @@ -131,7 +131,7 @@ opOUT_AX_DX(uint32_t fetchdat) return 0; } static int -opOUT_EAX_DX(uint32_t fetchdat) +opOUT_EAX_DX(UNUSED(uint32_t fetchdat)) { check_io_perm(DX, 4); outl(DX, EAX); diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 97ca673d7..fc99fc5fd 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -51,7 +51,7 @@ return 0; \ } \ \ - static int opJ##condition##_l(uint32_t fetchdat) \ + static int opJ##condition##_l(UNUSED(uint32_t fetchdat)) \ { \ uint32_t offset = getlong(); \ if (cpu_state.abrt) \ @@ -256,7 +256,7 @@ opJMP_r16(uint32_t fetchdat) return 0; } static int -opJMP_r32(uint32_t fetchdat) +opJMP_r32(UNUSED(uint32_t fetchdat)) { int32_t offset = (int32_t) getlong(); if (cpu_state.abrt) @@ -289,7 +289,7 @@ opJMP_far_a16(uint32_t fetchdat) return 0; } static int -opJMP_far_a32(uint32_t fetchdat) +opJMP_far_a32(UNUSED(uint32_t fetchdat)) { uint16_t seg; uint32_t addr; @@ -323,7 +323,7 @@ opCALL_r16(uint32_t fetchdat) return 0; } static int -opCALL_r32(uint32_t fetchdat) +opCALL_r32(UNUSED(uint32_t fetchdat)) { int32_t addr = getlong(); @@ -339,7 +339,7 @@ opCALL_r32(uint32_t fetchdat) } static int -opRET_w(uint32_t fetchdat) +opRET_w(UNUSED(uint32_t fetchdat)) { uint16_t ret; @@ -355,7 +355,7 @@ opRET_w(uint32_t fetchdat) return 0; } static int -opRET_l(uint32_t fetchdat) +opRET_l(UNUSED(uint32_t fetchdat)) { uint32_t ret; diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 073327c9c..ffc79f0e8 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -1,5 +1,5 @@ static int -opCBW(uint32_t fetchdat) +opCBW(UNUSED(uint32_t fetchdat)) { AH = (AL & 0x80) ? 0xff : 0; CLOCK_CYCLES(3); @@ -7,7 +7,7 @@ opCBW(uint32_t fetchdat) return 0; } static int -opCWDE(uint32_t fetchdat) +opCWDE(UNUSED(uint32_t fetchdat)) { EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; CLOCK_CYCLES(3); @@ -15,7 +15,7 @@ opCWDE(uint32_t fetchdat) return 0; } static int -opCWD(uint32_t fetchdat) +opCWD(UNUSED(uint32_t fetchdat)) { DX = (AX & 0x8000) ? 0xFFFF : 0; CLOCK_CYCLES(2); @@ -23,7 +23,7 @@ opCWD(uint32_t fetchdat) return 0; } static int -opCDQ(uint32_t fetchdat) +opCDQ(UNUSED(uint32_t fetchdat)) { EDX = (EAX & 0x80000000) ? 0xffffffff : 0; CLOCK_CYCLES(2); @@ -32,7 +32,7 @@ opCDQ(uint32_t fetchdat) } static int -opNOP(uint32_t fetchdat) +opNOP(UNUSED(uint32_t fetchdat)) { CLOCK_CYCLES((is486) ? 1 : 3); PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); @@ -40,7 +40,7 @@ opNOP(uint32_t fetchdat) } static int -opSETALC(uint32_t fetchdat) +opSETALC(UNUSED(uint32_t fetchdat)) { AL = (CF_SET()) ? 0xff : 0; CLOCK_CYCLES(timing_rr); @@ -701,7 +701,7 @@ opF7_l_a32(uint32_t fetchdat) } static int -opHLT(uint32_t fetchdat) +opHLT(UNUSED(uint32_t fetchdat)) { if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); @@ -856,7 +856,7 @@ opBOUND_l_a32(uint32_t fetchdat) } static int -opCLTS(uint32_t fetchdat) +opCLTS(UNUSED(uint32_t fetchdat)) { if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { x86gpf(NULL, 0); @@ -869,22 +869,26 @@ opCLTS(uint32_t fetchdat) } static int -opINVD(uint32_t fetchdat) +opINVD(UNUSED(uint32_t fetchdat)) { CLOCK_CYCLES(1000); CPU_BLOCK_END(); return 0; } static int -opWBINVD(uint32_t fetchdat) +opWBINVD(UNUSED(uint32_t fetchdat)) { + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } CLOCK_CYCLES(10000); CPU_BLOCK_END(); return 0; } static int -opLOADALL(uint32_t fetchdat) +opLOADALL(UNUSED(uint32_t fetchdat)) { if (CPL && (cr0 & 1)) { x86gpf(NULL, 0); @@ -994,7 +998,7 @@ loadall_load_segment(uint32_t addr, x86seg *s) } static int -opLOADALL386(uint32_t fetchdat) +opLOADALL386(UNUSED(uint32_t fetchdat)) { uint32_t la_addr = es + EDI; @@ -1042,7 +1046,7 @@ opLOADALL386(uint32_t fetchdat) } static int -opCPUID(uint32_t fetchdat) +opCPUID(UNUSED(uint32_t fetchdat)) { if (CPUID) { cpu_CPUID(); @@ -1055,7 +1059,7 @@ opCPUID(uint32_t fetchdat) } static int -opRDMSR(uint32_t fetchdat) +opRDMSR(UNUSED(uint32_t fetchdat)) { if (cpu_has_feature(CPU_FEATURE_MSR)) { cpu_RDMSR(); @@ -1068,7 +1072,7 @@ opRDMSR(uint32_t fetchdat) } static int -opWRMSR(uint32_t fetchdat) +opWRMSR(UNUSED(uint32_t fetchdat)) { if (cpu_has_feature(CPU_FEATURE_MSR)) { cpu_WRMSR(); @@ -1081,7 +1085,7 @@ opWRMSR(uint32_t fetchdat) } static int -opRSM(uint32_t fetchdat) +opRSM(UNUSED(uint32_t fetchdat)) { if (in_smm) { leave_smm(); diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index ab5e19762..338948af5 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -34,7 +34,7 @@ x87_set_mmx() static int -opEMMS(uint32_t fetchdat) +opEMMS(UNUSED(uint32_t fetchdat)) { if (!cpu_has_feature(CPU_FEATURE_MMX)) { cpu_state.pc = cpu_state.oldpc; diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index c72c8143d..8855f8ccd 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -110,7 +110,7 @@ opMOVD_mm_l_a32(uint32_t fetchdat) return 0; } -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +#ifdef USE_CYRIX_6X86 /*Cyrix maps both MOVD and SMINT to the same opcode*/ static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) @@ -170,7 +170,7 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat) return 0; } -#endif +#endif /* USE_CYRIX_6X86 */ static int opMOVQ_q_mm_a16(uint32_t fetchdat) diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index e77876d5c..787a727d3 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -129,7 +129,7 @@ opMOV_SP_imm(uint32_t fetchdat) } static int -opMOV_EAX_imm(uint32_t fetchdat) +opMOV_EAX_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -140,7 +140,7 @@ opMOV_EAX_imm(uint32_t fetchdat) return 0; } static int -opMOV_EBX_imm(uint32_t fetchdat) +opMOV_EBX_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -151,7 +151,7 @@ opMOV_EBX_imm(uint32_t fetchdat) return 0; } static int -opMOV_ECX_imm(uint32_t fetchdat) +opMOV_ECX_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -162,7 +162,7 @@ opMOV_ECX_imm(uint32_t fetchdat) return 0; } static int -opMOV_EDX_imm(uint32_t fetchdat) +opMOV_EDX_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -173,7 +173,7 @@ opMOV_EDX_imm(uint32_t fetchdat) return 0; } static int -opMOV_ESI_imm(uint32_t fetchdat) +opMOV_ESI_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -184,7 +184,7 @@ opMOV_ESI_imm(uint32_t fetchdat) return 0; } static int -opMOV_EDI_imm(uint32_t fetchdat) +opMOV_EDI_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -195,7 +195,7 @@ opMOV_EDI_imm(uint32_t fetchdat) return 0; } static int -opMOV_EBP_imm(uint32_t fetchdat) +opMOV_EBP_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -206,7 +206,7 @@ opMOV_EBP_imm(uint32_t fetchdat) return 0; } static int -opMOV_ESP_imm(uint32_t fetchdat) +opMOV_ESP_imm(UNUSED(uint32_t fetchdat)) { uint32_t templ = getlong(); if (cpu_state.abrt) @@ -326,7 +326,7 @@ opMOV_AL_a16(uint32_t fetchdat) return 0; } static int -opMOV_AL_a32(uint32_t fetchdat) +opMOV_AL_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; uint32_t addr = getlong(); @@ -356,7 +356,7 @@ opMOV_AX_a16(uint32_t fetchdat) return 0; } static int -opMOV_AX_a32(uint32_t fetchdat) +opMOV_AX_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; uint32_t addr = getlong(); @@ -386,7 +386,7 @@ opMOV_EAX_a16(uint32_t fetchdat) return 0; } static int -opMOV_EAX_a32(uint32_t fetchdat) +opMOV_EAX_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; uint32_t addr = getlong(); @@ -413,7 +413,7 @@ opMOV_a16_AL(uint32_t fetchdat) return cpu_state.abrt; } static int -opMOV_a32_AL(uint32_t fetchdat) +opMOV_a32_AL(UNUSED(uint32_t fetchdat)) { uint32_t addr = getlong(); SEG_CHECK_WRITE(cpu_state.ea_seg); @@ -435,7 +435,7 @@ opMOV_a16_AX(uint32_t fetchdat) return cpu_state.abrt; } static int -opMOV_a32_AX(uint32_t fetchdat) +opMOV_a32_AX(UNUSED(uint32_t fetchdat)) { uint32_t addr = getlong(); if (cpu_state.abrt) @@ -459,7 +459,7 @@ opMOV_a16_EAX(uint32_t fetchdat) return cpu_state.abrt; } static int -opMOV_a32_EAX(uint32_t fetchdat) +opMOV_a32_EAX(UNUSED(uint32_t fetchdat)) { uint32_t addr = getlong(); if (cpu_state.abrt) @@ -515,7 +515,7 @@ opLEA_l_a32(uint32_t fetchdat) } static int -opXLAT_a16(uint32_t fetchdat) +opXLAT_a16(UNUSED(uint32_t fetchdat)) { uint32_t addr = (BX + AL) & 0xFFFF; uint8_t temp; @@ -530,7 +530,7 @@ opXLAT_a16(uint32_t fetchdat) return 0; } static int -opXLAT_a32(uint32_t fetchdat) +opXLAT_a32(UNUSED(uint32_t fetchdat)) { uint32_t addr = EBX + AL; uint8_t temp; diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index bcfed831b..b4f0c498a 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat) switch (cpu_reg) { case 0: cpu_state.regs[cpu_rm].l = cr0; + if (cpu_flush_pending) + cpu_state.regs[cpu_rm].l ^= 0x80000000; if (is486 || isibm486) cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ else { @@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat) switch (cpu_reg) { case 0: cpu_state.regs[cpu_rm].l = cr0; + if (cpu_flush_pending) + cpu_state.regs[cpu_rm].l ^= 0x80000000; if (is486 || isibm486) cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ else { @@ -180,8 +184,16 @@ opMOV_CRx_r_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) flushmmucache(); + else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { + if (is_p6 || cpu_use_dynarec) + flushmmucache(); + else { + flushmmucache_nopc(); + cpu_flush_pending = 1; + } + } /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; @@ -210,7 +222,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) break; case 4: if (cpu_has_feature(CPU_FEATURE_CR4)) { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE)) flushmmucache(); cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; @@ -237,8 +249,16 @@ opMOV_CRx_r_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) flushmmucache(); + else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { + if (is_p6 || cpu_use_dynarec) + flushmmucache(); + else { + flushmmucache_nopc(); + cpu_flush_pending = 1; + } + } /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; @@ -267,7 +287,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) break; case 4: if (cpu_has_feature(CPU_FEATURE_CR4)) { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE)) flushmmucache(); cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; diff --git a/src/cpu/x86_ops_mov_ctrl_2386.h b/src/cpu/x86_ops_mov_ctrl_2386.h index cae6c9957..13e08a145 100644 --- a/src/cpu/x86_ops_mov_ctrl_2386.h +++ b/src/cpu/x86_ops_mov_ctrl_2386.h @@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat) switch (cpu_reg) { case 0: cpu_state.regs[cpu_rm].l = cr0; + if (cpu_flush_pending) + cpu_state.regs[cpu_rm].l ^= 0x80000000; if (is486 || isibm486) cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ else { @@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat) switch (cpu_reg) { case 0: cpu_state.regs[cpu_rm].l = cr0; + if (cpu_flush_pending) + cpu_state.regs[cpu_rm].l ^= 0x80000000; if (is486 || isibm486) cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ else { @@ -176,8 +180,12 @@ opMOV_CRx_r_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) flushmmucache(); + else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { + flushmmucache_nopc(); + cpu_flush_pending = 1; + } /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; @@ -206,7 +214,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat) break; case 4: if (cpu_has_feature(CPU_FEATURE_CR4)) { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE)) flushmmucache(); cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; @@ -233,8 +241,12 @@ opMOV_CRx_r_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); switch (cpu_reg) { case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) + if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG)) flushmmucache(); + else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) { + flushmmucache_nopc(); + cpu_flush_pending = 1; + } /* Make sure CPL = 0 when switching from real mode to protected mode. */ if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) cpu_state.seg_cs.access &= 0x9f; @@ -263,7 +275,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat) break; case 4: if (cpu_has_feature(CPU_FEATURE_CR4)) { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE)) + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE)) flushmmucache(); cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; diff --git a/src/cpu/x86_ops_msr.h b/src/cpu/x86_ops_msr.h index daae01d84..a59cecdd4 100644 --- a/src/cpu/x86_ops_msr.h +++ b/src/cpu/x86_ops_msr.h @@ -1,5 +1,5 @@ static int -opRDTSC(uint32_t fetchdat) +opRDTSC(UNUSED(uint32_t fetchdat)) { if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { cpu_state.pc = cpu_state.oldpc; @@ -21,7 +21,7 @@ opRDTSC(uint32_t fetchdat) } static int -opRDPMC(uint32_t fetchdat) +opRDPMC(UNUSED(uint32_t fetchdat)) { if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) { x86gpf("RDPMC not allowed", 0); diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index 4f32b0e37..81f194f14 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -172,12 +172,12 @@ opLAR(w_a16, fetch_ea_16, 0, 0) return cpu_state.abrt; \ } - opLSL(w_a16, fetch_ea_16, 0, 0) - opLSL(w_a32, fetch_ea_32, 0, 1) - opLSL(l_a16, fetch_ea_16, 1, 0) - opLSL(l_a32, fetch_ea_32, 1, 1) +opLSL(w_a16, fetch_ea_16, 0, 0) +opLSL(w_a32, fetch_ea_32, 0, 1) +opLSL(l_a16, fetch_ea_16, 1, 0) +opLSL(l_a32, fetch_ea_32, 1, 1) - static int op0F00_common(uint32_t fetchdat, int ea32) +static int op0F00_common(uint32_t fetchdat, UNUSED(int ea32)) { int dpl; int valid; @@ -359,7 +359,7 @@ op0F00_a32(uint32_t fetchdat) } static int -op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) +op0F01_common(UNUSED(uint32_t fetchdat), int is32, int is286, UNUSED(int ea32)) { uint32_t base; uint16_t limit; diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index a49db7e81..c75684d31 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -1,5 +1,5 @@ #define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ - static int opREP_INSB_##size(uint32_t fetchdat) \ + static int opREP_INSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -38,7 +38,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_INSW_##size(uint32_t fetchdat) \ + static int opREP_INSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -77,7 +77,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_INSL_##size(uint32_t fetchdat) \ + static int opREP_INSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -117,7 +117,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_OUTSB_##size(uint32_t fetchdat) \ + static int opREP_OUTSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -148,7 +148,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_OUTSW_##size(uint32_t fetchdat) \ + static int opREP_OUTSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -179,7 +179,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_OUTSL_##size(uint32_t fetchdat) \ + static int opREP_OUTSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -211,7 +211,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_MOVSB_##size(uint32_t fetchdat) \ + static int opREP_MOVSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -264,7 +264,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_MOVSW_##size(uint32_t fetchdat) \ + static int opREP_MOVSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -318,7 +318,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_MOVSL_##size(uint32_t fetchdat) \ + static int opREP_MOVSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -373,7 +373,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_STOSB_##size(uint32_t fetchdat) \ + static int opREP_STOSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -405,7 +405,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_STOSW_##size(uint32_t fetchdat) \ + static int opREP_STOSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -437,7 +437,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_STOSL_##size(uint32_t fetchdat) \ + static int opREP_STOSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -470,7 +470,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_LODSB_##size(uint32_t fetchdat) \ + static int opREP_LODSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -502,7 +502,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_LODSW_##size(uint32_t fetchdat) \ + static int opREP_LODSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -534,7 +534,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_LODSL_##size(uint32_t fetchdat) \ + static int opREP_LODSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -570,7 +570,7 @@ #define CHEK_READ(a, b, c) #define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ - static int opREP_CMPSB_##size(uint32_t fetchdat) \ + static int opREP_CMPSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ \ @@ -623,7 +623,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_CMPSW_##size(uint32_t fetchdat) \ + static int opREP_CMPSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ \ @@ -677,7 +677,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_CMPSL_##size(uint32_t fetchdat) \ + static int opREP_CMPSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ \ @@ -732,7 +732,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_SCASB_##size(uint32_t fetchdat) \ + static int opREP_SCASB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -767,7 +767,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_SCASW_##size(uint32_t fetchdat) \ + static int opREP_SCASW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -802,7 +802,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_SCASL_##size(uint32_t fetchdat) \ + static int opREP_SCASL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ diff --git a/src/cpu/x86_ops_rep_2386.h b/src/cpu/x86_ops_rep_2386.h index fe5048340..aa1984f81 100644 --- a/src/cpu/x86_ops_rep_2386.h +++ b/src/cpu/x86_ops_rep_2386.h @@ -1,5 +1,5 @@ #define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ - static int opREP_INSB_##size(uint32_t fetchdat) \ + static int opREP_INSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -38,7 +38,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_INSW_##size(uint32_t fetchdat) \ + static int opREP_INSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -77,7 +77,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_INSL_##size(uint32_t fetchdat) \ + static int opREP_INSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -117,7 +117,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_OUTSB_##size(uint32_t fetchdat) \ + static int opREP_OUTSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -148,7 +148,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_OUTSW_##size(uint32_t fetchdat) \ + static int opREP_OUTSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -179,7 +179,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_OUTSL_##size(uint32_t fetchdat) \ + static int opREP_OUTSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ \ @@ -211,7 +211,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_MOVSB_##size(uint32_t fetchdat) \ + static int opREP_MOVSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -264,7 +264,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_MOVSW_##size(uint32_t fetchdat) \ + static int opREP_MOVSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -318,7 +318,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_MOVSL_##size(uint32_t fetchdat) \ + static int opREP_MOVSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -373,7 +373,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_STOSB_##size(uint32_t fetchdat) \ + static int opREP_STOSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -405,7 +405,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_STOSW_##size(uint32_t fetchdat) \ + static int opREP_STOSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -437,7 +437,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_STOSL_##size(uint32_t fetchdat) \ + static int opREP_STOSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int writes = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -470,7 +470,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_LODSB_##size(uint32_t fetchdat) \ + static int opREP_LODSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -502,7 +502,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_LODSW_##size(uint32_t fetchdat) \ + static int opREP_LODSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -534,7 +534,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_LODSL_##size(uint32_t fetchdat) \ + static int opREP_LODSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -570,7 +570,7 @@ #define CHEK_READ(a, b, c) #define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ - static int opREP_CMPSB_##size(uint32_t fetchdat) \ + static int opREP_CMPSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ \ @@ -619,7 +619,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_CMPSW_##size(uint32_t fetchdat) \ + static int opREP_CMPSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ \ @@ -669,7 +669,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_CMPSL_##size(uint32_t fetchdat) \ + static int opREP_CMPSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ \ @@ -720,7 +720,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_SCASB_##size(uint32_t fetchdat) \ + static int opREP_SCASB_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -755,7 +755,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_SCASW_##size(uint32_t fetchdat) \ + static int opREP_SCASW_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ @@ -790,7 +790,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_SCASL_##size(uint32_t fetchdat) \ + static int opREP_SCASL_##size(UNUSED(uint32_t fetchdat)) \ { \ int reads = 0, total_cycles = 0, tempz; \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ diff --git a/src/cpu/x86_ops_rep_dyn.h b/src/cpu/x86_ops_rep_dyn.h index cf32209cc..bdb721ab0 100644 --- a/src/cpu/x86_ops_rep_dyn.h +++ b/src/cpu/x86_ops_rep_dyn.h @@ -1,5 +1,5 @@ #define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ - static int opREP_INSB_##size(uint32_t fetchdat) \ + static int opREP_INSB_##size(UNUSED(uint32_t fetchdat)) \ { \ addr64 = 0x00000000; \ \ @@ -32,7 +32,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_INSW_##size(uint32_t fetchdat) \ + static int opREP_INSW_##size(UNUSED(uint32_t fetchdat)) \ { \ addr64a[0] = addr64a[1] = 0x00000000; \ \ @@ -65,7 +65,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_INSL_##size(uint32_t fetchdat) \ + static int opREP_INSL_##size(UNUSED(uint32_t fetchdat)) \ { \ addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ \ @@ -99,7 +99,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_OUTSB_##size(uint32_t fetchdat) \ + static int opREP_OUTSB_##size(UNUSED(uint32_t fetchdat)) \ { \ if (CNT_REG > 0) { \ uint8_t temp; \ @@ -124,7 +124,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_OUTSW_##size(uint32_t fetchdat) \ + static int opREP_OUTSW_##size(UNUSED(uint32_t fetchdat)) \ { \ if (CNT_REG > 0) { \ uint16_t temp; \ @@ -149,7 +149,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_OUTSL_##size(uint32_t fetchdat) \ + static int opREP_OUTSL_##size(UNUSED(uint32_t fetchdat)) \ { \ if (CNT_REG > 0) { \ uint32_t temp; \ @@ -175,7 +175,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_MOVSB_##size(uint32_t fetchdat) \ + static int opREP_MOVSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ addr64 = addr64_2 = 0x00000000; \ @@ -223,7 +223,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_MOVSW_##size(uint32_t fetchdat) \ + static int opREP_MOVSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ addr64a[0] = addr64a[1] = 0x00000000; \ @@ -272,7 +272,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_MOVSL_##size(uint32_t fetchdat) \ + static int opREP_MOVSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ @@ -322,7 +322,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_STOSB_##size(uint32_t fetchdat) \ + static int opREP_STOSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ @@ -350,7 +350,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_STOSW_##size(uint32_t fetchdat) \ + static int opREP_STOSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ @@ -378,7 +378,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_STOSL_##size(uint32_t fetchdat) \ + static int opREP_STOSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ @@ -407,7 +407,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_LODSB_##size(uint32_t fetchdat) \ + static int opREP_LODSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ @@ -435,7 +435,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_LODSW_##size(uint32_t fetchdat) \ + static int opREP_LODSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ @@ -463,7 +463,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_LODSL_##size(uint32_t fetchdat) \ + static int opREP_LODSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ if (trap) \ @@ -495,7 +495,7 @@ #define CHEK_READ(a, b, c) #define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ - static int opREP_CMPSB_##size(uint32_t fetchdat) \ + static int opREP_CMPSB_##size(UNUSED(uint32_t fetchdat)) \ { \ int tempz; \ \ @@ -545,7 +545,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_CMPSW_##size(uint32_t fetchdat) \ + static int opREP_CMPSW_##size(UNUSED(uint32_t fetchdat)) \ { \ int tempz; \ \ @@ -596,7 +596,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_CMPSL_##size(uint32_t fetchdat) \ + static int opREP_CMPSL_##size(UNUSED(uint32_t fetchdat)) \ { \ int tempz; \ \ @@ -648,7 +648,7 @@ return cpu_state.abrt; \ } \ \ - static int opREP_SCASB_##size(uint32_t fetchdat) \ + static int opREP_SCASB_##size(UNUSED(uint32_t fetchdat)) \ { \ int tempz; \ int cycles_end = cycles - 1000; \ @@ -680,7 +680,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_SCASW_##size(uint32_t fetchdat) \ + static int opREP_SCASW_##size(UNUSED(uint32_t fetchdat)) \ { \ int tempz; \ int cycles_end = cycles - 1000; \ @@ -712,7 +712,7 @@ } \ return cpu_state.abrt; \ } \ - static int opREP_SCASL_##size(uint32_t fetchdat) \ + static int opREP_SCASL_##size(UNUSED(uint32_t fetchdat)) \ { \ int tempz; \ int cycles_end = cycles - 1000; \ diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index d30d4eb8f..935fb5aa0 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -47,7 +47,7 @@ cycles -= timing_retf_rm; static int -opRETF_a16(uint32_t fetchdat) +opRETF_a16(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -60,7 +60,7 @@ opRETF_a16(uint32_t fetchdat) return 0; } static int -opRETF_a32(uint32_t fetchdat) +opRETF_a32(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -103,7 +103,7 @@ opRETF_a32_imm(uint32_t fetchdat) } static int -opIRET_186(uint32_t fetchdat) +opIRET_186(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -146,7 +146,7 @@ opIRET_186(uint32_t fetchdat) } static int -opIRET_286(uint32_t fetchdat) +opIRET_286(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -189,7 +189,7 @@ opIRET_286(uint32_t fetchdat) } static int -opIRET(uint32_t fetchdat) +opIRET(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -260,7 +260,7 @@ opIRET(uint32_t fetchdat) } static int -opIRETD(uint32_t fetchdat) +opIRETD(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); diff --git a/src/cpu/x86_ops_ret_2386.h b/src/cpu/x86_ops_ret_2386.h index ca85bf2b0..155925dfe 100644 --- a/src/cpu/x86_ops_ret_2386.h +++ b/src/cpu/x86_ops_ret_2386.h @@ -47,7 +47,7 @@ cycles -= timing_retf_rm; static int -opRETF_a16(uint32_t fetchdat) +opRETF_a16(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -60,7 +60,7 @@ opRETF_a16(uint32_t fetchdat) return 0; } static int -opRETF_a32(uint32_t fetchdat) +opRETF_a32(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -103,7 +103,7 @@ opRETF_a32_imm(uint32_t fetchdat) } static int -opIRET_186(uint32_t fetchdat) +opIRET_186(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -144,7 +144,7 @@ opIRET_186(uint32_t fetchdat) } static int -opIRET_286(uint32_t fetchdat) +opIRET_286(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -185,7 +185,7 @@ opIRET_286(uint32_t fetchdat) } static int -opIRET(uint32_t fetchdat) +opIRET(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); @@ -254,7 +254,7 @@ opIRET(uint32_t fetchdat) } static int -opIRETD(uint32_t fetchdat) +opIRETD(UNUSED(uint32_t fetchdat)) { int cycles_old = cycles; UN_USED(cycles_old); diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index fbf603ddb..f5d608fbb 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -1,5 +1,5 @@ #define PUSH_W_OP(reg) \ - static int opPUSH_##reg(uint32_t fetchdat) \ + static int opPUSH_##reg(UNUSED(uint32_t fetchdat)) \ { \ PUSH_W(reg); \ CLOCK_CYCLES((is486) ? 1 : 2); \ @@ -8,7 +8,7 @@ } #define PUSH_L_OP(reg) \ - static int opPUSH_##reg(uint32_t fetchdat) \ + static int opPUSH_##reg(UNUSED(uint32_t fetchdat)) \ { \ PUSH_L(reg); \ CLOCK_CYCLES((is486) ? 1 : 2); \ @@ -17,7 +17,7 @@ } #define POP_W_OP(reg) \ - static int opPOP_##reg(uint32_t fetchdat) \ + static int opPOP_##reg(UNUSED(uint32_t fetchdat)) \ { \ reg = POP_W(); \ CLOCK_CYCLES((is486) ? 1 : 4); \ @@ -26,7 +26,7 @@ } #define POP_L_OP(reg) \ - static int opPOP_##reg(uint32_t fetchdat) \ + static int opPOP_##reg(UNUSED(uint32_t fetchdat)) \ { \ reg = POP_L(); \ CLOCK_CYCLES((is486) ? 1 : 4); \ @@ -71,7 +71,7 @@ POP_L_OP(EBP) POP_L_OP(ESP) static int -opPUSHA_w(uint32_t fetchdat) +opPUSHA_w(UNUSED(uint32_t fetchdat)) { if (stack32) { writememw(ss, ESP - 2, AX); @@ -101,7 +101,7 @@ opPUSHA_w(uint32_t fetchdat) return cpu_state.abrt; } static int -opPUSHA_l(uint32_t fetchdat) +opPUSHA_l(UNUSED(uint32_t fetchdat)) { if (stack32) { writememl(ss, ESP - 4, EAX); @@ -132,7 +132,7 @@ opPUSHA_l(uint32_t fetchdat) } static int -opPOPA_w(uint32_t fetchdat) +opPOPA_w(UNUSED(uint32_t fetchdat)) { if (stack32) { DI = readmemw(ss, ESP); @@ -186,7 +186,7 @@ opPOPA_w(uint32_t fetchdat) return 0; } static int -opPOPA_l(uint32_t fetchdat) +opPOPA_l(UNUSED(uint32_t fetchdat)) { if (stack32) { EDI = readmeml(ss, ESP); @@ -250,7 +250,7 @@ opPUSH_imm_w(uint32_t fetchdat) return cpu_state.abrt; } static int -opPUSH_imm_l(uint32_t fetchdat) +opPUSH_imm_l(UNUSED(uint32_t fetchdat)) { uint32_t val = getlong(); if (cpu_state.abrt) @@ -550,7 +550,7 @@ opENTER_l(uint32_t fetchdat) } static int -opLEAVE_w(uint32_t fetchdat) +opLEAVE_w(UNUSED(uint32_t fetchdat)) { uint32_t tempESP = ESP; uint16_t temp; @@ -568,7 +568,7 @@ opLEAVE_w(uint32_t fetchdat) return 0; } static int -opLEAVE_l(uint32_t fetchdat) +opLEAVE_l(UNUSED(uint32_t fetchdat)) { uint32_t tempESP = ESP; uint32_t temp; @@ -587,14 +587,14 @@ opLEAVE_l(uint32_t fetchdat) } #define PUSH_SEG_OPS(seg) \ - static int opPUSH_##seg##_w(uint32_t fetchdat) \ + static int opPUSH_##seg##_w(UNUSED(uint32_t fetchdat)) \ { \ PUSH_W(seg); \ CLOCK_CYCLES(2); \ PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ return cpu_state.abrt; \ } \ - static int opPUSH_##seg##_l(uint32_t fetchdat) \ + static int opPUSH_##seg##_l(UNUSED(uint32_t fetchdat)) \ { \ PUSH_L(seg); \ CLOCK_CYCLES(2); \ @@ -603,7 +603,7 @@ opLEAVE_l(uint32_t fetchdat) } #define POP_SEG_OPS(seg, realseg) \ - static int opPOP_##seg##_w(uint32_t fetchdat) \ + static int opPOP_##seg##_w(UNUSED(uint32_t fetchdat)) \ { \ uint16_t temp_seg; \ uint32_t temp_esp = ESP; \ @@ -617,7 +617,7 @@ opLEAVE_l(uint32_t fetchdat) PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ return cpu_state.abrt; \ } \ - static int opPOP_##seg##_l(uint32_t fetchdat) \ + static int opPOP_##seg##_l(UNUSED(uint32_t fetchdat)) \ { \ uint32_t temp_seg; \ uint32_t temp_esp = ESP; \ diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 619386fcb..d3a7d89a9 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -1,5 +1,5 @@ static int -opMOVSB_a16(uint32_t fetchdat) +opMOVSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -35,7 +35,7 @@ opMOVSB_a16(uint32_t fetchdat) return 0; } static int -opMOVSB_a32(uint32_t fetchdat) +opMOVSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -71,7 +71,7 @@ opMOVSB_a32(uint32_t fetchdat) } static int -opMOVSW_a16(uint32_t fetchdat) +opMOVSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -107,7 +107,7 @@ opMOVSW_a16(uint32_t fetchdat) return 0; } static int -opMOVSW_a32(uint32_t fetchdat) +opMOVSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -144,7 +144,7 @@ opMOVSW_a32(uint32_t fetchdat) } static int -opMOVSL_a16(uint32_t fetchdat) +opMOVSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -180,7 +180,7 @@ opMOVSL_a16(uint32_t fetchdat) return 0; } static int -opMOVSL_a32(uint32_t fetchdat) +opMOVSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -217,7 +217,7 @@ opMOVSL_a32(uint32_t fetchdat) } static int -opCMPSB_a16(uint32_t fetchdat) +opCMPSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t src; uint8_t dst; @@ -258,7 +258,7 @@ opCMPSB_a16(uint32_t fetchdat) return 0; } static int -opCMPSB_a32(uint32_t fetchdat) +opCMPSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t src; uint8_t dst; @@ -300,7 +300,7 @@ opCMPSB_a32(uint32_t fetchdat) } static int -opCMPSW_a16(uint32_t fetchdat) +opCMPSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t src; uint16_t dst; @@ -342,7 +342,7 @@ opCMPSW_a16(uint32_t fetchdat) return 0; } static int -opCMPSW_a32(uint32_t fetchdat) +opCMPSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t src; uint16_t dst; @@ -385,7 +385,7 @@ opCMPSW_a32(uint32_t fetchdat) } static int -opCMPSL_a16(uint32_t fetchdat) +opCMPSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t src; uint32_t dst; @@ -427,7 +427,7 @@ opCMPSL_a16(uint32_t fetchdat) return 0; } static int -opCMPSL_a32(uint32_t fetchdat) +opCMPSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t src; uint32_t dst; @@ -470,7 +470,7 @@ opCMPSL_a32(uint32_t fetchdat) } static int -opSTOSB_a16(uint32_t fetchdat) +opSTOSB_a16(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, DI, DI); @@ -486,7 +486,7 @@ opSTOSB_a16(uint32_t fetchdat) return 0; } static int -opSTOSB_a32(uint32_t fetchdat) +opSTOSB_a32(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); @@ -503,7 +503,7 @@ opSTOSB_a32(uint32_t fetchdat) } static int -opSTOSW_a16(uint32_t fetchdat) +opSTOSW_a16(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); @@ -519,7 +519,7 @@ opSTOSW_a16(uint32_t fetchdat) return 0; } static int -opSTOSW_a32(uint32_t fetchdat) +opSTOSW_a32(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); @@ -536,7 +536,7 @@ opSTOSW_a32(uint32_t fetchdat) } static int -opSTOSL_a16(uint32_t fetchdat) +opSTOSL_a16(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); @@ -552,7 +552,7 @@ opSTOSL_a16(uint32_t fetchdat) return 0; } static int -opSTOSL_a32(uint32_t fetchdat) +opSTOSL_a32(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); @@ -569,7 +569,7 @@ opSTOSL_a32(uint32_t fetchdat) } static int -opLODSB_a16(uint32_t fetchdat) +opLODSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -588,7 +588,7 @@ opLODSB_a16(uint32_t fetchdat) return 0; } static int -opLODSB_a32(uint32_t fetchdat) +opLODSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -608,7 +608,7 @@ opLODSB_a32(uint32_t fetchdat) } static int -opLODSW_a16(uint32_t fetchdat) +opLODSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -627,7 +627,7 @@ opLODSW_a16(uint32_t fetchdat) return 0; } static int -opLODSW_a32(uint32_t fetchdat) +opLODSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -647,7 +647,7 @@ opLODSW_a32(uint32_t fetchdat) } static int -opLODSL_a16(uint32_t fetchdat) +opLODSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -666,7 +666,7 @@ opLODSL_a16(uint32_t fetchdat) return 0; } static int -opLODSL_a32(uint32_t fetchdat) +opLODSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -686,7 +686,7 @@ opLODSL_a32(uint32_t fetchdat) } static int -opSCASB_a16(uint32_t fetchdat) +opSCASB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -705,7 +705,7 @@ opSCASB_a16(uint32_t fetchdat) return 0; } static int -opSCASB_a32(uint32_t fetchdat) +opSCASB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -725,7 +725,7 @@ opSCASB_a32(uint32_t fetchdat) } static int -opSCASW_a16(uint32_t fetchdat) +opSCASW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -744,7 +744,7 @@ opSCASW_a16(uint32_t fetchdat) return 0; } static int -opSCASW_a32(uint32_t fetchdat) +opSCASW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -764,7 +764,7 @@ opSCASW_a32(uint32_t fetchdat) } static int -opSCASL_a16(uint32_t fetchdat) +opSCASL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -783,7 +783,7 @@ opSCASL_a16(uint32_t fetchdat) return 0; } static int -opSCASL_a32(uint32_t fetchdat) +opSCASL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -803,7 +803,7 @@ opSCASL_a32(uint32_t fetchdat) } static int -opINSB_a16(uint32_t fetchdat) +opINSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -829,7 +829,7 @@ opINSB_a16(uint32_t fetchdat) return 0; } static int -opINSB_a32(uint32_t fetchdat) +opINSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -856,7 +856,7 @@ opINSB_a32(uint32_t fetchdat) } static int -opINSW_a16(uint32_t fetchdat) +opINSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -882,7 +882,7 @@ opINSW_a16(uint32_t fetchdat) return 0; } static int -opINSW_a32(uint32_t fetchdat) +opINSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -909,7 +909,7 @@ opINSW_a32(uint32_t fetchdat) } static int -opINSL_a16(uint32_t fetchdat) +opINSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -935,7 +935,7 @@ opINSL_a16(uint32_t fetchdat) return 0; } static int -opINSL_a32(uint32_t fetchdat) +opINSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -962,7 +962,7 @@ opINSL_a32(uint32_t fetchdat) } static int -opOUTSB_a16(uint32_t fetchdat) +opOUTSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -982,7 +982,7 @@ opOUTSB_a16(uint32_t fetchdat) return 0; } static int -opOUTSB_a32(uint32_t fetchdat) +opOUTSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -1003,7 +1003,7 @@ opOUTSB_a32(uint32_t fetchdat) } static int -opOUTSW_a16(uint32_t fetchdat) +opOUTSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -1023,7 +1023,7 @@ opOUTSW_a16(uint32_t fetchdat) return 0; } static int -opOUTSW_a32(uint32_t fetchdat) +opOUTSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -1044,7 +1044,7 @@ opOUTSW_a32(uint32_t fetchdat) } static int -opOUTSL_a16(uint32_t fetchdat) +opOUTSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -1064,7 +1064,7 @@ opOUTSL_a16(uint32_t fetchdat) return 0; } static int -opOUTSL_a32(uint32_t fetchdat) +opOUTSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; diff --git a/src/cpu/x86_ops_string_2386.h b/src/cpu/x86_ops_string_2386.h index 98875e54f..32d69d4b2 100644 --- a/src/cpu/x86_ops_string_2386.h +++ b/src/cpu/x86_ops_string_2386.h @@ -1,5 +1,5 @@ static int -opMOVSB_a16(uint32_t fetchdat) +opMOVSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -35,7 +35,7 @@ opMOVSB_a16(uint32_t fetchdat) return 0; } static int -opMOVSB_a32(uint32_t fetchdat) +opMOVSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -71,7 +71,7 @@ opMOVSB_a32(uint32_t fetchdat) } static int -opMOVSW_a16(uint32_t fetchdat) +opMOVSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -107,7 +107,7 @@ opMOVSW_a16(uint32_t fetchdat) return 0; } static int -opMOVSW_a32(uint32_t fetchdat) +opMOVSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -144,7 +144,7 @@ opMOVSW_a32(uint32_t fetchdat) } static int -opMOVSL_a16(uint32_t fetchdat) +opMOVSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -180,7 +180,7 @@ opMOVSL_a16(uint32_t fetchdat) return 0; } static int -opMOVSL_a32(uint32_t fetchdat) +opMOVSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -217,7 +217,7 @@ opMOVSL_a32(uint32_t fetchdat) } static int -opCMPSB_a16(uint32_t fetchdat) +opCMPSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t src; uint8_t dst; @@ -254,7 +254,7 @@ opCMPSB_a16(uint32_t fetchdat) return 0; } static int -opCMPSB_a32(uint32_t fetchdat) +opCMPSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t src; uint8_t dst; @@ -292,7 +292,7 @@ opCMPSB_a32(uint32_t fetchdat) } static int -opCMPSW_a16(uint32_t fetchdat) +opCMPSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t src; uint16_t dst; @@ -330,7 +330,7 @@ opCMPSW_a16(uint32_t fetchdat) return 0; } static int -opCMPSW_a32(uint32_t fetchdat) +opCMPSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t src; uint16_t dst; @@ -369,7 +369,7 @@ opCMPSW_a32(uint32_t fetchdat) } static int -opCMPSL_a16(uint32_t fetchdat) +opCMPSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t src; uint32_t dst; @@ -407,7 +407,7 @@ opCMPSL_a16(uint32_t fetchdat) return 0; } static int -opCMPSL_a32(uint32_t fetchdat) +opCMPSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t src; uint32_t dst; @@ -446,7 +446,7 @@ opCMPSL_a32(uint32_t fetchdat) } static int -opSTOSB_a16(uint32_t fetchdat) +opSTOSB_a16(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, DI, DI); @@ -462,7 +462,7 @@ opSTOSB_a16(uint32_t fetchdat) return 0; } static int -opSTOSB_a32(uint32_t fetchdat) +opSTOSB_a32(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); @@ -479,7 +479,7 @@ opSTOSB_a32(uint32_t fetchdat) } static int -opSTOSW_a16(uint32_t fetchdat) +opSTOSW_a16(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); @@ -495,7 +495,7 @@ opSTOSW_a16(uint32_t fetchdat) return 0; } static int -opSTOSW_a32(uint32_t fetchdat) +opSTOSW_a32(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); @@ -512,7 +512,7 @@ opSTOSW_a32(uint32_t fetchdat) } static int -opSTOSL_a16(uint32_t fetchdat) +opSTOSL_a16(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); @@ -528,7 +528,7 @@ opSTOSL_a16(uint32_t fetchdat) return 0; } static int -opSTOSL_a32(uint32_t fetchdat) +opSTOSL_a32(UNUSED(uint32_t fetchdat)) { SEG_CHECK_WRITE(&cpu_state.seg_es); CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); @@ -545,7 +545,7 @@ opSTOSL_a32(uint32_t fetchdat) } static int -opLODSB_a16(uint32_t fetchdat) +opLODSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -564,7 +564,7 @@ opLODSB_a16(uint32_t fetchdat) return 0; } static int -opLODSB_a32(uint32_t fetchdat) +opLODSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -584,7 +584,7 @@ opLODSB_a32(uint32_t fetchdat) } static int -opLODSW_a16(uint32_t fetchdat) +opLODSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -603,7 +603,7 @@ opLODSW_a16(uint32_t fetchdat) return 0; } static int -opLODSW_a32(uint32_t fetchdat) +opLODSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -623,7 +623,7 @@ opLODSW_a32(uint32_t fetchdat) } static int -opLODSL_a16(uint32_t fetchdat) +opLODSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -642,7 +642,7 @@ opLODSL_a16(uint32_t fetchdat) return 0; } static int -opLODSL_a32(uint32_t fetchdat) +opLODSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -662,7 +662,7 @@ opLODSL_a32(uint32_t fetchdat) } static int -opSCASB_a16(uint32_t fetchdat) +opSCASB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -681,7 +681,7 @@ opSCASB_a16(uint32_t fetchdat) return 0; } static int -opSCASB_a32(uint32_t fetchdat) +opSCASB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -701,7 +701,7 @@ opSCASB_a32(uint32_t fetchdat) } static int -opSCASW_a16(uint32_t fetchdat) +opSCASW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -720,7 +720,7 @@ opSCASW_a16(uint32_t fetchdat) return 0; } static int -opSCASW_a32(uint32_t fetchdat) +opSCASW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -740,7 +740,7 @@ opSCASW_a32(uint32_t fetchdat) } static int -opSCASL_a16(uint32_t fetchdat) +opSCASL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -759,7 +759,7 @@ opSCASL_a16(uint32_t fetchdat) return 0; } static int -opSCASL_a32(uint32_t fetchdat) +opSCASL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -779,7 +779,7 @@ opSCASL_a32(uint32_t fetchdat) } static int -opINSB_a16(uint32_t fetchdat) +opINSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -805,7 +805,7 @@ opINSB_a16(uint32_t fetchdat) return 0; } static int -opINSB_a32(uint32_t fetchdat) +opINSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -832,7 +832,7 @@ opINSB_a32(uint32_t fetchdat) } static int -opINSW_a16(uint32_t fetchdat) +opINSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -858,7 +858,7 @@ opINSW_a16(uint32_t fetchdat) return 0; } static int -opINSW_a32(uint32_t fetchdat) +opINSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -885,7 +885,7 @@ opINSW_a32(uint32_t fetchdat) } static int -opINSL_a16(uint32_t fetchdat) +opINSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -911,7 +911,7 @@ opINSL_a16(uint32_t fetchdat) return 0; } static int -opINSL_a32(uint32_t fetchdat) +opINSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -938,7 +938,7 @@ opINSL_a32(uint32_t fetchdat) } static int -opOUTSB_a16(uint32_t fetchdat) +opOUTSB_a16(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -958,7 +958,7 @@ opOUTSB_a16(uint32_t fetchdat) return 0; } static int -opOUTSB_a32(uint32_t fetchdat) +opOUTSB_a32(UNUSED(uint32_t fetchdat)) { uint8_t temp; @@ -979,7 +979,7 @@ opOUTSB_a32(uint32_t fetchdat) } static int -opOUTSW_a16(uint32_t fetchdat) +opOUTSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -999,7 +999,7 @@ opOUTSW_a16(uint32_t fetchdat) return 0; } static int -opOUTSW_a32(uint32_t fetchdat) +opOUTSW_a32(UNUSED(uint32_t fetchdat)) { uint16_t temp; @@ -1020,7 +1020,7 @@ opOUTSW_a32(uint32_t fetchdat) } static int -opOUTSL_a16(uint32_t fetchdat) +opOUTSL_a16(UNUSED(uint32_t fetchdat)) { uint32_t temp; @@ -1040,7 +1040,7 @@ opOUTSL_a16(uint32_t fetchdat) return 0; } static int -opOUTSL_a32(uint32_t fetchdat) +opOUTSL_a32(UNUSED(uint32_t fetchdat)) { uint32_t temp; diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index 70e7be58c..826181a8e 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -116,7 +116,7 @@ opXCHG_l_a32(uint32_t fetchdat) } static int -opXCHG_AX_BX(uint32_t fetchdat) +opXCHG_AX_BX(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = BX; @@ -126,7 +126,7 @@ opXCHG_AX_BX(uint32_t fetchdat) return 0; } static int -opXCHG_AX_CX(uint32_t fetchdat) +opXCHG_AX_CX(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = CX; @@ -136,7 +136,7 @@ opXCHG_AX_CX(uint32_t fetchdat) return 0; } static int -opXCHG_AX_DX(uint32_t fetchdat) +opXCHG_AX_DX(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = DX; @@ -146,7 +146,7 @@ opXCHG_AX_DX(uint32_t fetchdat) return 0; } static int -opXCHG_AX_SI(uint32_t fetchdat) +opXCHG_AX_SI(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = SI; @@ -156,7 +156,7 @@ opXCHG_AX_SI(uint32_t fetchdat) return 0; } static int -opXCHG_AX_DI(uint32_t fetchdat) +opXCHG_AX_DI(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = DI; @@ -166,7 +166,7 @@ opXCHG_AX_DI(uint32_t fetchdat) return 0; } static int -opXCHG_AX_BP(uint32_t fetchdat) +opXCHG_AX_BP(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = BP; @@ -176,7 +176,7 @@ opXCHG_AX_BP(uint32_t fetchdat) return 0; } static int -opXCHG_AX_SP(uint32_t fetchdat) +opXCHG_AX_SP(UNUSED(uint32_t fetchdat)) { uint16_t temp = AX; AX = SP; @@ -187,7 +187,7 @@ opXCHG_AX_SP(uint32_t fetchdat) } static int -opXCHG_EAX_EBX(uint32_t fetchdat) +opXCHG_EAX_EBX(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = EBX; @@ -197,7 +197,7 @@ opXCHG_EAX_EBX(uint32_t fetchdat) return 0; } static int -opXCHG_EAX_ECX(uint32_t fetchdat) +opXCHG_EAX_ECX(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = ECX; @@ -207,7 +207,7 @@ opXCHG_EAX_ECX(uint32_t fetchdat) return 0; } static int -opXCHG_EAX_EDX(uint32_t fetchdat) +opXCHG_EAX_EDX(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = EDX; @@ -217,7 +217,7 @@ opXCHG_EAX_EDX(uint32_t fetchdat) return 0; } static int -opXCHG_EAX_ESI(uint32_t fetchdat) +opXCHG_EAX_ESI(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = ESI; @@ -227,7 +227,7 @@ opXCHG_EAX_ESI(uint32_t fetchdat) return 0; } static int -opXCHG_EAX_EDI(uint32_t fetchdat) +opXCHG_EAX_EDI(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = EDI; @@ -237,7 +237,7 @@ opXCHG_EAX_EDI(uint32_t fetchdat) return 0; } static int -opXCHG_EAX_EBP(uint32_t fetchdat) +opXCHG_EAX_EBP(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = EBP; @@ -247,7 +247,7 @@ opXCHG_EAX_EBP(uint32_t fetchdat) return 0; } static int -opXCHG_EAX_ESP(uint32_t fetchdat) +opXCHG_EAX_ESP(UNUSED(uint32_t fetchdat)) { uint32_t temp = EAX; EAX = ESP; @@ -258,7 +258,7 @@ opXCHG_EAX_ESP(uint32_t fetchdat) } #define opBSWAP(reg) \ - static int opBSWAP_##reg(uint32_t fetchdat) \ + static int opBSWAP_##reg(UNUSED(uint32_t fetchdat)) \ { \ reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ CLOCK_CYCLES(1); \ @@ -275,4 +275,4 @@ opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP) - // clang-format on +// clang-format on diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 61e9e558a..61c0edd9f 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -48,12 +48,12 @@ #define seg_writememwl writememwl_2386 #define seg_writememll writememll_2386 #else -#define seg_readmembl readmembl_2386 -#define seg_readmemwl readmemwl_2386 -#define seg_readmemll readmemll_2386 -#define seg_writemembl writemembl_2386 -#define seg_writememwl writememwl_2386 -#define seg_writememll writememll_2386 +#define seg_readmembl readmembl +#define seg_readmemwl readmemwl +#define seg_readmemll readmemll +#define seg_writemembl writemembl +#define seg_writememwl writememwl +#define seg_writememll writememll #endif #define DPL ((segdat[2] >> 13) & 3) diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 390c06dc2..fecca0772 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -20,6 +20,7 @@ #include "softfloat3e/config.h" #include "softfloat3e/fpu_trans.h" #include "softfloat3e/specialize.h" +#include <86box/plat_unused.h> uint32_t x87_pc_off; uint32_t x87_op_off; @@ -312,7 +313,7 @@ FPU_write_eflags_fpu_compare(int float_relation) } uint16_t -FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) +FPU_exception(UNUSED(uint32_t fetchdat), uint16_t exceptions, int store) { uint16_t status; uint16_t unmasked; @@ -355,7 +356,10 @@ FPU_exception(uint32_t fetchdat, uint16_t exceptions, int store) nmi = 1; } #else - picint(1 << 13); + if (cr0 & 0x20) + new_ne = 1; + else + picint(1 << 13); #endif // FPU_8087 } return unmasked; diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 197e18bfe..4d53725c9 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -228,13 +228,10 @@ FPU_save_regi_tag(extFloat80_t reg, int tag, int stnr) #define FPU_check_pending_exceptions() \ do { \ if (fpu_state.swd & FPU_SW_Summary) { \ - pclog("SW Summary.\n"); \ - if (cr0 & 0x20) { \ - x86_int(16); \ - return 1; \ - } else { \ + if (cr0 & 0x20) \ + new_ne = 1; \ + else \ picint(1 << 13); \ - return 1; \ - } \ + return 1; \ } \ } while (0) diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 6be9d7648..f1362bf76 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -99,7 +99,10 @@ typedef union { dst = src1 / (double) src2; \ else { \ fpu_log("FPU : divide by zero\n"); \ - picint(1 << 13); \ + if (cr0 & 0x20) \ + new_ne = 1; \ + else \ + picint(1 << 13); \ return 1; \ } \ } else \ @@ -539,7 +542,7 @@ op_nofpu_a32(uint32_t fetchdat) #ifdef FPU_8087 static int -FPU_ILLEGAL_a16(uint32_t fetchdat) +FPU_ILLEGAL_a16(UNUSED(uint32_t fetchdat)) { geteaw(); wait(timing_rr, 0); diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 31c26231b..8d0c02167 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -1,5 +1,5 @@ #define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ - static int opFADD##name##_a##a_size(uint32_t fetchdat) \ + static int opFADD##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -18,7 +18,7 @@ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFCOM##name##_a##a_size(uint32_t fetchdat) \ + static int opFCOM##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -27,13 +27,13 @@ load_var = get(); \ if (cpu_state.abrt) \ return 1; \ - cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFCOMP##name##_a##a_size(uint32_t fetchdat) \ + static int opFCOMP##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -42,14 +42,14 @@ load_var = get(); \ if (cpu_state.abrt) \ return 1; \ - cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ + cpu_state.npxs &= ~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_C3); \ cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ x87_pop(); \ CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFDIV##name##_a##a_size(uint32_t fetchdat) \ + static int opFDIV##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -64,7 +64,7 @@ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFDIVR##name##_a##a_size(uint32_t fetchdat) \ + static int opFDIVR##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -79,7 +79,7 @@ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFMUL##name##_a##a_size(uint32_t fetchdat) \ + static int opFMUL##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -94,7 +94,7 @@ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFSUB##name##_a##a_size(uint32_t fetchdat) \ + static int opFSUB##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -109,7 +109,7 @@ CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ return 0; \ } \ - static int opFSUBR##name##_a##a_size(uint32_t fetchdat) \ + static int opFSUBR##name##_a##a_size(UNUSED(uint32_t fetchdat)) \ { \ optype t; \ FP_ENTER(); \ @@ -208,7 +208,7 @@ opFCOMP(uint32_t fetchdat) } static int -opFCOMPP(uint32_t fetchdat) +opFCOMPP(UNUSED(uint32_t fetchdat)) { uint64_t *p, *q; FP_ENTER(); @@ -229,7 +229,7 @@ opFCOMPP(uint32_t fetchdat) } #ifndef FPU_8087 static int -opFUCOMPP(uint32_t fetchdat) +opFUCOMPP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index 0936f325b..d0b31ac85 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -17,7 +17,7 @@ * Copyright 2016-2019 Miran Grca. */ static int -opFILDiw_a16(uint32_t fetchdat) +opFILDiw_a16(UNUSED(uint32_t fetchdat)) { int16_t temp; FP_ENTER(); @@ -50,7 +50,7 @@ opFILDiw_a32(uint32_t fetchdat) #endif static int -opFISTiw_a16(uint32_t fetchdat) +opFISTiw_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -75,7 +75,7 @@ opFISTiw_a32(uint32_t fetchdat) #endif static int -opFISTPiw_a16(uint32_t fetchdat) +opFISTPiw_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -106,7 +106,7 @@ opFISTPiw_a32(uint32_t fetchdat) #endif static int -opFILDiq_a16(uint32_t fetchdat) +opFILDiq_a16(UNUSED(uint32_t fetchdat)) { int64_t temp64; FP_ENTER(); @@ -145,7 +145,7 @@ opFILDiq_a32(uint32_t fetchdat) #endif static int -FBLD_a16(uint32_t fetchdat) +FBLD_a16(UNUSED(uint32_t fetchdat)) { uint16_t load_reg_hi = 0xffff; uint64_t load_reg_lo = BX_CONST64(0xC000000000000000); @@ -228,7 +228,7 @@ FBLD_a32(uint32_t fetchdat) #endif static int -FBSTP_a16(uint32_t fetchdat) +FBSTP_a16(UNUSED(uint32_t fetchdat)) { double dt; double tempd; @@ -296,7 +296,7 @@ FBSTP_a32(uint32_t fetchdat) #endif static int -FISTPiq_a16(uint32_t fetchdat) +FISTPiq_a16(UNUSED(uint32_t fetchdat)) { int64_t temp64; FP_ENTER(); @@ -337,7 +337,7 @@ FISTPiq_a32(uint32_t fetchdat) #endif static int -opFILDil_a16(uint32_t fetchdat) +opFILDil_a16(UNUSED(uint32_t fetchdat)) { int32_t templ; FP_ENTER(); @@ -370,7 +370,7 @@ opFILDil_a32(uint32_t fetchdat) #endif static int -opFISTil_a16(uint32_t fetchdat) +opFISTil_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -395,7 +395,7 @@ opFISTil_a32(uint32_t fetchdat) #endif static int -opFISTPil_a16(uint32_t fetchdat) +opFISTPil_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -426,7 +426,7 @@ opFISTPil_a32(uint32_t fetchdat) #endif static int -opFLDe_a16(uint32_t fetchdat) +opFLDe_a16(UNUSED(uint32_t fetchdat)) { double t; FP_ENTER(); @@ -459,7 +459,7 @@ opFLDe_a32(uint32_t fetchdat) #endif static int -opFSTPe_a16(uint32_t fetchdat) +opFSTPe_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -490,7 +490,7 @@ opFSTPe_a32(uint32_t fetchdat) #endif static int -opFLDd_a16(uint32_t fetchdat) +opFLDd_a16(UNUSED(uint32_t fetchdat)) { x87_td t; FP_ENTER(); @@ -523,7 +523,7 @@ opFLDd_a32(uint32_t fetchdat) #endif static int -opFSTd_a16(uint32_t fetchdat) +opFSTd_a16(UNUSED(uint32_t fetchdat)) { x87_td t; FP_ENTER(); @@ -552,7 +552,7 @@ opFSTd_a32(uint32_t fetchdat) #endif static int -opFSTPd_a16(uint32_t fetchdat) +opFSTPd_a16(UNUSED(uint32_t fetchdat)) { x87_td t; FP_ENTER(); @@ -587,7 +587,7 @@ opFSTPd_a32(uint32_t fetchdat) #endif static int -opFLDs_a16(uint32_t fetchdat) +opFLDs_a16(UNUSED(uint32_t fetchdat)) { x87_ts ts; FP_ENTER(); @@ -620,7 +620,7 @@ opFLDs_a32(uint32_t fetchdat) #endif static int -opFSTs_a16(uint32_t fetchdat) +opFSTs_a16(UNUSED(uint32_t fetchdat)) { x87_ts ts; FP_ENTER(); @@ -649,7 +649,7 @@ opFSTs_a32(uint32_t fetchdat) #endif static int -opFSTPs_a16(uint32_t fetchdat) +opFSTPs_a16(UNUSED(uint32_t fetchdat)) { x87_ts ts; FP_ENTER(); diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 96750468a..c1f09fda9 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -12,7 +12,7 @@ opFI(uint32_t fetchdat) } #else static int -opFSTSW_AX(uint32_t fetchdat) +opFSTSW_AX(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -24,7 +24,7 @@ opFSTSW_AX(uint32_t fetchdat) #endif static int -opFNOP(uint32_t fetchdat) +opFNOP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -34,7 +34,7 @@ opFNOP(uint32_t fetchdat) } static int -opFXTRACT(uint32_t fetchdat) +opFXTRACT(UNUSED(uint32_t fetchdat)) { x87_conv_t test; int64_t exp80; @@ -56,7 +56,7 @@ opFXTRACT(uint32_t fetchdat) } static int -opFCLEX(uint32_t fetchdat) +opFCLEX(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -67,7 +67,7 @@ opFCLEX(uint32_t fetchdat) } static int -opFINIT(uint32_t fetchdat) +opFINIT(UNUSED(uint32_t fetchdat)) { uint64_t *p; FP_ENTER(); @@ -208,7 +208,7 @@ FSTOR(void) return cpu_state.abrt; } static int -opFSTOR_a16(uint32_t fetchdat) +opFSTOR_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -429,7 +429,7 @@ FSAVE(void) return cpu_state.abrt; } static int -opFSAVE_a16(uint32_t fetchdat) +opFSAVE_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -450,7 +450,7 @@ opFSAVE_a32(uint32_t fetchdat) #endif static int -opFSTSW_a16(uint32_t fetchdat) +opFSTSW_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -516,7 +516,7 @@ opFXCH(uint32_t fetchdat) } static int -opFCHS(uint32_t fetchdat) +opFCHS(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -528,7 +528,7 @@ opFCHS(uint32_t fetchdat) } static int -opFABS(uint32_t fetchdat) +opFABS(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -540,7 +540,7 @@ opFABS(uint32_t fetchdat) } static int -opFTST(uint32_t fetchdat) +opFTST(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -555,7 +555,7 @@ opFTST(uint32_t fetchdat) } static int -opFXAM(uint32_t fetchdat) +opFXAM(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -579,7 +579,7 @@ opFXAM(uint32_t fetchdat) } static int -opFLD1(uint32_t fetchdat) +opFLD1(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -590,7 +590,7 @@ opFLD1(uint32_t fetchdat) } static int -opFLDL2T(uint32_t fetchdat) +opFLDL2T(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -601,7 +601,7 @@ opFLDL2T(uint32_t fetchdat) } static int -opFLDL2E(uint32_t fetchdat) +opFLDL2E(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -612,7 +612,7 @@ opFLDL2E(uint32_t fetchdat) } static int -opFLDPI(uint32_t fetchdat) +opFLDPI(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -623,7 +623,7 @@ opFLDPI(uint32_t fetchdat) } static int -opFLDEG2(uint32_t fetchdat) +opFLDEG2(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -634,7 +634,7 @@ opFLDEG2(uint32_t fetchdat) } static int -opFLDLN2(uint32_t fetchdat) +opFLDLN2(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -645,7 +645,7 @@ opFLDLN2(uint32_t fetchdat) } static int -opFLDZ(uint32_t fetchdat) +opFLDZ(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -657,7 +657,7 @@ opFLDZ(uint32_t fetchdat) } static int -opF2XM1(uint32_t fetchdat) +opF2XM1(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -669,7 +669,7 @@ opF2XM1(uint32_t fetchdat) } static int -opFYL2X(uint32_t fetchdat) +opFYL2X(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -682,7 +682,7 @@ opFYL2X(uint32_t fetchdat) } static int -opFYL2XP1(uint32_t fetchdat) +opFYL2XP1(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -695,7 +695,7 @@ opFYL2XP1(uint32_t fetchdat) } static int -opFPTAN(uint32_t fetchdat) +opFPTAN(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -709,7 +709,7 @@ opFPTAN(uint32_t fetchdat) } static int -opFPATAN(uint32_t fetchdat) +opFPATAN(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -722,7 +722,7 @@ opFPATAN(uint32_t fetchdat) } static int -opFDECSTP(uint32_t fetchdat) +opFDECSTP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -737,7 +737,7 @@ opFDECSTP(uint32_t fetchdat) } static int -opFINCSTP(uint32_t fetchdat) +opFINCSTP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -752,7 +752,7 @@ opFINCSTP(uint32_t fetchdat) } static int -opFPREM(uint32_t fetchdat) +opFPREM(UNUSED(uint32_t fetchdat)) { int64_t temp64; FP_ENTER(); @@ -773,7 +773,7 @@ opFPREM(uint32_t fetchdat) } static int -opFPREM1(uint32_t fetchdat) +opFPREM1(UNUSED(uint32_t fetchdat)) { int64_t temp64; FP_ENTER(); @@ -794,7 +794,7 @@ opFPREM1(uint32_t fetchdat) } static int -opFSQRT(uint32_t fetchdat) +opFSQRT(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -807,7 +807,7 @@ opFSQRT(uint32_t fetchdat) #ifndef FPU_8087 static int -opFSINCOS(uint32_t fetchdat) +opFSINCOS(UNUSED(uint32_t fetchdat)) { double td; FP_ENTER(); @@ -824,7 +824,7 @@ opFSINCOS(uint32_t fetchdat) #endif static int -opFRNDINT(uint32_t fetchdat) +opFRNDINT(UNUSED(uint32_t fetchdat)) { double dst0; @@ -839,7 +839,7 @@ opFRNDINT(uint32_t fetchdat) } static int -opFSCALE(uint32_t fetchdat) +opFSCALE(UNUSED(uint32_t fetchdat)) { int64_t temp64; FP_ENTER(); @@ -855,7 +855,7 @@ opFSCALE(uint32_t fetchdat) #ifndef FPU_8087 static int -opFSIN(uint32_t fetchdat) +opFSIN(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -868,7 +868,7 @@ opFSIN(uint32_t fetchdat) } static int -opFCOS(uint32_t fetchdat) +opFCOS(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -909,7 +909,7 @@ FLDENV(void) } static int -opFLDENV_a16(uint32_t fetchdat) +opFLDENV_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -930,7 +930,7 @@ opFLDENV_a32(uint32_t fetchdat) #endif static int -opFLDCW_a16(uint32_t fetchdat) +opFLDCW_a16(UNUSED(uint32_t fetchdat)) { uint16_t tempw; FP_ENTER(); @@ -1011,7 +1011,7 @@ FSTENV(void) } static int -opFSTENV_a16(uint32_t fetchdat) +opFSTENV_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -1032,7 +1032,7 @@ opFSTENV_a32(uint32_t fetchdat) #endif static int -opFSTCW_a16(uint32_t fetchdat) +opFSTCW_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index 31416447e..0d4fee81a 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -235,7 +235,7 @@ fpu_load_environment(void) } static int -sf_FLDCW_a16(uint32_t fetchdat) +sf_FLDCW_a16(UNUSED(uint32_t fetchdat)) { uint16_t tempw; @@ -288,7 +288,7 @@ sf_FLDCW_a32(uint32_t fetchdat) #endif static int -sf_FNSTCW_a16(uint32_t fetchdat) +sf_FNSTCW_a16(UNUSED(uint32_t fetchdat)) { uint16_t cwd = i387_get_control_word(); @@ -317,7 +317,7 @@ sf_FNSTCW_a32(uint32_t fetchdat) #endif static int -sf_FNSTSW_a16(uint32_t fetchdat) +sf_FNSTSW_a16(UNUSED(uint32_t fetchdat)) { uint16_t swd = i387_get_status_word(); @@ -359,7 +359,7 @@ sf_FI(uint32_t fetchdat) } #else static int -sf_FNSTSW_AX(uint32_t fetchdat) +sf_FNSTSW_AX(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -371,7 +371,7 @@ sf_FNSTSW_AX(uint32_t fetchdat) #endif static int -sf_FRSTOR_a16(uint32_t fetchdat) +sf_FRSTOR_a16(UNUSED(uint32_t fetchdat)) { floatx80 tmp; int offset; @@ -414,7 +414,7 @@ sf_FRSTOR_a32(uint32_t fetchdat) #endif static int -sf_FNSAVE_a16(uint32_t fetchdat) +sf_FNSAVE_a16(UNUSED(uint32_t fetchdat)) { floatx80 stn; int offset; @@ -488,7 +488,7 @@ sf_FNSAVE_a32(uint32_t fetchdat) #endif static int -sf_FNCLEX(uint32_t fetchdat) +sf_FNCLEX(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -499,7 +499,7 @@ sf_FNCLEX(uint32_t fetchdat) } static int -sf_FNINIT(uint32_t fetchdat) +sf_FNINIT(UNUSED(uint32_t fetchdat)) { FP_ENTER(); cpu_state.pc++; @@ -525,7 +525,7 @@ sf_FNINIT(uint32_t fetchdat) } static int -sf_FLDENV_a16(uint32_t fetchdat) +sf_FLDENV_a16(UNUSED(uint32_t fetchdat)) { int tag; @@ -572,7 +572,7 @@ sf_FLDENV_a32(uint32_t fetchdat) #endif static int -sf_FNSTENV_a16(uint32_t fetchdat) +sf_FNSTENV_a16(UNUSED(uint32_t fetchdat)) { FP_ENTER(); fetch_ea_16(fetchdat); @@ -605,7 +605,7 @@ sf_FNSTENV_a32(uint32_t fetchdat) #endif static int -sf_FNOP(uint32_t fetchdat) +sf_FNOP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); FPU_check_pending_exceptions(); diff --git a/src/cpu/x87_ops_sf_arith.h b/src/cpu/x87_ops_sf_arith.h index edbd64dcf..c9e25e97c 100644 --- a/src/cpu/x87_ops_sf_arith.h +++ b/src/cpu/x87_ops_sf_arith.h @@ -1,7 +1,7 @@ #define sf_FPU(name, optype, a_size, load_var, rw, use_var, is_nan, cycle_postfix) \ static int sf_FADD##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ + floatx80 a, result; \ struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ @@ -31,7 +31,7 @@ next_ins: } \ static int sf_FDIV##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ + floatx80 a, result; \ struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ @@ -61,7 +61,7 @@ next_ins: } \ static int sf_FDIVR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ + floatx80 a, result; \ struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ @@ -91,7 +91,7 @@ next_ins: } \ static int sf_FMUL##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ + floatx80 a, result; \ struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ @@ -121,7 +121,7 @@ next_ins: } \ static int sf_FSUB##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ + floatx80 a, result; \ struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ @@ -151,7 +151,7 @@ next_ins: } \ static int sf_FSUBR##name##_a##a_size(uint32_t fetchdat) \ { \ - floatx80 a, result; \ + floatx80 a, result; \ struct softfloat_status_t status; \ optype temp; \ FP_ENTER(); \ diff --git a/src/cpu/x87_ops_sf_compare.h b/src/cpu/x87_ops_sf_compare.h index c4a38b375..945ed99d3 100644 --- a/src/cpu/x87_ops_sf_compare.h +++ b/src/cpu/x87_ops_sf_compare.h @@ -460,7 +460,7 @@ sf_FTST(uint32_t fetchdat) } static int -sf_FXAM(uint32_t fetchdat) +sf_FXAM(UNUSED(uint32_t fetchdat)) { floatx80 reg; int sign; diff --git a/src/cpu/x87_ops_sf_misc.h b/src/cpu/x87_ops_sf_misc.h index 0aab2ec08..746e85c6f 100644 --- a/src/cpu/x87_ops_sf_misc.h +++ b/src/cpu/x87_ops_sf_misc.h @@ -81,7 +81,7 @@ sf_FABS(uint32_t fetchdat) } static int -sf_FDECSTP(uint32_t fetchdat) +sf_FDECSTP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); FPU_check_pending_exceptions(); @@ -94,7 +94,7 @@ sf_FDECSTP(uint32_t fetchdat) } static int -sf_FINCSTP(uint32_t fetchdat) +sf_FINCSTP(UNUSED(uint32_t fetchdat)) { FP_ENTER(); FPU_check_pending_exceptions(); diff --git a/src/ddma.c b/src/ddma.c index 7cbe2831e..0ca1bb879 100644 --- a/src/ddma.c +++ b/src/ddma.c @@ -193,7 +193,7 @@ const device_t ddma_device = { .init = ddma_init, .close = ddma_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device.c b/src/device.c index 41f4b74d5..8b2ddf35e 100644 --- a/src/device.c +++ b/src/device.c @@ -19,7 +19,7 @@ * Copyright 2016-2019 Miran Grca. * Copyright 2008-2019 Sarah Walker. * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * 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 @@ -45,6 +45,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/ini.h> @@ -52,8 +53,10 @@ #include <86box/device.h> #include <86box/machine.h> #include <86box/mem.h> +#include <86box/plat.h> #include <86box/rom.h> #include <86box/sound.h> +#include <86box/ui.h> #define DEVICE_MAX 256 /* max # of devices */ @@ -89,22 +92,38 @@ device_init(void) } void -device_set_context(device_context_t *c, const device_t *dev, int inst) +device_set_context(device_context_t *ctx, const device_t *dev, int inst) { - memset(c, 0, sizeof(device_context_t)); - c->dev = dev; - c->instance = inst; + memset(ctx, 0, sizeof(device_context_t)); + ctx->dev = dev; + ctx->instance = inst; if (inst) { - sprintf(c->name, "%s #%i", dev->name, inst); + sprintf(ctx->name, "%s #%i", dev->name, inst); /* If a numbered section is not present, but a non-numbered of the same name is, rename the non-numbered section to numbered. */ - const void *sec = config_find_section(c->name); + const void *sec = config_find_section(ctx->name); void * single_sec = config_find_section((char *) dev->name); if ((sec == NULL) && (single_sec != NULL)) - config_rename_section(single_sec, c->name); + config_rename_section(single_sec, ctx->name); + } else if (!strcmp(dev->name, "PS/2 Mouse")) { + sprintf(ctx->name, "%s", dev->name); + + /* Migrate the old "Standard PS/2 Mouse" section */ + const void *sec = config_find_section(ctx->name); + void * old_sec = config_find_section("Standard PS/2 Mouse"); + if ((sec == NULL) && (old_sec != NULL)) + config_rename_section(old_sec, ctx->name); + } else if (!strcmp(dev->name, "Microsoft RAMCard")) { + sprintf(ctx->name, "%s", dev->name); + + /* Migrate the old "Microsoft RAMCard for IBM PC" section */ + const void *sec = config_find_section(ctx->name); + void * old_sec = config_find_section("Microsoft RAMCard for IBM PC"); + if ((sec == NULL) && (old_sec != NULL)) + config_rename_section(old_sec, ctx->name); } else - sprintf(c->name, "%s", dev->name); + sprintf(ctx->name, "%s", dev->name); } static void @@ -137,7 +156,25 @@ device_add_common(const device_t *dev, void *p, void *params, int inst) { device_t *init_dev = NULL; void *priv = NULL; - int c; + int16_t c; + + /* + IMPORTANT: This is needed to gracefully handle machine + device addition if the relevant device is NULL. + */ + if (dev == NULL) + return NULL; + + if (!device_available(dev)) { + wchar_t temp[512] = { 0 }; + swprintf(temp, sizeof_w(temp), + plat_get_string(STRING_HW_NOT_AVAILABLE_DEVICE), + dev->name); + ui_msgbox_header(MBX_INFO, + plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), + temp); + return ((void *) dev->name); + } if (params != NULL) { init_dev = calloc(1, sizeof(device_t)); @@ -146,7 +183,7 @@ device_add_common(const device_t *dev, void *p, void *params, int inst) } else init_dev = (device_t *) dev; - for (c = 0; c < 256; c++) { + for (c = 0; c < DEVICE_MAX; c++) { if (!inst && (devices[c] == dev)) { device_log("DEVICE: device already exists!\n"); return (NULL); @@ -155,7 +192,8 @@ device_add_common(const device_t *dev, void *p, void *params, int inst) break; } if (c >= DEVICE_MAX) { - fatal("DEVICE: too many devices\n"); + fatal("Attempting to initialize more than the maximum " + "limit of %i devices\n", DEVICE_MAX); return NULL; } @@ -228,6 +266,7 @@ void * device_add_linked(const device_t *dev, void *priv) { void *ret; + device_common_priv = priv; ret = device_add_common(dev, NULL, NULL, 0); device_common_priv = NULL; @@ -295,7 +334,8 @@ device_close_all(void) #endif if (devices[c]->close != NULL) devices[c]->close(device_priv[c]); - devices[c] = device_priv[c] = NULL; + devices[c] = NULL; + device_priv[c] = NULL; } } } @@ -356,7 +396,7 @@ device_available(const device_t *dev) if (dev != NULL) { config = dev->config; if (config != NULL) { - while (config->type != -1) { + while (config->type != CONFIG_END) { if (config->type == CONFIG_BIOS) { int roms_present = 0; @@ -398,7 +438,7 @@ device_get_bios_file(const device_t *dev, const char *internal_name, int file_no if (dev != NULL) { config = dev->config; if (config != NULL) { - while (config->type != -1) { + while (config->type != CONFIG_END) { if (config->type == CONFIG_BIOS) { bios = config->bios; @@ -436,7 +476,7 @@ device_has_config(const device_t *dev) config = dev->config; - while (config->type != -1) { + while (config->type != CONFIG_END) { c++; config++; } @@ -444,28 +484,13 @@ device_has_config(const device_t *dev) return (c > 0) ? 1 : 0; } -int -device_poll(const device_t *dev) -{ - for (uint16_t c = 0; c < DEVICE_MAX; c++) { - if (devices[c] != NULL) { - if (devices[c] == dev) { - if (devices[c]->poll) - return (devices[c]->poll(device_priv[c])); - } - } - } - - return 0; -} - void device_get_name(const device_t *dev, int bus, char *name) { const char *sbus = NULL; const char *fbus; char *tname; - char pbus[8] = { 0 }; + char pbus[12] = { 0 }; if (dev == NULL) return; @@ -473,18 +498,45 @@ device_get_name(const device_t *dev, int bus, char *name) name[0] = 0x00; if (bus) { - if (dev->flags & DEVICE_ISA) - sbus = (dev->flags & DEVICE_AT) ? "ISA16" : "ISA"; + if ((dev->flags & (DEVICE_SIDECAR | DEVICE_ISA)) == + (DEVICE_SIDECAR | DEVICE_ISA)) + sbus = "ISA/Sidecar"; + else if (dev->flags & DEVICE_SIDECAR) + sbus = "Sidecar"; + else if (dev->flags & DEVICE_XT_KBC) + sbus = "XT KBC"; + else if (dev->flags & DEVICE_ISA16) + sbus = "ISA16"; + else if (dev->flags & DEVICE_AT_KBC) + sbus = "AT KBC"; + else if (dev->flags & DEVICE_PS2_KBC) + sbus = "PS/2 KBC"; + else if (dev->flags & DEVICE_ISA) + sbus = "ISA"; else if (dev->flags & DEVICE_CBUS) sbus = "C-BUS"; + else if (dev->flags & DEVICE_PCMCIA) + sbus = "PCMCIA"; else if (dev->flags & DEVICE_MCA) sbus = "MCA"; + else if (dev->flags & DEVICE_MCA32) + sbus = "MCA32"; + else if (dev->flags & DEVICE_HIL) + sbus = "HP HIL"; else if (dev->flags & DEVICE_EISA) sbus = "EISA"; + else if (dev->flags & DEVICE_AT32) + sbus = "AT/32"; + else if (dev->flags & DEVICE_OLB) + sbus = "OLB"; else if (dev->flags & DEVICE_VLB) sbus = "VLB"; else if (dev->flags & DEVICE_PCI) sbus = "PCI"; + else if (dev->flags & DEVICE_CARDBUS) + sbus = "CardBus"; + else if (dev->flags & DEVICE_USB) + sbus = "USB"; else if (dev->flags & DEVICE_AGP) sbus = "AGP"; else if (dev->flags & DEVICE_AC97) @@ -515,8 +567,7 @@ device_get_name(const device_t *dev, int bus, char *name) strcat(pbus, ")"); /* Allocate the temporary device name string and set it to all zeroes. */ - tname = (char *) malloc(strlen(dev->name) + 1); - memset(tname, 0x00, strlen(dev->name) + 1); + tname = (char *) calloc(1, strlen(dev->name) + 1); /* First strip the bus string with parentheses. */ fbus = strstr(dev->name, pbus); @@ -584,259 +635,220 @@ device_get_instance(void) } const char * -device_get_config_string(const char *s) +device_get_config_string(const char *str) { - const device_config_t *c = device_current.dev->config; + const char *ret = ""; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_string((char *) device_current.name, (char *) s, (char *) c->default_string)); + if (device_current.dev != NULL) { + const device_config_t *cfg = device_current.dev->config; - c++; + while ((cfg != NULL) && (cfg->type != CONFIG_END)) { + if (!strcmp(str, cfg->name)) { + const char *s = (config_get_string((char *) device_current.name, + (char *) str, (char *) cfg->default_string)); + ret = (s == NULL) ? "" : s; + break; + } + + cfg++; + } } - return (NULL); + return ret; } int -device_get_config_int(const char *s) +device_get_config_int(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_int((char *) device_current.name, (char *) s, c->default_int)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_int((char *) device_current.name, (char *) str, cfg->default_int)); - c++; + cfg++; } return 0; } int -device_get_config_int_ex(const char *s, int def) +device_get_config_int_ex(const char *str, int def) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_int((char *) device_current.name, (char *) s, def)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_int((char *) device_current.name, (char *) str, def)); - c++; + cfg++; } return def; } int -device_get_config_hex16(const char *s) +device_get_config_hex16(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_hex16((char *) device_current.name, (char *) s, c->default_int)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_hex16((char *) device_current.name, (char *) str, cfg->default_int)); - c++; + cfg++; } return 0; } int -device_get_config_hex20(const char *s) +device_get_config_hex20(const char *str) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_hex20((char *) device_current.name, (char *) s, c->default_int)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_hex20((char *) device_current.name, (char *) str, cfg->default_int)); - c++; + cfg++; } return 0; } int -device_get_config_mac(const char *s, int def) +device_get_config_mac(const char *str, int def) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_mac((char *) device_current.name, (char *) s, def)); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_mac((char *) device_current.name, (char *) str, def)); - c++; + cfg++; } return def; } void -device_set_config_int(const char *s, int val) +device_set_config_int(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_int((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_int((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } void -device_set_config_hex16(const char *s, int val) +device_set_config_hex16(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_hex16((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_hex16((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } void -device_set_config_hex20(const char *s, int val) +device_set_config_hex20(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_hex20((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_hex20((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } void -device_set_config_mac(const char *s, int val) +device_set_config_mac(const char *str, int val) { - const device_config_t *c = device_current.dev->config; + const device_config_t *cfg = device_current.dev->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) { - config_set_mac((char *) device_current.name, (char *) s, val); + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) { + config_set_mac((char *) device_current.name, (char *) str, val); break; } - c++; + cfg++; } } int -device_is_valid(const device_t *device, int m) +device_is_valid(const device_t *device, int mch) { - if (device == NULL) - return 1; + int ret = 1; - if ((device->flags & DEVICE_PCJR) && !machine_has_bus(m, MACHINE_BUS_PCJR)) - return 0; + if ((device != NULL) && ((device->flags & DEVICE_BUS) != 0)) + ret = machine_has_bus(mch, device->flags & DEVICE_BUS); - if ((device->flags & DEVICE_XTKBC) && machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC)) - return 0; - - if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16)) - return 0; - - if ((device->flags & DEVICE_ATKBC) && !machine_has_bus(m, MACHINE_BUS_ISA16) && !machine_has_bus(m, MACHINE_BUS_DM_KBC)) - return 0; - - if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA)) - return 0; - - if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS)) - return 0; - - if ((device->flags & DEVICE_PCMCIA) && !machine_has_bus(m, MACHINE_BUS_PCMCIA)) - return 0; - - if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA)) - return 0; - - if ((device->flags & DEVICE_HIL) && !machine_has_bus(m, MACHINE_BUS_HIL)) - return 0; - - if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA)) - return 0; - - if ((device->flags & DEVICE_OLB) && !machine_has_bus(m, MACHINE_BUS_OLB)) - return 0; - - if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB)) - return 0; - - if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI)) - return 0; - - if ((device->flags & DEVICE_CARDBUS) && !machine_has_bus(m, MACHINE_BUS_CARDBUS)) - return 0; - - if ((device->flags & DEVICE_USB) && !machine_has_bus(m, MACHINE_BUS_USB)) - return 0; - - if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP)) - return 0; - - if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2_PORTS)) - return 0; - - if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97)) - return 0; - - return 1; + return ret; } int -machine_get_config_int(char *s) +machine_get_config_int(char *str) { - const device_t *d = machine_get_device(machine); - const device_config_t *c; + const device_t *dev = machine_get_device(machine); + const device_config_t *cfg; - if (d == NULL) + if (dev == NULL) return 0; - c = d->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_int((char *) d->name, s, c->default_int)); + cfg = dev->config; + while (cfg && cfg->type != CONFIG_END) { + if (!strcmp(str, cfg->name)) + return (config_get_int((char *) dev->name, str, cfg->default_int)); - c++; + cfg++; } return 0; } -char * -machine_get_config_string(char *s) +const char * +machine_get_config_string(char *str) { - const device_t *d = machine_get_device(machine); - const device_config_t *c; + const device_t *dev = machine_get_device(machine); + const char *ret = ""; - if (d == NULL) - return 0; + if (dev != NULL) { + const device_config_t *cfg; - c = d->config; - while (c && c->type != -1) { - if (!strcmp(s, c->name)) - return (config_get_string((char *) d->name, s, (char *) c->default_string)); + cfg = dev->config; + while ((cfg != NULL) && (cfg->type != CONFIG_END)) { + if (!strcmp(str, cfg->name)) { + const char *s = config_get_string((char *) dev->name, str, + (char *) cfg->default_string); + ret = (s == NULL) ? "" : s; + break; + } - c++; + cfg++; + } } - return NULL; + return ret; } -const device_t* +const device_t * device_context_get_device(void) { return device_current.dev; @@ -850,7 +862,7 @@ const device_t device_none = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -864,7 +876,7 @@ const device_t device_internal = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index e48f30d0f..bbbab22fd 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -9,24 +9,56 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. # Copyright 2021 Andreas J. Reichel. -# Copyright 2021-2022 Jasmine Iwanek. +# Copyright 2021-2025 Jasmine Iwanek. # -add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c - hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c - postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c - smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c - kbc_at.c kbc_at_dev.c +add_library(dev OBJECT + access_bus.c + bugger.c + cartridge.c + cassette.c + clock_ics9xxx.c + hasp.c + hwm.c + hwm_gl518sm.c + hwm_lm75.c + hwm_lm78.c + hwm_vt82c686.c + i2c.c + i2c_gpio.c + ibm_5161.c + isamem.c + isartc.c + isapnp.c + kbc_at.c + kbc_at_dev.c + keyboard.c keyboard_at.c - mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c - serial_passthrough.c + keyboard_xt.c + ../lpt.c + mouse.c + mouse_bus.c + mouse_microtouch_touchscreen.c + mouse_ps2.c + mouse_serial.c + nec_mate_unk.c novell_cardkey.c - mouse_microtouch_touchscreen.c) + pci_bridge.c + phoenix_486_jumper.c + postcard.c + serial.c + serial_passthrough.c + smbus_ali7101.c + smbus_piix4.c + smbus_sis5595.c + unittester.c +) -if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") +if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT MSVC) target_link_libraries(86Box atomic) endif() @@ -45,3 +77,12 @@ endif() if(LASERXT) target_compile_definitions(dev PRIVATE USE_LASERXT) endif() + +if(PCL) + target_compile_definitions(dev PRIVATE USE_PCL) +endif() + +if(WACOM) + target_compile_definitions(dev PRIVATE USE_WACOM) + target_sources(dev PRIVATE mouse_wacom_tablet.c) +endif() diff --git a/src/device/access_bus.c b/src/device/access_bus.c new file mode 100644 index 000000000..951454e19 --- /dev/null +++ b/src/device/access_bus.c @@ -0,0 +1,122 @@ +/* + * 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 ACCESS.bus. + * + * Authors: Miran Grca, + * + * Copyright 2024-2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/access_bus.h> +#include <86box/plat_unused.h> + +static uint8_t +access_bus_in(uint16_t port, void *priv) +{ + const access_bus_t *dev = (access_bus_t *) priv; + uint8_t ret = 0xff; + + switch (port & 3) { + case 0: + ret = (dev->status & 0xbf); + break; + case 1: + ret = (dev->own_addr & 0x7f); + break; + case 2: + ret = dev->data; + break; + case 3: + ret = (dev->clock & 0x87); + break; + + default: + break; + } + + return ret; +} + +static void +access_bus_out(uint16_t port, uint8_t val, void *priv) +{ + access_bus_t *dev = (access_bus_t *) priv; + + switch (port & 3) { + case 0: + dev->control = (val & 0xcf); + break; + case 1: + dev->own_addr = (val & 0x7f); + break; + case 2: + dev->data = val; + break; + case 3: + dev->clock &= 0x80; + dev->clock |= (val & 0x07); + break; + + default: + break; + } +} + +void +access_bus_handler(access_bus_t *dev, uint8_t enable, uint16_t base) +{ + if (dev->enable && (dev->base >= 0x0100) && (dev->base <= 0x0ffc)) + io_removehandler(dev->base, 0x0004, + access_bus_in, NULL, NULL, access_bus_out, NULL, NULL, dev); + + dev->enable = enable; + dev->base = base; + + if (dev->enable && (dev->base >= 0x0100) && (dev->base <= 0x0ffc)) + io_sethandler(dev->base, 0x0004, + access_bus_in, NULL, NULL, access_bus_out, NULL, NULL, dev); +} + + +static void +access_bus_close(void *priv) +{ + access_bus_t *dev = (access_bus_t *) priv; + + free(dev); +} + +static void * +access_bus_init(UNUSED(const device_t *info)) +{ + access_bus_t *dev = (access_bus_t *) calloc(1, sizeof(access_bus_t)); + + return dev; +} + +const device_t access_bus_device = { + .name = "ACCESS.bus", + .internal_name = "access_bus", + .flags = 0, + .local = 0, + .init = access_bus_init, + .close = access_bus_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/device/bugger.c b/src/device/bugger.c index c2678d66a..b56937a43 100644 --- a/src/device/bugger.c +++ b/src/device/bugger.c @@ -346,12 +346,12 @@ bug_close(UNUSED(void *priv)) const device_t bugger_device = { .name = "ISA/PCI Bus Bugger", .internal_name = "bugger", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = bug_init, .close = bug_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/cartridge.c b/src/device/cartridge.c index edabd3ed0..d2e91ecb3 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -35,6 +35,7 @@ typedef struct cart_t { } cart_t; char cart_fns[2][512]; +char *cart_image_history[2][CART_IMAGE_HISTORY]; static cart_t carts[2]; @@ -103,6 +104,7 @@ cart_image_load(int drive, char *fn) if (size < 0x1200) { cartridge_log("cart_image_load(): File size %i is too small\n", size); cart_load_error(drive, fn); + fclose(fp); return; } if (size & 0x00000fff) { @@ -111,8 +113,7 @@ cart_image_load(int drive, char *fn) (void) !fread(&base, 1, 2, fp); base <<= 4; fseek(fp, 0x00000200, SEEK_SET); - carts[drive].buf = (uint8_t *) malloc(size); - memset(carts[drive].buf, 0x00, size); + carts[drive].buf = (uint8_t *) calloc(1, size); (void) !fread(carts[drive].buf, 1, size, fp); fclose(fp); } else { @@ -120,8 +121,7 @@ cart_image_load(int drive, char *fn) if (size == 32768) base += 0x8000; fseek(fp, 0x00000000, SEEK_SET); - carts[drive].buf = (uint8_t *) malloc(size); - memset(carts[drive].buf, 0x00, size); + carts[drive].buf = (uint8_t *) calloc(1, size); (void) !fread(carts[drive].buf, 1, size, fp); fclose(fp); } @@ -169,6 +169,7 @@ cart_close(int drive) cart_image_close(drive); cart_fns[drive][0] = 0; ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1); + resetx86(); } void diff --git a/src/device/cassette.c b/src/device/cassette.c index 1d0b88531..ac79edff2 100644 --- a/src/device/cassette.c +++ b/src/device/cassette.c @@ -45,6 +45,7 @@ pc_cassette_t *cassette; char cassette_fname[512]; char cassette_mode[512]; +char * cassette_image_history[CASSETTE_IMAGE_HISTORY]; unsigned long cassette_pos; unsigned long cassette_srate; int cassette_enable; @@ -130,9 +131,7 @@ pc_cas_free(pc_cassette_t *cas) pc_cassette_t * pc_cas_new(void) { - pc_cassette_t *cas; - - cas = malloc(sizeof(pc_cassette_t)); + pc_cassette_t *cas = calloc(1, sizeof( pc_cassette_t)); if (cas == NULL) { return (NULL); @@ -721,7 +720,7 @@ const device_t cassette_device = { .init = cassette_init, .close = cassette_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/clock_ics9xxx.c b/src/device/clock_ics9xxx.c index 263170741..02f033e9b 100644 --- a/src/device/clock_ics9xxx.c +++ b/src/device/clock_ics9xxx.c @@ -1181,8 +1181,7 @@ ics9xxx_find_bus_match(ics9xxx_t *dev, uint32_t bus, uint8_t preset_mask, uint8_ static void * ics9xxx_init(const device_t *info) { - ics9xxx_t *dev = (ics9xxx_t *) malloc(sizeof(ics9xxx_t)); - memset(dev, 0, sizeof(ics9xxx_t)); + ics9xxx_t *dev = (ics9xxx_t *) calloc(1, sizeof(ics9xxx_t)); dev->model_idx = info->local; dev->model = (ics9xxx_model_t *) &ics9xxx_models[dev->model_idx]; @@ -1267,8 +1266,7 @@ ics9xxx_close(void *priv) device_t * ics9xxx_get(uint8_t model) { - device_t *dev = (device_t *) malloc(sizeof(device_t)); - memset(dev, 0, sizeof(device_t)); + device_t *dev = (device_t *) calloc(1, sizeof(device_t)); dev->name = "ICS9xxx-xx Clock Generator"; dev->local = model; diff --git a/src/device/hasp.c b/src/device/hasp.c index 9873c3460..3834af4cd 100644 --- a/src/device/hasp.c +++ b/src/device/hasp.c @@ -305,8 +305,7 @@ hasp_read_status(void *priv) static void * hasp_init(void *lpt, int type) { - hasp_t *dev = malloc(sizeof(hasp_t)); - memset(dev, 0, sizeof(hasp_t)); + hasp_t *dev = calloc(1, sizeof(hasp_t)); hasp_log("HASP: init(%d)\n", type); diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index 6ba1083d9..cfc16664a 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -282,8 +282,7 @@ gl518sm_close(void *priv) static void * gl518sm_init(const device_t *info) { - gl518sm_t *dev = (gl518sm_t *) malloc(sizeof(gl518sm_t)); - memset(dev, 0, sizeof(gl518sm_t)); + gl518sm_t *dev = (gl518sm_t *) calloc(1, sizeof(gl518sm_t)); dev->local = info->local; @@ -325,7 +324,7 @@ const device_t gl518sm_2c_device = { .init = gl518sm_init, .close = gl518sm_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -340,7 +339,7 @@ const device_t gl518sm_2d_device = { .init = gl518sm_init, .close = gl518sm_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -355,7 +354,7 @@ const device_t gl520sm_2c_device = { .init = gl518sm_init, .close = gl518sm_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -371,7 +370,7 @@ const device_t gl520sm_2d_device = { .init = gl518sm_init, .close = gl518sm_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/hwm_lm75.c b/src/device/hwm_lm75.c index 14b638365..29fe2024f 100644 --- a/src/device/hwm_lm75.c +++ b/src/device/hwm_lm75.c @@ -216,8 +216,7 @@ lm75_close(void *priv) static void * lm75_init(const device_t *info) { - lm75_t *dev = (lm75_t *) malloc(sizeof(lm75_t)); - memset(dev, 0, sizeof(lm75_t)); + lm75_t *dev = (lm75_t *) calloc(1, sizeof(lm75_t)); dev->local = info->local; @@ -243,7 +242,7 @@ const device_t lm75_1_4a_device = { .init = lm75_init, .close = lm75_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -259,7 +258,7 @@ const device_t lm75_w83781d_device = { .init = lm75_init, .close = lm75_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index f3003db26..909713833 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -102,9 +102,9 @@ lm78_log(const char *fmt, ...) void lm78_nvram(lm78_t *dev, uint8_t save) { - size_t l = strlen(machine_get_internal_name_ex(machine)) + 14; + size_t l = strlen(machine_get_nvr_name_ex(machine)) + 14; char *nvr_path = (char *) malloc(l); - sprintf(nvr_path, "%s_as99127f.nvr", machine_get_internal_name_ex(machine)); + sprintf(nvr_path, "%s_as99127f.nvr", machine_get_nvr_name_ex(machine)); FILE *fp = nvr_fopen(nvr_path, save ? "wb" : "rb"); if (fp) { @@ -771,8 +771,7 @@ lm78_close(void *priv) static void * lm78_init(const device_t *info) { - lm78_t *dev = (lm78_t *) malloc(sizeof(lm78_t)); - memset(dev, 0, sizeof(lm78_t)); + lm78_t *dev = (lm78_t *) calloc(1, sizeof(lm78_t)); dev->local = info->local; @@ -857,7 +856,7 @@ const device_t lm78_device = { .init = lm78_init, .close = lm78_close, .reset = lm78_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -872,7 +871,7 @@ const device_t w83781d_device = { .init = lm78_init, .close = lm78_close, .reset = lm78_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -887,7 +886,7 @@ const device_t w83781d_p5a_device = { .init = lm78_init, .close = lm78_close, .reset = lm78_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -903,7 +902,7 @@ const device_t as99127f_device = { .init = lm78_init, .close = lm78_close, .reset = lm78_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -918,7 +917,7 @@ const device_t as99127f_rev2_device = { .init = lm78_init, .close = lm78_close, .reset = lm78_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -933,7 +932,7 @@ const device_t w83782d_device = { .init = lm78_init, .close = lm78_close, .reset = lm78_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/hwm_vt82c686.c b/src/device/hwm_vt82c686.c index b6a0dddda..8623a9f6b 100644 --- a/src/device/hwm_vt82c686.c +++ b/src/device/hwm_vt82c686.c @@ -183,8 +183,7 @@ vt82c686_close(void *priv) static void * vt82c686_init(UNUSED(const device_t *info)) { - vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); - memset(dev, 0, sizeof(vt82c686_t)); + vt82c686_t *dev = (vt82c686_t *) calloc(1, sizeof(vt82c686_t)); /* Set default values. Since this hardware monitor has a complex voltage factor system, the values struct contains voltage values *before* applying their respective factors. */ @@ -222,7 +221,7 @@ const device_t via_vt82c686_hwm_device = { .init = vt82c686_init, .close = vt82c686_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/i2c.c b/src/device/i2c.c index 56e6f8f4c..eb80f413b 100644 --- a/src/device/i2c.c +++ b/src/device/i2c.c @@ -67,8 +67,7 @@ i2c_log(const char *fmt, ...) void * i2c_addbus(char *name) { - i2c_bus_t *bus = (i2c_bus_t *) malloc(sizeof(i2c_bus_t)); - memset(bus, 0, sizeof(i2c_bus_t)); + i2c_bus_t *bus = (i2c_bus_t *) calloc(1, sizeof(i2c_bus_t)); bus->name = name; @@ -127,8 +126,7 @@ i2c_sethandler(void *bus_handle, uint8_t base, int size, for (int c = 0; c < size; c++) { p = bus->last[base + c]; - q = (i2c_t *) malloc(sizeof(i2c_t)); - memset(q, 0, sizeof(i2c_t)); + q = (i2c_t *) calloc(1, sizeof(i2c_t)); if (p) { p->next = q; q->prev = p; diff --git a/src/device/i2c_gpio.c b/src/device/i2c_gpio.c index 22bdaffd3..61a3dbe05 100644 --- a/src/device/i2c_gpio.c +++ b/src/device/i2c_gpio.c @@ -59,8 +59,7 @@ i2c_gpio_log(int level, const char *fmt, ...) void * i2c_gpio_init(char *bus_name) { - i2c_gpio_t *dev = (i2c_gpio_t *) malloc(sizeof(i2c_gpio_t)); - memset(dev, 0, sizeof(i2c_gpio_t)); + i2c_gpio_t *dev = (i2c_gpio_t *) calloc(1, sizeof(i2c_gpio_t)); i2c_gpio_log(1, "I2C GPIO %s: init()\n", bus_name); diff --git a/src/device/ibm_5161.c b/src/device/ibm_5161.c index 762a379a1..456227676 100644 --- a/src/device/ibm_5161.c +++ b/src/device/ibm_5161.c @@ -116,7 +116,7 @@ const device_t ibm_5161_device = { .init = ibm_5161_init, .close = ibm_5161_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/isamem.c b/src/device/isamem.c index d6fa04a64..62fb96f5d 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -27,16 +27,20 @@ * modern boards even have multiple 'copies' of those registers, * which can be switched very fast, to allow for multitasking. * - * TODO: The EV159 is supposed to support 16b EMS transfers, but the + * TODO: The EV-159 is supposed to support 16b EMS transfers, but the * EMM.sys driver for it doesn't seem to want to do that.. * + * EV-125 (It supports backfill) + * https://theretroweb.com/expansioncard/documentation/50250.pdf * + * EV-158 (RAM 10000) + * http://web.archive.org/web/19961104093221/http://www.everex.com/supp/techlib/memmem.html * * Authors: Fred N. van Kempen, * Jasmine Iwanek * * Copyright 2018 Fred N. van Kempen. - * Copyright 2022-2024 Jasmine Iwanek. + * Copyright 2022-2025 Jasmine Iwanek. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -102,7 +106,7 @@ #define ISAMEM_BRXT_CARD 13 #define ISAMEM_BRAT_CARD 14 #define ISAMEM_EV165A_CARD 15 -#define ISAMEM_LOTECH_CARD 16 +#define ISAMEM_LOTECH_EMS_CARD 16 #define ISAMEM_DEBUG 0 @@ -304,16 +308,13 @@ ems_writew(uint32_t addr, uint16_t val, void *priv) static uint8_t ems_in(uint16_t port, void *priv) { - const emsreg_t *dev = (emsreg_t *) priv; - uint8_t ret = 0xff; -#ifdef ENABLE_ISAMEM_LOG - int vpage; -#endif - + const emsreg_t *dev = (emsreg_t *) priv; + uint8_t ret = 0xff; /* Get the viewport page number. */ #ifdef ENABLE_ISAMEM_LOG - vpage = (port / EMS_PGSIZE); + int vpage = (port / EMS_PGSIZE); #endif + port &= (EMS_PGSIZE - 1); switch (port & 0x0001) { @@ -339,13 +340,11 @@ ems_in(uint16_t port, void *priv) static uint8_t consecutive_ems_in(uint16_t port, void *priv) { - const memdev_t *dev = (memdev_t *) priv; - uint8_t ret = 0xff; - int vpage; - + const memdev_t *dev = (memdev_t *) priv; + uint8_t ret = 0xff; /* Get the viewport page number. */ - vpage = (port - dev->base_addr[0]); - + int vpage = (port - dev->base_addr[0]); + ret = dev->ems[vpage].page; if (dev->ems[vpage].enabled) ret |= 0x80; @@ -359,11 +358,10 @@ consecutive_ems_in(uint16_t port, void *priv) static void ems_out(uint16_t port, uint8_t val, void *priv) { - emsreg_t *dev = (emsreg_t *) priv; - int vpage; - + emsreg_t *dev = (emsreg_t *) priv; /* Get the viewport page number. */ - vpage = (port / EMS_PGSIZE); + int vpage = (port / EMS_PGSIZE); + port &= (EMS_PGSIZE - 1); switch (port & 0x0001) { @@ -433,11 +431,9 @@ ems_out(uint16_t port, uint8_t val, void *priv) static void consecutive_ems_out(uint16_t port, uint8_t val, void *priv) { - memdev_t *dev = (memdev_t *) priv; - int vpage; - + memdev_t *dev = (memdev_t *) priv; /* Get the viewport page number. */ - vpage = (port - dev->base_addr[0]); + int vpage = (port - dev->base_addr[0]); isamem_log("ISAMEM: write(%04x, %02x) to page mapping registers! (page=%d)\n", port, val, vpage); @@ -483,8 +479,7 @@ isamem_init(const device_t *info) uint8_t *ptr; /* Find our device and create an instance. */ - dev = (memdev_t *) malloc(sizeof(memdev_t)); - memset(dev, 0x00, sizeof(memdev_t)); + dev = (memdev_t *) calloc(1, sizeof(memdev_t)); dev->name = info->name; dev->board = info->local; @@ -579,7 +574,7 @@ isamem_init(const device_t *info) dev->flags |= FLAG_FAST; break; - case ISAMEM_LOTECH_CARD: /* Lotech EMS */ + case ISAMEM_LOTECH_EMS_CARD: /* Lotech EMS */ /* The Lotech EMS cannot have more than 4096KB per board. */ ems_max = EMS_LOTECH_MAXSIZE; fallthrough; @@ -801,7 +796,7 @@ isamem_init(const device_t *info) mem_mapping_disable(&dev->ems[i].mapping); /* Set up an I/O port handler. */ - if (dev->board != ISAMEM_LOTECH_CARD) + if (dev->board != ISAMEM_LOTECH_EMS_CARD) io_sethandler(dev->base_addr[0] + (EMS_PGSIZE * i), 2, ems_in, NULL, NULL, ems_out, NULL, NULL, &(dev->ems[i])); @@ -832,7 +827,7 @@ isamem_init(const device_t *info) } } - if (dev->board == ISAMEM_LOTECH_CARD) + if (dev->board == ISAMEM_LOTECH_EMS_CARD) io_sethandler(dev->base_addr[0], 4, consecutive_ems_in, NULL, NULL, consecutive_ems_out, NULL, NULL, dev); } @@ -856,32 +851,34 @@ isamem_close(void *priv) static const device_config_t ibmxt_32k_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 32, - .file_filter = "", - .spinner = { - .min = 32, - .max = 576, - .step = 32 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 32, + .file_filter = NULL, + .spinner = { + .min = 32, + .max = 576, + .step = 32 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 64, - .file_filter = "", - .spinner = { - .min = 0, - .max = 608, - .step = 32 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 608, + .step = 32 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -895,7 +892,7 @@ static const device_t ibmxt_32k_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ibmxt_32k_config @@ -904,32 +901,34 @@ static const device_t ibmxt_32k_device = { static const device_config_t ibmxt_64k_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 64, - .file_filter = "", - .spinner = { - .min = 64, - .max = 576, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 64, + .max = 576, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 64, - .file_filter = "", - .spinner = { - .min = 0, - .max = 576, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 576, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -943,7 +942,7 @@ static const device_t ibmxt_64k_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ibmxt_64k_config @@ -952,32 +951,34 @@ static const device_t ibmxt_64k_device = { static const device_config_t ibmxt_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 128, - .file_filter = "", - .spinner = { - .min = 64, - .max = 576, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 128, + .file_filter = NULL, + .spinner = { + .min = 64, + .max = 576, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 256, - .file_filter = "", - .spinner = { - .min = 0, - .max = 576, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 576, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -991,7 +992,7 @@ static const device_t ibmxt_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ibmxt_config @@ -1000,37 +1001,40 @@ static const device_t ibmxt_device = { static const device_config_t genericxt_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 16, - .file_filter = "", - .spinner = { - .min = 0, - .max = 640, - .step = 16 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 16, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 640, + .step = 16 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 624, - .step = 16 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 640, + .step = 16 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; +// This also nicely accounts for the Everex EV-138 static const device_t genericxt_device = { .name = "Generic PC/XT Memory Expansion", .internal_name = "genericxt", @@ -1039,7 +1043,7 @@ static const device_t genericxt_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = genericxt_config @@ -1048,46 +1052,48 @@ static const device_t genericxt_device = { static const device_config_t msramcard_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 64, - .file_filter = "", - .spinner = { - .min = 0, - .max = 256, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 256, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 624, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 624, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_t msramcard_device = { - .name = "Microsoft RAMCard for IBM PC", + .name = "Microsoft RAMCard", .internal_name = "msramcard", .flags = DEVICE_ISA, .local = ISAMEM_RAMCARD_CARD, .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = msramcard_config @@ -1096,32 +1102,34 @@ static const device_t msramcard_device = { static const device_config_t mssystemcard_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 64, - .file_filter = "", - .spinner = { - .min = 0, - .max = 256, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 256, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 624, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 624, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1135,7 +1143,7 @@ static const device_t mssystemcard_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mssystemcard_config @@ -1149,7 +1157,7 @@ static const device_t ibmat_128k_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1158,32 +1166,34 @@ static const device_t ibmat_128k_device = { static const device_config_t ibmat_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 0, - .max = 12288, - .step = 512 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 12288, + .step = 512 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 1024, - .file_filter = "", - .spinner = { - .min = 0, - .max = 15872, - .step = 512 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 15872, + .step = 512 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1197,7 +1207,7 @@ static const device_t ibmat_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ibmat_config @@ -1206,37 +1216,40 @@ static const device_t ibmat_device = { static const device_config_t genericat_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 0, - .max = 16384, - .step = 128 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 16384, + .step = 128 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 1024, - .file_filter = "", - .spinner = { - .min = 0, - .max = 15872, - .step = 128 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 15872, + .step = 128 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; +// This also nicely accounts for the Everex EV-135 static const device_t genericat_device = { .name = "Generic PC/AT Memory Expansion", .internal_name = "genericat", @@ -1245,7 +1258,7 @@ static const device_t genericat_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = genericat_config @@ -1254,32 +1267,34 @@ static const device_t genericat_device = { static const device_config_t p5pak_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 128, - .file_filter = "", - .spinner = { - .min = 0, - .max = 384, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 128, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 384, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 64, - .max = 576, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { + .min = 64, + .max = 576, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1293,7 +1308,7 @@ static const device_t p5pak_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = p5pak_config @@ -1302,32 +1317,34 @@ static const device_t p5pak_device = { static const device_config_t a6pak_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 64, - .file_filter = "", - .spinner = { - .min = 0, - .max = 576, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 384, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 256, - .file_filter = "", - .spinner = { - .min = 64, - .max = 512, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { + .min = 64, + .max = 512, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1341,7 +1358,7 @@ static const device_t a6pak_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = a6pak_config @@ -1350,28 +1367,29 @@ static const device_t a6pak_device = { static const device_config_t ems5150_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 256, - .file_filter = "", - .spinner = { - .min = 0, - .max = 2048, - .step = 64 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 2048, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x0000 }, { .description = "Board 1", .value = 0x0208 }, { .description = "Board 2", .value = 0x020a }, @@ -1379,6 +1397,7 @@ static const device_config_t ems5150_config[] = { { .description = "Board 4", .value = 0x020e }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1392,7 +1411,7 @@ static const device_t ems5150_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ems5150_config @@ -1401,98 +1420,104 @@ static const device_t ems5150_device = { static const device_config_t ev159_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 0, - .max = 3072, - .step = 512 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 3072, + .step = 512 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 16128, - .step = 128 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 16128, + .step = 128 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "length", - .description = "Contiguous Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 16384, - .step = 128 + .name = "length", + .description = "Contiguous Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 16384, + .step = 128 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "width", - .description = "I/O Width", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "width", + .description = "I/O Width", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "8-bit", .value = 0 }, { .description = "16-bit", .value = 1 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "speed", - .description = "Transfer Speed", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "speed", + .description = "Transfer Speed", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Standard (150ns)", .value = 0 }, { .description = "High-Speed (120ns)", .value = 1 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "ems", - .description = "EMS mode", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "ems", + .description = "EMS mode", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0 }, { .description = "Enabled", .value = 1 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0258, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0258, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, @@ -1502,16 +1527,17 @@ static const device_config_t ev159_config[] = { { .description = "2E8H", .value = 0x02E8 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "base2", - .description = "Address for > 2 MB", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0268, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base2", + .description = "Address for > 2 MB", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0268, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, @@ -1521,6 +1547,7 @@ static const device_config_t ev159_config[] = { { .description = "2E8H", .value = 0x02E8 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1534,7 +1561,7 @@ static const device_t ev159_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ev159_config @@ -1543,70 +1570,74 @@ static const device_t ev159_device = { static const device_config_t ev165a_config[] = { // clang-format off { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 0, - .max = 2048, - .step = 512 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 2048, + .step = 256 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 896, - .step = 128 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { + .min = 64, + .max = 640, + .step = 64 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "length", .description = "Contiguous Size", .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 16384, - .step = 128 + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 2048, + .step = 256 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "ems", - .description = "EMS mode", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "ems", + .description = "EMS mode", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0 }, { .description = "Enabled", .value = 1 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0258, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0258, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, @@ -1616,20 +1647,21 @@ static const device_config_t ev165a_config[] = { { .description = "2E8H", .value = 0x02E8 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_t ev165a_device = { - .name = "Everex Magi Magic EV-165A", + .name = "Everex Maxi Magic EV-165A", .internal_name = "ev165a", .flags = DEVICE_ISA, .local = ISAMEM_EV165A_CARD, .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ev165a_config @@ -1638,48 +1670,51 @@ static const device_t ev165a_device = { static const device_config_t brxt_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0268, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0268, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, { .description = "268H", .value = 0x0268 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "frame", - .description = "Frame Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD0000, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "D000H", .value = 0xD0000 }, - { .description = "E000H", .value = 0xE0000 }, - { .description = "" } + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "D000H", .value = 0xD0000 }, + { .description = "E000H", .value = 0xE0000 }, + { .description = "" } }, + .bios = { { 0 } } }, { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 0, - .max = 2048, - .step = 512 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 2048, + .step = 512 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1693,99 +1728,106 @@ static const device_t brxt_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = brxt_config }; -#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) +#ifdef USE_ISAMEM_BRAT static const device_config_t brat_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0268, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0268, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, { .description = "268H", .value = 0x0268 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "frame", - .description = "Frame Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD0000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "D000H", .value = 0xD0000 }, { .description = "E000H", .value = 0xE0000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "width", - .description = "I/O Width", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 8, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "width", + .description = "I/O Width", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 8, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "8-bit", .value = 8 }, { .description = "16-bit", .value = 16 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "speed", - .description = "Transfer Speed", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "speed", + .description = "Transfer Speed", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Standard", .value = 0 }, { .description = "High-Speed", .value = 1 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { - .min = 0, - .max = 4096, - .step = 512 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 4096, + .step = 512 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { - .min = 0, - .max = 14336, - .step = 512 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 14336, + .step = 512 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1799,92 +1841,95 @@ static const device_t brat_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = brat_config }; -#endif +#endif /* USE_ISAMEM_BRAT */ static const device_config_t lotech_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0260, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0260, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "260H", .value = 0x0260 }, { .description = "264H", .value = 0x0264 }, { .description = "268H", .value = 0x0268 }, { .description = "26CH", .value = 0x026C }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "frame", - .description = "Frame Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xe0000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xe0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C000H", .value = 0xC0000 }, { .description = "D000H", .value = 0xD0000 }, { .description = "E000H", .value = 0xE0000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 2048, - .file_filter = "", - .spinner = { - .min = 512, - .max = 4096, - .step = 512 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 2048, + .file_filter = NULL, + .spinner = { + .min = 512, + .max = 4096, + .step = 512 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; -static const device_t lotech_device = { - .name = "Lo-tech EMS Board", +static const device_t lotech_ems_device = { + .name = "Lo-tech EMS Board", .internal_name = "lotechems", - .flags = DEVICE_ISA, - .local = ISAMEM_LOTECH_CARD, - .init = isamem_init, - .close = isamem_close, - .reset = NULL, - { .available = NULL }, + .flags = DEVICE_ISA, + .local = ISAMEM_LOTECH_EMS_CARD, + .init = isamem_init, + .close = isamem_close, + .reset = NULL, + .available = NULL, .speed_changed = NULL, - .force_redraw = NULL, - .config = lotech_config + .force_redraw = NULL, + .config = lotech_config }; -#if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) +#ifdef USE_ISAMEM_RAMPAGE // TODO: Dual Paging support // TODO: Conventional memory suppport static const device_config_t rampage_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0218, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0218, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, @@ -1894,33 +1939,37 @@ static const device_config_t rampage_config[] = { { .description = "2E8H", .value = 0x02E8 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 256, /* Technically 128k, but banks 2-7 must be 256, headaches elsewise */ - .file_filter = "", - .spinner = { - .min = 256, - .max = 2048, - .step = 256 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 256, /* Technically 128k, but banks 2-7 must be 256, headaches elsewise */ + .file_filter = NULL, + .spinner = { + .min = 256, + .max = 2048, + .step = 256 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "start", - .description = "Start Address", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 640, - .file_filter = "", - .spinner = { - .min = 0, - .max = 640, - .step = 64 + .name = "start", + .description = "Start Address", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 640, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 640, + .step = 64 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1934,25 +1983,25 @@ static const device_t rampage_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = rampage_config }; -#endif +#endif /* USE_ISAMEM_RAMPAGE */ -#if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB) +#ifdef USE_ISAMEM_IAB static const device_config_t iab_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0258, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0258, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "208H", .value = 0x0208 }, { .description = "218H", .value = 0x0218 }, { .description = "258H", .value = 0x0258 }, @@ -1962,64 +2011,69 @@ static const device_config_t iab_config[] = { { .description = "2E8H", .value = 0x02E8 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "frame", - .description = "Frame Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "frame", + .description = "Frame Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C000H", .value = 0xC0000 }, { .description = "D000H", .value = 0xD0000 }, { .description = "E000H", .value = 0xE0000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "width", - .description = "I/O Width", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 8, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "width", + .description = "I/O Width", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 8, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "8-bit", .value = 8 }, { .description = "16-bit", .value = 16 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "speed", - .description = "Transfer Speed", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "speed", + .description = "Transfer Speed", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Standard", .value = 0 }, { .description = "High-Speed", .value = 1 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "size", - .description = "Memory Size", - .type = CONFIG_SPINNER, - .default_string = "", - .default_int = 128, - .file_filter = "", - .spinner = { - .min = 0, - .max = 8192, - .step = 128 + .name = "size", + .description = "Memory size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 128, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 8192, + .step = 128 }, - .selection = { { 0 } } + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -2033,12 +2087,12 @@ static const device_t iab_device = { .init = isamem_init, .close = isamem_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = iab_config }; -#endif +#endif /* USE_ISAMEM_IAB */ static const struct { const device_t *dev; @@ -2063,16 +2117,16 @@ static const struct { { &ev159_device }, { &ev165a_device }, { &brxt_device }, -#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT) +#ifdef USE_ISAMEM_BRAT { &brat_device }, -#endif -#if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE) +#endif /* USE_ISAMEM_BRAT */ +#ifdef USE_ISAMEM_RAMPAGE { &rampage_device }, -#endif -#if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB) +#endif /* USE_ISAMEM_RAMPAGE */ +#ifdef USE_ISAMEM_IAB { &iab_device }, -#endif - { &lotech_device }, +#endif /* USE_ISAMEM_IAB */ + { &lotech_ems_device }, { NULL } // clang-format on }; diff --git a/src/device/isapnp.c b/src/device/isapnp.c index da9e623c1..1ee8be040 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -110,6 +110,7 @@ typedef struct _isapnp_card_ { } isapnp_card_t; typedef struct { + uint8_t in_isolation; uint8_t reg; uint8_t key_pos : 5; uint16_t read_data_addr; @@ -120,6 +121,25 @@ typedef struct { isapnp_device_t *current_ld; } isapnp_t; +static isapnp_device_t * +isapnp_create_ld(isapnp_card_t *card) +{ + /* Allocate logical device. */ + isapnp_device_t *ld = calloc(1, sizeof(isapnp_device_t)); + + /* Add to the end of the card's logical device list. */ + isapnp_device_t *prev_ld = card->first_ld; + if (prev_ld) { + while (prev_ld->next) + prev_ld = prev_ld->next; + prev_ld->next = ld; + } else { + card->first_ld = ld; + } + + return ld; +} + static void isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) { @@ -136,6 +156,8 @@ isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) card->config.mem[i].size = (ld->regs[reg_base + 3] << 16) | (ld->regs[reg_base + 4] << 8); if (ld->regs[reg_base + 2] & 0x01) /* upper limit */ card->config.mem[i].size -= card->config.mem[i].base; + else + card->config.mem[i].size = (card->config.mem[i].size | 0xff) ^ 0xffffffff; } for (uint8_t i = 0; i < 4; i++) { reg_base = (i == 0) ? 0x76 : (0x80 + (16 * i)); @@ -313,6 +335,8 @@ isapnp_read_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uint case 0x05: /* Status */ ret = 0x00; + if (dev->in_isolation) + ret = 0x01; CHECK_CURRENT_CARD(); isapnp_log("ISAPnP: Query status for CSN %02X\n", card->csn); @@ -485,15 +509,16 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin case 0x03: /* Wake[CSN] */ isapnp_log("ISAPnP: Wake[%02X]\n", val); card = dev->first_card; + if (val == 0) + dev->in_isolation |= 1; while (card) { if (card->csn == val) { card->rom_pos = 0; card->id_checksum = isapnp_init_key[0]; if (card->state == PNP_STATE_SLEEP) card->state = (val == 0) ? PNP_STATE_ISOLATION : PNP_STATE_CONFIG; - } else { + } else card->state = PNP_STATE_SLEEP; - } card = card->next; } @@ -505,6 +530,7 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin isapnp_set_csn(dev->isolated_card, val); dev->isolated_card->state = PNP_STATE_CONFIG; dev->isolated_card = NULL; + dev->in_isolation = 0; } else { isapnp_log("ISAPnP: Set CSN %02X but no card is isolated\n", val); } @@ -525,8 +551,12 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin ld = ld->next; } - if (!ld) - isapnp_log("ISAPnP: CSN %02X has no device %02X\n", card->csn, val); + if (!ld) { + isapnp_log("ISAPnP: CSN %02X has no device %02X, creating one\n", card->csn, val); + dev->current_ld_card = card; + dev->current_ld = isapnp_create_ld(card); + dev->current_ld->number = val; + } break; @@ -649,7 +679,7 @@ isapnp_write_data(UNUSED(uint16_t addr), uint8_t val, void *priv) static void * isapnp_init(UNUSED(const device_t *info)) { - isapnp_t *dev = (isapnp_t *) malloc(sizeof(isapnp_t)); + isapnp_t *dev = (isapnp_t *) calloc(1, sizeof(isapnp_t)); memset(dev, 0, sizeof(isapnp_t)); io_sethandler(0x279, 1, NULL, NULL, NULL, isapnp_write_addr, NULL, NULL, dev); @@ -698,8 +728,7 @@ isapnp_add_card(uint8_t *rom, uint16_t rom_size, if (!dev) dev = (isapnp_t *) device_add(&isapnp_device); - isapnp_card_t *card = (isapnp_card_t *) malloc(sizeof(isapnp_card_t)); - memset(card, 0, sizeof(isapnp_card_t)); + isapnp_card_t *card = (isapnp_card_t *) calloc(1, sizeof(isapnp_card_t)); card->enable = 1; card->priv = priv; @@ -756,8 +785,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) uint8_t mem_range_df = 0; uint8_t mem_range_32_df = 0; uint32_t len; - isapnp_device_t *ld = NULL; - isapnp_device_t *prev_ld = NULL; + isapnp_device_t *ld = NULL; /* Check if this is an existing card which already has logical devices. Any new logical devices will be added to the list after existing ones. @@ -784,10 +812,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X, align %d", - in_df ? ">" : "", mem_range, - *((uint16_t *) &card->rom[i + 10]) << 8, *((uint16_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint16_t *) &card->rom[i + 4]) << 8)) + (*((uint16_t *) &card->rom[i + 6]) << 8), - (*((uint16_t *) &card->rom[i + 8]) + 1) << 16); + isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X to %06X-%06X, align %d", + /* %s */ in_df ? ">" : "", + /* %d */ mem_range, + /* %d */ *((uint16_t *) &card->rom[i + 8]), + /* %06X */ *((uint16_t *) &card->rom[i + 4]) << 8, + /* %06X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + (*((uint16_t *) &card->rom[i + 10]) << 8) : + /* Range. */ + (*((uint16_t *) &card->rom[i + 4]) << 8)) + + (*((uint16_t *) &card->rom[i + 10]) << 8), + /* %06X */ *((uint16_t *) &card->rom[i + 6]) << 8, + /* %06X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + (*((uint16_t *) &card->rom[i + 10]) << 8) : + /* Range. */ + (*((uint16_t *) &card->rom[i + 6]) << 8)) + + (*((uint16_t *) &card->rom[i + 10]) << 8), + /* %d */ *((uint16_t *) &card->rom[i + 8])); res = 1 << mem_range; mem_range++; } else { @@ -801,9 +844,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", in_df ? ">" : "", mem_range_32, - *((uint32_t *) &card->rom[i + 16]) << 8, *((uint32_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint32_t *) &card->rom[i + 4]) << 8)) + (*((uint32_t *) &card->rom[i + 8]) << 8), - *((uint32_t *) &card->rom[i + 12])); + isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", + /* %s */ in_df ? ">" : "", + /* %d */ mem_range_32, + /* %d */ *((uint32_t *) &card->rom[i + 12]), + /* %08X */ *((uint32_t *) &card->rom[i + 4]), + /* %08X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + *((uint32_t *) &card->rom[i + 16]) : + /* Range. */ + *((uint32_t *) &card->rom[i + 4])) + + *((uint32_t *) &card->rom[i + 16]), + /* %08X */ *((uint32_t *) &card->rom[i + 8]), + /* %08X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + *((uint32_t *) &card->rom[i + 16]) : + /* Range. */ + *((uint32_t *) &card->rom[i + 8])) + + *((uint32_t *) &card->rom[i + 16]), + /* %d */ *((uint32_t *) &card->rom[i + 12])); res = 1 << (4 + mem_range_32); mem_range_32++; } @@ -874,18 +933,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) memset(ld->io_len, 0, sizeof(ld->io_len)); } else { /* Create logical device. */ - ld = (isapnp_device_t *) malloc(sizeof(isapnp_device_t)); - memset(ld, 0, sizeof(isapnp_device_t)); - - /* Add to end of list. */ - prev_ld = card->first_ld; - if (prev_ld) { - while (prev_ld->next) - prev_ld = prev_ld->next; - prev_ld->next = ld; - } else { - card->first_ld = ld; - } + ld = isapnp_create_ld(card); } /* Set and increment logical device number. */ @@ -1182,7 +1230,7 @@ static const device_t isapnp_device = { .init = isapnp_init, .close = isapnp_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/isartc.c b/src/device/isartc.c index 7721d9885..63ce0b065 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -76,17 +76,23 @@ #include <86box/machine.h> #include <86box/io.h> #include <86box/device.h> +#include <86box/mem.h> #include <86box/nvr.h> +#include <86box/rom.h> #include <86box/ui.h> #include <86box/plat.h> #include <86box/pic.h> #include <86box/isartc.h> -#define ISARTC_EV170 0 -#define ISARTC_DTK 1 -#define ISARTC_P5PAK 2 -#define ISARTC_A6PAK 3 -#define ISARTC_VENDEX 4 +#define ISARTC_EV170 0 +#define ISARTC_DTK 1 +#define ISARTC_P5PAK 2 +#define ISARTC_A6PAK 3 +#define ISARTC_VENDEX 4 +#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_DEBUG 0 @@ -101,6 +107,7 @@ typedef struct rtcdev_t { int8_t irq; /* configured IRQ channel */ int8_t base_addrsz; uint32_t base_addr; /* configured I/O address */ + rom_t rom; /* BIOS ROM, If configured */ /* Fields for the specific driver. */ void (*f_wr)(uint16_t, uint8_t, void *); @@ -513,8 +520,7 @@ isartc_init(const device_t *info) is_at = is_at || !strcmp(machine_get_internal_name(), "xi8088"); /* Create a device instance. */ - dev = (rtcdev_t *) malloc(sizeof(rtcdev_t)); - memset(dev, 0x00, sizeof(rtcdev_t)); + dev = (rtcdev_t *) calloc(1, sizeof(rtcdev_t)); dev->name = info->name; dev->board = info->local; dev->irq = -1; @@ -524,6 +530,14 @@ isartc_init(const device_t *info) /* Do per-board initialization. */ switch (dev->board) { + case ISARTC_MM58167: /* Generic MM58167 RTC */ + { + int rom_addr = device_get_config_hex20("bios_addr"); + if (rom_addr != -1) + rom_init(&dev->rom, ISARTC_ROM_MM58167_1, + rom_addr, 0x0800, 0x7ff, 0, MEM_MAPPING_EXTERNAL); + + } case ISARTC_EV170: /* Everex EV-170 Magic I/O */ dev->flags |= FLAG_YEAR80; dev->base_addr = device_get_config_hex16("base"); @@ -614,24 +628,38 @@ isartc_close(void *priv) static const device_config_t ev170_config[] = { // clang-format off { - "base", "Address", CONFIG_HEX16, "", 0x02C0, "", { 0 }, - { - { "240H", 0x0240 }, - { "2C0H", 0x02c0 }, - { "" } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x02C0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "240H", .value = 0x0240 }, + { .description = "2C0H", .value = 0x02c0 }, + { .description = "" } }, + .bios = { { 0 } } }, { - "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, - { - { "Disabled", -1 }, - { "IRQ2", 2 }, - { "IRQ5", 5 }, - { "IRQ7", 7 }, - { "" } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "IRQ2", .value = 2 }, + { .description = "IRQ5", .value = 5 }, + { .description = "IRQ7", .value = 7 }, + { .description = "" } }, + .bios = { { 0 } } }, - { "", "", -1 } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -643,7 +671,7 @@ static const device_t ev170_device = { .init = isartc_init, .close = isartc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ev170_config @@ -652,14 +680,21 @@ static const device_t ev170_device = { static const device_config_t pii147_config[] = { // clang-format off { - "base", "Address", CONFIG_HEX16, "", 0x0240, "", { 0 }, - { - { "Clock 1", 0x0240 }, - { "Clock 2", 0x0340 }, - { "" } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0240, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Clock 1", .value = 0x0240 }, + { .description = "Clock 2", .value = 0x0340 }, + { .description = "" } }, + .bios = { { 0 } } }, - { "", "", -1 } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -671,7 +706,7 @@ static const device_t pii147_device = { .init = isartc_init, .close = isartc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pii147_config @@ -680,16 +715,23 @@ static const device_t pii147_device = { static const device_config_t p5pak_config[] = { // clang-format off { - "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, - { - { "Disabled", -1 }, - { "IRQ2", 2 }, - { "IRQ3", 3 }, - { "IRQ5", 5 }, - { "" } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", -1 }, + { .description = "IRQ2", 2 }, + { .description = "IRQ3", 3 }, + { .description = "IRQ5", 5 }, + { .description = "" } }, + .bios = { { 0 } } }, - { "", "", -1 } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -701,7 +743,7 @@ static const device_t p5pak_device = { .init = isartc_init, .close = isartc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = p5pak_config @@ -710,16 +752,23 @@ static const device_t p5pak_device = { static const device_config_t a6pak_config[] = { // clang-format off { - "irq", "IRQ", CONFIG_SELECTION, "", -1, "", { 0 }, - { - { "Disabled", -1 }, - { "IRQ2", 2 }, - { "IRQ3", 3 }, - { "IRQ5", 5 }, - { "" } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "IRQ2", .value = 2 }, + { .description = "IRQ3", .value = 3 }, + { .description = "IRQ5", .value = 5 }, + { .description = "" } }, + .bios = { { 0 } } }, - { "", "", -1 } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -731,12 +780,99 @@ static const device_t a6pak_device = { .init = isartc_init, .close = isartc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = a6pak_config }; +static const device_config_t mm58167_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x02C0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "240H", .value = 0x0240 }, + { .description = "2C0H", .value = 0x02c0 }, + { .description = "340H", .value = 0x0340 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "IRQ2", .value = 2 }, + { .description = "IRQ5", .value = 5 }, + { .description = "IRQ7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xcc000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "C800H", .value = 0xc8000 }, + { .description = "CA00H", .value = 0xca000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "CE00H", .value = 0xce000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D200H", .value = 0xd2000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D600H", .value = 0xd6000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DA00H", .value = 0xda000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "DE00H", .value = 0xde000 }, + { .description = "E000H", .value = 0xe0000 }, + { .description = "E200H", .value = 0xe2000 }, + { .description = "E400H", .value = 0xe4000 }, + { .description = "E600H", .value = 0xe6000 }, + { .description = "E800H", .value = 0xe8000 }, + { .description = "EA00H", .value = 0xea000 }, + { .description = "EC00H", .value = 0xec000 }, + { .description = "EE00H", .value = 0xee000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +static const device_t mm58167_device = { + .name = "Generic MM58167 RTC", + .internal_name = "rtc_mm58167", + .flags = DEVICE_ISA, + .local = ISARTC_MM58167, + .init = isartc_init, + .close = isartc_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = mm58167_config +}; + /* Onboard RTC devices */ const device_t vendex_xt_rtc_onboard_device = { .name = "National Semiconductor MM58167 (Vendex)", @@ -746,7 +882,7 @@ const device_t vendex_xt_rtc_onboard_device = { .init = isartc_init, .close = isartc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -756,12 +892,13 @@ static const struct { const device_t *dev; } boards[] = { // clang-format off - { &device_none }, - { &ev170_device }, - { &pii147_device }, - { &p5pak_device }, - { &a6pak_device }, - { NULL }, + { &device_none }, + { &ev170_device }, + { &pii147_device }, + { &p5pak_device }, + { &a6pak_device }, + { &mm58167_device }, + { NULL } // clang-format on }; diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index d38a9bb72..09855a387 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -277,9 +277,26 @@ kbc_translate(atkbc_t *dev, uint8_t val) return ret; } + kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off"); +#ifdef ENABLE_KEYBOARD_AT_LOG + kbc_at_log("scan code: "); + if (translate) { + kbc_at_log("%02X (original: ", (nont_to_t[val] | dev->sc_or)); + if (dev->sc_or == 0x80) + kbc_at_log("F0 "); + kbc_at_log("%02X)\n", val); + } else + kbc_at_log("%02X\n", val); +#endif + + ret = translate ? (nont_to_t[val] | dev->sc_or) : val; + + if (dev->sc_or == 0x80) + dev->sc_or = 0; + /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) && - (keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (val) { + (keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (ret) { case 0x4f: t3100e_notify_set(0x01); break; /* End */ @@ -329,23 +346,6 @@ kbc_translate(atkbc_t *dev, uint8_t val) break; } - kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off"); -#ifdef ENABLE_KEYBOARD_AT_LOG - kbc_at_log("scan code: "); - if (translate) { - kbc_at_log("%02X (original: ", (nont_to_t[val] | dev->sc_or)); - if (dev->sc_or == 0x80) - kbc_at_log("F0 "); - kbc_at_log("%02X)\n", val); - } else - kbc_at_log("%02X\n", val); -#endif - - ret = translate ? (nont_to_t[val] | dev->sc_or) : val; - - if (dev->sc_or == 0x80) - dev->sc_or = 0; - return ret; } @@ -810,27 +810,18 @@ write_p2(atkbc_t *dev, uint8_t val) if (!(val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbc_at_log("write_p2(): Pulse reset!\n"); - if (machines[machine].flags & MACHINE_COREBOOT) { - /* The SeaBIOS hard reset code attempts a KBC reset if ACPI RESET_REG - is not available. However, the KBC reset is normally a soft reset, so - SeaBIOS gets caught in a soft reset loop as it tries to hard reset the - machine. Hack around this by making the KBC reset a hard reset only on - coreboot machines. */ - pc_reset_hard(); - } else { - softresetx86(); /* Pulse reset! */ - cpu_set_edx(); - flushmmucache(); - if (kbc_ven == KBC_VEN_ALI) - smbase = 0x00030000; + softresetx86(); /* Pulse reset! */ + cpu_set_edx(); + flushmmucache(); + if ((kbc_ven == KBC_VEN_ALI) || !strcmp(machine_get_internal_name(), "spc7700plw")) + smbase = 0x00030000; - /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L - and can find out what they actually did to make it boot from FFFFF0 - correctly despite A20 being gated when the CPU is reset, this will - have to do. */ - if (kbc_ven == KBC_VEN_SIEMENS) - is486 ? loadcs(0xf000) : loadcs_2386(0xf000); - } + /* Yes, this is a hack, but until someone gets ahold of the real PCD-2L + and can find out what they actually did to make it boot from FFFFF0 + correctly despite A20 being gated when the CPU is reset, this will + have to do. */ + if ((kbc_ven == KBC_VEN_SIEMENS) || !strcmp(machine_get_internal_name(), "acera1g")) + is486 ? loadcs(0xf000) : loadcs_2386(0xf000); } } @@ -2127,6 +2118,13 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv) } else if (fast_reset && ((val & 0xf0) == 0xf0)) { pulse_output(dev, val & 0x0f); + 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); + dev->state = STATE_MAIN_IBF; return; } @@ -2275,8 +2273,7 @@ kbc_at_init(const device_t *info) atkbc_t *dev; int max_ports; - dev = (atkbc_t *) malloc(sizeof(atkbc_t)); - memset(dev, 0x00, sizeof(atkbc_t)); + dev = (atkbc_t *) calloc(1, sizeof(atkbc_t)); dev->flags = info->local; @@ -2386,8 +2383,7 @@ kbc_at_init(const device_t *info) #endif for (int i = 0; i < max_ports; i++) { - kbc_at_ports[i] = (kbc_at_port_t *) malloc(sizeof(kbc_at_port_t)); - memset(kbc_at_ports[i], 0x00, sizeof(kbc_at_port_t)); + kbc_at_ports[i] = (kbc_at_port_t *) calloc(1, sizeof(kbc_at_port_t)); kbc_at_ports[i]->out_new = -1; } @@ -2410,7 +2406,7 @@ const device_t keyboard_at_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2424,7 +2420,7 @@ const device_t keyboard_at_siemens_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2438,7 +2434,7 @@ const device_t keyboard_at_ami_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2452,7 +2448,7 @@ const device_t keyboard_at_tg_ami_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2466,7 +2462,7 @@ const device_t keyboard_at_toshiba_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2480,7 +2476,7 @@ const device_t keyboard_at_olivetti_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2494,7 +2490,7 @@ const device_t keyboard_at_ncr_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2508,7 +2504,7 @@ const device_t keyboard_at_compaq_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2522,7 +2518,7 @@ const device_t keyboard_ps2_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2536,7 +2532,7 @@ const device_t keyboard_ps2_ps1_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2550,7 +2546,7 @@ const device_t keyboard_ps2_ps1_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2564,7 +2560,7 @@ const device_t keyboard_ps2_xi8088_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2578,7 +2574,7 @@ const device_t keyboard_ps2_ami_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2592,7 +2588,7 @@ const device_t keyboard_ps2_holtek_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2606,7 +2602,7 @@ const device_t keyboard_ps2_phoenix_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2620,7 +2616,7 @@ const device_t keyboard_ps2_tg_ami_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2634,7 +2630,7 @@ const device_t keyboard_ps2_mca_1_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2648,7 +2644,7 @@ const device_t keyboard_ps2_mca_2_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2662,7 +2658,7 @@ const device_t keyboard_ps2_quadtel_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2676,7 +2672,7 @@ const device_t keyboard_ps2_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2690,7 +2686,7 @@ const device_t keyboard_ps2_ami_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2704,7 +2700,7 @@ const device_t keyboard_ps2_ali_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2718,7 +2714,7 @@ const device_t keyboard_ps2_intel_ami_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2732,7 +2728,7 @@ const device_t keyboard_ps2_tg_ami_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2746,7 +2742,7 @@ const device_t keyboard_ps2_acer_pci_device = { .init = kbc_at_init, .close = kbc_at_close, .reset = kbc_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 4b8bc7365..3fa7760c5 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -32,25 +32,17 @@ #include "cpu.h" -int keyboard_scan; +uint16_t scancode_map[768] = { 0 }; -#ifdef _WIN32 -/* Windows: F8+F12 */ +int keyboard_scan; + +/* F8+F12 */ uint16_t key_prefix_1_1 = 0x042; /* F8 */ uint16_t key_prefix_1_2 = 0x000; /* Invalid */ uint16_t key_prefix_2_1 = 0x000; /* Invalid */ uint16_t key_prefix_2_2 = 0x000; /* Invalid */ uint16_t key_uncapture_1 = 0x058; /* F12 */ uint16_t key_uncapture_2 = 0x000; /* Invalid */ -#else -/* WxWidgets cannot do two regular keys.. CTRL+END */ -uint16_t key_prefix_1_1 = 0x01d; /* Left Ctrl */ -uint16_t key_prefix_1_2 = 0x11d; /* Right Ctrl */ -uint16_t key_prefix_2_1 = 0x000; /* Invalid */ -uint16_t key_prefix_2_2 = 0x000; /* Invalid */ -uint16_t key_uncapture_1 = 0x04f; /* Numpad End */ -uint16_t key_uncapture_2 = 0x14f; /* End */ -#endif #ifdef ENABLE_KBC_AT_LOG int kbc_at_do_log = ENABLE_KBC_AT_LOG; @@ -502,3 +494,22 @@ keyboard_ismsexit(void) return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) && (recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2])); } + +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +uint16_t +convert_scan_code(uint16_t scan_code) +{ + if ((scan_code & 0xff00) == 0xe000) + scan_code = (scan_code & 0xff) | 0x0100; + + if (scan_code == 0xE11D) + scan_code = 0x0100; + /* E0 00 is sent by some USB keyboards for their special keys, as it is an + invalid scan code (it has no untranslated set 2 equivalent), we mark it + appropriately so it does not get passed through. */ + else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) + scan_code = 0xFFFF; + + return scan_code; +} diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 161a13e0c..b78fbd653 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -2512,18 +2512,24 @@ keyboard_at_write(void *priv) } } else { if (dev->flags & FLAG_CTRLDAT) { - /* Special case - another command during another command that wants input - proceed + /* + Special case - another command during another command that wants input - proceed as normal but do not cancel the command (so keep waiting for input), unless the - command in progress is ED (Set/reset LEDs). */ - if (val == 0xed) { - keyboard_scan = 1; + command in progress is ED (Set/reset LEDs). + + It appears to also apply to command EE (Echo), F4 (Enable), F5 (Diable and Set + Default), and F6 (SetDefault). + */ + if ((val == 0xed) || (val == 0xee) || (val == 0xf4) || (val == 0xf5) || (val == 0xf6)) dev->flags &= ~FLAG_CTRLDAT; - } else + else dev->state = DEV_STATE_MAIN_WANT_IN; } switch (val) { case 0xed: /* set/reset LEDs */ + if ((dev->flags & FLAG_CTRLDAT) && (dev->command == 0xed)) + keyboard_scan = 1; dev->command = val; keyboard_at_log("%s: set/reset LEDs\n", dev->name); dev->flags |= FLAG_CTRLDAT; @@ -2653,6 +2659,7 @@ 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; @@ -2731,14 +2738,14 @@ keyboard_at_close(void *priv) static const device_config_t keyboard_at_config[] = { // clang-format off { - .name = "type", - .description = "Type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "type", + .description = "Type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .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 }, @@ -2747,7 +2754,8 @@ static const device_config_t keyboard_at_config[] = { { .description = "PS/2 106-key JIS", .value = FLAG_PS2 | KBD_JIS }, { .description = "PS/2 Korean", .value = FLAG_PS2 | KBD_KOREAN }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END @@ -2759,12 +2767,12 @@ static const device_config_t keyboard_at_config[] = { const device_t keyboard_at_generic_device = { .name = "Standard AT or PS/2 Keyboard", .internal_name = "ps2", - .flags = DEVICE_PS2, + .flags = DEVICE_PS2_KBC, .local = 0, .init = keyboard_at_init, .close = keyboard_at_close, .reset = NULL, - { .poll = 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 63882222e..644168004 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -928,11 +928,11 @@ kbd_read(uint16_t port, void *priv) else { /* LaserXT = Always 512k RAM; LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ -#if defined(DEV_BRANCH) && defined(USE_LASERXT) +#ifdef USE_LASERXT if (kbd->type == KBD_TYPE_VTECH) ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00); else -#endif +#endif /* USE_LASERXT */ ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00); } } @@ -1000,8 +1000,7 @@ kbd_init(const device_t *info) { xtkbd_t *kbd; - kbd = (xtkbd_t *) malloc(sizeof(xtkbd_t)); - memset(kbd, 0x00, sizeof(xtkbd_t)); + kbd = (xtkbd_t *) calloc(1, sizeof(xtkbd_t)); io_sethandler(0x0060, 4, kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); @@ -1188,7 +1187,7 @@ const device_t keyboard_pc_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1202,7 +1201,7 @@ const device_t keyboard_pc82_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1216,7 +1215,7 @@ const device_t keyboard_pravetz_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1230,7 +1229,7 @@ const device_t keyboard_xt_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1244,7 +1243,7 @@ const device_t keyboard_xt86_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1258,7 +1257,7 @@ const device_t keyboard_xt_compaq_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1272,7 +1271,7 @@ const device_t keyboard_tandy_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1286,13 +1285,13 @@ const device_t keyboard_xt_t1x00_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; -#if defined(DEV_BRANCH) && defined(USE_LASERXT) +#ifdef USE_LASERXT const device_t keyboard_xt_lxt3_device = { .name = "VTech Laser XT3 Keyboard", .internal_name = "keyboard_xt_lxt3", @@ -1301,12 +1300,12 @@ const device_t keyboard_xt_lxt3_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; -#endif +#endif /* USE_LASERXT */ const device_t keyboard_xt_olivetti_device = { .name = "Olivetti XT Keyboard", @@ -1316,7 +1315,7 @@ const device_t keyboard_xt_olivetti_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1330,7 +1329,7 @@ const device_t keyboard_xt_zenith_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1344,7 +1343,7 @@ const device_t keyboard_xt_hyundai_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1358,7 +1357,7 @@ const device_t keyboard_xtclone_device = { .init = kbd_init, .close = kbd_close, .reset = kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/mouse.c b/src/device/mouse.c index 8fd783ee2..f0446d781 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -61,7 +61,7 @@ static const device_t mouse_none_device = { .init = NULL, .close = NULL, .reset = NULL, - { .poll = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -75,7 +75,7 @@ static const device_t mouse_internal_device = { .init = NULL, .close = NULL, .reset = NULL, - { .poll = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -98,7 +98,7 @@ static mouse_t mouse_devices[] = { { &mouse_wacom_device }, { &mouse_wacom_artpad_device }, #endif - { &mouse_mtouch_device }, + { &mouse_mtouch_device }, { NULL } // clang-format on }; @@ -111,7 +111,6 @@ static atomic_int mouse_buttons; static int mouse_delta_b; static int mouse_old_b; -static const device_t *mouse_curr; static void *mouse_priv; static int mouse_nbut; static int mouse_raw; @@ -482,10 +481,10 @@ mouse_subtract_z(int *delta_z, int min, int max, int invert) int z = atomic_load(&mouse_z); int real_z = invert ? -z : z; - if (mouse_z > max) { + if (real_z > max) { *delta_z = max; real_z -= max; - } else if (mouse_z < min) { + } else if (real_z < min) { *delta_z = min; real_z += ABS(min); } else { @@ -537,17 +536,10 @@ mouse_get_abs_coords(double *x_abs, double *y_abs) void mouse_process(void) { - if (mouse_curr == NULL) - return; - if ((mouse_input_mode >= 1) && mouse_poll_ex) mouse_poll_ex(); - else if ((mouse_input_mode == 0) && ((mouse_dev_poll != NULL) || (mouse_curr->poll != NULL))) { - if (mouse_curr->poll != NULL) - mouse_curr->poll(mouse_priv); - else - mouse_dev_poll(mouse_priv); - } + else if ((mouse_input_mode == 0) && (mouse_dev_poll != NULL)) + mouse_dev_poll(mouse_priv); } void @@ -559,9 +551,6 @@ mouse_set_poll_ex(void (*poll_ex)(void)) void mouse_set_poll(int (*func)(void *), void *arg) { - if (mouse_type != MOUSE_TYPE_INTERNAL) - return; - mouse_dev_poll = func; mouse_priv = arg; } @@ -629,7 +618,7 @@ mouse_set_raw(int raw) void mouse_reset(void) { - if (mouse_curr != NULL) + if (mouse_priv != NULL) return; /* Mouse already initialized. */ mouse_log("MOUSE: reset(type=%d, '%s')\n", @@ -651,19 +640,13 @@ mouse_reset(void) sample_rate = 100.0; timer_on_auto(&mouse_timer, 1000000.0 / sample_rate); - mouse_curr = mouse_devices[mouse_type].device; - - if ((mouse_type > 1) && (mouse_curr != NULL)) - mouse_priv = device_add(mouse_curr); + if ((mouse_type > 1) && (mouse_devices[mouse_type].device != NULL)) + mouse_priv = device_add(mouse_devices[mouse_type].device); } void mouse_close(void) { - if (mouse_curr == NULL) - return; - - mouse_curr = NULL; mouse_priv = NULL; mouse_nbut = 0; mouse_dev_poll = NULL; @@ -680,7 +663,6 @@ mouse_init(void) mouse_clear_buttons(); mouse_type = MOUSE_TYPE_NONE; - mouse_curr = NULL; mouse_priv = NULL; mouse_nbut = 0; mouse_dev_poll = NULL; diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index 554704c9d..7074a71ac 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -614,8 +614,7 @@ bm_init(const device_t *info) mouse_t *dev; int hz; - dev = (mouse_t *) malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); + dev = (mouse_t *) calloc(1, sizeof(mouse_t)); if ((info->local & ~MOUSE_TYPE_ONBOARD) == MOUSE_TYPE_INPORT) dev->flags = FLAG_INPORT; @@ -681,72 +680,78 @@ bm_init(const device_t *info) mouse_set_sample_rate(0.0); + mouse_set_poll(bm_poll, dev); + return dev; } static const device_config_t lt_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x23c, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x23c, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x230", .value = 0x230 }, { .description = "0x234", .value = 0x234 }, { .description = "0x238", .value = 0x238 }, { .description = "0x23C", .value = 0x23c }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "hz", - .description = "Hz", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 45, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "hz", + .description = "Hz", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 45, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Non-timed (original)", .value = 0 }, { .description = "30 Hz (JMP2 = 1)", .value = 30 }, { .description = "45 Hz (JMP2 not populated)", .value = 45 }, - { .description = "60 Hz (JMP 2 = 2)", .value = 60 }, + { .description = "60 Hz (JMP2 = 2)", .value = 60 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -755,50 +760,53 @@ static const device_config_t lt_config[] = { static const device_config_t ms_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x23c, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x23c, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x230", .value = 0x230 }, { .description = "0x234", .value = 0x234 }, { .description = "0x238", .value = 0x238 }, { .description = "0x23C", .value = 0x23c }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -812,7 +820,7 @@ const device_t mouse_logibus_device = { .init = bm_init, .close = bm_close, .reset = NULL, - { .poll = bm_poll }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = lt_config @@ -826,7 +834,7 @@ const device_t mouse_logibus_onboard_device = { .init = bm_init, .close = bm_close, .reset = NULL, - { .poll = bm_poll }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -840,7 +848,7 @@ const device_t mouse_msinport_device = { .init = bm_init, .close = bm_close, .reset = NULL, - { .poll = bm_poll }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ms_config diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 9767d5c04..512fcc0df 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * 3M MicroTouch SMT3 emulation. + * 3M MicroTouch Serial emulation. * * * @@ -19,10 +19,8 @@ /* TODO: - Properly implement GP/SP commands (formats are not documented at all, like anywhere; no dumps yet). - - Decouple serial packet generation from mouse poll rate. - - Dynamic baud rate selection from software following this. - Add additional SMT2/3 formats as we currently only support Tablet, Hex and Dec. - - Add additional SMT2/3 modes as we currently hardcode Mode Stream. + - Mode Polled. */ #include #include @@ -30,6 +28,7 @@ #include #include #include +#include #include <86box/86box.h> #include <86box/device.h> #include <86box/timer.h> @@ -38,7 +37,10 @@ #include <86box/plat.h> #include <86box/fifo8.h> #include <86box/fifo.h> -#include <86box/video.h> /* Needed to account for overscan. */ +#include <86box/video.h> +#include <86box/nvr.h> + +#define NVR_SIZE 16 enum mtouch_formats { FORMAT_DEC = 1, @@ -47,6 +49,13 @@ enum mtouch_formats { FORMAT_TABLET = 4 }; +enum mtouch_modes { + MODE_DOWNUP = 1, + MODE_INACTIVE = 2, + MODE_POINT = 3, + MODE_STREAM = 4, +}; + const char* mtouch_identity[] = { "A30100", /* SMT2 Serial / SMT3(R)V */ "A40100", /* SMT2 PCBus */ @@ -55,16 +64,17 @@ const char* mtouch_identity[] = { }; typedef struct mouse_microtouch_t { - double baud_rate; - unsigned int abs_x_int, abs_y_int; - int b; char cmd[256]; - int cmd_pos; - uint8_t format; - bool mode_status; + double abs_x, abs_x_old, abs_y, abs_y_old; + float scale_x, scale_y, off_x, off_y; + int but, but_old; + int baud_rate, cmd_pos; + uint8_t format, mode; uint8_t id, cal_cntr, pen_mode; - bool soh; - bool in_reset; + bool mode_status, cal_ex, soh; + bool in_reset, reset; + uint8_t *nvr; + char nvr_path[64]; serial_t *serial; Fifo8 resp; pc_timer_t host_to_serial_timer; @@ -73,112 +83,348 @@ typedef struct mouse_microtouch_t { static mouse_microtouch_t *mtouch_inst = NULL; -void -microtouch_reset_complete(void *priv) +static void +mtouch_savenvr(void *priv) { - mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - mtouch->in_reset = false; - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ -} + FILE *fp; -void -microtouch_calibrate_timer(void *priv) -{ - mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; - - if (!fifo8_num_used(&mtouch->resp)) { - mtouch->cal_cntr--; - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x31\x0D", 3); /* 1 */ + fp = nvr_fopen(dev->nvr_path, "wb"); + if (fp) { + fwrite(dev->nvr, 1, NVR_SIZE, fp); + fclose(fp); + fp = NULL; } } -void -microtouch_process_commands(mouse_microtouch_t *mtouch) +static void +mtouch_writenvr(void *priv, float scale_x, float scale_y, float off_x, float off_y) { - mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; - pclog("MT Command: %s\n", mtouch->cmd); + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { /* Calibrate New/Extended */ - mtouch->cal_cntr = 2; - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'D') { /* Format Decimal */ - mouse_set_sample_rate(106); - mtouch->format = FORMAT_DEC; - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { /* Finger Only */ - mtouch->pen_mode = 1; - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'H') { /* Format Hexadecimal */ - mouse_set_sample_rate(106); - mtouch->format = FORMAT_HEX; - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') { /* Format Raw */ - mouse_set_sample_rate(106); - mtouch->format = FORMAT_RAW; - mtouch->cal_cntr = 0; - } - if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { /* Format Tablet */ - mouse_set_sample_rate(192); - mtouch->format = FORMAT_TABLET; - } - if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Get Parameter Block 1 */ - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ - fifo8_push_all(&mtouch->resp, (uint8_t *) "0000000000000000000000000\r", 26); - } - if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'T') { /* Mode Status */ - mtouch->mode_status = true; - } - if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { /* Output Identity */ - fifo8_push(&mtouch->resp, 0x01); - fifo8_push_all(&mtouch->resp, (uint8_t *) mtouch_identity[mtouch->id], 6); - fifo8_push(&mtouch->resp, 0x0D); + memcpy(&dev->nvr[0], &scale_x, 4); + memcpy(&dev->nvr[4], &scale_y, 4); + memcpy(&dev->nvr[8], &off_x, 4); + memcpy(&dev->nvr[12], &off_y, 4); +} + +static void +mtouch_readnvr(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + memcpy(&dev->scale_x, &dev->nvr[0], 4); + memcpy(&dev->scale_y, &dev->nvr[4], 4); + memcpy(&dev->off_x, &dev->nvr[8], 4); + memcpy(&dev->off_y, &dev->nvr[12], 4); + + pclog("MT NVR CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); +} + +static void +mtouch_initnvr(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + FILE *fp; + + /* Allocate and initialize the EEPROM. */ + dev->nvr = (uint8_t *) calloc(1, NVR_SIZE); + + fp = nvr_fopen(dev->nvr_path, "rb"); + if (fp) { + if (fread(dev->nvr, 1, NVR_SIZE, fp) != NVR_SIZE) + fatal("mtouch_initnvr(): Error reading data\n"); + fclose(fp); + fp = NULL; + } else + mtouch_writenvr(dev, 1, 1, 0, 0); +} + +static void +mtouch_reset_complete(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + dev->reset = true; + dev->in_reset = false; + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ +} + +static void +mtouch_calibrate_timer(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + if ((dev->cal_cntr == 2 && (dev->abs_x > 0.25 || dev->abs_y < 0.75)) || \ + (dev->cal_cntr == 1 && (dev->abs_x < 0.75 || dev->abs_y > 0.25))) { return; } - if (mtouch->cmd[0] == 'P') { - if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3; /* Pen or Finger */ - else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2; /* Pen Only */ + + dev->cal_cntr--; + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x31\x0D", 3); /* 1 */ + + if (dev->cal_ex) { + if (!dev->cal_cntr) { + double x1_ref = 0.125; + double y1_ref = 0.875; + double x2_ref = 0.875; + double y2_ref = 0.125; + double x1 = dev->abs_x_old; + double y1 = dev->abs_y_old; + double x2 = dev->abs_x; + double y2 = dev->abs_y; + + dev->scale_x = (x2_ref - x1_ref) / (x2 - x1); + dev->off_x = x1_ref - dev->scale_x * x1; + dev->scale_y = (y2_ref - y1_ref) / (y2 - y1); + dev->off_y = y1_ref - dev->scale_y * y1; + dev->cal_ex = false; + + pclog("MT NEW CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); + mtouch_writenvr(dev, dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); + mtouch_savenvr(dev); + } + dev->abs_x_old = dev->abs_x; + dev->abs_y_old = dev->abs_y; + } +} + +static void +mtouch_process_commands(mouse_microtouch_t *dev) +{ + dev->cmd[strcspn(dev->cmd, "\r")] = '\0'; + pclog("MT Command: %s\n", dev->cmd); + + if (dev->cmd[0] == 'C' && dev->cmd[1] == 'N') { /* Calibrate New */ + dev->cal_cntr = 2; } - if (mtouch->cmd[0] == 'R') { /* Reset */ - mtouch->in_reset = true; - mtouch->cal_cntr = 0; - mtouch->pen_mode = 3; - mtouch->mode_status = false; - - if (mtouch->id < 2) { - mouse_set_sample_rate(106); - mtouch->format = FORMAT_DEC; + else if (dev->cmd[0] == 'C' && dev->cmd[1] == 'X') { /* Calibrate Extended */ + dev->scale_x = 1; + dev->scale_y = 1; + dev->off_x = 0; + dev->off_y = 0; + dev->cal_ex = true; + dev->cal_cntr = 2; + } + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'D') { /* Format Decimal */ + dev->format = FORMAT_DEC; + dev->mode_status = false; + } + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'O') { /* Finger Only */ + dev->pen_mode = 1; + } + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'H') { /* Format Hexadecimal */ + dev->format = FORMAT_HEX; + dev->mode_status = false; + } + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'R') { /* Format Raw */ + dev->format = FORMAT_RAW; + dev->mode = MODE_INACTIVE; + dev->cal_cntr = 0; + } + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'T') { /* Format Tablet */ + dev->format = FORMAT_TABLET; + } + else if (dev->cmd[0] == 'G' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Get Parameter Block 1 */ + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ + fifo8_push_all(&dev->resp, (uint8_t *) "0000000000000000000000000\r", 26); + } + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'D' && dev->cmd[2] == 'U') { /* Mode Down/Up */ + dev->mode = MODE_DOWNUP; + } + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'I') { /* Mode Inactive */ + dev->mode = MODE_INACTIVE; + } + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'P') { /* Mode Point */ + dev->mode = MODE_POINT; + } + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'T') { /* Mode Status */ + dev->mode_status = true; + } + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'S') { /* Mode Stream */ + dev->mode = MODE_STREAM; + } + else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'I') { /* Output Identity */ + fifo8_push(&dev->resp, 0x01); + fifo8_push_all(&dev->resp, (uint8_t *) mtouch_identity[dev->id], 6); + fifo8_push(&dev->resp, 0x0D); + return; + } + else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'S') { /* Output Status */ + if (dev->reset) { + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x60\x0D", 4); } else { - mouse_set_sample_rate(192); - mtouch->format = FORMAT_TABLET; + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x40\x0D", 4); + } + return; + } + else if (dev->cmd[0] == 'P') { + if (strlen(dev->cmd) == 2) { /* Pen */ + if (dev->cmd[1] == 'F') dev->pen_mode = 3; /* Pen or Finger */ + else if (dev->cmd[1] == 'O') dev->pen_mode = 2; /* Pen Only */ + } + else if (strlen(dev->cmd) == 5) { /* Serial Options */ + if (dev->cmd[4] == 1) dev->baud_rate = 19200; + else if (dev->cmd[4] == 2) dev->baud_rate = 9600; + else if (dev->cmd[4] == 3) dev->baud_rate = 4600; + else if (dev->cmd[4] == 4) dev->baud_rate = 2400; + else if (dev->cmd[4] == 5) dev->baud_rate = 1200; + + timer_stop(&dev->host_to_serial_timer); + timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10); + } + } + else if (dev->cmd[0] == 'R') { /* Reset */ + dev->in_reset = true; + dev->cal_cntr = 0; + dev->pen_mode = 3; + + if (dev->cmd[0] == 'D') { /* Restore Defaults */ + dev->mode = MODE_STREAM; + dev->mode_status = false; + + if (dev->id < 2) { + dev->format = FORMAT_DEC; + } else { + dev->format = FORMAT_TABLET; + } } - timer_on_auto(&mtouch->reset_timer, 500. * 1000.); + timer_on_auto(&dev->reset_timer, 500. * 1000.); return; } - if (mtouch->cmd[0] == 'S' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Set Parameter Block 1 */ - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ + else if (dev->cmd[0] == 'S' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Set Parameter Block 1 */ + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ return; } - if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { /* Unit Type */ - fifo8_push(&mtouch->resp, 0x01); + else if (dev->cmd[0] == 'U' && dev->cmd[1] == 'T') { /* Unit Type */ + fifo8_push(&dev->resp, 0x01); - if (mtouch->id == 2) { - fifo8_push_all(&mtouch->resp, (uint8_t *) "TP****00", 8); + if (dev->id == 2) { + fifo8_push_all(&dev->resp, (uint8_t *) "TP****00", 8); } else { - fifo8_push_all(&mtouch->resp, (uint8_t *) "QM****00", 8); + fifo8_push_all(&dev->resp, (uint8_t *) "QM****00", 8); } - fifo8_push(&mtouch->resp, 0x0D); + fifo8_push(&dev->resp, 0x0D); return; } - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ } -void +static void +mtouch_write(UNUSED(serial_t *serial), void *priv, uint8_t data) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + if (data == '\x1') { + dev->soh = 1; + } + else if (dev->soh) { + if (data != '\r') { + dev->cmd[dev->cmd_pos++] = data; + } else { + dev->soh = 0; + + if (!dev->cmd_pos) { + return; + } + + dev->cmd[dev->cmd_pos++] = data; + dev->cmd_pos = 0; + mtouch_process_commands(dev); + } + } +} + +static int +mtouch_prepare_transmit(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + char buffer[16]; + double abs_x = dev->abs_x; + double abs_y = dev->abs_y; + int but = dev->but; + + if (dev->mode == MODE_INACTIVE) { + return 0; + } + + if (dev->cal_cntr || (!dev->but && !dev->but_old)) { /* Calibration or no buttonpress */ + if (!dev->but && dev->but_old) { + mtouch_calibrate_timer(dev); + } + dev->but_old = but; /* Save buttonpress */ + return 0; + } + + if (dev->format == FORMAT_TABLET) { + if (but) { /* Touchdown/Continuation */ + fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((but & 3))) : 0)); + fifo8_push(&dev->resp, (uint16_t)(16383 * abs_x) & 0b1111111); + fifo8_push(&dev->resp, ((uint16_t)(16383 * abs_x) >> 7) & 0b1111111); + fifo8_push(&dev->resp, (uint16_t)(16383 * (1 - abs_y)) & 0b1111111); + fifo8_push(&dev->resp, ((uint16_t)(16383 * (1 - abs_y)) >> 7) & 0b1111111); + } + else if (dev->but_old) { /* Liftoff */ + fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0)); + fifo8_push(&dev->resp, (uint16_t)(16383 * dev->abs_x_old) & 0b1111111); + fifo8_push(&dev->resp, ((uint16_t)(16383 * dev->abs_x_old) >> 7) & 0b1111111); + fifo8_push(&dev->resp, (uint16_t)(16383 * (1 - dev->abs_y_old))& 0b1111111); + fifo8_push(&dev->resp, ((uint16_t)(16383 * (1 - dev->abs_y_old)) >> 7) & 0b1111111); + } + } + + else if (dev->format == FORMAT_DEC || dev->format == FORMAT_HEX) { + if (but) { + if (!dev->but_old) { /* Touchdown (MS, MP, MDU) */ + fifo8_push(&dev->resp, (dev->mode_status) ? 0x19 : 0x01); + if (dev->format == FORMAT_DEC){ + snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * abs_x), (uint16_t)(999 * (1 - abs_y))); + } + else if (dev->format == FORMAT_HEX) { + snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * abs_x), (uint16_t)(1023 * (1 - abs_y))); + } + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); + } + else if (dev->mode == MODE_STREAM){ /* Touch Continuation (MS) */ + fifo8_push(&dev->resp, (dev->mode_status) ? 0x1c : 0x01); + if (dev->format == FORMAT_DEC){ + snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * abs_x), (uint16_t)(999 * (1 - abs_y))); + } + else if (dev->format == FORMAT_HEX) { + snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * abs_x), (uint16_t)(1023 * (1 - abs_y))); + } + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); + } + } + else if (dev->but_old && dev->mode != MODE_POINT) { /* Touch Liftoff (MS, MDU) */ + fifo8_push(&dev->resp, (dev->mode_status) ? 0x18 : 0x01); + if (dev->format == FORMAT_DEC) { + snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * dev->abs_x_old), (uint16_t)(999 * (1 - dev->abs_y_old))); + } + else if (dev->format == FORMAT_HEX) { + snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * dev->abs_x_old), (uint16_t)(1023 * (1 - dev->abs_y_old))); + } + fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); + } + } + + /* Save old states*/ + dev->abs_x_old = abs_x; + dev->abs_y_old = abs_y; + dev->but_old = but; + return 0; +} + +static void mtouch_write_to_host(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + if (dev->serial == NULL) + goto no_write_to_machine; if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { if (fifo_get_full(dev->serial->rcvr_fifo)) { goto no_write_to_machine; @@ -194,162 +440,51 @@ mtouch_write_to_host(void *priv) if (fifo8_num_used(&dev->resp)) { serial_write_fifo(dev->serial, fifo8_pop(&dev->resp)); } + else { + mtouch_prepare_transmit(dev); + } no_write_to_machine: timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baud_rate) * (double) (1 + 8 + 1)); } -void -mtouch_write(serial_t *serial, void *priv, uint8_t data) -{ - mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - if (data == '\x1') { - dev->soh = 1; - } else if (dev->soh) { - if (data != '\r') { - dev->cmd[dev->cmd_pos++] = data; - } else { - dev->soh = 0; - - if (!dev->cmd_pos) { - return; - } - - dev->cmd[dev->cmd_pos++] = data; - dev->cmd_pos = 0; - microtouch_process_commands(dev); - } - } -} - static int mtouch_poll(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - if (fifo8_num_free(&dev->resp) <= 256 - 10 || dev->format == FORMAT_RAW) { - return 0; - } + dev->but = mouse_get_buttons_ex(); + mouse_get_abs_coords(&dev->abs_x, &dev->abs_y); - unsigned int abs_x_int = 0, abs_y_int = 0; - double abs_x; - double abs_y; - int b = mouse_get_buttons_ex(); - - mouse_get_abs_coords(&abs_x, &abs_y); - - if (abs_x >= 1.0) - abs_x = 1.0; - if (abs_y >= 1.0) - abs_y = 1.0; - if (abs_x <= 0.0) - abs_x = 0.0; - if (abs_y <= 0.0) - abs_y = 0.0; if (enable_overscan) { int index = mouse_tablet_in_proximity - 1; if (mouse_tablet_in_proximity == -1) { mouse_tablet_in_proximity = 0; } - abs_x *= monitors[index].mon_unscaled_size_x - 1; - abs_y *= monitors[index].mon_efscrnsz_y - 1; + dev->abs_x *= monitors[index].mon_unscaled_size_x - 1; + dev->abs_y *= monitors[index].mon_efscrnsz_y - 1; - if (abs_x <= (monitors[index].mon_overscan_x / 2.)) { - abs_x = (monitors[index].mon_overscan_x / 2.); + if (dev->abs_x <= (monitors[index].mon_overscan_x / 2.)) { + dev->abs_x = (monitors[index].mon_overscan_x / 2.); } - if (abs_y <= (monitors[index].mon_overscan_y / 2.)) { - abs_y = (monitors[index].mon_overscan_y / 2.); + if (dev->abs_y <= (monitors[index].mon_overscan_y / 2.)) { + dev->abs_y = (monitors[index].mon_overscan_y / 2.); } - abs_x -= (monitors[index].mon_overscan_x / 2.); - abs_y -= (monitors[index].mon_overscan_y / 2.); - abs_x = abs_x / (double) monitors[index].mon_xsize; - abs_y = abs_y / (double) monitors[index].mon_ysize; - if (abs_x >= 1.0) - abs_x = 1.0; - if (abs_y >= 1.0) - abs_y = 1.0; + dev->abs_x -= (monitors[index].mon_overscan_x / 2.); + dev->abs_y -= (monitors[index].mon_overscan_y / 2.); + dev->abs_x = dev->abs_x / (double) monitors[index].mon_xsize; + dev->abs_y = dev->abs_y / (double) monitors[index].mon_ysize; } - if (dev->cal_cntr || (!b && !dev->b)) { /* Calibration or no buttonpress */ - if (!b && dev->b) { - microtouch_calibrate_timer(dev); - } - dev->b = b; /* Save buttonpress */ - return 0; - } + dev->abs_x = dev->scale_x * dev->abs_x + dev->off_x; + dev->abs_y = dev->scale_y * dev->abs_y + dev->off_y; - if (dev->format == FORMAT_DEC) { - abs_x_int = abs_x * 999; - abs_y_int = 999 - (abs_y * 999); - char buffer[10]; - - if (!dev->mode_status) { - if (b) { // Touch - snprintf(buffer, sizeof(buffer), "\x1%03d,%03d\r", abs_x_int, abs_y_int); - fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); - } - } else { - if (b) { - if (!dev->b) { /* Touchdown Status */ - snprintf(buffer, sizeof(buffer), "\x19%03d,%03d\r", abs_x_int, abs_y_int); - } else { /* Touch Continuation Status */ - snprintf(buffer, sizeof(buffer), "\x1c%03d,%03d\r", abs_x_int, abs_y_int); - } - } else if (dev->b) { /* Liftoff Status */ - snprintf(buffer, sizeof(buffer), "\x18%03d,%03d\r", dev->abs_x_int, dev->abs_y_int); - } - fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); - } - } + if (dev->abs_x >= 1.0) dev->abs_x = 1.0; + if (dev->abs_y >= 1.0) dev->abs_y = 1.0; + if (dev->abs_x <= 0.0) dev->abs_x = 0.0; + if (dev->abs_y <= 0.0) dev->abs_y = 0.0; - else if (dev->format == FORMAT_HEX) { - abs_x_int = abs_x * 1023; - abs_y_int = 1023 - (abs_y * 1023); - char buffer[10]; - - if (!dev->mode_status) { - if (b) { // Touch - snprintf(buffer, sizeof(buffer), "\x1%03X,%03X\r", abs_x_int, abs_y_int); - fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); - } - } else { - if (b) { - if (!dev->b) { /* Touchdown Status */ - snprintf(buffer, sizeof(buffer), "\x19%03X,%03X\r", abs_x_int, abs_y_int); - } else { /* Touch Continuation Status */ - snprintf(buffer, sizeof(buffer), "\x1c%03X,%03X\r", abs_x_int, abs_y_int); - } - } else if (dev->b) { /* Liftoff Status */ - snprintf(buffer, sizeof(buffer), "\x18%03X,%03X\r", dev->abs_x_int, dev->abs_y_int); - } - fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer)); - } - } - - else if (dev->format == FORMAT_TABLET) { - abs_x_int = abs_x * 16383; - abs_y_int = 16383 - abs_y * 16383; - - if (b) { /* Touchdown/Continuation */ - fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((b & 3))) : 0)); - fifo8_push(&dev->resp, abs_x_int & 0b1111111); - fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111); - fifo8_push(&dev->resp, abs_y_int & 0b1111111); - fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111); - } else if (dev->b) { /* Liftoff */ - fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0)); - fifo8_push(&dev->resp, dev->abs_x_int & 0b1111111); - fifo8_push(&dev->resp, (dev->abs_x_int >> 7) & 0b1111111); - fifo8_push(&dev->resp, dev->abs_y_int & 0b1111111); - fifo8_push(&dev->resp, (dev->abs_y_int >> 7) & 0b1111111); - } - } - - /* Save old states*/ - dev->abs_x_int = abs_x_int; - dev->abs_y_int = abs_y_int; - dev->b = b; return 0; } @@ -360,37 +495,38 @@ mtouch_poll_global(void) } void * -mtouch_init(const device_t *info) +mtouch_init(UNUSED(const device_t *info)) { mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t)); dev->serial = serial_attach(device_get_config_int("port"), NULL, mtouch_write, dev); - dev->baud_rate = device_get_config_int("baudrate"); + dev->baud_rate = 9600; serial_set_cts(dev->serial, 1); serial_set_dsr(dev->serial, 1); serial_set_dcd(dev->serial, 1); fifo8_create(&dev->resp, 256); timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0); - timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); + timer_add(&dev->reset_timer, mtouch_reset_complete, dev, 0); timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10); dev->id = device_get_config_int("identity"); dev->pen_mode = 3; - dev->mode_status = false; + dev->mode = MODE_STREAM; + + sprintf(dev->nvr_path, "mtouch_%s.nvr", mtouch_identity[dev->id]); + mtouch_initnvr(dev); + mtouch_readnvr(dev); if (dev->id < 2) { /* legacy controllers */ dev->format = FORMAT_DEC; - mouse_set_sample_rate(106); - } - else { + } else { dev->format = FORMAT_TABLET; - mouse_set_sample_rate(192); } mouse_input_mode = device_get_config_int("crosshair") + 1; mouse_set_buttons(2); + mouse_set_poll(mtouch_poll, dev); mouse_set_poll_ex(mtouch_poll_global); - mtouch_inst = dev; return dev; @@ -403,8 +539,9 @@ mtouch_close(void *priv) fifo8_destroy(&dev->resp); /* Detach serial port from the mouse. */ - if (dev && dev->serial && dev->serial->sd) + if (dev && dev->serial && dev->serial->sd) { memset(dev->serial->sd, 0, sizeof(serial_device_t)); + } free(dev); mtouch_inst = NULL; @@ -413,58 +550,49 @@ mtouch_close(void *priv) static const device_config_t mtouch_config[] = { // clang-format off { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 } } }, { - .name = "baudrate", - .description = "Baud Rate", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 9600, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "19200", .value = 19200 }, - { .description = "9600", .value = 9600 }, - { .description = "4800", .value = 4800 }, - { .description = "2400", .value = 2400 }, - { .description = "1200", .value = 1200 } - } + .name = "identity", + .description = "Controller", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "A3 - SMT2 Serial / SMT3(R)V", .value = 0 }, + { .description = "A4 - SMT2 PCBus", .value = 1 }, + { .description = "P5 - TouchPen 4(+)", .value = 2 }, + { .description = "Q1 - SMT3(R) Serial", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "identity", - .description = "Controller", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "A3 - SMT2 Serial / SMT3(R)V", .value = 0 }, - { .description = "A4 - SMT2 PCBus", .value = 1 }, - { .description = "P5 - TouchPen 4(+)", .value = 2 }, - { .description = "Q1 - SMT3(R) Serial", .value = 3 } - } - }, - { - .name = "crosshair", - .description = "Show Crosshair", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "crosshair", + .description = "Show Crosshair", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -478,8 +606,8 @@ const device_t mouse_mtouch_device = { .init = mtouch_init, .close = mtouch_close, .reset = NULL, - { .poll = mtouch_poll }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mtouch_config -}; +}; \ No newline at end of file diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index c3a7310f0..79d7afc96 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -352,6 +352,8 @@ mouse_ps2_init(const device_t *info) if (dev->port != NULL) kbc_at_dev_reset(dev, 0); + mouse_set_poll(ps2_poll, dev); + /* Return our private data to the I/O layer. */ return dev; } @@ -367,20 +369,21 @@ ps2_close(void *priv) static const device_config_t ps2_config[] = { // clang-format off { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END @@ -389,14 +392,14 @@ static const device_config_t ps2_config[] = { }; const device_t mouse_ps2_device = { - .name = "Standard PS/2 Mouse", + .name = "PS/2 Mouse", .internal_name = "ps2", - .flags = DEVICE_PS2, + .flags = DEVICE_PS2_KBC, .local = MOUSE_TYPE_PS2, .init = mouse_ps2_init, .close = ps2_close, .reset = NULL, - { .poll = ps2_poll }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ps2_config diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 08aee09d8..96d3a867c 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -142,7 +142,8 @@ sermouse_transmit_byte(mouse_t *dev, int do_next) if (dev->buf_pos == 0) dev->acc_time = 0.0; - serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); + if (dev->serial) + serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]); if (do_next) { dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len; @@ -844,8 +845,7 @@ sermouse_init(const device_t *info) void (*dev_write)(struct serial_s *serial, void *priv, uint8_t data); void (*transmit_period_callback)(struct serial_s *serial, void *priv, double transmit_period); - dev = (mouse_t *) malloc(sizeof(mouse_t)); - memset(dev, 0x00, sizeof(mouse_t)); + dev = (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"); @@ -909,6 +909,8 @@ sermouse_init(const device_t *info) /* Tell them how many buttons we have. */ mouse_set_buttons(dev->but); + mouse_set_poll(sermouse_poll, dev); + /* Return our private data to the I/O layer. */ return dev; } @@ -916,41 +918,47 @@ sermouse_init(const device_t *info) static const device_config_t msssermouse_config[] = { // clang-format off { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 } } }, { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "" } - } + }, + .bios = { { 0 } } }, { - .name = "rts_toggle", - .description = "RTS toggle", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "rts_toggle", + .description = "RTS toggle", + .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 @@ -959,35 +967,37 @@ static const device_config_t msssermouse_config[] = { static const device_config_t mssermouse_config[] = { // clang-format off { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 } } }, { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -996,57 +1006,64 @@ static const device_config_t mssermouse_config[] = { static const device_config_t ltsermouse_config[] = { // clang-format off { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 } } }, { - .name = "buttons", - .description = "Buttons", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "" } - } + }, + .bios = { { 0 } } }, { - .name = "revision", - .description = "Revision", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "revision", + .description = "Revision", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "LOGIMOUSE R7 1.0", .value = 1 }, { .description = "LOGIMOUSE R7 2.0", .value = 2 }, { .description = "LOGIMOUSE C7 3.0", .value = 3 }, { .description = "Logitech MouseMan", .value = 4 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "rts_toggle", - .description = "Microsoft-compatible RTS toggle", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "rts_toggle", + .description = "RTS toggle", + .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 @@ -1060,7 +1077,7 @@ const device_t mouse_mssystems_device = { .init = sermouse_init, .close = sermouse_close, .reset = NULL, - { .poll = sermouse_poll }, + .available = NULL, .speed_changed = sermouse_speed_changed, .force_redraw = NULL, .config = msssermouse_config @@ -1074,7 +1091,7 @@ const device_t mouse_msserial_device = { .init = sermouse_init, .close = sermouse_close, .reset = NULL, - { .poll = sermouse_poll }, + .available = NULL, .speed_changed = sermouse_speed_changed, .force_redraw = NULL, .config = mssermouse_config @@ -1088,7 +1105,7 @@ const device_t mouse_ltserial_device = { .init = sermouse_init, .close = sermouse_close, .reset = NULL, - { .poll = sermouse_poll }, + .available = NULL, .speed_changed = sermouse_speed_changed, .force_redraw = NULL, .config = ltsermouse_config diff --git a/src/device/mouse_wacom_tablet.c b/src/device/mouse_wacom_tablet.c index d299d8bab..3b50882ab 100644 --- a/src/device/mouse_wacom_tablet.c +++ b/src/device/mouse_wacom_tablet.c @@ -662,8 +662,10 @@ wacom_init(const device_t *info) if (dev->tablet_type->type == WACOM_TYPE_IV) { wacom_reset_artpad(dev); wacom_process_settings_dword(dev, 0xE2018000); - } - else wacom_reset(dev); + } else + wacom_reset(dev); + + mouse_set_poll(wacom_poll, dev); return dev; } @@ -693,20 +695,21 @@ wacom_close(void *priv) static const device_config_t wacom_config[] = { // clang-format off { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, + .name = "port", + .description = "Serial Port", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "COM1", .value = 0 }, { .description = "COM2", .value = 1 }, { .description = "COM3", .value = 2 }, { .description = "COM4", .value = 3 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -720,7 +723,7 @@ const device_t mouse_wacom_device = { .init = wacom_init, .close = wacom_close, .reset = NULL, - { .poll = wacom_poll }, + .available = NULL, .speed_changed = wacom_speed_changed, .force_redraw = NULL, .config = wacom_config @@ -730,11 +733,11 @@ const device_t mouse_wacom_artpad_device = { .name = "Wacom ArtPad", .internal_name = "wacom_serial_artpad", .flags = DEVICE_COM, - .local = (uintptr_t)&artpad_id, + .local = (uintptr_t) &artpad_id, .init = wacom_init, .close = wacom_close, .reset = NULL, - { .poll = wacom_poll }, + .available = NULL, .speed_changed = wacom_speed_changed, .force_redraw = NULL, .config = wacom_config diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c index 165962f30..c0393eaa2 100644 --- a/src/device/nec_mate_unk.c +++ b/src/device/nec_mate_unk.c @@ -30,7 +30,7 @@ #include <86box/plat_unused.h> static uint8_t -nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) +nec_mate_unk_read(UNUSED(uint16_t addr), UNUSED(void *priv)) { /* Expected by this NEC machine. @@ -49,7 +49,7 @@ nec_mate_unk_close(void *priv) } static void * -nec_mate_unk_init(const device_t *info) +nec_mate_unk_init(UNUSED(const device_t *info)) { /* We have to return something non-NULL. */ uint8_t *dev = (uint8_t *) calloc(1, sizeof(uint8_t)); @@ -68,7 +68,7 @@ const device_t nec_mate_unk_device = { .init = nec_mate_unk_init, .close = nec_mate_unk_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/novell_cardkey.c b/src/device/novell_cardkey.c index 4730b6bb4..8820addde 100644 --- a/src/device/novell_cardkey.c +++ b/src/device/novell_cardkey.c @@ -27,8 +27,7 @@ #include <86box/plat.h> #include <86box/novell_cardkey.h> -typedef struct novell_cardkey_t -{ +typedef struct novell_cardkey_t { char serial_number_str[13]; } novell_cardkey_t; @@ -61,7 +60,7 @@ novell_cardkey_read(uint16_t port, void *priv) return val ^ 0xFF; } -void* novell_cardkey_init(const device_t* info) +void* novell_cardkey_init(UNUSED(const device_t* info)) { char sernumstr[13] = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 0 }; int i = 0; @@ -95,14 +94,15 @@ void novell_cardkey_close(void* priv) static const device_config_t keycard_config[] = { // clang-format off { - .name = "serial_number", - .description = "Serial Number", - .type = CONFIG_STRING, + .name = "serial_number", + .description = "Serial Number", + .type = CONFIG_STRING, .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { { 0 } } + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -116,7 +116,7 @@ const device_t novell_keycard_device = { .init = novell_cardkey_init, .close = novell_cardkey_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = keycard_config diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index c1f551162..7dda00aee 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -491,8 +491,7 @@ pci_bridge_init(const device_t *info) uint8_t interrupt_mask; uint8_t slot_count; - pci_bridge_t *dev = (pci_bridge_t *) malloc(sizeof(pci_bridge_t)); - memset(dev, 0, sizeof(pci_bridge_t)); + pci_bridge_t *dev = (pci_bridge_t *) calloc(1, sizeof(pci_bridge_t)); dev->local = info->local; dev->bus_index = pci_register_bus(); @@ -542,7 +541,7 @@ const device_t dec21150_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -557,7 +556,7 @@ const device_t ali5243_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -572,7 +571,7 @@ const device_t ali5247_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -586,7 +585,7 @@ const device_t i440lx_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -600,7 +599,7 @@ const device_t i440bx_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -614,7 +613,7 @@ const device_t i440gx_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -628,7 +627,7 @@ const device_t via_vp3_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -642,7 +641,7 @@ const device_t via_mvp3_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -656,7 +655,7 @@ const device_t via_apro_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -670,7 +669,7 @@ const device_t via_vt8601_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -684,7 +683,7 @@ const device_t sis_5xxx_agp_device = { .init = pci_bridge_init, .close = NULL, .reset = pci_bridge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/phoenix_486_jumper.c b/src/device/phoenix_486_jumper.c index a3c891c90..a3e2f0e7e 100644 --- a/src/device/phoenix_486_jumper.c +++ b/src/device/phoenix_486_jumper.c @@ -110,8 +110,7 @@ phoenix_486_jumper_close(void *priv) static void * phoenix_486_jumper_init(const device_t *info) { - phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) malloc(sizeof(phoenix_486_jumper_t)); - memset(dev, 0, sizeof(phoenix_486_jumper_t)); + phoenix_486_jumper_t *dev = (phoenix_486_jumper_t *) calloc(1, sizeof(phoenix_486_jumper_t)); dev->type = info->local; @@ -130,7 +129,7 @@ const device_t phoenix_486_jumper_device = { .init = phoenix_486_jumper_init, .close = phoenix_486_jumper_close, .reset = phoenix_486_jumper_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -144,7 +143,7 @@ const device_t phoenix_486_jumper_pci_device = { .init = phoenix_486_jumper_init, .close = phoenix_486_jumper_close, .reset = phoenix_486_jumper_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/postcard.c b/src/device/postcard.c index dbae3232a..9e2c629c1 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -187,7 +187,7 @@ const device_t postcard_device = { .init = postcard_init, .close = postcard_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/serial.c b/src/device/serial.c index ecc08f15d..c25da0070 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -15,7 +15,7 @@ * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ #include @@ -197,6 +197,8 @@ serial_receive_timer(void *priv) /* Raise Data Ready interrupt. */ dev->lsr |= 0x01; dev->int_status |= SERIAL_INT_RECEIVE; + if (dev->lsr & 0x02) + dev->int_status |= SERIAL_INT_LSR; serial_update_ints(dev); } @@ -223,7 +225,7 @@ serial_write_fifo(serial_t *dev, uint8_t dat) ((dev->type >= SERIAL_16550) && dev->fifo_enabled) ? fifo_get_count(dev->rcvr_fifo) : 0); - if (!(dev->mctrl & 0x10)) + if ((dev != NULL) && !(dev->mctrl & 0x10)) write_fifo(dev, dat); } @@ -266,10 +268,6 @@ serial_move_to_txsr(serial_t *dev) /* Update interrupts to signal THRE and that TXSR is no longer empty. */ serial_update_ints(dev); } - if (dev->transmit_enabled & 2) - dev->baud_cycles++; - else - dev->baud_cycles = 0; /* If not moving while transmitting, reset BAUDOUT cycle count. */ if (!dev->fifo_enabled || (fifo_get_count(dev->xmit_fifo) == 0x0)) dev->transmit_enabled &= ~1; /* Stop moving. */ dev->transmit_enabled |= 2; /* Start transmitting. */ @@ -303,16 +301,26 @@ static void serial_transmit_timer(void *priv) { serial_t *dev = (serial_t *) priv; - int delay = 8; /* STOP to THRE delay is 8 BAUDOUT cycles. */ + /* + Norton Diagnostics waits for up to 2 bit periods, this is + confirmed by the NS16550A timings graph, which shows operation + as follows after write: 1 bit of delay, then start bit, and at + the end of the start bit, move from THR to TXSR. + */ + int delay = 1; if (dev->transmit_enabled & 3) { + /* + If already transmitting, move from THR to TXSR at the end of + the last data bit. + */ if ((dev->transmit_enabled & 1) && (dev->transmit_enabled & 2)) - delay = dev->data_bits; /* Delay by less if already transmitting. */ + delay = dev->data_bits + 1; dev->baud_cycles++; - /* We have processed (total bits) BAUDOUT cycles, transmit the byte. */ - if ((dev->baud_cycles == dev->bits) && (dev->transmit_enabled & 2)) + /* We have processed (delay + total bits) BAUDOUT cycles, transmit the byte. */ + if ((dev->baud_cycles == (dev->bits + 1)) && (dev->transmit_enabled & 2)) serial_process_txsr(dev); /* We have processed (data bits) BAUDOUT cycles. */ @@ -614,6 +622,11 @@ serial_write(uint16_t addr, uint8_t val, void *priv) dev->msr = new_msr; + if (dev->msr & 0x0f) { + dev->int_status |= SERIAL_INT_MSR; + serial_update_ints(dev); + } + /* TODO: Why reset the FIFO's here?! */ fifo_reset(dev->xmit_fifo); fifo_reset(dev->rcvr_fifo); @@ -769,6 +782,20 @@ serial_setup(serial_t *dev, uint16_t addr, uint8_t irq) dev->irq = irq; } +void +serial_irq(serial_t *dev, const uint8_t irq) +{ + if (dev == NULL) + return; + + if (com_ports[dev->inst].enabled) + dev->irq = irq; + else + dev->irq = 0xff; + + serial_log("Port %i IRQ = %02X\n", dev->inst, irq); +} + static void serial_rcvr_d_empty_evt(void *priv) { @@ -901,8 +928,7 @@ serial_reset(void *priv) static void * serial_init(const device_t *info) { - serial_t *dev = (serial_t *) malloc(sizeof(serial_t)); - memset(dev, 0, sizeof(serial_t)); + serial_t *dev = (serial_t *) calloc(1, sizeof(serial_t)); dev->inst = next_inst; @@ -922,7 +948,7 @@ serial_init(const device_t *info) serial_setup(dev, COM4_ADDR, COM4_IRQ); else if (next_inst == 2) serial_setup(dev, COM3_ADDR, COM3_IRQ); - else if ((next_inst == 1) || (info->flags & DEVICE_PCJR)) + else if ((next_inst == 1) || (info->local == SERIAL_8250_PCJR)) serial_setup(dev, COM2_ADDR, COM2_IRQ); else if (next_inst == 0) serial_setup(dev, COM1_ADDR, COM1_IRQ); @@ -983,7 +1009,7 @@ const device_t ns8250_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -992,12 +1018,12 @@ const device_t ns8250_device = { const device_t ns8250_pcjr_device = { .name = "National Semiconductor 8250(-compatible) UART for PCjr", .internal_name = "ns8250_pcjr", - .flags = DEVICE_PCJR, + .flags = 0, .local = SERIAL_8250_PCJR, .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -1011,7 +1037,7 @@ const device_t ns16450_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -1025,7 +1051,7 @@ const device_t ns16550_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -1039,7 +1065,7 @@ const device_t ns16650_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -1053,7 +1079,7 @@ const device_t ns16750_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -1067,7 +1093,7 @@ const device_t ns16850_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL @@ -1081,7 +1107,7 @@ const device_t ns16950_device = { .init = serial_init, .close = serial_close, .reset = serial_reset, - { .available = NULL }, + .available = NULL, .speed_changed = serial_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index eec9fa62a..3ad969006 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -178,8 +178,7 @@ serial_passthrough_dev_init(const device_t *info) { serial_passthrough_t *dev; - dev = (serial_passthrough_t *) malloc(sizeof(serial_passthrough_t)); - memset(dev, 0, sizeof(serial_passthrough_t)); + dev = (serial_passthrough_t *) calloc(1, sizeof(serial_passthrough_t)); dev->mode = device_get_config_int("mode"); dev->port = device_get_instance() - 1; @@ -232,151 +231,142 @@ const char *serpt_mode_names[SERPT_MODES_MAX] = { // clang-format off static const device_config_t serial_passthrough_config[] = { { - .name = "mode", - .description = "Passthrough Mode", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "mode", + .description = "Passthrough Mode", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { #ifdef _WIN32 - { - .description = "Named Pipe (Server)", - .value = SERPT_MODE_VCON - }, + { .description = "Named Pipe (Server)", .value = SERPT_MODE_VCON }, #if 0 /* TODO */ - { - .description = "Named Pipe (Client)", - .value = SERPT_MODE_VCON - }, -#endif -#else - { - .description = "Pseudo Terminal/Virtual Console", - .value = SERPT_MODE_VCON - }, + { .description = "Named Pipe (Client)", .value = SERPT_MODE_VCON }, #endif +#else /* _WIN32 */ + { .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_TCPSRV }, + { .description = "TCP Client", .value = SERPT_MODE_TCPCLNT }, #endif - { - .description = "Host Serial Passthrough", - .value = SERPT_MODE_HOSTSER - }, - { - .description = "" - } - } + { .description = "Host Serial Passthrough", .value = SERPT_MODE_HOSTSER }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "host_serial_path", - .description = "Host Serial Device", - .type = CONFIG_SERPORT, - .default_string = "", - .file_filter = NULL, - .spinner = {}, - .selection = {} + .name = "host_serial_path", + .description = "Host Serial Device", + .type = CONFIG_SERPORT, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, #ifdef _WIN32 { - .name = "named_pipe", - .description = "Name of pipe", - .type = CONFIG_STRING, + .name = "named_pipe", + .description = "Name of pipe", + .type = CONFIG_STRING, .default_string = "\\\\.\\pipe\\86Box\\test", - .file_filter = NULL, - .spinner = {}, - .selection = {} + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, -#endif +#endif /* _WIN32 */ { - .name = "data_bits", - .description = "Data bits", - .type = CONFIG_SELECTION, - .default_string = "8", - .default_int = 8, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { + .name = "data_bits", + .description = "Data bits", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 8, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { #if 0 /* Mentioned by WFW 3.1x, not supported, atleast on Linux */ { .description = "4", .value = 4 }, #endif { .description = "5", .value = 5 }, { .description = "6", .value = 6 }, { .description = "7", .value = 7 }, - { .description = "8", .value = 8 } - } + { .description = "8", .value = 8 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "stop_bits", - .description = "Stop bits", - .type = CONFIG_SELECTION, - .default_string = "1", - .default_int = 1, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { + .name = "stop_bits", + .description = "Stop bits", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "1", .value = 1 }, #if 0 { .description = "1.5", .value = 1.5 }, #endif - { .description = "2", .value = 2 } - } + { .description = "2", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "baudrate", - .description = "Baud Rate of Passthrough", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 115200, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { + .name = "baudrate", + .description = "Baud Rate of Passthrough", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 115200, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { #if 0 - { .description = "256000", .value = 256000 }, - { .description = "128000", .value = 128000 }, + { .description = "256000", .value = 256000 }, + { .description = "128000", .value = 128000 }, #endif - { .description = "115200", .value = 115200 }, - { .description = "57600", .value = 57600 }, - { .description = "56000", .value = 56000 }, - { .description = "38400", .value = 38400 }, - { .description = "19200", .value = 19200 }, - { .description = "14400", .value = 14400 }, - { .description = "9600", .value = 9600 }, - { .description = "7200", .value = 7200 }, - { .description = "4800", .value = 4800 }, - { .description = "2400", .value = 2400 }, - { .description = "1800", .value = 1800 }, - { .description = "1200", .value = 1200 }, - { .description = "600", .value = 600 }, - { .description = "300", .value = 300 }, - { .description = "150", .value = 150 }, + { .description = "115200", .value = 115200 }, + { .description = "57600", .value = 57600 }, + { .description = "56000", .value = 56000 }, + { .description = "38400", .value = 38400 }, + { .description = "19200", .value = 19200 }, + { .description = "14400", .value = 14400 }, + { .description = "9600", .value = 9600 }, + { .description = "7200", .value = 7200 }, + { .description = "4800", .value = 4800 }, + { .description = "2400", .value = 2400 }, + { .description = "1800", .value = 1800 }, + { .description = "1200", .value = 1200 }, + { .description = "600", .value = 600 }, + { .description = "300", .value = 300 }, + { .description = "150", .value = 150 }, #if 0 { .description = "134.5", .value = 134.5 }, #endif - { .description = "110", .value = 110 }, - { .description = "75", .value = 75 } - } + { .description = "110", .value = 110 }, + { .description = "75", .value = 75 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on const device_t serial_passthrough_device = { - .name = "Serial Passthrough Device", - .flags = 0, - .local = 0, - .init = serial_passthrough_dev_init, - .close = serial_passthrough_dev_close, - .reset = NULL, - { .poll = NULL }, + .name = "Serial Passthrough Device", + .flags = 0, + .local = 0, + .init = serial_passthrough_dev_init, + .close = serial_passthrough_dev_close, + .reset = NULL, + .available = NULL, .speed_changed = serial_passthrough_speed_changed, .force_redraw = NULL, .config = serial_passthrough_config diff --git a/src/device/smbus_ali7101.c b/src/device/smbus_ali7101.c index 349de470d..49eb44bc6 100644 --- a/src/device/smbus_ali7101.c +++ b/src/device/smbus_ali7101.c @@ -273,7 +273,7 @@ smbus_ali7101_reset(void *priv) static void * smbus_ali7101_init(const device_t *info) { - smbus_ali7101_t *dev = (smbus_ali7101_t *) malloc(sizeof(smbus_ali7101_t)); + smbus_ali7101_t *dev = (smbus_ali7101_t *) calloc(1, sizeof(smbus_ali7101_t)); memset(dev, 0, sizeof(smbus_ali7101_t)); dev->local = info->local; @@ -302,12 +302,12 @@ smbus_ali7101_close(void *priv) const device_t ali7101_smbus_device = { .name = "ALi M7101-compatible SMBus Host Controller", .internal_name = "ali7101_smbus", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = smbus_ali7101_init, .close = smbus_ali7101_close, .reset = smbus_ali7101_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index 6f2b1632e..ae37c72c4 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -357,8 +357,7 @@ smbus_piix4_setclock(smbus_piix4_t *dev, int clock) static void * smbus_piix4_init(const device_t *info) { - smbus_piix4_t *dev = (smbus_piix4_t *) malloc(sizeof(smbus_piix4_t)); - memset(dev, 0, sizeof(smbus_piix4_t)); + smbus_piix4_t *dev = (smbus_piix4_t *) calloc(1, sizeof(smbus_piix4_t)); dev->local = info->local; /* We save the I2C bus handle on dev but use i2c_smbus for all operations because @@ -387,12 +386,12 @@ smbus_piix4_close(void *priv) const device_t piix4_smbus_device = { .name = "PIIX4-compatible SMBus Host Controller", .internal_name = "piix4_smbus", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = SMBUS_PIIX4, .init = smbus_piix4_init, .close = smbus_piix4_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -401,12 +400,12 @@ const device_t piix4_smbus_device = { const device_t via_smbus_device = { .name = "VIA VT82C686B SMBus Host Controller", .internal_name = "via_smbus", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = SMBUS_VIA, .init = smbus_piix4_init, .close = smbus_piix4_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/smbus_sis5595.c b/src/device/smbus_sis5595.c index 191e7a6a5..42d1452ad 100644 --- a/src/device/smbus_sis5595.c +++ b/src/device/smbus_sis5595.c @@ -343,8 +343,7 @@ smbus_sis5595_reset(void *priv) static void * smbus_sis5595_init(const device_t *info) { - smbus_sis5595_t *dev = (smbus_sis5595_t *) malloc(sizeof(smbus_sis5595_t)); - memset(dev, 0, sizeof(smbus_sis5595_t)); + smbus_sis5595_t *dev = (smbus_sis5595_t *) calloc(1, sizeof(smbus_sis5595_t)); dev->local = info->local; @@ -374,12 +373,12 @@ smbus_sis5595_close(void *priv) const device_t sis5595_smbus_device = { .name = "SiS 5595-compatible SMBus Host Controller", .internal_name = "sis5595_smbus", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = smbus_sis5595_init, .close = smbus_sis5595_close, .reset = smbus_sis5595_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/device/unittester.c b/src/device/unittester.c index e52f3b56f..0e864aa0b 100644 --- a/src/device/unittester.c +++ b/src/device/unittester.c @@ -104,8 +104,8 @@ struct unittester_state { /* 0x04: Exit */ uint8_t exit_code; }; -static struct unittester_state unittester; -static const struct unittester_state unittester_defaults = { +static struct unittester_state unittester; +static struct unittester_state unittester_defaults = { .trigger_port = 0x0080, .iobase_port = 0xFFFF, .fsm1 = UT_FSM1_WAIT_8, @@ -114,15 +114,6 @@ static const struct unittester_state unittester_defaults = { .cmd_id = UT_CMD_NOOP, }; -static const device_config_t unittester_config[] = { - { .name = "exit_enabled", - .description = "Enable 0x04 \"Exit 86Box\" command", - .type = CONFIG_BINARY, - .default_int = 1, - .default_string = "" }, - { .type = CONFIG_END } -}; - /* Kept separate, as we will be reusing this object */ static bitmap_t *unittester_screen_buffer = NULL; @@ -589,7 +580,7 @@ unittester_trigger_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) static void * unittester_init(UNUSED(const device_t *info)) { - unittester = (struct unittester_state) unittester_defaults; + unittester = unittester_defaults; unittester_exit_enabled = !!device_get_config_int("exit_enabled"); @@ -620,6 +611,23 @@ unittester_close(UNUSED(void *priv)) unittester_log("[UT] 86Box Unit Tester closed\n"); } +static const device_config_t unittester_config[] = { + // clang-format off + { + .name = "exit_enabled", + .description = "Enable 0x04 \"Exit 86Box\" command", + .type = CONFIG_BINARY, + .default_int = 1, + .default_string = NULL, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t unittester_device = { .name = "86Box Unit Tester", .internal_name = "unittester", @@ -628,7 +636,7 @@ const device_t unittester_device = { .init = unittester_init, .close = unittester_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = unittester_config, diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 87b9593fa..3f6a4d018 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -9,14 +9,33 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c - hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c - hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c lba_enhancer.c) +add_library(hdd OBJECT + hdd.c + hdd_image.c + hdd_table.c + hdc.c + hdc_st506_xt.c + hdc_st506_at.c + hdc_xta.c + hdc_esdi_at.c + hdc_esdi_mca.c + hdc_xtide.c + hdc_ide.c + hdc_ide_ali5213.c + hdc_ide_opti611.c + hdc_ide_cmd640.c + hdc_ide_cmd646.c + hdc_ide_sff8038i.c + hdc_ide_um8673f.c + hdc_ide_w83769f.c + lba_enhancer.c +) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_esdi_at.c b/src/disk/hdc_esdi_at.c index e16d4d729..ab24aa6fa 100644 --- a/src/disk/hdc_esdi_at.c +++ b/src/disk/hdc_esdi_at.c @@ -552,6 +552,29 @@ esdi_read(uint16_t port, void *priv) return temp; } +/** + * Copy a string into a buffer, padding with spaces, and placing characters as + * if they were packed into 16-bit values, stored little-endian. + * + * @param str Destination buffer + * @param src Source string + * @param len Length of destination buffer to fill in. Strings shorter than + * this length will be padded with spaces. + */ +static void +esdi_padstr(char *str, const char *src, const int len) +{ + int v; + + for (int i = 0; i < len; i++) { + if (*src != '\0') + v = *src++; + else + v = ' '; + str[i ^ 1] = v; + } +} + static void esdi_callback(void *priv) { @@ -606,12 +629,16 @@ esdi_callback(void *priv) } else { if (get_sector(esdi, &addr)) { esdi->error = ERR_ID_NOT_FOUND; +read_error: esdi->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(esdi); break; } - hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer); + if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) { + esdi->error = ERR_BAD_BLOCK; + goto read_error; + } esdi->pos = 0; esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; irq_raise(esdi); @@ -628,13 +655,17 @@ esdi_callback(void *priv) } else { if (get_sector(esdi, &addr)) { esdi->error = ERR_ID_NOT_FOUND; +write_error: esdi->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(esdi); ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); break; } - hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer); + if (hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) { + esdi->error = ERR_BAD_BLOCK; + goto write_error; + } irq_raise(esdi); esdi->secount = (esdi->secount - 1) & 0xff; if (esdi->secount) { @@ -659,13 +690,17 @@ esdi_callback(void *priv) } else { if (get_sector(esdi, &addr)) { esdi->error = ERR_ID_NOT_FOUND; +verify_error: esdi->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(esdi); ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); break; } - hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer); + if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) { + esdi->error = ERR_BAD_BLOCK; + goto verify_error; + } ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1); next_sector(esdi); esdi->secount = (esdi->secount - 1) & 0xff; @@ -692,12 +727,16 @@ esdi_callback(void *priv) } else { if (get_sector_format(esdi, &addr)) { esdi->error = ERR_ID_NOT_FOUND; +format_error: esdi->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(esdi); break; } - hdd_image_zero(drive->hdd_num, addr, esdi->secount); + if (hdd_image_zero(drive->hdd_num, addr, esdi->secount) < 0) { + esdi->error = ERR_BAD_BLOCK; + goto format_error; + } esdi->status = STAT_READY | STAT_DSC; irq_raise(esdi); } @@ -795,28 +834,36 @@ esdi_callback(void *priv) irq_raise(esdi); } else { memset(esdi->buffer, 0x00, 512); - esdi->buffer[0] = 0x44; /* general configuration */ - esdi->buffer[1] = drive->real_tracks; /* number of non-removable cylinders */ - esdi->buffer[2] = 0; /* number of removable cylinders */ - esdi->buffer[3] = drive->real_hpc; /* number of heads */ - esdi->buffer[4] = 600; /* number of unformatted bytes/sector */ - esdi->buffer[5] = esdi->buffer[4] * drive->real_spt; /* number of unformatted bytes/track */ - esdi->buffer[6] = drive->real_spt; /* number of sectors */ - esdi->buffer[7] = 0; /*minimum bytes in inter-sector gap*/ - esdi->buffer[8] = 0; /* minimum bytes in postamble */ - esdi->buffer[9] = 0; /* number of words of vendor status */ - /* controller info */ - esdi->buffer[20] = 2; /* controller type */ - esdi->buffer[21] = 1; /* sector buffer size, in sectors */ - esdi->buffer[22] = 0; /* ecc bytes appended */ - esdi->buffer[27] = 'W' | ('D' << 8); - esdi->buffer[28] = '1' | ('0' << 8); - esdi->buffer[29] = '0' | ('7' << 8); - esdi->buffer[30] = 'V' | ('-' << 8); - esdi->buffer[31] = 'S' | ('E' << 8); - esdi->buffer[32] = '1'; - esdi->buffer[47] = 0; /* sectors per interrupt */ - esdi->buffer[48] = 0; /* can use double word read/write? */ + esdi->buffer[0] = 0x3244; /* + Soft sectored (0x0004), + Fixed drive (0x0040), + Transfer rate > 5 Mbps but <= 10 Mbps (0x0200), + Data strobe offset option (0x1000), + Track offset option (0x2000). + */ + if (drive->real_spt >= 26) + esdi->buffer[0] |= 0x0008; /* Not MFM encoded. */ + esdi->buffer[1] = drive->real_tracks; /* Fixed cylinders - the BIOS lists 2 less. */ + esdi->buffer[2] = 0; /* Removable cylinders. */ + esdi->buffer[3] = drive->real_hpc; /* Heads. */ + esdi->buffer[5] = 600; /* Unformatted bytes per sector. */ + esdi->buffer[4] = esdi->buffer[5] * drive->real_spt; /* Unformatted bytes per track. */ + esdi->buffer[6] = drive->real_spt; /* Sectors per track - the BIOS lists 1 less. */ + esdi->buffer[7] = 3088; /* Bytes in inter-sector gap. */ + esdi->buffer[8] = 11; /* Byce in sync fileds. */ + esdi->buffer[9] = 0xf; /* Number of vendor unique words. */ + /* Serial Number */ + esdi_padstr((char *) (esdi->buffer + 10), "00000000000000000000", 20); + /* Controller information. */ + esdi->buffer[20] = 3; /* Buffer type. */ + esdi->buffer[21] = 64; /* Buffer size in 512-byte increments. */ + esdi->buffer[22] = 4; /* Bytes of ECC. */ + /* Firmware */ + esdi_padstr((char *) (esdi->buffer + 23), "REV. A5", 8); + /* Model */ + esdi_padstr((char *) (esdi->buffer + 27), "WD1007V", 40); + esdi->buffer[47] = 1; /* Sectors per interrupt. */ + esdi->buffer[48] = 0; /* Can use DWord read/write? */ esdi->pos = 0; esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; irq_raise(esdi); @@ -873,12 +920,11 @@ wd1007vse1_init(UNUSED(const device_t *info)) { int c; - esdi_t *esdi = malloc(sizeof(esdi_t)); - memset(esdi, 0x00, sizeof(esdi_t)); + esdi_t *esdi = calloc(1, sizeof(esdi_t)); c = 0; for (uint8_t d = 0; d < HDD_NUM; d++) { - if ((hdd[d].bus == HDD_BUS_ESDI) && (hdd[d].esdi_channel < ESDI_NUM)) { + if ((hdd[d].bus_type == HDD_BUS_ESDI) && (hdd[d].esdi_channel < ESDI_NUM)) { loadhd(esdi, hdd[d].esdi_channel, d, hdd[d].fn); if (++c >= ESDI_NUM) @@ -938,12 +984,12 @@ wd1007vse1_available(void) const device_t esdi_at_wd1007vse1_device = { .name = "Western Digital WD1007V-SE1 (ESDI)", .internal_name = "esdi_at", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = wd1007vse1_init, .close = wd1007vse1_close, .reset = NULL, - { .available = wd1007vse1_available }, + .available = wd1007vse1_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index adc5cd6a0..5656181f0 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -193,6 +193,7 @@ enum { #define CMD_READ_VERIFY 0x03 #define CMD_WRITE_VERIFY 0x04 #define CMD_SEEK 0x05 +#define CMD_PARK_HEADS 0x06 #define CMD_GET_DEV_STATUS 0x08 #define CMD_GET_DEV_CONFIG 0x09 #define CMD_GET_POS_INFO 0x0a @@ -331,6 +332,27 @@ rba_out_of_range(esdi_t *dev) ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); } +static void +defective_block(esdi_t *dev) +{ + dev->status_len = 9; + dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev; + dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/ + dev->status_data[2] = 0x0009; /*Defective block*/ + dev->status_data[3] = 0; + dev->status_data[4] = 0; + dev->status_data[5] = 0; + dev->status_data[6] = 0; + dev->status_data[7] = 0; + dev->status_data[8] = 0; + + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + dev->irq_in_progress = 1; + set_irq(dev); + ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0); +} + static void complete_command_status(esdi_t *dev) { @@ -376,7 +398,9 @@ esdi_callback(void *priv) if (dev->in_reset) { esdi_mca_log("ESDI reset.\n"); dev->in_reset = 0; - dev->status = STATUS_IRQ; + dev->status = STATUS_IRQ | STATUS_TRANSFER_REQ | STATUS_STATUS_OUT_FULL; + dev->status_len = 1; /*ToDo: better implementation for Xenix?*/ + dev->status_data[0] = STATUS_LEN(1) | ATTN_HOST_ADAPTER; dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; return; } @@ -425,7 +449,10 @@ esdi_callback(void *priv) if (!dev->data_pos) { if (dev->rba >= drive->sectors) fatal("Read past end of drive\n"); - hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data); + if (hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data) < 0) { + defective_block(dev); + return; + } cmd_time += hdd_timing_read(&hdd[drive->hdd_num], dev->rba, 1); cmd_time += esdi_mca_get_xfer_time(dev, 1); } @@ -514,7 +541,10 @@ esdi_callback(void *priv) if (dev->rba >= drive->sectors) fatal("Write past end of drive\n"); - hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data); + if (hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data) < 0) { + defective_block(dev); + return; + } cmd_time += hdd_timing_write(&hdd[drive->hdd_num], dev->rba, 1); cmd_time += esdi_mca_get_xfer_time(dev, 1); dev->rba++; @@ -610,6 +640,35 @@ esdi_callback(void *priv) } break; + case CMD_PARK_HEADS: + ESDI_DRIVE_ONLY(); + + if (!drive->present) { + device_not_present(dev); + return; + } + + switch (dev->cmd_state) { + case 0: + dev->rba = 0x00000000; + cmd_time = hdd_seek_get_time(&hdd[drive->hdd_num], dev->rba, HDD_OP_SEEK, 0, 0.0); + esdi_mca_set_callback(dev, ESDI_TIME + cmd_time); + dev->cmd_state = 1; + break; + + case 1: + complete_command_status(dev); + dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + dev->irq_in_progress = 1; + set_irq(dev); + break; + + default: + break; + } + break; + case CMD_GET_DEV_STATUS: ESDI_DRIVE_ONLY(); @@ -1046,8 +1105,10 @@ esdi_readw(uint16_t port, void *priv) switch (port & 7) { case 0: /*Status Interface Register*/ - if (dev->status_pos >= dev->status_len) + if (dev->status_pos >= dev->status_len) { + esdi_mca_log("esdi_readw port=%04x, ret=0000 (pos=%d, len=%d).\n", port, dev->status_pos, dev->status_len); return 0; + } ret = dev->status_data[dev->status_pos++]; if (dev->status_pos >= dev->status_len) { dev->status &= ~STATUS_STATUS_OUT_FULL; @@ -1059,6 +1120,7 @@ esdi_readw(uint16_t port, void *priv) fatal("esdi_readw port=%04x\n", port); } + esdi_mca_log("esdi_readw port=%04x, ret=%04x.\n", port, ret); return ret; } @@ -1274,10 +1336,9 @@ esdi_init(UNUSED(const device_t *info)) uint8_t c; uint8_t i; - dev = malloc(sizeof(esdi_t)); + dev = calloc(1, sizeof(esdi_t)); if (dev == NULL) return (NULL); - memset(dev, 0x00, sizeof(esdi_t)); /* Mark as unconfigured. */ dev->irq_status = 0xff; @@ -1292,7 +1353,7 @@ esdi_init(UNUSED(const device_t *info)) dev->drives[0].present = dev->drives[1].present = 0; for (c = 0, i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_ESDI) && (hdd[i].esdi_channel < ESDI_NUM)) { + if ((hdd[i].bus_type == HDD_BUS_ESDI) && (hdd[i].esdi_channel < ESDI_NUM)) { /* This is an ESDI drive. */ drive = &dev->drives[hdd[i].esdi_channel]; @@ -1309,7 +1370,7 @@ esdi_init(UNUSED(const device_t *info)) drive->spt = hdd[i].spt; drive->hpc = hdd[i].hpc; drive->tracks = hdd[i].tracks; - drive->sectors = hdd_image_get_last_sector(i) + 1; + drive->sectors = hdd_image_get_last_sector(i); drive->hdd_num = i; /* Mark drive as present. */ @@ -1385,7 +1446,7 @@ const device_t esdi_ps2_device = { .init = esdi_init, .close = esdi_close, .reset = NULL, - { .available = esdi_available }, + .available = esdi_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 3793f778b..b69ddf128 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -145,7 +145,7 @@ typedef struct mcide_t { rom_t bios_rom; } mcide_t; -ide_board_t *ide_boards[IDE_BUS_MAX]; +ide_board_t *ide_boards[IDE_BUS_MAX] = { 0 }; static uint8_t ide_ter_pnp_rom[] = { /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ @@ -386,7 +386,7 @@ ide_atapi_get_period(uint8_t channel) } static void -ide_irq_update(ide_board_t *dev, int log) +ide_irq_update(ide_board_t *dev, UNUSED(int log)) { ide_t *ide; uint8_t set; @@ -486,7 +486,7 @@ ide_get_max(const ide_t *ide, const int type) int ret; if (ide->type == IDE_ATAPI) - ret = ide->get_max(!IDE_ATAPI_IS_EARLY && ata_4, type); + ret = ide->get_max(ide, !IDE_ATAPI_IS_EARLY && ata_4, type); else ret = max[ata_4][type]; @@ -501,7 +501,7 @@ ide_get_timings(const ide_t *ide, const int type) int ret; if (ide->type == IDE_ATAPI) - ret = ide->get_timings(!IDE_ATAPI_IS_EARLY && ata_4, type); + ret = ide->get_timings(ide, !IDE_ATAPI_IS_EARLY && ata_4, type); else ret = timings[ata_4][type]; @@ -558,7 +558,10 @@ ide_hd_identify(const ide_t *ide) /* Firmware */ ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Model */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); + if (hdd[ide->hdd_num].model) + ide_padstr((char *) (ide->buffer + 27), hdd[ide->hdd_num].model, 40); + else + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Fixed drive */ ide->buffer[0] = (1 << 6); /* Buffer type */ @@ -615,9 +618,12 @@ ide_hd_identify(const ide_t *ide) if (!ide_boards[ide->board]->force_ata3 && (bm != NULL)) { ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ ide->buffer[81] = 0x19; /*ATA-6 revision 3a supported*/ - } else { + } else ide->buffer[80] = 0x0e; /*ATA-1 to ATA-3 supported*/ - } + + ide->buffer[83] = ide->buffer[84] = 0x4000; + ide->buffer[86] = 0x0000; + ide->buffer[87] = 0x4000; } static void @@ -637,7 +643,7 @@ ide_identify(ide_t *ide) memset(ide->buffer, 0, 512); if (ide->type == IDE_ATAPI) - ide->identify(ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL)); + ide->identify((const ide_t *) ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL)); else if (ide->type == IDE_HDD) ide_hd_identify(ide); else { @@ -967,7 +973,7 @@ ide_atapi_attach(ide_t *ide) ide->type = IDE_ATAPI; ide_allocate_buffer(ide); ide_set_signature(ide); - ide->mdma_mode = (1 << ide->get_max(!IDE_ATAPI_IS_EARLY && + ide->mdma_mode = (1 << ide->get_max((const ide_t *) ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL), TYPE_PIO)); ide->tf->error = 1; ide->cfg_spt = ide->cfg_hpc = 0; @@ -1252,7 +1258,10 @@ ide_write_data(ide_t *ide, const uint16_t val) const double xfer_time = ide_get_xfer_time(ide, 512); const double wait_time = seek_time + xfer_time; if (ide->command == WIN_WRITE_MULTIPLE) { - if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { + if (hdd[ide->hdd_num].speed_preset == 0) { + ide->pending_delay = 0; + ide_callback(ide); + } else if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); ide->pending_delay = 0; } else { @@ -1607,9 +1616,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->sc->callback = 100.0 * IDE_TIME; ide_set_callback(ide, 100.0 * IDE_TIME); } else { - double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ? - ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0); - ide_set_callback(ide, seek_time); + if (hdd[ide->hdd_num].speed_preset == 0) + ide_set_callback(ide, 100.0 * IDE_TIME); + else { + double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ? + ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0); + ide_set_callback(ide, seek_time); + } } break; @@ -1642,7 +1655,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->sc->callback = 200.0 * IDE_TIME; if (ide->type == IDE_HDD) { - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); uint32_t sec_count; double wait_time; if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { @@ -1652,6 +1665,10 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time > xfer_time ? seek_time : xfer_time; + } else if ((val == WIN_READ_MULTIPLE) && (hdd[ide->hdd_num].speed_preset == 0)) { + ide_set_callback(ide, 200.0 * IDE_TIME); + ide->do_initial_read = 1; + break; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) { sec_count = ide->tf->secount ? ide->tf->secount : 256; if (sec_count > ide->blocksize) @@ -1680,7 +1697,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->blockcount = 0; /* Turn on the activity indicator *here* so that it gets turned on less times. */ - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); fallthrough; case WIN_WRITE: @@ -1848,7 +1865,9 @@ ide_read_data(ide_t *ide) ide_next_sector(ide); ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT; if (ide->command == WIN_READ_MULTIPLE) { - if (!ide->blockcount) { + if (hdd[ide->hdd_num].speed_preset == 0) + ide_callback(ide); + else if (!ide->blockcount) { uint32_t cnt = ide->tf->secount ? ide->tf->secount : 256; if (cnt > ide->blocksize) @@ -1866,7 +1885,7 @@ ide_read_data(ide_t *ide) ide_set_callback(ide, seek_us + xfer_us); } } else - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0); } } } @@ -1875,7 +1894,7 @@ ide_read_data(ide_t *ide) } static uint8_t -ide_status(ide_t *ide, ide_t *ide_other, int ch) +ide_status(ide_t *ide, UNUSED(ide_t *ide_other), UNUSED(int ch)) { uint8_t ret; @@ -1888,8 +1907,7 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch) /* On real hardware, a slave with a present master always returns a status of 0x00. Confirmed by the ATA-3 and ATA-4 specifications. */ - // ret = 0x00; - ret = 0x01; + ret = 0x00; } else { ret = ide->tf->atastat; if (ide->type == IDE_ATAPI) @@ -2202,9 +2220,10 @@ ide_callback(void *priv) if (ide->do_initial_read) { ide->do_initial_read = 0; ide->sector_pos = 0; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), - ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer); - } + ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide), + ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer); + } else + ret = 0; memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); @@ -2212,10 +2231,14 @@ ide_callback(void *priv) ide->tf->pos = 0; ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + if (ret < 0) { + ide_log("IDE %i: Read aborted (image read error)\n", ide->channel); + err = UNC_ERR; + } ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); } break; @@ -2233,11 +2256,13 @@ ide_callback(void *priv) ide->sector_pos = ide->tf->secount; else ide->sector_pos = 256; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer); ide->tf->pos = 0; - if (!ide_boards[ide->board]->force_ata3 && bm->dma) { + if (hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer) < 0) { + ide_log("IDE %i: DMA read aborted (image read error)\n", ide->channel); + err = UNC_ERR; + } else if (!ide_boards[ide->board]->force_ata3 && bm->dma) { /* We should not abort - we should simply wait for the host to start DMA. */ ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv); if (ret == 2) { @@ -2252,7 +2277,7 @@ ide_callback(void *priv) ide->tf->atastat = DRDY_STAT | DSC_STAT; ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0); } else { /* Bus master DMAS error, abort the command. */ ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); @@ -2280,8 +2305,10 @@ ide_callback(void *priv) if (ide->do_initial_read) { ide->do_initial_read = 0; ide->sector_pos = 0; - hdd_image_read(ide->hdd_num, ide_get_sector(ide), - ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer); + ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide), + ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer); + } else { + ret = 0; } memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); @@ -2290,6 +2317,10 @@ ide_callback(void *priv) ide->tf->pos = 0; ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; + if (ret < 0) { + ide_log("IDE %i: Read aborted (image read error)\n", ide->channel); + err = UNC_ERR; + } if (!ide->blockcount) ide_irq_raise(ide); ide->blockcount++; @@ -2308,18 +2339,20 @@ ide_callback(void *priv) else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide_irq_raise(ide); ide->tf->secount--; if (ide->tf->secount) { ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT; ide->tf->pos = 0; ide_next_sector(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); } else { ide->tf->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0); } + if (ret < 0) + err = UNC_ERR; } ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, sector); break; @@ -2348,15 +2381,17 @@ ide_callback(void *priv) return; } else if (ret == 1) { /* DMA successful */ - ide_log("IDE %i: DMA write successful\n", ide->channel); + ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), + ide->sector_pos, ide->sector_buffer); - hdd_image_write(ide->hdd_num, ide_get_sector(ide), - ide->sector_pos, ide->sector_buffer); + ide_log("IDE %i: DMA write %ssuccessful\n", ide->channel, (ret < 0) ? "un" : ""); ide->tf->atastat = DRDY_STAT | DSC_STAT; + if (ret < 0) + err = UNC_ERR; ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0); } else { /* Bus master DMA error, abort the command. */ ide_log("IDE %i: DMA read aborted (failed)\n", ide->channel); @@ -2381,7 +2416,7 @@ ide_callback(void *priv) else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { - hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->blockcount++; if (ide->blockcount >= ide->blocksize || ide->tf->secount == 1) { ide->blockcount = 0; @@ -2394,8 +2429,10 @@ ide_callback(void *priv) ide_next_sector(ide); } else { ide->tf->atastat = DRDY_STAT | DSC_STAT; - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 0); } + if (ret < 0) + err = UNC_ERR; } break; @@ -2409,7 +2446,7 @@ ide_callback(void *priv) ide->tf->pos = 0; ide->tf->atastat = DRDY_STAT | DSC_STAT; ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); } break; @@ -2419,12 +2456,14 @@ ide_callback(void *priv) else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { - hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount); + ret = hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount); ide->tf->atastat = DRDY_STAT | DSC_STAT; + if (ret < 0) + err = UNC_ERR; ide_irq_raise(ide); - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1); + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); } break; @@ -2720,7 +2759,7 @@ ide_board_setup(const int board) c = 0; for (d = 0; d < HDD_NUM; d++) { - const int is_ide = (hdd[d].bus == HDD_BUS_IDE); + const int is_ide = (hdd[d].bus_type == HDD_BUS_IDE); const int ch = hdd[d].ide_channel; const int valid_ch = ((ch >= min_ch) && (ch <= max_ch)); @@ -2863,6 +2902,25 @@ ide_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) } } +static void * +ide_sec_init(const device_t *info) +{ + /* Don't claim this channel again if it was already claimed. */ + if (ide_boards[1]) + return (NULL); + + ide_board_init(1, HDC_SECONDARY_IRQ, HDC_SECONDARY_BASE, HDC_SECONDARY_SIDE, info->local, info->flags); + + return (ide_boards[1]); +} + +/* Close a standalone IDE unit. */ +static void +ide_sec_close(UNUSED(void *priv)) +{ + ide_board_close(1); +} + static void * ide_ter_init(const device_t *info) { @@ -2881,9 +2939,8 @@ ide_ter_init(const device_t *info) if (irq == -1) isapnp_add_card(ide_ter_pnp_rom, sizeof(ide_ter_pnp_rom), ide_pnp_config_changed, NULL, NULL, NULL, (void *) 2); - } else { + } else ide_board_init(2, irq, HDC_TERTIARY_BASE, HDC_TERTIARY_SIDE, 0, 0); - } return (ide_boards[2]); } @@ -2965,10 +3022,10 @@ ide_init(const device_t *info) switch (info->local) { case 0 ... 5: - ide_board_init(0, 14, 0x1f0, 0x3f6, info->local, info->flags); + ide_board_init(0, HDC_PRIMARY_IRQ, HDC_PRIMARY_BASE, HDC_PRIMARY_SIDE, info->local, info->flags); if (info->local & 1) - ide_board_init(1, 15, 0x170, 0x376, info->local, info->flags); + ide_board_init(1, HDC_SECONDARY_IRQ, HDC_SECONDARY_BASE, HDC_SECONDARY_SIDE, info->local, info->flags); break; default: @@ -3083,8 +3140,8 @@ static void mcide_mca_write(const int port, const uint8_t val, void *priv) { mcide_t *dev = (mcide_t *) priv; - uint16_t bases[4] = { 0x01f0, 0x0170, 0x01e8, 0x0168 }; - int irqs[4] = { 10, 11, 14, 15 }; + uint16_t bases[4] = { HDC_PRIMARY_BASE, HDC_SECONDARY_BASE, HDC_TERTIARY_BASE, HDC_QUATERNARY_BASE }; + int irqs[4] = { HDC_QUATERNARY_IRQ, HDC_TERTIARY_IRQ, HDC_PRIMARY_IRQ, HDC_SECONDARY_IRQ }; if ((port >= 0x102) && (dev->pos_regs[port & 7] != val)) { ide_log("IDE: mcawr(%04x, %02x) pos[2]=%02x pos[3]=%02x\n", @@ -3168,7 +3225,7 @@ mcide_mca_reset(void *priv) } static void -mcide_reset(void *priv) +mcide_reset(UNUSED(void *priv)) { for (uint8_t i = 0; i < 2; i++) { if (ide_boards[i] != NULL) @@ -3225,12 +3282,26 @@ mcide_close(void *priv) const device_t ide_isa_device = { .name = "ISA PC/AT IDE Controller", .internal_name = "ide_isa", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = ide_init, .close = ide_close, .reset = ide_reset, - { .available = NULL }, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_isa_sec_device = { + .name = "ISA PC/AT IDE Controller (Secondary)", + .internal_name = "ide_isa_sec", + .flags = DEVICE_ISA16, + .local = 0, + .init = ide_sec_init, + .close = ide_sec_close, + .reset = ide_reset, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3239,12 +3310,12 @@ const device_t ide_isa_device = { const device_t ide_isa_2ch_device = { .name = "ISA PC/AT IDE Controller (Dual-Channel)", .internal_name = "ide_isa_2ch", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 1, .init = ide_init, .close = ide_close, .reset = ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3253,12 +3324,26 @@ const device_t ide_isa_2ch_device = { const device_t ide_vlb_device = { .name = "VLB IDE Controller", .internal_name = "ide_vlb", - .flags = DEVICE_VLB | DEVICE_AT, + .flags = DEVICE_VLB | DEVICE_ISA16, .local = 2, .init = ide_init, .close = ide_close, .reset = ide_reset, - { .available = NULL }, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_vlb_sec_device = { + .name = "VLB IDE Controller (Secondary)", + .internal_name = "ide_vlb_sec", + .flags = DEVICE_VLB | DEVICE_ISA16, + .local = 2, + .init = ide_sec_init, + .close = ide_sec_close, + .reset = ide_reset, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3267,12 +3352,12 @@ const device_t ide_vlb_device = { const device_t ide_vlb_2ch_device = { .name = "VLB IDE Controller (Dual-Channel)", .internal_name = "ide_vlb_2ch", - .flags = DEVICE_VLB | DEVICE_AT, + .flags = DEVICE_VLB | DEVICE_ISA16, .local = 3, .init = ide_init, .close = ide_close, .reset = ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3281,12 +3366,26 @@ const device_t ide_vlb_2ch_device = { const device_t ide_pci_device = { .name = "PCI IDE Controller", .internal_name = "ide_pci", - .flags = DEVICE_PCI | DEVICE_AT, + .flags = DEVICE_PCI | DEVICE_ISA16, .local = 4, .init = ide_init, .close = ide_close, .reset = ide_reset, - { .available = NULL }, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ide_pci_sec_device = { + .name = "PCI IDE Controller (Secondary)", + .internal_name = "ide_pci_sec", + .flags = DEVICE_PCI | DEVICE_ISA16, + .local = 4, + .init = ide_sec_init, + .close = ide_sec_close, + .reset = ide_reset, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3295,12 +3394,12 @@ const device_t ide_pci_device = { const device_t ide_pci_2ch_device = { .name = "PCI IDE Controller (Dual-Channel)", .internal_name = "ide_pci_2ch", - .flags = DEVICE_PCI | DEVICE_AT, + .flags = DEVICE_PCI | DEVICE_ISA16, .local = 5, .init = ide_init, .close = ide_close, .reset = ide_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3314,24 +3413,23 @@ const device_t mcide_device = { .init = mcide_init, .close = mcide_close, .reset = mcide_reset, - { .available = mcide_available }, + .available = mcide_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; - // clang-format off static const device_config_t ide_ter_config[] = { { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = HDC_TERTIARY_IRQ, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = HDC_TERTIARY_IRQ, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Plug and Play", .value = -1 }, { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, @@ -3343,21 +3441,22 @@ static const device_config_t ide_ter_config[] = { { .description = "IRQ 11", .value = 11 }, { .description = "IRQ 12", .value = 12 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t ide_qua_config[] = { { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = HDC_QUATERNARY_IRQ, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = HDC_QUATERNARY_IRQ, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Plug and Play", .value = -1 }, { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, @@ -3369,7 +3468,8 @@ static const device_config_t ide_qua_config[] = { { .description = "IRQ 11", .value = 11 }, { .description = "IRQ 12", .value = 12 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -3378,12 +3478,12 @@ static const device_config_t ide_qua_config[] = { const device_t ide_ter_device = { .name = "Tertiary IDE Controller", .internal_name = "ide_ter", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = ide_ter_init, .close = ide_ter_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ide_ter_config @@ -3392,12 +3492,12 @@ const device_t ide_ter_device = { const device_t ide_ter_pnp_device = { .name = "Tertiary IDE Controller (Plug and Play only)", .internal_name = "ide_ter_pnp", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 1, .init = ide_ter_init, .close = ide_ter_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -3406,12 +3506,12 @@ const device_t ide_ter_pnp_device = { const device_t ide_qua_device = { .name = "Quaternary IDE Controller", .internal_name = "ide_qua", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = ide_qua_init, .close = ide_qua_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ide_qua_config @@ -3420,12 +3520,12 @@ const device_t ide_qua_device = { const device_t ide_qua_pnp_device = { .name = "Quaternary IDE Controller (Plug and Play only)", .internal_name = "ide_qua_pnp", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 1, .init = ide_qua_init, .close = ide_qua_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_ali5213.c b/src/disk/hdc_ide_ali5213.c index 8ff3d392c..67f959e1a 100644 --- a/src/disk/hdc_ide_ali5213.c +++ b/src/disk/hdc_ide_ali5213.c @@ -246,7 +246,7 @@ const device_t ide_ali1489_device = { .init = ali5213_init, .close = ali5213_close, .reset = ali5213_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -260,7 +260,7 @@ const device_t ide_ali5213_device = { .init = ali5213_init, .close = ali5213_close, .reset = ali5213_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index 3e77730a2..84a40efa4 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -504,8 +504,7 @@ cmd640_close(void *priv) static void * cmd640_init(const device_t *info) { - cmd640_t *dev = (cmd640_t *) malloc(sizeof(cmd640_t)); - memset(dev, 0x00, sizeof(cmd640_t)); + cmd640_t *dev = (cmd640_t *) calloc(1, sizeof(cmd640_t)); dev->id = next_id | 0x60; @@ -563,7 +562,7 @@ const device_t ide_cmd640_vlb_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -577,7 +576,7 @@ const device_t ide_cmd640_vlb_178_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -591,7 +590,7 @@ const device_t ide_cmd640_vlb_pri_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -605,7 +604,7 @@ const device_t ide_cmd640_vlb_pri_178_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -619,7 +618,7 @@ const device_t ide_cmd640_vlb_sec_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -633,7 +632,7 @@ const device_t ide_cmd640_vlb_sec_178_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -647,7 +646,7 @@ const device_t ide_cmd640_pci_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -661,7 +660,7 @@ const device_t ide_cmd640_pci_legacy_only_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -675,7 +674,7 @@ const device_t ide_cmd640_pci_single_channel_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -689,7 +688,7 @@ const device_t ide_cmd640_pci_single_channel_sec_device = { .init = cmd640_init, .close = cmd640_close, .reset = cmd640_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 8367b9a41..b548390fd 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -391,8 +391,7 @@ cmd646_close(void *priv) static void * cmd646_init(const device_t *info) { - cmd646_t *dev = (cmd646_t *) malloc(sizeof(cmd646_t)); - memset(dev, 0x00, sizeof(cmd646_t)); + cmd646_t *dev = (cmd646_t *) calloc(1, sizeof(cmd646_t)); dev->local = info->local; @@ -431,7 +430,7 @@ const device_t ide_cmd646_device = { .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -445,7 +444,7 @@ const device_t ide_cmd646_legacy_only_device = { .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -459,7 +458,7 @@ const device_t ide_cmd646_single_channel_device = { .init = cmd646_init, .close = cmd646_close, .reset = cmd646_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_opti611.c b/src/disk/hdc_ide_opti611.c index 480331201..4927b5fe3 100644 --- a/src/disk/hdc_ide_opti611.c +++ b/src/disk/hdc_ide_opti611.c @@ -317,8 +317,7 @@ opti611_close(void *priv) static void * opti611_init(UNUSED(const device_t *info)) { - opti611_t *dev = (opti611_t *) malloc(sizeof(opti611_t)); - memset(dev, 0, sizeof(opti611_t)); + opti611_t *dev = (opti611_t *) calloc(1, sizeof(opti611_t)); dev->is_sec = info->local; @@ -341,7 +340,7 @@ const device_t ide_opti611_vlb_device = { .init = opti611_init, .close = opti611_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -355,7 +354,7 @@ const device_t ide_opti611_vlb_sec_device = { .init = opti611_init, .close = opti611_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 631afa931..73dc5f36b 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -475,19 +475,22 @@ sff_reset(void *priv) #endif for (uint8_t i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv) + if ((hdd[i].bus_type == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv) scsi_disk_reset((scsi_common_t *) hdd[i].priv); } for (uint8_t i = 0; i < CDROM_NUM; i++) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && + cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); } for (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) + 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 < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && mo_drives[i].priv) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel < 4) && + mo_drives[i].priv) mo_reset((scsi_common_t *) mo_drives[i].priv); } @@ -575,8 +578,7 @@ sff_close(void *priv) static void * sff_init(UNUSED(const device_t *info)) { - sff8038i_t *dev = (sff8038i_t *) malloc(sizeof(sff8038i_t)); - memset(dev, 0, sizeof(sff8038i_t)); + sff8038i_t *dev = (sff8038i_t *) calloc(1, sizeof(sff8038i_t)); /* Make sure to only add IDE once. */ if (next_id == 0) @@ -608,7 +610,7 @@ const device_t sff8038i_device = { .init = sff_init, .close = sff_close, .reset = sff_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_um8673f.c b/src/disk/hdc_ide_um8673f.c index bc046dd26..b40595750 100644 --- a/src/disk/hdc_ide_um8673f.c +++ b/src/disk/hdc_ide_um8673f.c @@ -191,7 +191,7 @@ const device_t ide_um8886af_device = { .init = um8673f_init, .close = um8673f_close, .reset = um8673f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -205,7 +205,7 @@ const device_t ide_um8673f_device = { .init = um8673f_init, .close = um8673f_close, .reset = um8673f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c index c2b053814..7829c5b92 100644 --- a/src/disk/hdc_ide_w83769f.c +++ b/src/disk/hdc_ide_w83769f.c @@ -10,7 +10,7 @@ * * Authors: Miran Grca, * - * Copyright 2020 Miran Grca. + * Copyright 2020-2025 Miran Grca. */ #include #include @@ -353,8 +353,7 @@ w83769f_close(void *priv) static void * w83769f_init(const device_t *info) { - w83769f_t *dev = (w83769f_t *) malloc(sizeof(w83769f_t)); - memset(dev, 0x00, sizeof(w83769f_t)); + w83769f_t *dev = (w83769f_t *) calloc(1, sizeof(w83769f_t)); dev->id = next_id | 0x60; @@ -410,7 +409,7 @@ const device_t ide_w83769f_vlb_device = { .init = w83769f_init, .close = w83769f_close, .reset = w83769f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -424,7 +423,7 @@ const device_t ide_w83769f_vlb_34_device = { .init = w83769f_init, .close = w83769f_close, .reset = w83769f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -438,7 +437,7 @@ const device_t ide_w83769f_pci_device = { .init = w83769f_init, .close = w83769f_close, .reset = w83769f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -452,9 +451,22 @@ const device_t ide_w83769f_pci_34_device = { .init = w83769f_init, .close = w83769f_close, .reset = w83769f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; +const device_t ide_w83769f_pci_single_channel_device = { + .name = "Winbond W83769F PCI (Single Channel)", + .internal_name = "ide_w83769f_pci_single_channel", + .flags = DEVICE_PCI, + .local = 0x200b4, + .init = w83769f_init, + .close = w83769f_close, + .reset = w83769f_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/hdc_st506_at.c b/src/disk/hdc_st506_at.c index d5bbf24d0..07c57b2ca 100644 --- a/src/disk/hdc_st506_at.c +++ b/src/disk/hdc_st506_at.c @@ -585,12 +585,16 @@ do_callback(void *priv) do_seek(mfm); if (get_sector(mfm, &addr)) { mfm->error = ERR_ID_NOT_FOUND; +read_error: mfm->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(mfm); break; } - hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer); + if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer) < 0) { + mfm->error = ERR_BAD_BLOCK; + goto read_error; + } mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; @@ -604,12 +608,16 @@ do_callback(void *priv) do_seek(mfm); if (get_sector(mfm, &addr)) { mfm->error = ERR_ID_NOT_FOUND; +write_error: mfm->status = STAT_READY | STAT_DSC | STAT_ERR; irq_raise(mfm); break; } - hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer); + if (hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) mfm->buffer) < 0) { + mfm->error = ERR_BAD_BLOCK; + goto write_error; + } irq_raise(mfm); mfm->secount = (mfm->secount - 1) & 0xff; @@ -736,12 +744,11 @@ mfm_init(UNUSED(const device_t *info)) int c; st506_at_log("WD1003: ISA MFM/RLL Fixed Disk Adapter initializing ...\n"); - mfm = malloc(sizeof(mfm_t)); - memset(mfm, 0x00, sizeof(mfm_t)); + mfm = calloc(1, sizeof(mfm_t)); c = 0; for (uint8_t d = 0; d < HDD_NUM; d++) { - if ((hdd[d].bus == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) { + if ((hdd[d].bus_type == HDD_BUS_MFM) && (hdd[d].mfm_channel < MFM_NUM)) { loadhd(mfm, hdd[d].mfm_channel, d, hdd[d].fn); st506_at_log("WD1003(%d): (%s) geometry %d/%d/%d\n", c, hdd[d].fn, @@ -788,12 +795,12 @@ mfm_close(void *priv) const device_t st506_at_wd1003_device = { .name = "WD1003 AT MFM/RLL Controller", .internal_name = "st506_at", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = mfm_init, .close = mfm_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index f3ac48a36..536fd76c0 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -715,6 +715,7 @@ st506_callback(void *priv) dev->head, dev->sector, dev->count); if (!get_sector(dev, drive, &addr)) { +read_error_start: st506_error(dev, dev->error); st506_complete(dev); return; @@ -722,8 +723,11 @@ st506_callback(void *priv) ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); /* Read data from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *) dev->buff); + if (hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff) < 0) { + dev->error = ERR_UNC_ERR; + goto read_error_start; + } /* Set up the data transfer. */ dev->buff_pos = 0; @@ -765,6 +769,7 @@ st506_callback(void *priv) next_sector(dev, drive); if (!get_sector(dev, drive, &addr)) { +read_error_sent: ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); st506_error(dev, dev->error); st506_complete(dev); @@ -772,8 +777,11 @@ st506_callback(void *priv) } /* Read data from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *) dev->buff); + if (hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff) < 0) { + dev->error = ERR_UNC_ERR; + goto read_error_sent; + } /* Set up the data transfer. */ dev->buff_pos = 0; @@ -856,6 +864,7 @@ st506_callback(void *priv) case STATE_RECEIVED_DATA: if (!get_sector(dev, drive, &addr)) { +write_error: ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); st506_error(dev, dev->error); st506_complete(dev); @@ -863,8 +872,11 @@ st506_callback(void *priv) } /* Write data to image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *) dev->buff); + if (hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff) < 0) { + dev->error = ERR_UNC_ERR; + goto write_error; + } if (--dev->count == 0) { ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); @@ -1156,8 +1168,12 @@ st506_callback(void *priv) ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 1); /* Write data to image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *) dev->buff); + if (hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->buff) < 0) { + st506_error(dev, ERR_UNC_ERR); + st506_complete(dev); + return; + } if (--dev->count == 0) { ui_sb_update_icon(SB_HDD | HDD_BUS_MFM, 0); @@ -1611,8 +1627,7 @@ st506_init(const device_t *info) int i; int c; - dev = (hdc_t *) malloc(sizeof(hdc_t)); - memset(dev, 0x00, sizeof(hdc_t)); + dev = (hdc_t *) calloc(1, sizeof(hdc_t)); dev->type = info->local & 255; /* Set defaults for the controller. */ @@ -1683,7 +1698,7 @@ st506_init(const device_t *info) dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) - dev->switches |= 0x40; + dev->switches |= 0x80; dev->bios_addr = device_get_config_hex20("bios_addr"); break; @@ -1702,7 +1717,7 @@ st506_init(const device_t *info) dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) - dev->switches |= 0x40; + dev->switches |= 0x80; dev->bios_addr = device_get_config_hex20("bios_addr"); break; @@ -1717,7 +1732,7 @@ st506_init(const device_t *info) dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) - dev->switches |= 0x40; + dev->switches |= 0x80; dev->bios_addr = device_get_config_hex20("bios_addr"); break; @@ -1732,7 +1747,7 @@ st506_init(const device_t *info) dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) - dev->switches |= 0x40; + dev->switches |= 0x80; dev->bios_addr = device_get_config_hex20("bios_addr"); break; @@ -1747,7 +1762,7 @@ st506_init(const device_t *info) dev->base = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); if (dev->irq == 2) - dev->switches |= 0x40; + dev->switches |= 0x80; dev->bios_addr = device_get_config_hex20("bios_addr"); break; @@ -1783,7 +1798,7 @@ st506_init(const device_t *info) st506_xt_log("ST506: looking for disks...\n"); #endif for (c = 0, i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) { + if ((hdd[i].bus_type == HDD_BUS_MFM) && (hdd[i].mfm_channel < MFM_NUM)) { st506_xt_log("ST506: disk '%s' on channel %i\n", hdd[i].fn, hdd[i].mfm_channel); loadhd(dev, hdd[i].mfm_channel, i, hdd[i].fn); @@ -1899,335 +1914,356 @@ victor_v86p_available(void) // clang-format off static const device_config_t dtc_config[] = { { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "CA00H", .value = 0xca000 }, { .description = "D800H", .value = 0xd8000 }, { .description = "F400H", .value = 0xf4000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t st11_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "328H", .value = 0x0328 }, { .description = "32CH", .value = 0x032c }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "D000H", .value = 0xd0000 }, { .description = "D800H", .value = 0xd8000 }, { .description = "E000H", .value = 0xe0000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "revision", - .description = "Board Revision", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 19, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "Rev. 05 (v1.7)", .value = 5 }, - { .description = "Rev. 19 (v2.0)", .value = 19 }, + .name = "revision", + .description = "BIOS Revision", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 19, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "v1.7", .value = 5 }, + { .description = "v2.0", .value = 19 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd_config[] = { { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd_nobios_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd_rll_config[] = { { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "translate", - .description = "Translate 26 -> 17", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "translate", + .description = "Translate 26 -> 17", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Off", .value = 0 }, { .description = "On", .value = 1 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd1004a_config[] = { { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd1004_rll_config[] = { { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "C800H", .value = 0xc8000 }, { .description = "CA00H", .value = 0xca000 }, { .description = "CC00H", .value = 0xcc000 }, { .description = "CE00H", .value = 0xce000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "328H", .value = 0x0328 }, { .description = "32CH", .value = 0x032c }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 5", .value = 5 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { - .name = "translate", - .description = "Translate 26 -> 17", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "translate", + .description = "Translate 26 -> 17", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Off", .value = 0 }, { .description = "On", .value = 1 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -2242,7 +2278,7 @@ const device_t st506_xt_xebec_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = xebec_available }, + .available = xebec_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2256,7 +2292,7 @@ const device_t st506_xt_wdxt_gen_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wdxt_available }, + .available = wdxt_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2270,7 +2306,7 @@ const device_t st506_xt_dtc5150x_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = dtc5150x_available }, + .available = dtc5150x_available, .speed_changed = NULL, .force_redraw = NULL, .config = dtc_config @@ -2284,7 +2320,7 @@ const device_t st506_xt_st11_m_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = st11_m_available }, + .available = st11_m_available, .speed_changed = NULL, .force_redraw = NULL, .config = st11_config @@ -2298,7 +2334,7 @@ const device_t st506_xt_st11_r_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = st11_r_available }, + .available = st11_r_available, .speed_changed = NULL, .force_redraw = NULL, .config = st11_config @@ -2312,7 +2348,7 @@ const device_t st506_xt_wd1002a_wx1_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wd1002a_wx1_available }, + .available = wd1002a_wx1_available, .speed_changed = NULL, .force_redraw = NULL, .config = wd_config @@ -2326,7 +2362,7 @@ const device_t st506_xt_wd1002a_wx1_nobios_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wd1002a_wx1_available }, + .available = wd1002a_wx1_available, .speed_changed = NULL, .force_redraw = NULL, .config = wd_nobios_config @@ -2340,7 +2376,7 @@ const device_t st506_xt_wd1002a_27x_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wd1002a_27x_available }, + .available = wd1002a_27x_available, .speed_changed = NULL, .force_redraw = NULL, .config = wd_rll_config @@ -2354,7 +2390,7 @@ const device_t st506_xt_wd1004a_wx1_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wd1004a_wx1_available }, + .available = wd1004a_wx1_available, .speed_changed = NULL, .force_redraw = NULL, .config = wd1004a_config @@ -2368,7 +2404,7 @@ const device_t st506_xt_wd1004_27x_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wd1004_27x_available }, + .available = wd1004_27x_available, .speed_changed = NULL, .force_redraw = NULL, .config = wd1004_rll_config @@ -2382,7 +2418,7 @@ const device_t st506_xt_wd1004a_27x_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = wd1004a_27x_available }, + .available = wd1004a_27x_available, .speed_changed = NULL, .force_redraw = NULL, .config = wd_rll_config @@ -2396,7 +2432,7 @@ const device_t st506_xt_victor_v86p_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = victor_v86p_available }, + .available = victor_v86p_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2410,7 +2446,7 @@ const device_t st506_xt_toshiba_t1200_device = { .init = st506_init, .close = st506_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdc_xta.c b/src/disk/hdc_xta.c index ede21caf2..b01d80c61 100644 --- a/src/disk/hdc_xta.c +++ b/src/disk/hdc_xta.c @@ -408,8 +408,9 @@ do_fmt: break; /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *) dev->sector_buf); + if (hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->sector_buf) < 0) + dev->sense = ERR_BADTRK; } } @@ -522,6 +523,7 @@ hdc_callback(void *priv) do_send: /* Get address of sector to load. */ if (get_sector(dev, drive, &addr)) { +read_error: /* De-activate the status icon. */ ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); dev->comp |= COMP_ERR; @@ -530,8 +532,11 @@ do_send: } /* Read the block from the image. */ - hdd_image_read(drive->hdd_num, addr, 1, - (uint8_t *) dev->sector_buf); + if (hdd_image_read(drive->hdd_num, addr, 1, + (uint8_t *) dev->sector_buf) < 0) { + dev->sense = ERR_BADTRK; + goto read_error; + } /* Ready to transfer the data out. */ dev->state = STATE_SDATA; @@ -673,6 +678,7 @@ do_recv: /* Get address of sector to write. */ if (get_sector(dev, drive, &addr)) { +write_error: /* De-activate the status icon. */ ui_sb_update_icon(SB_HDD | HDD_BUS_XTA, 0); @@ -682,8 +688,11 @@ do_recv: } /* Write the block to the image. */ - hdd_image_write(drive->hdd_num, addr, 1, - (uint8_t *) dev->sector_buf); + if (hdd_image_write(drive->hdd_num, addr, 1, + (uint8_t *) dev->sector_buf) < 0) { + dev->sense = ERR_BADTRK; + goto write_error; + } dev->buf_idx = 0; if (--dev->count == 0) { @@ -991,8 +1000,7 @@ xta_init(const device_t *info) int max = XTA_NUM; /* Allocate and initialize device block. */ - dev = malloc(sizeof(hdc_t)); - memset(dev, 0x00, sizeof(hdc_t)); + dev = calloc(1, sizeof(hdc_t)); dev->type = info->local; /* Do per-controller-type setup. */ @@ -1029,7 +1037,7 @@ xta_init(const device_t *info) /* Load any disks for this device class. */ c = 0; for (uint8_t i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) { + if ((hdd[i].bus_type == HDD_BUS_XTA) && (hdd[i].xta_channel < max)) { drive = &dev->drives[hdd[i].xta_channel]; if (!hdd_image_load(i)) { @@ -1099,60 +1107,77 @@ xta_close(void *priv) static const device_config_t wdxt150_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0320, - .file_filter = "", - .spinner = { 0 }, /*W2*/ - .selection = { + .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 = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, /*W3*/ - .selection = { + .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 = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .selection = { + .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", - .type = CONFIG_BIOS, + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, .default_string = "rev_1", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .bios = { - { .name = "Revision 1.0", .internal_name = "rev_1", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 8192, .files = { WD_REV_1_BIOS_FILE, "" } }, - { .name = "Revision 2.0", .internal_name = "rev_2", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 8192, .files = { WD_REV_2_BIOS_FILE, "" } }, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Revision 1.0", + .internal_name = "rev_1", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { WD_REV_1_BIOS_FILE, "" } + }, + { + .name = "Revision 2.0", + .internal_name = "rev_2", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { WD_REV_2_BIOS_FILE, "" } + }, { .files_no = 0 } }, }, @@ -1161,29 +1186,29 @@ static const device_config_t wdxt150_config[] = { }; const device_t xta_wdxt150_device = { - .name = "WDXT-150 XTA Fixed Disk Controller", + .name = "WDXT-150 XTA Fixed Disk Controller", .internal_name = "xta_wdxt150", - .flags = DEVICE_ISA, - .local = 0, - .init = xta_init, - .close = xta_close, - .reset = NULL, - { .available = NULL /*xta_available*/ }, + .flags = DEVICE_ISA, + .local = 0, + .init = xta_init, + .close = xta_close, + .reset = NULL, + .available = NULL /*xta_available*/, .speed_changed = NULL, - .force_redraw = NULL, - .config = wdxt150_config + .force_redraw = NULL, + .config = wdxt150_config }; const device_t xta_hd20_device = { - .name = "EuroPC HD20 Fixed Disk Controller", + .name = "EuroPC HD20 Fixed Disk Controller", .internal_name = "xta_hd20", - .flags = DEVICE_ISA, - .local = 1, - .init = xta_init, - .close = xta_close, - .reset = NULL, - { .available = NULL }, + .flags = DEVICE_ISA, + .local = 1, + .init = xta_init, + .close = xta_close, + .reset = NULL, + .available = NULL, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/disk/hdc_xtide.c b/src/disk/hdc_xtide.c index 057d4f0ed..c18a24c4e 100644 --- a/src/disk/hdc_xtide.c +++ b/src/disk/hdc_xtide.c @@ -132,13 +132,11 @@ xtide_read(uint16_t port, void *priv) static void * xtide_init(const device_t *info) { - xtide_t *xtide = malloc(sizeof(xtide_t)); + xtide_t *xtide = calloc(1, sizeof(xtide_t)); - memset(xtide, 0x00, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, - device_get_bios_file(info, device_get_config_bios("bios"), 0), - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, + device_get_bios_file(info, device_get_config_bios("bios"), 0), + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); xtide->ide_board = ide_xtide_init(); @@ -152,13 +150,11 @@ xtide_init(const device_t *info) static void * xtide_at_init(const device_t *info) { - xtide_t *xtide = malloc(sizeof(xtide_t)); + xtide_t *xtide = calloc(1, sizeof(xtide_t)); - memset(xtide, 0x00, sizeof(xtide_t)); - - rom_init(&xtide->bios_rom, - device_get_bios_file(info, device_get_config_bios("bios"), 0), - 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, + device_get_bios_file(info, device_get_config_bios("bios"), 0), + 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); device_add(&ide_isa_2ch_device); @@ -168,9 +164,7 @@ xtide_at_init(const device_t *info) static void * xtide_acculogic_init(UNUSED(const device_t *info)) { - xtide_t *xtide = malloc(sizeof(xtide_t)); - - memset(xtide, 0x00, sizeof(xtide_t)); + xtide_t *xtide = calloc(1, sizeof(xtide_t)); rom_init(&xtide->bios_rom, ROM_PATH_PS2, 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); @@ -203,9 +197,7 @@ xtide_close(void *priv) static void * xtide_at_ps2_init(UNUSED(const device_t *info)) { - xtide_t *xtide = malloc(sizeof(xtide_t)); - - memset(xtide, 0x00, sizeof(xtide_t)); + xtide_t *xtide = calloc(1, sizeof(xtide_t)); rom_init(&xtide->bios_rom, ROM_PATH_PS2AT, 0xc8000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); @@ -232,18 +224,33 @@ xtide_at_close(void *priv) static const device_config_t xtide_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS", - .type = CONFIG_BIOS, + .name = "bios", + .description = "BIOS Revision", + .type = CONFIG_BIOS, .default_string = "xt", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .bios = { - { .name = "Regular XT", .internal_name = "xt", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XT, "" } }, - { .name = "XT+ (V20/V30/8018x)", .internal_name = "xt_plus", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_XTP, "" } }, + .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 } }, }, @@ -254,18 +261,33 @@ static const device_config_t xtide_config[] = { static const device_config_t xtide_at_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS", - .type = CONFIG_BIOS, + .name = "bios", + .description = "BIOS Revision", + .type = CONFIG_BIOS, .default_string = "at", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .bios = { - { .name = "Regular AT", .internal_name = "at", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT, "" } }, - { .name = "386", .internal_name = "at_386", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 8192, .files = { ROM_PATH_AT_386, "" } }, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Regular AT", + .internal_name = "at", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { ROM_PATH_AT, "" } + }, + { + .name = "386", + .internal_name = "at_386", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { ROM_PATH_AT_386, "" } + }, { .files_no = 0 } }, }, @@ -281,7 +303,7 @@ const device_t xtide_device = { .init = xtide_init, .close = xtide_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = xtide_config @@ -290,12 +312,12 @@ const device_t xtide_device = { const device_t xtide_at_device = { .name = "PC/AT XTIDE", .internal_name = "xtide_at", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = xtide_at_init, .close = xtide_at_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = xtide_at_config @@ -309,7 +331,7 @@ const device_t xtide_acculogic_device = { .init = xtide_acculogic_init, .close = xtide_close, .reset = NULL, - { .available = xtide_acculogic_available }, + .available = xtide_acculogic_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -318,12 +340,12 @@ const device_t xtide_acculogic_device = { const device_t xtide_at_ps2_device = { .name = "PS/2 AT XTIDE (1.1.5)", .internal_name = "xtide_at_ps2", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = xtide_at_ps2_init, .close = xtide_at_close, .reset = NULL, - { .available = xtide_at_ps2_available }, + .available = xtide_at_ps2_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 7acfc82be..8292dc472 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -123,7 +123,7 @@ hdd_bus_to_string(int bus, UNUSED(int cdrom)) int hdd_is_valid(int c) { - if (hdd[c].bus == HDD_BUS_DISABLED) + if (hdd[c].bus_type == HDD_BUS_DISABLED) return 0; if (strlen(hdd[c].fn) == 0) @@ -407,15 +407,142 @@ hdd_zones_init(hard_disk_t *hdd) static hdd_preset_t hdd_speed_presets[] = { // clang-format off - { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, - { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, - { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, - { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, - { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, - { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, - // clang-format on + { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, + { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, + { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[PIO IDE] IBM WDA-L42", .internal_name = "WDAL42", .model = "WDA-L42", .zones = 1, .avg_spt = 85, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 2.5, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 1 }, + { .name = "[ATA-1] Conner CP3024", .internal_name = "CP3024", .model = "Conner Peripherals 20MB - CP3024", .zones = 1, .avg_spt = 33, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work + { .name = "[ATA-1] Conner CP3044", .internal_name = "CP3044", .model = "Conner Peripherals 40MB - CP3044", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3500, .full_stroke_ms = 50, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work + { .name = "[ATA-1] Conner CP3104", .internal_name = "CP3104", .model = "Conner Peripherals 104MB - CP3104", .zones = 1, .avg_spt = 33, .heads = 8, .rpm = 3500, .full_stroke_ms = 45, .track_seek_ms = 8, .rcache_num_seg = 4, .rcache_seg_size = 8, .max_multiple = 8 }, // Needed for GRiDcase 1520 to work + { .name = "[ATA-1] Conner CFS420A", .internal_name = "CFS420A", .model = "Conner Peripherals 420MB - CFS420A", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3600, .full_stroke_ms = 33, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 }, + { .name = "[ATA-1] HP Kittyhawk", .internal_name = "C3014A", .model = "HP C3014A", .zones = 6, .avg_spt = 80, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[ATA-1] IBM H3256-A3", .internal_name = "H3256A3", .model = "H3256-A3", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3600, .full_stroke_ms = 32, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 8 }, + { .name = "[ATA-1] IBM H3342-A4", .internal_name = "H3342A4", .model = "H3342-A4", .zones = 1, .avg_spt = 40, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 8 }, + { .name = "[ATA-1] Kalok KL343", .internal_name = "KL343", .model = "KALOK KL-343", .zones = 1, .avg_spt = 80, .heads = 6, .rpm = 3600, .full_stroke_ms = 50, .track_seek_ms = 2, .rcache_num_seg = 1, .rcache_seg_size = 8, .max_multiple = 8 }, + { .name = "[ATA-1] Kalok KL3100", .internal_name = "KL3100", .model = "KALOK KL-3100", .zones = 1, .avg_spt = 100, .heads = 6, .rpm = 3662, .full_stroke_ms = 50, .track_seek_ms = 2, .rcache_num_seg = 1, .rcache_seg_size = 32, .max_multiple = 8 }, + { .name = "[ATA-1] Maxtor 7060AT", .internal_name = "7060AT", .model = "Maxtor 7060 AT", .zones = 1, .avg_spt = 62, .heads = 2, .rpm = 3524, .full_stroke_ms = 30, .track_seek_ms = 3.6, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-1] Maxtor 7131AT", .internal_name = "7131AT", .model = "Maxtor 7131 AT", .zones = 2, .avg_spt = 54, .heads = 2, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4.5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-1] Maxtor 7213AT", .internal_name = "7213AT", .model = "Maxtor 7213 AT", .zones = 4, .avg_spt = 55, .heads = 4, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6.5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-1] Maxtor 7245AT", .internal_name = "7245AT", .model = "Maxtor 7245 AT", .zones = 4, .avg_spt = 49, .heads = 4, .rpm = 3551, .full_stroke_ms = 27, .track_seek_ms = 4.4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-1] Quantum ProDrive LPS 105", .internal_name = "LPS105AT", .model = "QUANTUM PRODRIVE 105", .zones = 1, .avg_spt = 70, .heads = 2, .rpm = 3662, .full_stroke_ms = 45, .track_seek_ms = 5, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-1] Quantum ProDrive LPS 120AT", .internal_name = "GM12A012", .model = "QUANTUM PRODRIVE 120AT", .zones = 1, .avg_spt = 50, .heads = 2, .rpm = 3605, .full_stroke_ms = 45, .track_seek_ms = 4, .rcache_num_seg = 1, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-1] Seagate ST3243A", .internal_name = "ST3243A", .model = "ST3243A", .zones = 1, .avg_spt = 40, .heads = 4, .rpm = 3811, .full_stroke_ms = 32, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 }, + { .name = "[ATA-1] Western Digital Caviar 140", .internal_name = "AC140", .model = "WDC AC140", .zones = 4, .avg_spt = 70, .heads = 2, .rpm = 3551, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 8, .rcache_seg_size = 8, .max_multiple = 8 }, + { .name = "[ATA-1] Western Digital Caviar 280", .internal_name = "AC280", .model = "WDC AC280", .zones = 4, .avg_spt = 70, .heads = 4, .rpm = 3595, .full_stroke_ms = 28, .track_seek_ms = 6, .rcache_num_seg = 8, .rcache_seg_size = 32, .max_multiple = 8 }, + { .name = "[ATA-1] Western Digital Caviar 1210", .internal_name = "AC1210", .model = "WDC AC1210F", .zones = 4, .avg_spt = 30, .heads = 2, .rpm = 3314, .full_stroke_ms = 33, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-1] Western Digital Caviar 2120", .internal_name = "AC2120", .model = "WDC AC2120M", .zones = 4, .avg_spt = 40, .heads = 2, .rpm = 3605, .full_stroke_ms = 28, .track_seek_ms = 2.8, .rcache_num_seg = 8, .rcache_seg_size = 32, .max_multiple = 8 }, + { .name = "[ATA-2] IBM DBOA-2720", .internal_name = "DBOA2720", .model = "DBOA-2720", .zones = 2, .avg_spt = 135, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-2] IBM DeskStar 4 (DCAA-32880)", .internal_name = "DCAA32880", .model = "IBM-DCAA-32880", .zones = 8, .avg_spt = 185, .heads = 2, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 }, + { .name = "[ATA-2] IBM DeskStar 4 (DCAA-33610)", .internal_name = "DCAA33610", .model = "IBM-DCAA-33610", .zones = 8, .avg_spt = 185, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 }, + { .name = "[ATA-2] IBM DeskStar 4 (DCAA-34330)", .internal_name = "DCAA34330", .model = "IBM-DCAA-34330", .zones = 8, .avg_spt = 185, .heads = 3, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.7, .rcache_num_seg = 4, .rcache_seg_size = 96, .max_multiple = 16 }, + { .name = "[ATA-2] Maxtor 7540AV", .internal_name = "7540AV", .model = "Maxtor 7540 AV", .zones = 2, .avg_spt = 120, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 4.3, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 8 }, + { .name = "[ATA-2] Maxtor 7546AT", .internal_name = "7546AT", .model = "Maxtor 7546 AT", .zones = 2, .avg_spt = 100, .heads = 4, .rpm = 4500, .full_stroke_ms = 28, .track_seek_ms = 2.3, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .name = "[ATA-2] Maxtor 7850AV", .internal_name = "7850AV", .model = "Maxtor 7850 AV", .zones = 4, .avg_spt = 120, .heads = 4, .rpm = 3551, .full_stroke_ms = 31, .track_seek_ms = 3.7, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-2] Maxtor 71336AP", .internal_name = "71336AP", .model = "Maxtor 71336 AP", .zones = 4, .avg_spt = 105, .heads = 4, .rpm = 4480, .full_stroke_ms = 12, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot 1.2AT", .internal_name = "BF12A011", .model = "QUANTUM BIGFOOT BF1.2A", .zones = 2, .avg_spt = 155, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Quantum Bigfoot (CY4320A)", .internal_name = "CY4320A", .model = "QUANTUM BIGFOOT_CY4320A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4000, .full_stroke_ms = 29, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, // from Hardcore Windows NT Final Segment by Kugee + { .name = "[ATA-2] Quantum Fireball 640AT", .internal_name = "FB64A341", .model = "QUANTUM FIREBALL 640AT", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3.1, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Quantum Fireball TM1080AT", .internal_name = "TM10A462", .model = "QUANTUM FIREBALL TM1.0A", .zones = 2, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Quantum Fireball TM1.2AT", .internal_name = "TM12A012", .model = "QUANTUM FIREBALL TM1.2A", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 4500, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Samsung PLS-31274A", .internal_name = "PLS31274A", .model = "SAMSUNG PLS-31274A", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 4500, .full_stroke_ms = 45, .track_seek_ms = 4.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 8 }, + { .name = "[ATA-2] Samsung Winner-1", .internal_name = "WNR31601A", .model = "SAMSUNG WNR-31601A", .zones = 8, .avg_spt = 110, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist (ST3780A)", .internal_name = "ST3780A", .model = "ST3780A", .zones = 8, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist (ST31220A)", .internal_name = "ST31220A", .model = "ST31220A", .zones = 8, .avg_spt = 140, .heads = 6, .rpm = 4500, .full_stroke_ms = 27, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 256, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist 210xe", .internal_name = "ST3250A", .model = "ST3250A", .zones = 4, .avg_spt = 148, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 4.1, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist 275xe", .internal_name = "ST3295A", .model = "ST3295A", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 3811, .full_stroke_ms = 30, .track_seek_ms = 3.4, .rcache_num_seg = 3, .rcache_seg_size = 120, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist 545xe", .internal_name = "ST3660A", .model = "ST3660A", .zones = 4, .avg_spt = 130, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.4, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist 640xe", .internal_name = "ST3630A", .model = "ST3630A", .zones = 4, .avg_spt = 130, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.5, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist 850xe", .internal_name = "ST3850A", .model = "ST3850A", .zones = 8, .avg_spt = 150, .heads = 4, .rpm = 3811, .full_stroke_ms = 34, .track_seek_ms = 3.8, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 8 }, + { .name = "[ATA-2] Seagate Medalist 1270SL", .internal_name = "ST51270A", .model = "ST51270A", .zones = 8, .avg_spt = 205, .heads = 3, .rpm = 5736, .full_stroke_ms = 25, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Seagate Medalist 3240", .internal_name = "ST33240A", .model = "ST33240A", .zones = 16, .avg_spt = 225, .heads = 8, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Toshiba MK2101MAN (HDD2616)", .internal_name = "HDD2616", .model = "TOSHIBA MK2101MAN", .zones = 8, .avg_spt = 130, .heads = 10, .rpm = 4200, .full_stroke_ms = 36, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Western Digital Caviar 2540", .internal_name = "AC2540", .model = "WDC AC2540H", .zones = 4, .avg_spt = 150, .heads = 2, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Western Digital Caviar 2850", .internal_name = "AC2850", .model = "WDC AC2850F", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Western Digital Caviar 11000", .internal_name = "AC11000", .model = "WDC AC11000H", .zones = 4, .avg_spt = 120, .heads = 2, .rpm = 5200, .full_stroke_ms = 12, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Western Digital Caviar 21200", .internal_name = "AC21200", .model = "WDC AC21200H", .zones = 4, .avg_spt = 110, .heads = 4, .rpm = 5200, .full_stroke_ms = 39, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Western Digital Caviar 21600", .internal_name = "AC21600", .model = "WDC AC21600H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Western Digital Caviar 22000", .internal_name = "AC22000", .model = "WDC AC22000LA", .zones = 8, .avg_spt = 130, .heads = 3, .rpm = 5200, .full_stroke_ms = 33, .track_seek_ms = 3.5, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 8 }, + { .name = "[ATA-2] Western Digital Caviar 22100", .internal_name = "AC22100", .model = "WDC AC22100H", .zones = 8, .avg_spt = 140, .heads = 4, .rpm = 5200, .full_stroke_ms = 30, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-2] Western Digital Caviar 31200", .internal_name = "AC31200", .model = "WDC AC31200F", .zones = 8, .avg_spt = 210, .heads = 4, .rpm = 4500, .full_stroke_ms = 12, .track_seek_ms = 4, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[ATA-3] Connor CFS1275A", .internal_name = "CFS1275A", .model = "Connor Peripherals 1275MB - CFS1275A", .zones = 4, .avg_spt = 130, .heads = 2, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.8, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, // Either ATA-2 or ATA-3 + { .name = "[ATA-3] Fujitsu MPA3017AT", .internal_name = "MPA3017AT", .model = "FUJITSU MPA3017AT", .zones = 5, .avg_spt = 195, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Fujitsu MPA3026AT", .internal_name = "MPA3026AT", .model = "FUJITSU MPA3026AT", .zones = 8, .avg_spt = 195, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Fujitsu MPA3035AT", .internal_name = "MPA3035AT", .model = "FUJITSU MPA3035AT", .zones = 11, .avg_spt = 195, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Fujitsu MPA3043AT", .internal_name = "MPA3043AT", .model = "FUJITSU MPA3043AT", .zones = 15, .avg_spt = 195, .heads = 5, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Fujitsu MPA3052AT", .internal_name = "MPA3052AT", .model = "FUJITSU MPA3052AT", .zones = 16, .avg_spt = 195, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3.2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Samsung Voyager 6", .internal_name = "SV0844A", .model = "SAMSUNG SV0844A", .zones = 8, .avg_spt = 205, .heads = 4, .rpm = 5400, .full_stroke_ms = 22, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-3] Samsung Winner 5X", .internal_name = "WU33205A", .model = "SAMSUNG WU33205A", .zones = 16, .avg_spt = 200, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Seagate Medalist 636", .internal_name = "ST3636A", .model = "Seagate Technology 636MB - ST3636A", .zones = 2, .avg_spt = 130, .heads = 2, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.8, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-3] Seagate Medalist 1082", .internal_name = "ST31082A", .model = "Seagate Technology 1082MB - ST31082A", .zones = 4, .avg_spt = 130, .heads = 3, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.8, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 8 }, + { .name = "[ATA-3] Seagate Medalist 1276", .internal_name = "ST31276A", .model = "Seagate Technology 1275MB - ST31276A", .zones = 4, .avg_spt = 130, .heads = 3, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 3.8, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[ATA-3] Seagate Medalist 1720", .internal_name = "ST31720A", .model = "ST31720A", .zones = 4, .avg_spt = 120, .heads = 4, .rpm = 4500, .full_stroke_ms = 25, .track_seek_ms = 2, .rcache_num_seg = 4, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-3] Seagate Medalist 2132", .internal_name = "ST32132A", .model = "ST32132A", .zones = 8, .avg_spt = 125, .heads = 6, .rpm = 4500, .full_stroke_ms = 30, .track_seek_ms = 2.3, .rcache_num_seg = 8, .rcache_seg_size = 120, .max_multiple = 16 }, + { .name = "[ATA-3] Western Digital Caviar 21700", .internal_name = "AC21700", .model = "WDC AC21700H", .zones = 8, .avg_spt = 185, .heads = 3, .rpm = 5200, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, // Apple Computer OEM only, not retail version + { .name = "[ATA-4] Fujitsu MPB3021AT", .internal_name = "MPB3021AT", .model = "FUJITSU MPB3021AT", .zones = 7, .avg_spt = 200, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 16 }, + { .name = "[ATA-4] Fujitsu MPD3043AT", .internal_name = "MPD3043AT", .model = "FUJITSU MPD3043AT", .zones = 5, .avg_spt = 195, .heads = 2, .rpm = 5400, .full_stroke_ms = 29, .track_seek_ms = 1.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-4] Fujitsu MPD3064AT", .internal_name = "MPD3064AT", .model = "FUJITSU MPD3064AT", .zones = 7, .avg_spt = 195, .heads = 3, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-4] Fujitsu MPD3084AT", .internal_name = "MPD3084AT", .model = "FUJITSU MPD3084AT", .zones = 7, .avg_spt = 195, .heads = 4, .rpm = 5400, .full_stroke_ms = 19, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-4] Fujitsu MPE3064AT", .internal_name = "MPE3064AT", .model = "FUJITSU MPE3064AT", .zones = 7, .avg_spt = 295, .heads = 2, .rpm = 5400, .full_stroke_ms = 30, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax 2160", .internal_name = "86480D6", .model = "Maxtor 86480D6", .zones = 8, .avg_spt = 197, .heads = 4, .rpm = 5200, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax 2880", .internal_name = "90432D3", .model = "Maxtor 90432D3", .zones = 16, .avg_spt = 190, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax 3400", .internal_name = "90644D3", .model = "Maxtor 90644D3", .zones = 16, .avg_spt = 290, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax 4320 (90432D2)", .internal_name = "90432D2", .model = "Maxtor 90432D2", .zones = 16, .avg_spt = 290, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax 4320 (90845D4)", .internal_name = "90845D4", .model = "Maxtor 90845D4", .zones = 16, .avg_spt = 290, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (90683U2)", .internal_name = "90683U2", .model = "Maxtor 90683U2", .zones = 16, .avg_spt = 290, .heads = 2, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (91024U3)", .internal_name = "91024U3", .model = "Maxtor 91024U3", .zones = 16, .avg_spt = 290, .heads = 3, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (91366U4)", .internal_name = "91366U4", .model = "Maxtor 91366U4", .zones = 16, .avg_spt = 290, .heads = 4, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (92049U6)", .internal_name = "92049U6", .model = "Maxtor 92049U6", .zones = 16, .avg_spt = 290, .heads = 6, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Maxtor DiamondMax Plus 6800 (92732U8)", .internal_name = "92732U8", .model = "Maxtor 92732U8", .zones = 16, .avg_spt = 290, .heads = 8, .rpm = 7200, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Quantum Bigfoot TX4.3AT", .internal_name = "TX043A011", .model = "QUANTUM BIGFOOT TX4.3A", .zones = 2, .avg_spt = 220, .heads = 2, .rpm = 4000, .full_stroke_ms = 30, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[ATA-4] Quantum Fireball ST3.2AT", .internal_name = "ST32A461", .model = "QUANTUM FIREBALL ST3.2A", .zones = 4, .avg_spt = 200, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Quantum Fireball SE4.3A", .internal_name = "SE43A011", .model = "QUANTUM FIREBALL SE4.3A", .zones = 2, .avg_spt = 200, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Quantum Fireball SE6.4A", .internal_name = "SE64A011", .model = "QUANTUM FIREBALL SE6.4A", .zones = 3, .avg_spt = 200, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Quantum Fireball SE8.4A", .internal_name = "SE84A011", .model = "QUANTUM FIREBALL SE8.4A", .zones = 4, .avg_spt = 200, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Seagate Medalist 2122", .internal_name = "ST32122A", .model = "ST32122A", .zones = 16, .avg_spt = 215, .heads = 2, .rpm = 4500, .full_stroke_ms = 23, .track_seek_ms = 3.8, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Seagate Medalist 3321", .internal_name = "ST33221A", .model = "ST33221A", .zones = 16, .avg_spt = 210, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1.7, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Seagate Medalist 4321", .internal_name = "ST34321A", .model = "ST34321A", .zones = 16, .avg_spt = 210, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Seagate Medalist 6531", .internal_name = "ST36531A", .model = "ST36531A", .zones = 16, .avg_spt = 215, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1.7, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 16 }, + { .name = "[ATA-4] Seagate Medalist 8420", .internal_name = "ST38420A", .model = "ST38420A", .zones = 16, .avg_spt = 290, .heads = 4, .rpm = 5400, .full_stroke_ms = 16, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Seagate Medalist 13030", .internal_name = "ST313030A", .model = "ST313030A", .zones = 16, .avg_spt = 290, .heads = 6, .rpm = 5400, .full_stroke_ms = 16, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Seagate Medalist 17240", .internal_name = "ST317240A", .model = "ST317240A", .zones = 16, .avg_spt = 290, .heads = 8, .rpm = 5400, .full_stroke_ms = 16, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Toshiba MK4006MAV", .internal_name = "MK4006MAV", .model = "TOSHIBA MK4006MAV", .zones = 8, .avg_spt = 230, .heads = 6, .rpm = 4200, .full_stroke_ms = 25, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Western Digital Caviar 14300", .internal_name = "AC14300", .model = "WDC AC14300RT", .zones = 16, .avg_spt = 195, .heads = 2, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 5.5, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-4] Western Digital Caviar 23200", .internal_name = "AC23200", .model = "WDC AC23200LB", .zones = 16, .avg_spt = 210, .heads = 4, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-4] Western Digital Caviar 26400", .internal_name = "AC26400", .model = "WDC AC26400RN", .zones = 16, .avg_spt = 295, .heads = 5, .rpm = 5400, .full_stroke_ms = 21, .track_seek_ms = 3, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-4] Western Digital Caviar 33200", .internal_name = "AC33200", .model = "WDC AC33200LA", .zones = 16, .avg_spt = 310, .heads = 5, .rpm = 5200, .full_stroke_ms = 40, .track_seek_ms = 3, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-5] IBM Travelstar 6GN", .internal_name = "DARA206000", .model = "IBM-DARA-206000", .zones = 12, .avg_spt = 292, .heads = 2, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] IBM Travelstar 9GN", .internal_name = "DARA209000", .model = "IBM-DARA-209000", .zones = 12, .avg_spt = 292, .heads = 3, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] IBM/Hitachi Travelstar 12GN", .internal_name = "DARA212000", .model = "IBM-DARA-212000", .zones = 12, .avg_spt = 292, .heads = 4, .rpm = 4200, .full_stroke_ms = 31, .track_seek_ms = 4, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, // Either Hitachi or IBM OEM + { .name = "[ATA-5] Maxtor DiamondMax VL 17", .internal_name = "90871U2", .model = "Maxtor 90871U2", .zones = 16, .avg_spt = 290, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 0.9, .rcache_num_seg = 16, .rcache_seg_size = 256, .max_multiple = 32 }, + { .name = "[ATA-5] Maxtor DiamondMax VL 20 (91021U2)", .internal_name = "91021U2", .model = "Maxtor 91021U2", .zones = 16, .avg_spt = 295, .heads = 2, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Maxtor DiamondMax VL 20 (91531U3)", .internal_name = "91531U3", .model = "Maxtor 91531U3", .zones = 16, .avg_spt = 295, .heads = 3, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Maxtor DiamondMax VL 20 (92041U4)", .internal_name = "92041U4", .model = "Maxtor 92041U4", .zones = 16, .avg_spt = 295, .heads = 4, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 1, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Quantum Fireball EX3.2A", .internal_name = "EX32A012", .model = "QUANTUM FIREBALL EX3.2A", .zones = 1, .avg_spt = 210, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball EX5.1A", .internal_name = "EX51A012", .model = "QUANTUM FIREBALL EX5.1A", .zones = 2, .avg_spt = 210, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball EX6.4A", .internal_name = "EX64A012", .model = "QUANTUM FIREBALL EX6.4A", .zones = 2, .avg_spt = 210, .heads = 4, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball EX10.2A", .internal_name = "EX10A011", .model = "QUANTUM FIREBALL EX10.2A", .zones = 3, .avg_spt = 210, .heads = 6, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball EX12.7A", .internal_name = "EX12A011", .model = "QUANTUM FIREBALL EX12.7A", .zones = 4, .avg_spt = 210, .heads = 8, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball CR4.3A", .internal_name = "CR43A013", .model = "QUANTUM FIREBALL CR4.3A", .zones = 2, .avg_spt = 310, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball CR6.4A", .internal_name = "CR64A011", .model = "QUANTUM FIREBALL CR6.4A", .zones = 2, .avg_spt = 310, .heads = 4, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball CR8.4A", .internal_name = "CR84A011", .model = "QUANTUM FIREBALL CR8.4A", .zones = 3, .avg_spt = 310, .heads = 6, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Quantum Fireball CR13.0A", .internal_name = "CR13A011", .model = "QUANTUM FIREBALL CR13.0A", .zones = 4, .avg_spt = 310, .heads = 8, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 512, .max_multiple = 16 }, + { .name = "[ATA-5] Samsung SpinPoint V6800 (SV0682D)", .internal_name = "SV0682D", .model = "SAMSUNG SV0682D", .zones = 8, .avg_spt = 295, .heads = 2, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Samsung SpinPoint V6800 (SV1023D)", .internal_name = "SV1023D", .model = "SAMSUNG SV1023D", .zones = 8, .avg_spt = 295, .heads = 3, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Samsung SpinPoint V6800 (SV1364D)", .internal_name = "SV1364D", .model = "SAMSUNG SV1364D", .zones = 8, .avg_spt = 295, .heads = 4, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Samsung SpinPoint V6800 (SV1705D)", .internal_name = "SV1705D", .model = "SAMSUNG SV1705D", .zones = 8, .avg_spt = 295, .heads = 5, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Samsung SpinPoint V6800 (SV2046D)", .internal_name = "SV2046D", .model = "SAMSUNG SV2046D", .zones = 8, .avg_spt = 295, .heads = 6, .rpm = 5400, .full_stroke_ms = 18, .track_seek_ms = 1.3, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Seagate U8 - 4.3gb", .internal_name = "ST34313A", .model = "ST34313A", .zones = 16, .avg_spt = 289, .heads = 1, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Seagate U8 - 8.4gb", .internal_name = "ST38410A", .model = "ST38410A", .zones = 16, .avg_spt = 289, .heads = 2, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Seagate U8 - 13gb", .internal_name = "ST313021A", .model = "ST313021A", .zones = 16, .avg_spt = 289, .heads = 4, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Seagate U8 - 17.2gb", .internal_name = "ST317221A", .model = "ST317221A", .zones = 16, .avg_spt = 289, .heads = 3, .rpm = 5400, .full_stroke_ms = 25, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Western Digital Caviar 102AA", .internal_name = "WD102AA", .model = "WDC WD102AA-00ANA0", .zones = 16, .avg_spt = 295, .heads = 8, .rpm = 5400, .full_stroke_ms = 12, .track_seek_ms = 1.5, .rcache_num_seg = 16, .rcache_seg_size = 512, .max_multiple = 32 }, + { .name = "[ATA-5] Western Digital Expert", .internal_name = "WD135BA", .model = "WDC WD135BA-60AK", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 1920, .max_multiple = 32 }, + // clang-format on }; int @@ -472,6 +599,8 @@ hdd_preset_apply(int hdd_id) hd->cache.num_segments = preset->rcache_num_seg; hd->cache.segment_size = preset->rcache_seg_size; hd->max_multiple_block = preset->max_multiple; + if (preset->model) + hd->model = preset->model; if (!hd->speed_preset) return; diff --git a/src/disk/hdd_image.c b/src/disk/hdd_image.c index db56d5b78..09f48ad50 100644 --- a/src/disk/hdd_image.c +++ b/src/disk/hdd_image.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef __unix__ +#include +#endif #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/path.h> @@ -181,8 +184,12 @@ hdd_image_calc_chs(uint32_t *c, uint32_t *h, uint32_t *s, uint32_t size) static int prepare_new_hard_disk(uint8_t id, uint64_t full_size) { + if (!hdd_images[id].file) + return -1; + uint64_t target_size = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file); +#ifndef __unix__ uint32_t size; uint32_t t; @@ -217,7 +224,16 @@ prepare_new_hard_disk(uint8_t id, uint64_t full_size) pclog_toggle_suppr(); free(empty_sector_1mb); +#else + pclog("Creating hard disk image: "); + int ret = ftruncate(fileno(hdd_images[id].file), (size_t) target_size); + if (ret) { + pclog("failed\n"); + fatal("Could not create hard disk image\n"); + } + pclog("OK!\n"); +#endif hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; hdd_images[id].loaded = 1; @@ -279,7 +295,7 @@ hdd_image_load(int id) if (fn[0] == '.') { hdd_image_log("File name starts with .\n"); memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; + goto fail_raw; } hdd_images[id].file = plat_fopen(fn, "rb+"); if (hdd_images[id].file == NULL) { @@ -290,14 +306,14 @@ hdd_image_load(int id) if (hdd[id].wp) { hdd_image_log("A write-protected image must exist\n"); memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; + goto fail_raw; } hdd_images[id].file = plat_fopen(fn, "wb+"); if (hdd_images[id].file == NULL) { hdd_image_log("Unable to open image\n"); memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; + goto fail_raw; } else { if (image_is_hdi(fn)) { full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; @@ -373,11 +389,16 @@ retry_vhd: s = full_size = ((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks) << 9LL; ret = prepare_new_hard_disk(id, full_size); + if (ret <= 0) + goto fail_raw; return ret; } else { /* Failed for another reason */ hdd_image_log("Failed for another reason\n"); - return 0; +fail_raw: + hdd_images[id].type = HDD_IMAGE_RAW; + hdd_images[id].last_sector = (uint32_t) (((uint64_t) hdd[id].spt) * ((uint64_t) hdd[id].hpc) * ((uint64_t) hdd[id].tracks)) - 1; + return 1; } } else { if (image_is_hdi(fn)) { @@ -400,7 +421,7 @@ retry_vhd: fclose(hdd_images[id].file); hdd_images[id].file = NULL; memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; + goto fail_raw; } if (fread(&spt, 1, 4, hdd_images[id].file) != 4) fatal("hdd_image_load(): HDI: Error reading sectors per track\n"); @@ -428,7 +449,7 @@ retry_vhd: fclose(hdd_images[id].file); hdd_images[id].file = NULL; memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - return 0; + goto fail_raw; } if (fread(&spt, 1, 4, hdd_images[id].file) != 4) fatal("hdd_image_load(): HDI: Error reading sectors per track\n"); @@ -487,7 +508,7 @@ retry_vhd: return ret; } -void +int hdd_image_seek(uint8_t id, uint32_t sector) { off64_t addr = sector; @@ -495,29 +516,40 @@ hdd_image_seek(uint8_t id, uint32_t sector) hdd_images[id].pos = sector; if (hdd_images[id].type != HDD_IMAGE_VHD) { - if (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1) - fatal("hdd_image_seek(): Error seeking\n"); + if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, addr + hdd_images[id].base, SEEK_SET) == -1)) { + hdd_image_log("hdd_image_seek(): Error seeking\n"); + return -1; + } } + + return 0; } -void +int hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) { int non_transferred_sectors; size_t num_read; if (hdd_images[id].type == HDD_IMAGE_VHD) { - non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer); - hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + hdd_images[id].vhd->error = 0; + non_transferred_sectors = mvhd_read_sectors(hdd_images[id].vhd, sector, count, buffer); + hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + if (hdd_images[id].vhd->error) + return -1; } else { - if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) { - fatal("Hard disk image %i: Read error during seek\n", id); - return; + if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) { + hdd_image_log("Hard disk image %i: Read error during seek\n", id); + return -1; } num_read = fread(buffer, 512, count, hdd_images[id].file); hdd_images[id].pos = sector + num_read; + if ((num_read < count) && !feof(hdd_images[id].file)) + return -1; } + + return 0; } uint32_t @@ -541,31 +573,40 @@ hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) if ((sectors - sector) < transfer_sectors) transfer_sectors = sectors - sector; - hdd_image_read(id, sector, transfer_sectors, buffer); + if (hdd_image_read(id, sector, transfer_sectors, buffer) < 0) + return -1; if (count != transfer_sectors) return 1; return 0; } -void +int hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) { int non_transferred_sectors; size_t num_write; if (hdd_images[id].type == HDD_IMAGE_VHD) { - non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer); - hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + hdd_images[id].vhd->error = 0; + non_transferred_sectors = mvhd_write_sectors(hdd_images[id].vhd, sector, count, buffer); + hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + if (hdd_images[id].vhd->error) + return -1; } else { - if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) { - fatal("Hard disk image %i: Write error during seek\n", id); - return; + if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) { + hdd_image_log("Hard disk image %i: Write error during seek\n", id); + return -1; } num_write = fwrite(buffer, 512, count, hdd_images[id].file); hdd_images[id].pos = sector + num_write; + fflush(hdd_images[id].file); + if (num_write < count) + return -1; } + + return 0; } int @@ -577,25 +618,29 @@ hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) if ((sectors - sector) < transfer_sectors) transfer_sectors = sectors - sector; - hdd_image_write(id, sector, transfer_sectors, buffer); + if (hdd_image_write(id, sector, transfer_sectors, buffer) < 0) + return -1; if (count != transfer_sectors) return 1; return 0; } -void +int hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count) { if (hdd_images[id].type == HDD_IMAGE_VHD) { + hdd_images[id].vhd->error = 0; int non_transferred_sectors = mvhd_format_sectors(hdd_images[id].vhd, sector, count); hdd_images[id].pos = sector + count - non_transferred_sectors - 1; + if (hdd_images[id].vhd->error) + return -1; } else { memset(empty_sector, 0, 512); - if (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1) { - fatal("Hard disk image %i: Zero error during seek\n", id); - return; + if (!hdd_images[id].file || (fseeko64(hdd_images[id].file, ((uint64_t) (sector) << 9LL) + hdd_images[id].base, SEEK_SET) == -1)) { + hdd_image_log("Hard disk image %i: Zero error during seek\n", id); + return -1; } for (uint32_t i = 0; i < count; i++) { @@ -603,9 +648,14 @@ hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count) break; hdd_images[id].pos = sector + i; - fwrite(empty_sector, 512, 1, hdd_images[id].file); + if (!fwrite(empty_sector, 512, 1, hdd_images[id].file)) + return -1; } + + fflush(hdd_images[id].file); } + + return 0; } int diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c index 35c845c16..ef9e167d3 100644 --- a/src/disk/lba_enhancer.c +++ b/src/disk/lba_enhancer.c @@ -44,7 +44,7 @@ lba_enhancer_close(void* priv) } void * -lba_enhancer_init(const device_t *info) +lba_enhancer_init(UNUSED(const device_t *info)) { lba_enhancer_t *dev = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); @@ -63,22 +63,23 @@ lba_enhancer_available(void) // clang-format off static const device_config_t lba_enhancer_config[] = { { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .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 = "" } + .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 } }; @@ -87,12 +88,12 @@ static const device_config_t lba_enhancer_config[] = { const device_t lba_enhancer_device = { .name = "Vision Systems LBA Enhancer", .internal_name = "lba_enhancer", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = lba_enhancer_init, .close = lba_enhancer_close, .reset = NULL, - { .available = lba_enhancer_available }, + .available = lba_enhancer_available, .speed_changed = NULL, .force_redraw = NULL, .config = lba_enhancer_config diff --git a/src/disk/minivhd/internal.h b/src/disk/minivhd/internal.h index d3f930110..4caef7c47 100644 --- a/src/disk/minivhd/internal.h +++ b/src/disk/minivhd/internal.h @@ -115,6 +115,7 @@ typedef struct MVHDSparseHeader { struct MVHDMeta { FILE* f; bool readonly; + bool error; char filename[MVHD_MAX_PATH_BYTES]; struct MVHDMeta* parent; MVHDFooter footer; @@ -271,7 +272,7 @@ struct MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t * \param [in] f File to write sectors to * \param [in] sector_count The number of sectors to write */ -void mvhd_write_empty_sectors(FILE* f, int sector_count); +bool mvhd_write_empty_sectors(FILE* f, int sector_count); /** * \brief Read a fixed VHD image diff --git a/src/disk/minivhd/minivhd_io.c b/src/disk/minivhd/minivhd_io.c index 2912cf5b2..3b75ca74d 100644 --- a/src/disk/minivhd/minivhd_io.c +++ b/src/disk/minivhd/minivhd_io.c @@ -37,6 +37,7 @@ #ifndef _FILE_OFFSET_BITS # define _FILE_OFFSET_BITS 64 #endif +#include #include #include #include @@ -45,6 +46,10 @@ #include #include "minivhd.h" #include "internal.h" +#define HAVE_STDARG_H + +#include "cpu.h" +#include <86box/86box.h> /* * The following bit array macros adapted from: @@ -77,13 +82,18 @@ check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *tra } } -void +bool mvhd_write_empty_sectors(FILE *f, int sector_count) { uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; - for (int i = 0; i < sector_count; i++) - fwrite(zero_bytes, sizeof zero_bytes, 1, f); + for (int i = 0; i < sector_count; i++) { + if (!fwrite(zero_bytes, sizeof zero_bytes, 1, f)) + return 0; + } + + fflush(f); + return 1; } /** @@ -100,7 +110,8 @@ read_sect_bitmap(MVHDMeta *vhdm, int blk) { if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); - (void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); + if (!fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f)) + vhdm->error = 1; } else memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); @@ -117,8 +128,10 @@ write_curr_sect_bitmap(MVHDMeta* vhdm) { if (vhdm->bitmap.curr_block >= 0) { int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET); - fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f); + if (mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET) == -1) + vhdm->error = 1; + if (!fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f)) + vhdm->error = 1; } } @@ -134,8 +147,11 @@ write_bat_entry(MVHDMeta *vhdm, int blk) uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); - mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET); - fwrite(&offset, sizeof offset, 1, vhdm->f); + if (mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET) == -1) + vhdm->error = 1; + if (!fwrite(&offset, sizeof offset, 1, vhdm->f)) + vhdm->error = 1; + fflush(vhdm->f); } /** @@ -165,7 +181,8 @@ create_block(MVHDMeta *vhdm, int blk) if (!mvhd_is_conectix_str(footer)) { /* Oh dear. We use the header instead, since something has gone wrong at the footer */ mvhd_fseeko64(vhdm->f, 0, SEEK_SET); - (void) !fread(footer, sizeof footer, 1, vhdm->f); + if (!fread(footer, sizeof footer, 1, vhdm->f)) + vhdm->error = 1; mvhd_fseeko64(vhdm->f, 0, SEEK_END); } @@ -174,24 +191,31 @@ create_block(MVHDMeta *vhdm, int blk) /* Yikes! We're supposed to be on a sector boundary. Add some padding */ int64_t padding_amount = ((int64_t) MVHD_SECTOR_SIZE) - (abs_offset % MVHD_SECTOR_SIZE); uint8_t zero_byte = 0; - for (int i = 0; i < padding_amount; i++) - fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); + for (int i = 0; i < padding_amount; i++) { + if (!fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f)) + vhdm->error = 1; + } abs_offset += padding_amount; } uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE); int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; - mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors); + if (!mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors)) + vhdm->error = 1; /* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */ - mvhd_write_empty_sectors(vhdm->f, 5); + if (!mvhd_write_empty_sectors(vhdm->f, 5)) + vhdm->error = 1; /* And we finish with the footer */ - fwrite(footer, sizeof footer, 1, vhdm->f); + if (!fwrite(footer, sizeof footer, 1, vhdm->f)) + vhdm->error = 1; /* We no longer have a sparse block. Update that BAT! */ vhdm->block_offset[blk] = sect_offset; write_bat_entry(vhdm, blk); + + fflush(vhdm->f); } int @@ -204,8 +228,10 @@ mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); addr = ((int64_t) offset) * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - (void) !fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); + if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1) + vhdm->error = 1; + if (!fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f) && !feof(vhdm->f)) + vhdm->error = 1; return truncated_sectors; } @@ -235,17 +261,20 @@ mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buf prev_blk = blk; if (vhdm->bitmap.curr_block != blk) { read_sect_bitmap(vhdm, blk); - mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); + if (mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR) == -1) + vhdm->error = 1; } else { addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1) + vhdm->error = 1; } } - if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) - (void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - else { + if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { + if (!fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f) && !feof(vhdm->f)) + vhdm->error = 1; + } else { memset(buff, 0, MVHD_SECTOR_SIZE); mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR); } @@ -291,6 +320,10 @@ mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) mvhd_sparse_read(curr_vhdm, s, 1, buff); else mvhd_fixed_read(curr_vhdm, s, 1, buff); + if (curr_vhdm->error) { + curr_vhdm->error = 0; + vhdm->error = 1; + } curr_vhdm = vhdm; buff += MVHD_SECTOR_SIZE; @@ -310,8 +343,11 @@ mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); addr = (int64_t)offset * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); + if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1) + vhdm->error = 1; + if (!fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f)) + vhdm->error = 1; + fflush(vhdm->f); return truncated_sectors; } @@ -334,41 +370,48 @@ mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *i int sib = 0; ls = offset + transfer_sectors; - for (s = offset; s < ls; s++) { - blk = s / vhdm->sect_per_block; - sib = s % vhdm->sect_per_block; - if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { - /* Write the sector bitmap for the previous block, before we replace it. */ - write_curr_sect_bitmap(vhdm); - } - - if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { - /* "read" the sector bitmap first, before creating a new block, as the bitmap will be - zero either way */ - read_sect_bitmap(vhdm, blk); - create_block(vhdm, blk); - } - - if (blk != prev_blk) { - if (vhdm->bitmap.curr_block != blk) { - read_sect_bitmap(vhdm, blk); - mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); - } else { - addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * - MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + if (offset < total_sectors) { + for (s = offset; s < ls; s++) { + blk = s / vhdm->sect_per_block; + sib = s % vhdm->sect_per_block; + if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { + /* Write the sector bitmap for the previous block, before we replace it. */ + write_curr_sect_bitmap(vhdm); } - prev_blk = blk; - } - fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); - buff += MVHD_SECTOR_SIZE; + if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { + /* "read" the sector bitmap first, before creating a new block, as the bitmap will be + zero either way */ + read_sect_bitmap(vhdm, blk); + create_block(vhdm, blk); + } + + if (blk != prev_blk) { + if (vhdm->bitmap.curr_block != blk) { + read_sect_bitmap(vhdm, blk); + if (mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR) == -1) + vhdm->error = 1; + } else { + addr = (((int64_t) vhdm->block_offset[blk]) + vhdm->bitmap.sector_count + sib) * + MVHD_SECTOR_SIZE; + if (mvhd_fseeko64(vhdm->f, addr, SEEK_SET) == -1) + vhdm->error = 1; + } + prev_blk = blk; + } + + if (!fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f)) + vhdm->error = 1; + VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); + buff += MVHD_SECTOR_SIZE; + } } /* And write the sector bitmap for the last block we visited to disk */ write_curr_sect_bitmap(vhdm); + fflush(vhdm->f); + return truncated_sectors; } diff --git a/src/disk/mo.c b/src/disk/mo.c index 44f68effa..5494fc9a8 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -9,35 +9,31 @@ * Implementation of a generic Magneto-Optical Disk drive * commands, for both ATAPI and SCSI usage. * - * - * * Authors: Natalia Portillo * Miran Grca, * Fred N. van Kempen, * - * Copyright 2020-2021 Natalia Portillo. - * Copyright 2020-2021 Miran Grca. - * Copyright 2020-2021 Fred N. van Kempen + * Copyright 2020-2025 Natalia Portillo. + * Copyright 2020-2025 Miran Grca. + * Copyright 2020-2025 Fred N. van Kempen */ -#include -#include -#include -#include +#ifdef ENABLE_MO_LOG #include -#include -#define HAVE_STDARG_H +#endif +#include +#include +#include +#include #include <86box/86box.h> #include <86box/timer.h> -#include <86box/config.h> -#include <86box/timer.h> #include <86box/device.h> +#include <86box/log.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/nvr.h> #include <86box/path.h> #include <86box/plat.h> #include <86box/ui.h> -#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/mo.h> #include <86box/version.h> @@ -53,235 +49,50 @@ mo_drive_t mo_drives[MO_NUM]; -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ +// clang-format off +/* + Table of all SCSI commands and their flags, needed for the new disc change / + not ready handler. + */ const uint8_t mo_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2C */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 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, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, - IMPLEMENTED | CHECK_READY | NONDATA, /* 0xAC */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + [0x00] = IMPLEMENTED | CHECK_READY, + [0x01] = IMPLEMENTED | ALLOW_UA | SCSI_ONLY, + [0x03] = IMPLEMENTED | ALLOW_UA, + [0x04] = IMPLEMENTED | CHECK_READY | ALLOW_UA | SCSI_ONLY, + [0x08] = IMPLEMENTED | CHECK_READY, + [0x0a] = IMPLEMENTED | CHECK_READY, + [0x0b] = IMPLEMENTED | CHECK_READY, + [0x12] = IMPLEMENTED | ALLOW_UA, + [0x13] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x15] = IMPLEMENTED, + [0x16] = IMPLEMENTED | SCSI_ONLY, + [0x17] = IMPLEMENTED | SCSI_ONLY, + [0x1a] = IMPLEMENTED, + [0x1b] = IMPLEMENTED | CHECK_READY, + [0x1d] = IMPLEMENTED, + [0x1e] = IMPLEMENTED | CHECK_READY, + [0x25] = IMPLEMENTED | CHECK_READY, + [0x28] = IMPLEMENTED | CHECK_READY, + [0x2a ... 0x2c] = IMPLEMENTED | CHECK_READY, + [0x2e] = IMPLEMENTED | CHECK_READY, + [0x2f] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x41] = IMPLEMENTED | CHECK_READY, + [0x55] = IMPLEMENTED, + [0x5a] = IMPLEMENTED, + [0xa8] = IMPLEMENTED | CHECK_READY, + [0xaa] = IMPLEMENTED | CHECK_READY, + [0xac] = IMPLEMENTED | CHECK_READY, + [0xae] = IMPLEMENTED | CHECK_READY, + [0xaf] = IMPLEMENTED | CHECK_READY | SCSI_ONLY }; static uint64_t mo_mode_sense_page_flags = GPMODEP_ALL_PAGES; -static const mode_sense_pages_t mo_mode_sense_pages_default = - // clang-format off -{ { - { 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 }, - { 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 } -} }; -// clang-format on +static const mode_sense_pages_t mo_mode_sense_pages_default = { 0 }; -static const mode_sense_pages_t mo_mode_sense_pages_default_scsi = - // clang-format off -{ { - { 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 }, - { 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 } -} }; -// clang-format on +static const mode_sense_pages_t mo_mode_sense_pages_default_scsi = { 0 }; -static const mode_sense_pages_t mo_mode_sense_pages_changeable = - // clang-format off -{ { - { 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 }, - { 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 } -} }; +static const mode_sense_pages_t mo_mode_sense_pages_changeable = { 0 }; // clang-format on static void mo_command_complete(mo_t *dev); @@ -291,32 +102,22 @@ static void mo_init(mo_t *dev); int mo_do_log = ENABLE_MO_LOG; static void -mo_log(const char *fmt, ...) +mo_log(void *priv, const char *fmt, ...) { va_list ap; if (mo_do_log) { va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define mo_log(fmt, ...) +# define mo_log(priv, fmt, ...) #endif -int -find_mo_for_channel(uint8_t channel) -{ - for (uint8_t i = 0; i < MO_NUM; i++) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && (mo_drives[i].ide_channel == channel)) - return i; - } - return 0xff; -} - static int -mo_load_abort(mo_t *dev) +mo_load_abort(const mo_t *dev) { if (dev->drv->fp) fclose(dev->drv->fp); @@ -330,105 +131,125 @@ mo_load_abort(mo_t *dev) int image_is_mdi(const char *s) { - if (!strcasecmp(path_get_extension((char *) s), "MDI")) - return 1; - else - return 0; + return !strcasecmp(path_get_extension((char *) s), "MDI"); } int -mo_load(mo_t *dev, char *fn) +mo_is_empty(const uint8_t id) { - int is_mdi; - uint32_t size = 0; - unsigned int found = 0; + const mo_t *dev = (const mo_t *) mo_drives[id].priv; + int ret = 0; - if (!dev->drv) { + if ((dev->drv == NULL) || (dev->drv->fp == NULL)) + ret = 1; + + return ret; +} + +void +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; + + if (dev->drv == NULL) mo_eject(dev->id); - return 0; - } + else { + const int is_mdi = image_is_mdi(fn); - is_mdi = image_is_mdi(fn); + dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); + ret = 1; - dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); - if (!dev->drv->fp) { - if (!dev->drv->read_only) { - dev->drv->fp = plat_fopen(fn, "rb"); - if (dev->drv->fp) - dev->drv->read_only = 1; - else - return mo_load_abort(dev); - } else - return mo_load_abort(dev); - } + if (dev->drv->fp == NULL) { + if (!dev->drv->read_only) { + dev->drv->fp = plat_fopen(fn, "rb"); + if (dev->drv->fp == NULL) + ret = mo_load_abort(dev); + else + dev->drv->read_only = 1; + } else + ret = mo_load_abort(dev); + } - fseek(dev->drv->fp, 0, SEEK_END); - size = (uint32_t) ftell(dev->drv->fp); + if (ret) { + fseek(dev->drv->fp, 0, SEEK_END); - if (is_mdi) { - /* This is a MDI image. */ - size -= 0x1000LL; - dev->drv->base = 0x1000; - } + uint32_t size = (uint32_t) ftell(dev->drv->fp); + unsigned int found = 0; - for (uint8_t i = 0; i < KNOWN_MO_TYPES; i++) { - if (size == (mo_types[i].sectors * mo_types[i].bytes_per_sector)) { - found = 1; - dev->drv->medium_size = mo_types[i].sectors; - dev->drv->sector_size = mo_types[i].bytes_per_sector; - break; + if (is_mdi) { + /* This is a MDI image. */ + size -= 0x1000LL; + dev->drv->base = 0x1000; + } else + dev->drv->base = 0; + + for (uint8_t i = 0; i < KNOWN_MO_TYPES; i++) { + if (size == (mo_types[i].sectors * mo_types[i].bytes_per_sector)) { + found = 1; + dev->drv->medium_size = mo_types[i].sectors; + dev->drv->sector_size = mo_types[i].bytes_per_sector; + break; + } + } + + if (found) { + if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) + 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); + + ret = 1; + } else + ret = mo_load_abort(dev); } } - if (!found) - return mo_load_abort(dev); + if (ret && !skip_insert) { + /* Signal media change to the emulated machine. */ + mo_insert((mo_t *) dev); - if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) - fatal("mo_load(): Error seeking to the beginning of the file\n"); - - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); - - return 1; + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + mo_insert((mo_t *) dev); + } } void -mo_disk_reload(mo_t *dev) +mo_disk_reload(const mo_t *dev) { - int ret = 0; - - if (strlen(dev->drv->prev_image_path) == 0) - return; - else - ret = mo_load(dev, dev->drv->prev_image_path); - - if (ret) - dev->unit_attention = 1; + if (strlen(dev->drv->prev_image_path) != 0) + (void) mo_load(dev, dev->drv->prev_image_path, 0); } -void -mo_disk_unload(mo_t *dev) +static void +mo_disk_unload(const mo_t *dev) { - if (dev->drv && dev->drv->fp) { + if ((dev->drv != NULL) && (dev->drv->fp != NULL)) { fclose(dev->drv->fp); dev->drv->fp = NULL; } } void -mo_disk_close(mo_t *dev) +mo_disk_close(const mo_t *dev) { - if (dev->drv && dev->drv->fp) { + if ((dev->drv != NULL) && (dev->drv->fp != NULL)) { mo_disk_unload(dev); - memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); + memcpy(dev->drv->prev_image_path, dev->drv->image_path, + sizeof(dev->drv->prev_image_path)); memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); dev->drv->medium_size = 0; + + mo_insert((mo_t *) dev); } } static void -mo_set_callback(mo_t *dev) +mo_set_callback(const mo_t *dev) { if (dev->drv->bus_type != MO_BUS_SCSI) ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); @@ -437,55 +258,55 @@ mo_set_callback(mo_t *dev) static void mo_init(mo_t *dev) { - if (dev->id >= MO_NUM) - return; - - dev->requested_blocks = 1; - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->drv->bus_mode = 0; - if (dev->drv->bus_type >= MO_BUS_ATAPI) - dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < MO_BUS_SCSI) - dev->drv->bus_mode |= 1; - mo_log("MO %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - if (dev->drv->bus_type < MO_BUS_SCSI) { - dev->tf->phase = 1; - dev->tf->request_length = 0xEB14; + if (dev->id < MO_NUM) { + dev->requested_blocks = 1; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + dev->drv->bus_mode = 0; + if (dev->drv->bus_type >= MO_BUS_ATAPI) + dev->drv->bus_mode |= 2; + if (dev->drv->bus_type < MO_BUS_SCSI) + dev->drv->bus_mode |= 1; + mo_log(dev->log, "Bus type %i, bus mode %i\n", dev->drv->bus_type, dev->drv->bus_mode); + if (dev->drv->bus_type < MO_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; + mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = dev->transition = 0; + mo_info = 0x00000000; } - dev->tf->status = READY_STAT | DSC_STAT; - dev->tf->pos = 0; - dev->packet_status = PHASE_NONE; - mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = 0; } static int -mo_supports_pio(mo_t *dev) +mo_supports_pio(const mo_t *dev) { return (dev->drv->bus_mode & 1); } static int -mo_supports_dma(mo_t *dev) +mo_supports_dma(const mo_t *dev) { return (dev->drv->bus_mode & 2); } /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -mo_current_mode(mo_t *dev) +mo_current_mode(const mo_t *dev) { if (!mo_supports_pio(dev) && !mo_supports_dma(dev)) return 0; if (mo_supports_pio(dev) && !mo_supports_dma(dev)) { - mo_log("MO %i: Drive does not support DMA, setting to PIO\n", dev->id); + mo_log(dev->log, "Drive does not support DMA, setting to PIO\n"); return 1; } if (!mo_supports_pio(dev) && mo_supports_dma(dev)) return 2; if (mo_supports_pio(dev) && mo_supports_dma(dev)) { - mo_log("MO %i: Drive supports both, setting to %s\n", dev->id, - (dev->tf->features & 1) ? "DMA" : "PIO"); + mo_log(dev->log, "Drive supports both, setting to %s\n", (dev->tf->features & 1) ? + "DMA" : "PIO"); return (dev->tf->features & 1) ? 2 : 1; } @@ -495,21 +316,21 @@ mo_current_mode(mo_t *dev) static void mo_mode_sense_load(mo_t *dev) { - FILE *fp; - char fn[512]; + char fn[512] = { 0 }; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (mo_drives[dev->id].bus_type == MO_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default_scsi, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default_scsi, + sizeof(mode_sense_pages_t)); else - memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &mo_mode_sense_pages_default, + sizeof(mode_sense_pages_t)); - memset(fn, 0, 512); if (dev->drv->bus_type == MO_BUS_SCSI) sprintf(fn, "scsi_mo_%02i_mode_sense_bin", dev->id); else sprintf(fn, "mo_%02i_mode_sense_bin", dev->id); - fp = plat_fopen(nvr_path(fn), "rb"); + FILE *fp = plat_fopen(nvr_path(fn), "rb"); if (fp) { /* Nothing to read, not used by MO. */ fclose(fp); @@ -517,28 +338,27 @@ mo_mode_sense_load(mo_t *dev) } static void -mo_mode_sense_save(mo_t *dev) +mo_mode_sense_save(const mo_t *dev) { - FILE *fp; - char fn[512]; + char fn[512] = { 0 }; - memset(fn, 0, 512); if (dev->drv->bus_type == MO_BUS_SCSI) sprintf(fn, "scsi_mo_%02i_mode_sense_bin", dev->id); else sprintf(fn, "mo_%02i_mode_sense_bin", dev->id); - fp = plat_fopen(nvr_path(fn), "wb"); + FILE *fp = plat_fopen(nvr_path(fn), "wb"); if (fp) { /* Nothing to write, not used by MO. */ fclose(fp); } } -/*SCSI Mode Sense 6/10*/ +/* SCSI Mode Sense 6/10. */ static uint8_t -mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) +mo_mode_sense_read(const mo_t *dev, const uint8_t pgctl, + const uint8_t page, const uint8_t pos) { - switch (page_control) { + switch (pgctl) { case 0: case 3: return dev->ms_pages_saved.pages[page][pos]; @@ -558,14 +378,11 @@ mo_mode_sense_read(mo_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) } static uint32_t -mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) +mo_mode_sense(const mo_t *dev, uint8_t *buf, uint32_t pos, + uint8_t page, const uint8_t block_descriptor_len) { - uint64_t pf; - uint8_t page_control = (page >> 6) & 3; - - pf = mo_mode_sense_page_flags; - - uint8_t msplen; + const uint64_t pf = mo_mode_sense_page_flags; + const uint8_t pgctl = (page >> 6) & 3; page &= 0x3f; @@ -583,12 +400,12 @@ mo_mode_sense(mo_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block for (uint8_t i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { if (pf & (1LL << ((uint64_t) page))) { - buf[pos++] = mo_mode_sense_read(dev, page_control, i, 0); - msplen = mo_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - mo_log("MO %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + const uint8_t msplen = mo_mode_sense_read(dev, pgctl, i, 1); + buf[pos++] = mo_mode_sense_read(dev, pgctl, i, 0); + buf[pos++] = msplen; + mo_log(dev->log, "MODE SENSE: Page [%02X] length %i\n", i, msplen); for (uint8_t j = 0; j < msplen; j++) - buf[pos++] = mo_mode_sense_read(dev, page_control, i, 2 + j); + buf[pos++] = mo_mode_sense_read(dev, pgctl, i, 2 + j); } } } @@ -604,7 +421,10 @@ mo_update_request_length(mo_t *dev, int len, int block_len) dev->max_transfer_len = dev->tf->request_length; - /* For media access commands, make sure the requested DRQ length matches the block length. */ + /* + For media access commands, make sure the requested DRQ length + matches the block length. + */ switch (dev->current_cdb[0]) { case 0x08: case 0x0a: @@ -615,8 +435,10 @@ mo_update_request_length(mo_t *dev, int len, int block_len) /* Round it to the nearest 2048 bytes. */ dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ + /* + Make sure total length is not bigger than sum of the lengths of + all the requested blocks. + */ bt = (dev->requested_blocks * block_len); if (len > bt) len = bt; @@ -641,7 +463,10 @@ mo_update_request_length(mo_t *dev, int len, int block_len) /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) dev->max_transfer_len &= 0xfffe; - /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ + /* + If the DRQ length is smaller or equal in size to the total remaining length, + set it to that. + */ if (!dev->max_transfer_len) dev->max_transfer_len = 65534; @@ -649,8 +474,6 @@ mo_update_request_length(mo_t *dev, int len, int block_len) dev->tf->request_length = dev->max_transfer_len = len; else if (len > dev->max_transfer_len) dev->tf->request_length = dev->max_transfer_len; - - return; } static double @@ -676,23 +499,22 @@ mo_bus_speed(mo_t *dev) static void mo_command_common(mo_t *dev) { - double bytes_per_second; - double period; - dev->tf->status = BUSY_STAT; dev->tf->phase = 1; dev->tf->pos = 0; if (dev->packet_status == PHASE_COMPLETE) dev->callback = 0.0; else { + double bytes_per_second; + if (dev->drv->bus_type == MO_BUS_SCSI) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return; } else bytes_per_second = mo_bus_speed(dev); - period = 1000000.0 / bytes_per_second; - dev->callback = period * (double) (dev->packet_len); + const double period = 1000000.0 / bytes_per_second; + dev->callback = period * (double) (dev->packet_len); } mo_set_callback(dev); @@ -733,16 +555,20 @@ mo_command_write_dma(mo_t *dev) mo_command_common(dev); } -/* id = Current MO device ID; +/* + dev = Pointer to current MO 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). */ + direction = Transfer direction (0 = read from host, 1 = write to host). + */ static void -mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int direction) +mo_data_command_finish(mo_t *dev, int len, const int block_len, + const int alloc_len, const int direction) { - mo_log("MO %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length); + mo_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; if (alloc_len >= 0) { if (alloc_len < len) @@ -771,27 +597,26 @@ mo_data_command_finish(mo_t *dev, int len, int block_len, int alloc_len, int dir } } - mo_log("MO %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, - dev->tf->phase); + mo_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 mo_sense_clear(mo_t *dev, UNUSED(int command)) { mo_sense_key = mo_asc = mo_ascq = 0; + mo_info = 0x00000000; } static void -mo_set_phase(mo_t *dev, uint8_t phase) +mo_set_phase(const mo_t *dev, const uint8_t phase) { - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + 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 != MO_BUS_SCSI) - return; - - scsi_devices[scsi_bus][scsi_id].phase = phase; + if (dev->drv->bus_type == MO_BUS_SCSI) + scsi_devices[scsi_bus][scsi_id].phase = phase; } static void @@ -799,8 +624,6 @@ mo_cmd_error(mo_t *dev) { mo_set_phase(dev, SCSI_PHASE_STATUS); dev->tf->error = ((mo_sense_key & 0xf) << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->tf->error |= MCR_ERR; dev->tf->status = READY_STAT | ERR_STAT; dev->tf->phase = 3; dev->tf->pos = 0; @@ -808,31 +631,30 @@ mo_cmd_error(mo_t *dev) dev->callback = 50.0 * MO_TIME; mo_set_callback(dev); ui_sb_update_icon(SB_MO | dev->id, 0); - mo_log("MO %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], mo_sense_key, mo_asc, mo_ascq); + mo_log(dev->log, "[%02X] ERROR: %02X/%02X/%02X\n", dev->current_cdb[0], mo_sense_key, + mo_asc, mo_ascq); } static void mo_unit_attention(mo_t *dev) { mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->tf->error |= MCR_ERR; - dev->tf->status = READY_STAT | ERR_STAT; - dev->tf->phase = 3; - dev->tf->pos = 0; - dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * MO_TIME; + 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 * MO_TIME; mo_set_callback(dev); ui_sb_update_icon(SB_MO | dev->id, 0); - mo_log("MO %i: UNIT ATTENTION\n", dev->id); + mo_log(dev->log, "UNIT ATTENTION\n"); } static void mo_buf_alloc(mo_t *dev, uint32_t len) { - mo_log("MO %i: Allocated buffer length: %i\n", dev->id, len); - if (!dev->buffer) + mo_log(dev->log, "Allocated buffer length: %i\n", len); + if (dev->buffer == NULL) dev->buffer = (uint8_t *) malloc(len); } @@ -840,7 +662,7 @@ static void mo_buf_free(mo_t *dev) { if (dev->buffer) { - mo_log("MO %i: Freeing buffer...\n", dev->id); + mo_log(dev->log, "Freeing buffer...\n"); free(dev->buffer); dev->buffer = NULL; } @@ -853,6 +675,10 @@ mo_bus_master_error(scsi_common_t *sc) mo_buf_free(dev); mo_sense_key = mo_asc = mo_ascq = 0; + mo_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); mo_cmd_error(dev); } @@ -862,6 +688,7 @@ mo_not_ready(mo_t *dev) mo_sense_key = SENSE_NOT_READY; mo_asc = ASC_MEDIUM_NOT_PRESENT; mo_ascq = 0; + mo_info = 0x00000000; mo_cmd_error(dev); } @@ -871,24 +698,56 @@ mo_write_protected(mo_t *dev) mo_sense_key = SENSE_UNIT_ATTENTION; mo_asc = ASC_WRITE_PROTECTED; mo_ascq = 0; + mo_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); mo_cmd_error(dev); } static void -mo_invalid_lun(mo_t *dev) +mo_write_error(mo_t *dev) +{ + mo_sense_key = SENSE_MEDIUM_ERROR; + mo_asc = ASC_WRITE_ERROR; + mo_ascq = 0; + mo_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + mo_cmd_error(dev); +} + +static void +mo_read_error(mo_t *dev) +{ + mo_sense_key = SENSE_MEDIUM_ERROR; + mo_asc = ASC_UNRECOVERED_READ_ERROR; + mo_ascq = 0; + mo_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + mo_cmd_error(dev); +} + +static void +mo_invalid_lun(mo_t *dev, const uint8_t lun) { mo_sense_key = SENSE_ILLEGAL_REQUEST; mo_asc = ASC_INV_LUN; mo_ascq = 0; + mo_info = lun << 24; mo_cmd_error(dev); } static void -mo_illegal_opcode(mo_t *dev) +mo_illegal_opcode(mo_t *dev, const uint8_t opcode) { mo_sense_key = SENSE_ILLEGAL_REQUEST; mo_asc = ASC_ILLEGAL_OPCODE; mo_ascq = 0; + mo_info = opcode << 24; mo_cmd_error(dev); } @@ -898,127 +757,171 @@ mo_lba_out_of_range(mo_t *dev) mo_sense_key = SENSE_ILLEGAL_REQUEST; mo_asc = ASC_LBA_OUT_OF_RANGE; mo_ascq = 0; + mo_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); mo_cmd_error(dev); } static void -mo_invalid_field(mo_t *dev) +mo_invalid_field(mo_t *dev, const uint32_t field) { mo_sense_key = SENSE_ILLEGAL_REQUEST; mo_asc = ASC_INV_FIELD_IN_CMD_PACKET; mo_ascq = 0; + mo_info = (field >> 24) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); mo_cmd_error(dev); dev->tf->status = 0x53; } static void -mo_invalid_field_pl(mo_t *dev) +mo_invalid_field_pl(mo_t *dev, const uint32_t field) { mo_sense_key = SENSE_ILLEGAL_REQUEST; mo_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; mo_ascq = 0; + mo_info = (field >> 24) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); mo_cmd_error(dev); dev->tf->status = 0x53; } static int -mo_blocks(mo_t *dev, int32_t *len, UNUSED(int first_batch), int out) +mo_blocks(mo_t *dev, int32_t *len, int out) { - *len = 0; + int ret = 0; - if (!dev->sector_len) { + *len = 0; + + if (!dev->sector_len) mo_command_complete(dev); - return -1; - } + else { + mo_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", + dev->requested_blocks, dev->sector_pos); - mo_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) { - mo_log("MO %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); - mo_lba_out_of_range(dev); - return 0; - } - - *len = dev->requested_blocks * dev->drv->sector_size; - - for (int i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == 1) - break; - - if (feof(dev->drv->fp)) - break; - - if (out) { - if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) - fatal("mo_blocks(): Error writing data\n"); + if (dev->sector_pos >= dev->drv->medium_size) { + mo_log(dev->log, "Trying to %s beyond the end of disk\n", out ? "write" : "read"); + mo_lba_out_of_range(dev); } else { - if (fread(dev->buffer + (i * dev->drv->sector_size), 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) - fatal("mo_blocks(): Error reading data\n"); + *len = dev->requested_blocks * dev->drv->sector_size; + ret = 1; + + for (int i = 0; i < dev->requested_blocks; i++) { + if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size) + (i * dev->drv->sector_size), SEEK_SET) == -1) { + if (out) + mo_write_error(dev); + else + mo_read_error(dev); + + ret = -1; + } else { + if (!feof(dev->drv->fp)) + break; + + if (out) { + if (fwrite(dev->buffer + (i * dev->drv->sector_size), 1, + dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) { + mo_log(dev->log, "mo_blocks(): Error writing data\n"); + mo_write_error(dev); + ret = -1; + } else + fflush(dev->drv->fp); + } else { + if (fread(dev->buffer + (i * dev->drv->sector_size), 1, + dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) { + mo_log(dev->log, "mo_blocks(): Error reading data\n"); + mo_read_error(dev); + ret = -1; + } + } + } + + if (ret == -1) + break; + + dev->sector_pos++; + } + + if (ret == 1) { + mo_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); + + dev->sector_len -= dev->requested_blocks; + } } } - mo_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); - - dev->sector_pos += dev->requested_blocks; - dev->sector_len -= dev->requested_blocks; - - return 1; + return ret; } void mo_insert(mo_t *dev) { - dev->unit_attention = 1; + if ((dev != NULL) && (dev->drv != NULL)) { + if (dev->drv->fp == NULL) { + dev->unit_attention = 0; + dev->transition = 0; + mo_log(dev->log, "Media removal\n"); + } else if (dev->transition) { + dev->unit_attention = 1; + /* Turn off the medium changed status. */ + dev->transition = 0; + mo_log(dev->log, "Media insert\n"); + } else { + dev->unit_attention = 0; + dev->transition = 1; + mo_log(dev->log, "Media transition\n"); + } + } } void mo_format(mo_t *dev) { - long size; int ret; int fd; - mo_log("MO %i: Formatting media...\n", dev->id); + mo_log(dev->log, "Formatting media...\n"); fseek(dev->drv->fp, 0, SEEK_END); - size = ftell(dev->drv->fp); + long size = ftell(dev->drv->fp); #ifdef _WIN32 - HANDLE fh; LARGE_INTEGER liSize; - fd = _fileno(dev->drv->fp); - fh = (HANDLE) _get_osfhandle(fd); + fd = _fileno(dev->drv->fp); + const HANDLE fh = (HANDLE) _get_osfhandle(fd); liSize.QuadPart = 0; ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - if (!ret) { - mo_log("MO %i: Failed seek to start of image file\n", dev->id); - return; - } + if (ret) { + ret = (int) SetEndOfFile(fh); - ret = (int) SetEndOfFile(fh); + if (ret) { + liSize.QuadPart = size; + ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - if (!ret) { - mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); - return; - } + if (ret) { + ret = (int) SetEndOfFile(fh); - liSize.QuadPart = size; - ret = (int) SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - - if (!ret) { - mo_log("MO %i: Failed seek to end of image file\n", dev->id); - return; - } - - ret = (int) SetEndOfFile(fh); - - if (!ret) { - mo_log("MO %i: Failed to truncate image file to %llu\n", dev->id, size); - return; + if (!ret) { + mo_log(dev->log, "Failed to truncate image file to %llu\n", size); + } + } else { + mo_log(dev->log, "Failed seek to end of image file\n"); + } + } else { + mo_log(dev->log, "Failed to truncate image file to 0\n"); + } + } else { + mo_log(dev->log, "Failed seek to start of image file\n"); } #else fd = fileno(dev->drv->fp); @@ -1026,15 +929,13 @@ mo_format(mo_t *dev) ret = ftruncate(fd, 0); if (ret) { - mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); - return; - } + mo_log(dev->log, "Failed to truncate image file to 0\n"); + } else { + ret = ftruncate(fd, size); - ret = ftruncate(fd, size); - - if (ret) { - mo_log("MO %i: Failed to truncate image file to %llu", dev->id, size); - return; + if (ret) { + mo_log(dev->log, "Failed to truncate image file to %llu", size); + } } #endif } @@ -1049,10 +950,11 @@ mo_erase(mo_t *dev) return -1; } - mo_log("MO %i: Erasing %i blocks starting from %i...\n", dev->id, dev->sector_len, dev->sector_pos); + mo_log(dev->log, "Erasing %i blocks starting from %i...\n", + dev->sector_len, dev->sector_pos); if (dev->sector_pos >= dev->drv->medium_size) { - mo_log("MO %i: Trying to erase beyond the end of disk\n", dev->id); + mo_log(dev->log, "Trying to erase beyond the end of disk\n"); mo_lba_out_of_range(dev); return 0; } @@ -1060,7 +962,8 @@ mo_erase(mo_t *dev) mo_buf_alloc(dev, dev->drv->sector_size); memset(dev->buffer, 0, dev->drv->sector_size); - fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size), SEEK_SET); + fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos * dev->drv->sector_size), + SEEK_SET); for (i = 0; i < dev->requested_blocks; i++) { if (feof(dev->drv->fp)) @@ -1069,7 +972,9 @@ mo_erase(mo_t *dev) fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->fp); } - mo_log("MO %i: Erased %i bytes of blocks...\n", dev->id, i * dev->drv->sector_size); + fflush(dev->drv->fp); + + mo_log(dev->log, "Erased %i bytes of blocks...\n", i * dev->drv->sector_size); dev->sector_pos += i; dev->sector_len -= i; @@ -1077,96 +982,110 @@ mo_erase(mo_t *dev) return 1; } -/*SCSI Sense Initialization*/ -void -mo_sense_code_ok(mo_t *dev) -{ - mo_sense_key = SENSE_NONE; - mo_asc = 0; - mo_ascq = 0; -} - static int -mo_pre_execution_check(mo_t *dev, uint8_t *cdb) +mo_pre_execution_check(mo_t *dev, const uint8_t *cdb) { - int ready = 0; + int ready; - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - mo_log("MO %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && + (cdb[1] & 0xe0)) { + mo_log(dev->log, "Attempting to execute a unknown command targeted at SCSI LUN %i\n", ((dev->tf->request_length >> 5) & 7)); - mo_invalid_lun(dev); + mo_invalid_lun(dev, cdb[1] >> 5); return 0; } if (!(mo_command_flags[cdb[0]] & IMPLEMENTED)) { - mo_log("MO %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == MO_BUS_SCSI) ? "SCSI" : "ATAPI"); + mo_log(dev->log, "Attempting to execute unknown command %02X over %s\n", + cdb[0], (dev->drv->bus_type == MO_BUS_SCSI) ? + "SCSI" : "ATAPI"); - mo_illegal_opcode(dev); + mo_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type < MO_BUS_SCSI) && (mo_command_flags[cdb[0]] & SCSI_ONLY)) { - mo_log("MO %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - mo_illegal_opcode(dev); + if ((dev->drv->bus_type < MO_BUS_SCSI) && + (mo_command_flags[cdb[0]] & SCSI_ONLY)) { + mo_log(dev->log, "Attempting to execute SCSI-only command %02X " + "over ATAPI\n", cdb[0]); + mo_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type == MO_BUS_SCSI) && (mo_command_flags[cdb[0]] & ATAPI_ONLY)) { - mo_log("MO %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - mo_illegal_opcode(dev); + if ((dev->drv->bus_type == MO_BUS_SCSI) && + (mo_command_flags[cdb[0]] & ATAPI_ONLY)) { + mo_log(dev->log, "Attempting to execute ATAPI-only command %02X " + "over SCSI\n", cdb[0]); + mo_illegal_opcode(dev, cdb[0]); return 0; } - ready = (dev->drv->fp != NULL); + if (dev->transition) { + if ((cdb[0] == GPCMD_TEST_UNIT_READY) || (cdb[0] == GPCMD_REQUEST_SENSE)) + ready = 0; + else { + if (!(mo_command_flags[cdb[0]] & ALLOW_UA)) { + mo_log(dev->log, "(ext_medium_changed != 0): mo_insert()\n"); + mo_insert((void *) dev); + } - /* If the drive is not ready, there is no reason to keep the + ready = (dev->drv->fp != NULL); + } + } else + ready = (dev->drv->fp != NULL); + + /* + If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - if (!ready && dev->unit_attention) + disc changes. + */ + if (!ready && (dev->unit_attention > 0)) dev->unit_attention = 0; - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ + /* + If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. + */ if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ + /* + Only increment the unit attention phase if the command can + not pass through it. + */ if (!(mo_command_flags[cdb[0]] & ALLOW_UA)) { - /* mo_log("MO %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention = 2; - mo_log("MO %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); + mo_log(dev->log, "Unit attention now 2\n"); + dev->unit_attention++; + mo_log(dev->log, "UNIT ATTENTION: Command %02X not allowed to " + "pass through\n", cdb[0]); mo_unit_attention(dev); return 0; } } else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* mo_log("MO %i: Unit attention now 0\n", dev->id); */ + mo_log(dev->log, "MO %i: Unit attention now 0\n"); dev->unit_attention = 0; } } - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ + /* + Unless the command is REQUEST SENSE, clear the sense. This will *NOT* clear + the UNIT ATTENTION condition if it's set. + */ if (cdb[0] != GPCMD_REQUEST_SENSE) mo_sense_clear(dev, cdb[0]); - /* Next it's time for NOT READY. */ - if ((mo_command_flags[cdb[0]] & CHECK_READY) && !ready) { - mo_log("MO %i: Not ready (%02X)\n", dev->id, cdb[0]); + if (!ready && (mo_command_flags[cdb[0]] & CHECK_READY)) { + mo_log(dev->log, "Not ready (%02X)\n", cdb[0]); mo_not_ready(dev); return 0; } - mo_log("MO %i: Continuing with command %02X\n", dev->id, cdb[0]); - + mo_log(dev->log, "Continuing with command %02X\n", cdb[0]); return 1; } static void mo_seek(mo_t *dev, uint32_t pos) { -#if 0 - mo_log("MO %i: Seek %08X\n", dev->id, pos); -#endif dev->sector_pos = pos; } @@ -1187,28 +1106,30 @@ mo_reset(scsi_common_t *sc) dev->callback = 0.0; mo_set_callback(dev); dev->tf->phase = 1; - dev->tf->request_length = 0xEB14; + dev->tf->request_length = 0xeb14; dev->packet_status = PHASE_NONE; - dev->unit_attention = 0; dev->cur_lun = SCSI_LUN_USE_CDB; + mo_sense_key = mo_asc = mo_ascq = dev->unit_attention = dev->transition = 0; + mo_info = 0x00000000; } static void -mo_request_sense(mo_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) +mo_request_sense(mo_t *dev, uint8_t *buffer, const uint8_t alloc_length, const int desc) { - /*Will return 18 bytes of 0*/ + /* Will return 18 bytes of 0. */ if (alloc_length != 0) { - memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { + memset(buffer, 0x00, alloc_length); + if (desc) { buffer[1] = mo_sense_key; buffer[2] = mo_asc; buffer[3] = mo_ascq; - } + } else + memcpy(buffer, dev->sense, alloc_length); } - buffer[0] = desc ? 0x72 : 0x70; + buffer[0] = desc ? 0x72 : 0xf0; + if (!desc) + buffer[7] = 10; if (dev->unit_attention && (mo_sense_key == 0)) { buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; @@ -1216,25 +1137,27 @@ mo_request_sense(mo_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) buffer[desc ? 3 : 13] = 0; } - mo_log("MO %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); + mo_log(dev->log, "Reporting sense: %02X %02X %02X\n", buffer[2], buffer[12], buffer[13]); if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { - /* If the last remaining sense is unit attention, clear - that condition. */ + /* If the last remaining sense is unit attention, clear that condition. */ dev->unit_attention = 0; } /* Clear the sense stuff as per the spec. */ mo_sense_clear(dev, GPCMD_REQUEST_SENSE); + + if (dev->transition) { + mo_log(dev->log, "MO_TRANSITION: mo_insert()\n"); + mo_insert((void *) dev); + } } static void mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { - mo_t *dev = (mo_t *) sc; - int ready = 0; - - ready = (dev->drv->fp != NULL); + mo_t *dev = (mo_t *) sc; + const int ready = (dev->drv->fp != NULL); if (!ready && dev->unit_attention) { /* If the drive is not ready, there is no reason to keep the @@ -1244,12 +1167,11 @@ mo_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_leng } /* Do *NOT* advance the unit attention phase. */ - mo_request_sense(dev, buffer, alloc_length, 0); } static void -mo_set_buf_len(mo_t *dev, int32_t *BufLen, int32_t *src_len) +mo_set_buf_len(const mo_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == MO_BUS_SCSI) { if (*BufLen == -1) @@ -1258,29 +1180,28 @@ mo_set_buf_len(mo_t *dev, int32_t *BufLen, int32_t *src_len) *BufLen = MIN(*src_len, *BufLen); *src_len = *BufLen; } - mo_log("MO %i: Actual transfer length: %i\n", dev->id, *BufLen); + mo_log(dev->log, "Actual transfer length: %i\n", *BufLen); } } static void -mo_command(scsi_common_t *sc, uint8_t *cdb) +mo_command(scsi_common_t *sc, const uint8_t *cdb) { - mo_t *dev = (mo_t *) sc; - int pos = 0; - int block_desc = 0; - int ret; - int32_t len; - int32_t max_len; - int32_t alloc_length; - int size_idx; - int idx = 0; - unsigned preamble_len; - char device_identify[9] = { '8', '6', 'B', '_', 'M', 'O', '0', '0', 0 }; - int32_t blen = 0; - int32_t *BufLen; - uint32_t previous_pos = 0; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + mo_t * dev = (mo_t *) sc; + char device_identify[9] = { '8', '6', 'B', '_', 'M', 'O', '0', '0', 0 }; + uint32_t previous_pos = 0; + int32_t blen = 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 len; + int32_t max_len; + int32_t alloc_length; + unsigned preamble_len; + int block_desc; + int size_idx; + int32_t * BufLen; if (dev->drv->bus_type == MO_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -1298,11 +1219,13 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - mo_log("MO %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention); - mo_log("MO %i: Request length: %04X\n", dev->id, dev->tf->request_length); + mo_log(dev->log, "Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, " + "Unit attention: %i\n", + cdb[0], mo_sense_key, mo_asc, mo_ascq, dev->unit_attention); + mo_log(dev->log, "Request length: %04X\n", dev->tf->request_length); - mo_log("MO %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + mo_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]); } @@ -1311,14 +1234,17 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_set_phase(dev, SCSI_PHASE_STATUS); - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ + /* + This handles the Not Ready/Unit Attention check if it has to be + handled at this point. + */ if (mo_pre_execution_check(dev, cdb) == 0) return; switch (cdb[0]) { case GPCMD_SEND_DIAGNOSTIC: if (!(cdb[1] & (1 << 2))) { - mo_invalid_field(dev); + mo_invalid_field(dev, cdb[1]); return; } fallthrough; @@ -1347,8 +1273,6 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) break; case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ mo_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; @@ -1389,158 +1313,187 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) switch (cdb[0]) { case GPCMD_READ_6: dev->sector_len = cdb[4]; - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); if (dev->sector_len == 0) dev->sector_len = 256; - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + mo_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]; - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; + mo_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) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + mo_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; default: break; } - if (!dev->sector_len) { + if (dev->sector_len) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; + + dev->packet_len = max_len * alloc_length; + mo_buf_alloc(dev, dev->packet_len); + + const int ret = mo_blocks(dev, &alloc_length, 0); + + if (ret > 0) { + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + mo_data_command_finish(dev, alloc_length, dev->drv->sector_size, alloc_length, 0); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_MO | dev->id, 1); + else + ui_sb_update_icon(SB_MO | dev->id, 0); + } else { + mo_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; + dev->callback = 20.0 * MO_TIME; + mo_set_callback(dev); + mo_buf_free(dev); + } + } else { mo_set_phase(dev, SCSI_PHASE_STATUS); - /* mo_log("MO %i: All done - callback set\n", dev->id); */ + /* mo_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * MO_TIME; mo_set_callback(dev); - break; } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - mo_buf_alloc(dev, dev->packet_len); - - ret = mo_blocks(dev, &alloc_length, 1, 0); - if (ret <= 0) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * MO_TIME; - mo_set_callback(dev); - mo_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - mo_data_command_finish(dev, alloc_length, dev->drv->sector_size, alloc_length, 0); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_MO | dev->id, 1); - else - ui_sb_update_icon(SB_MO | dev->id, 0); - return; + break; case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: - /* Data and blank verification cannot be set at the same time */ - if ((cdb[1] & 2) && (cdb[1] & 4)) { - mo_invalid_field(dev); - return; - } - if (!(cdb[1] & 2) || (cdb[1] & 4)) { + if (!(cdb[1] & 2)) { mo_set_phase(dev, SCSI_PHASE_STATUS); mo_command_complete(dev); break; } - /*TODO: Implement*/ - mo_invalid_field(dev); - return; - + fallthrough; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: mo_set_phase(dev, SCSI_PHASE_DATA_OUT); - alloc_length = dev->drv->sector_size; - - if (dev->drv->read_only) { - mo_write_protected(dev); - return; - } + alloc_length = 512; switch (cdb[0]) { case GPCMD_VERIFY_6: case GPCMD_WRITE_6: dev->sector_len = cdb[4]; + /* + For READ (6) and WRITE (6), a length of 0 indicates a + transfer of 256 sectors. + */ if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + mo_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_10: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - mo_log("MO %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; + mo_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_12: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; default: break; } - if ((dev->sector_pos >= dev->drv->medium_size) /* || - ((dev->sector_pos + dev->sector_len - 1) >= dev->drv->medium_size)*/ - ) { + if (dev->sector_pos > (mo_types[dev->drv->type].sectors - 1)) mo_lba_out_of_range(dev); - return; + else { + if (dev->sector_len) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; + + dev->packet_len = max_len * alloc_length; + mo_buf_alloc(dev, dev->packet_len); + + dev->requested_blocks = max_len; + dev->packet_len = max_len << 9; + + mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + mo_data_command_finish(dev, dev->packet_len, 512, + dev->packet_len, 1); + + ui_sb_update_icon(SB_MO | dev->id, + dev->packet_status != PHASE_COMPLETE); + } else { + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_log(dev->log, "All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + mo_set_callback(dev); + } } + break; - if (!dev->sector_len) { - mo_set_phase(dev, SCSI_PHASE_STATUS); - /* mo_log("MO %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * MO_TIME; - mo_set_callback(dev); - break; + case GPCMD_WRITE_SAME_10: + alloc_length = 512; + + if ((cdb[1] & 6) == 6) + mo_invalid_field(dev, cdb[1]); + 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 > (mo_types[dev->drv->type].sectors - 1)) + mo_lba_out_of_range(dev); + else if (dev->sector_len) { + mo_buf_alloc(dev, alloc_length); + mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + dev->requested_blocks = 1; + dev->packet_len = alloc_length; + + mo_set_phase(dev, SCSI_PHASE_DATA_OUT); + + mo_data_command_finish(dev, 512, 512, + alloc_length, 1); + + ui_sb_update_icon(SB_MO | dev->id, + dev->packet_status != PHASE_COMPLETE); + } else { + mo_set_phase(dev, SCSI_PHASE_STATUS); + mo_log(dev->log, "All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + mo_set_callback(dev); + } } - - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're writing all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ - - dev->packet_len = max_len * alloc_length; - mo_buf_alloc(dev, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = max_len << 9; - - mo_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - mo_data_command_finish(dev, dev->packet_len, dev->drv->sector_size, dev->packet_len, 1); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_MO | dev->id, 1); - else - ui_sb_update_icon(SB_MO | dev->id, 0); - return; + break; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: @@ -1560,7 +1513,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) } if (!(mo_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - mo_invalid_field(dev); + mo_invalid_field(dev, cdb[2]); mo_buf_free(dev); return; } @@ -1569,14 +1522,16 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) alloc_length = len; if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = mo_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); + len = mo_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 = mo_mode_sense(dev, dev->buffer, 8, cdb[2], block_desc); + len = mo_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; @@ -1589,7 +1544,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_set_buf_len(dev, BufLen, &len); - mo_log("MO %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + mo_log(dev->log, "Reading mode page: %02X...\n", cdb[2]); mo_data_command_finish(dev, len, len, alloc_length, 0); return; @@ -1649,7 +1604,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) preamble_len = 4; size_idx = 3; - dev->buffer[idx++] = 7; /*Optical disk*/ + dev->buffer[idx++] = 7; /* Optical disk */ dev->buffer[idx++] = cdb[2]; dev->buffer[idx++] = 0; @@ -1660,14 +1615,15 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[idx++] = 0x00; dev->buffer[idx++] = 0x80; break; - case 0x80: /*Unit serial number page*/ + case 0x80: /*Unit serial number page*/ dev->buffer[idx++] = strlen("VCM!10") + 1; - ide_padstr8(dev->buffer + idx, 20, "VCM!10"); /* Serial */ + /* Serial */ + ide_padstr8(dev->buffer + idx, 20, "VCM!10"); idx += strlen("VCM!10"); break; default: - mo_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - mo_invalid_field(dev); + mo_log(dev->log, "INQUIRY: Invalid page: %02X\n", cdb[2]); + mo_invalid_field(dev, cdb[2]); mo_buf_free(dev); return; } @@ -1677,30 +1633,34 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) memset(dev->buffer, 0, 8); if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) - dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + dev->buffer[0] = 0x7f; /* No physical device on this LUN */ else - dev->buffer[0] = 0x07; /*Optical disk*/ - dev->buffer[1] = 0x80; /*Removable*/ - dev->buffer[2] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + dev->buffer[0] = 0x07; /* Optical disk */ + dev->buffer[1] = 0x80; /* Removable */ + /* SCSI-2 compliant */ + dev->buffer[2] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x00; dev->buffer[3] = (dev->drv->bus_type == MO_BUS_SCSI) ? 0x02 : 0x21; -#if 0 - dev->buffer[4] = 31; -#endif dev->buffer[4] = 0; if (dev->drv->bus_type == MO_BUS_SCSI) { - dev->buffer[6] = 1; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ + dev->buffer[6] = 1; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ } dev->buffer[7] |= 0x02; if (dev->drv->type > 0) { - ide_padstr8(dev->buffer + 8, 8, mo_drive_types[dev->drv->type].vendor); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, mo_drive_types[dev->drv->type].model); /* Product */ - ide_padstr8(dev->buffer + 32, 4, mo_drive_types[dev->drv->type].revision); /* Revision */ + ide_padstr8(dev->buffer + 8, 8, + mo_drive_types[dev->drv->type].vendor); /* Vendor */ + ide_padstr8(dev->buffer + 16, 16, + mo_drive_types[dev->drv->type].model); /* Product */ + ide_padstr8(dev->buffer + 32, 4, + mo_drive_types[dev->drv->type].revision); /* Revision */ } 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 */ + 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; @@ -1751,7 +1711,8 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_buf_alloc(dev, 8); - max_len = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ + /* IMPORTANT: What's returned is the last LBA block. */ + max_len = dev->drv->medium_size - 1; memset(dev->buffer, 0, 8); dev->buffer[0] = (max_len >> 24) & 0xff; dev->buffer[1] = (max_len >> 16) & 0xff; @@ -1768,7 +1729,7 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_ERASE_10: case GPCMD_ERASE_12: - /*Relative address*/ + /* Relative address. */ if (cdb[1] & 1) previous_pos = dev->sector_pos; @@ -1777,18 +1738,20 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) dev->sector_len = (cdb[7] << 8) | cdb[8]; break; case GPCMD_ERASE_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); break; default: break; } - /*Erase all remaining sectors*/ + /* Erase all remaining sectors. */ if (cdb[1] & 4) { - /* Cannot have a sector number when erase all*/ + /* Cannot have a sector number when erase all. */ if (dev->sector_len) { - mo_invalid_field(dev); + mo_invalid_field(dev, dev->sector_len); return; } mo_format(dev); @@ -1799,10 +1762,13 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) switch (cdb[0]) { case GPCMD_ERASE_10: - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; break; case GPCMD_ERASE_12: - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; default: @@ -1816,7 +1782,10 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) mo_command_complete(dev); break; - /*Never seen media that supports generations but it's interesting to know if any implementation calls this commmand*/ + /* + Never seen media that supports generations but it's interesting to know if any + implementation calls this commmand. + */ case GPCMD_READ_GENERATION: mo_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -1833,12 +1802,13 @@ mo_command(scsi_common_t *sc, uint8_t *cdb) break; default: - mo_illegal_opcode(dev); + mo_illegal_opcode(dev, cdb[0]); break; } #if 0 - mo_log("MO %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length); + mo_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)) @@ -1858,22 +1828,16 @@ mo_command_stop(scsi_common_t *sc) static uint8_t mo_phase_data_out(scsi_common_t *sc) { - mo_t *dev = (mo_t *) sc; - - uint16_t block_desc_len; - uint16_t pos; - uint16_t param_list_len; - - uint8_t error = 0; - uint8_t page; - uint8_t page_len; - - uint8_t hdr_len; - uint8_t val; - uint8_t old_val; - uint8_t ch; - - int len = 0; + mo_t * dev = (mo_t *) sc; + const uint32_t last_sector = mo_types[dev->drv->type].sectors - 1; + int len = 0; + uint8_t error = 0; + uint32_t last_to_write; + uint16_t block_desc_len; + uint16_t pos; + uint16_t param_list_len; + uint8_t hdr_len; + uint8_t val; switch (dev->current_cdb[0]) { case GPCMD_VERIFY_6: @@ -1886,7 +1850,40 @@ mo_phase_data_out(scsi_common_t *sc) case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: if (dev->requested_blocks > 0) - mo_blocks(dev, &len, 1, 1); + mo_blocks(dev, &len, 1); + break; + case GPCMD_WRITE_SAME_10: + if (!dev->current_cdb[7] && !dev->current_cdb[8]) + last_to_write = last_sector; + else + last_to_write = dev->sector_pos + dev->sector_len - 1; + + for (int i = dev->sector_pos; i <= (int) last_to_write; i++) { + if (dev->current_cdb[1] & 2) { + dev->buffer[0] = (i >> 24) & 0xff; + dev->buffer[1] = (i >> 16) & 0xff; + dev->buffer[2] = (i >> 8) & 0xff; + dev->buffer[3] = i & 0xff; + } else if (dev->current_cdb[1] & 4) { + uint32_t s = (i % 63); + uint32_t h = ((i - s) / 63) % 16; + uint32_t c = ((i - s) / 63) / 16; + dev->buffer[0] = (c >> 16) & 0xff; + dev->buffer[1] = (c >> 8) & 0xff; + dev->buffer[2] = c & 0xff; + dev->buffer[3] = h & 0xff; + dev->buffer[4] = (s >> 24) & 0xff; + dev->buffer[5] = (s >> 16) & 0xff; + dev->buffer[6] = (s >> 8) & 0xff; + dev->buffer[7] = s & 0xff; + } + if (fseek(dev->drv->fp, (i * dev->drv->sector_size), SEEK_SET) == -1) + mo_write_error(dev); + if (feof(dev->drv->fp)) + break; + if (fwrite(dev->buffer, 1, dev->drv->sector_size, dev->drv->fp) != dev->drv->sector_size) + mo_write_error(dev); + } break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -1917,27 +1914,27 @@ mo_phase_data_out(scsi_common_t *sc) while (1) { if (pos >= param_list_len) { - mo_log("MO %i: Buffer has only block descriptor\n", dev->id); + mo_log(dev->log, "Buffer has only block descriptor\n"); break; } - page = dev->buffer[pos] & 0x3F; - page_len = dev->buffer[pos + 1]; + const uint8_t page = dev->buffer[pos] & 0x3F; + const uint8_t page_len = dev->buffer[pos + 1]; pos += 2; if (!(mo_mode_sense_page_flags & (1LL << ((uint64_t) page)))) error |= 1; - else { - for (uint8_t i = 0; i < page_len; i++) { - ch = mo_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; + else for (uint8_t i = 0; i < page_len; i++) { + const uint8_t ch = mo_mode_sense_pages_changeable.pages[page][i + 2]; + const uint8_t old_val = dev->ms_pages_saved.pages[page][i + 2]; + val = dev->buffer[pos + i]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else { + error |= 1; + mo_invalid_field_pl(dev, val); } } } @@ -1957,7 +1954,6 @@ mo_phase_data_out(scsi_common_t *sc) if (error) { mo_buf_free(dev); - mo_invalid_field_pl(dev); return 0; } break; @@ -1979,7 +1975,7 @@ mo_global_init(void) } static int -mo_get_max(int ide_has_dma, int type) +mo_get_max(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -2003,7 +1999,7 @@ mo_get_max(int ide_has_dma, int type) } static int -mo_get_timings(int ide_has_dma, int type) +mo_get_timings(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -2026,7 +2022,7 @@ mo_get_timings(int ide_has_dma, int type) } static void -mo_do_identify(ide_t *ide, int ide_has_dma) +mo_do_identify(const ide_t *ide, const int ide_has_dma) { char model[40]; @@ -2035,56 +2031,65 @@ mo_do_identify(ide_t *ide, int ide_has_dma) memset(model, 0, 40); if (mo_drives[mo->id].type > 0) { - snprintf(model, 40, "%s %s", mo_drive_types[mo_drives[mo->id].type].vendor, mo_drive_types[mo_drives[mo->id].type].model); - ide_padstr((char *) (ide->buffer + 23), mo_drive_types[mo_drives[mo->id].type].revision, 8); /* Firmware */ + snprintf(model, 40, "%s %s", mo_drive_types[mo_drives[mo->id].type].vendor, + mo_drive_types[mo_drives[mo->id].type].model); + /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), + mo_drive_types[mo_drives[mo->id].type].revision, 8); ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ } else { snprintf(model, 40, "%s %s%02i", EMU_NAME, "86B_MO", mo->id); - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ + 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*/ - ide->buffer[81] = 0x19; /*Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a*/ + /* Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6 */ + ide->buffer[80] = 0x70; + /* Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a */ + ide->buffer[81] = 0x19; } } static void -mo_identify(ide_t *ide, int ide_has_dma) +mo_identify(const ide_t *ide, const int ide_has_dma) { - ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + /* ATAPI device, direct-access device, removable media, interrupt DRQ */ + ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide->buffer[49] = 0x200; /* LBA supported */ + /* Interpret zero byte count limit as maximum length */ + ide->buffer[126] = 0xfffe; mo_do_identify(ide, ide_has_dma); } static void -mo_drive_reset(int c) +mo_drive_reset(const int c) { - mo_t *dev; - scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f; + const uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f; - if (!mo_drives[c].priv) { - mo_drives[c].priv = (mo_t *) malloc(sizeof(mo_t)); - memset(mo_drives[c].priv, 0, sizeof(mo_t)); + if (mo_drives[c].priv == NULL) { + mo_drives[c].priv = (mo_t *) calloc(1, sizeof(mo_t)); + mo_t *dev = (mo_t *) mo_drives[c].priv; + + char n[1024] = { 0 }; + + sprintf(n, "MO %i", c + 1); + dev->log = log_open(n); } - dev = (mo_t *) mo_drives[c].priv; + mo_t *dev = (mo_t *) mo_drives[c].priv; dev->id = c; dev->cur_lun = SCSI_LUN_USE_CDB; if (mo_drives[c].bus_type == MO_BUS_SCSI) { - if (!dev->tf) + if (dev->tf == NULL) dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); /* SCSI MO, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + scsi_device_t *sd = &scsi_devices[scsi_bus][scsi_id]; sd->sc = (scsi_common_t *) dev; sd->command = mo_command; @@ -2095,7 +2100,7 @@ mo_drive_reset(int c) sd->type = SCSI_REMOVABLE_DISK; } else if (mo_drives[c].bus_type == MO_BUS_ATAPI) { /* ATAPI MO, attach to the IDE bus. */ - id = ide_get_drive(mo_drives[c].ide_channel); + ide_t *id = ide_get_drive(mo_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. */ @@ -2122,17 +2127,11 @@ mo_drive_reset(int c) void mo_hard_reset(void) { - mo_t *dev; - uint8_t scsi_id; - uint8_t scsi_bus; - for (uint8_t c = 0; c < MO_NUM; c++) { if ((mo_drives[c].bus_type == MO_BUS_ATAPI) || (mo_drives[c].bus_type == MO_BUS_SCSI)) { - mo_log("MO hard_reset drive=%d\n", c); - if (mo_drives[c].bus_type == MO_BUS_SCSI) { - scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = mo_drives[c].scsi_device_id & 0x0f; + const uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f; /* Make sure to ignore any SCSI MO drive that has an out of range SCSI Bus. */ if (scsi_bus >= SCSI_BUS_MAX) @@ -2149,7 +2148,9 @@ mo_hard_reset(void) mo_drive_reset(c); - dev = (mo_t *) mo_drives[c].priv; + mo_t *dev = (mo_t *) mo_drives[c].priv; + + mo_log(dev->log, "MO hard_reset drive=%d\n", c); if (dev->tf == NULL) continue; @@ -2160,14 +2161,16 @@ mo_hard_reset(void) mo_init(dev); if (strlen(mo_drives[c].image_path)) - mo_load(dev, mo_drives[c].image_path); + mo_load(dev, mo_drives[c].image_path, 0); mo_mode_sense_load(dev); if (mo_drives[c].bus_type == MO_BUS_SCSI) - mo_log("SCSI MO drive %i attached to SCSI ID %i\n", c, mo_drives[c].scsi_device_id); + mo_log(dev->log, "SCSI MO drive %i attached to SCSI ID %i\n", + c, mo_drives[c].scsi_device_id); else if (mo_drives[c].bus_type == MO_BUS_ATAPI) - mo_log("ATAPI MO drive %i attached to IDE channel %i\n", c, mo_drives[c].ide_channel); + mo_log(dev->log, "ATAPI MO drive %i attached to IDE channel %i\n", + c, mo_drives[c].ide_channel); } } } @@ -2175,19 +2178,15 @@ mo_hard_reset(void) void mo_close(void) { - mo_t *dev; - uint8_t scsi_id; - uint8_t scsi_bus; - for (uint8_t c = 0; c < MO_NUM; c++) { if (mo_drives[c].bus_type == MO_BUS_SCSI) { - scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = mo_drives[c].scsi_device_id & 0x0f; + const uint8_t scsi_bus = (mo_drives[c].scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = mo_drives[c].scsi_device_id & 0x0f; memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); } - dev = (mo_t *) mo_drives[c].priv; + mo_t *dev = (mo_t *) mo_drives[c].priv; if (dev) { mo_disk_unload(dev); @@ -2195,6 +2194,13 @@ mo_close(void) if (dev->tf) free(dev->tf); + if (dev->log != NULL) { + mo_log(dev->log, "Log closed\n"); + + log_close(dev->log); + dev->log = NULL; + } + free(dev); mo_drives[c].priv = NULL; } diff --git a/src/disk/zip.c b/src/disk/zip.c index 764dc1f53..72781281a 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,30 +9,27 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * - * * Authors: Miran Grca, * - * Copyright 2018-2019 Miran Grca. + * Copyright 2018-2025 Miran Grca. */ -#include -#include -#include -#include +#ifdef ENABLE_ZIP_LOG #include -#include -#define HAVE_STDARG_H +#endif +#include +#include +#include +#include #include <86box/86box.h> #include <86box/timer.h> -#include <86box/config.h> -#include <86box/timer.h> #include <86box/device.h> +#include <86box/log.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/nvr.h> +#include <86box/path.h> #include <86box/plat.h> #include <86box/ui.h> -#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/zip.h> @@ -40,402 +37,107 @@ zip_drive_t zip_drives[ZIP_NUM]; -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ +// 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] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, - IMPLEMENTED, /* 0x06 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - IMPLEMENTED, /* 0x0C */ - IMPLEMENTED | ATAPI_ONLY, /* 0x0D */ - 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, - IMPLEMENTED | ATAPI_ONLY, /* 0x23 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ - 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, 0, 0 + [0x00] = IMPLEMENTED | CHECK_READY, + [0x01] = IMPLEMENTED | ALLOW_UA | SCSI_ONLY, + [0x03] = IMPLEMENTED | ALLOW_UA, + [0x04] = IMPLEMENTED | CHECK_READY | ALLOW_UA | SCSI_ONLY, + [0x06] = IMPLEMENTED, + [0x08] = IMPLEMENTED | CHECK_READY, + [0x0a ... 0x0b] = IMPLEMENTED | CHECK_READY, + [0x0c] = IMPLEMENTED, + [0x0d] = IMPLEMENTED | ATAPI_ONLY, + [0x12] = IMPLEMENTED | ALLOW_UA, + [0x13] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x15] = IMPLEMENTED, + [0x16 ... 0x17] = IMPLEMENTED | SCSI_ONLY, + [0x1a] = IMPLEMENTED, + [0x1b] = IMPLEMENTED | CHECK_READY, + [0x1d] = IMPLEMENTED, + [0x1e] = IMPLEMENTED | CHECK_READY, + [0x23] = IMPLEMENTED | ATAPI_ONLY, + [0x25] = IMPLEMENTED | CHECK_READY, + [0x28] = IMPLEMENTED | CHECK_READY, + [0x2a ... 0x2b] = IMPLEMENTED | CHECK_READY, + [0x2e] = IMPLEMENTED | CHECK_READY, + [0x2f] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x41] = IMPLEMENTED | CHECK_READY, + [0x55] = IMPLEMENTED, + [0x5a] = IMPLEMENTED, + [0xa8] = IMPLEMENTED | CHECK_READY, + [0xaa] = IMPLEMENTED | CHECK_READY, + [0xae] = IMPLEMENTED | CHECK_READY, + [0xaf] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xbd] = IMPLEMENTED }; -static uint64_t zip_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_IOMEGA_PAGE | GPMODEP_ALL_PAGES); -static uint64_t zip_250_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_FLEXIBLE_DISK_PAGE | GPMODEP_CACHING_PAGE | GPMODEP_IOMEGA_PAGE | GPMODEP_ALL_PAGES); +static uint64_t zip_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | + GPMODEP_IOMEGA_PAGE | GPMODEP_ALL_PAGES); +static uint64_t zip_250_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_FLEXIBLE_DISK_PAGE | + GPMODEP_CACHING_PAGE | GPMODEP_IOMEGA_PAGE | + GPMODEP_ALL_PAGES); -static const mode_sense_pages_t zip_mode_sense_pages_default = - // clang-format off -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 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 }, - { 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 }, - { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; -// clang-format on +static const mode_sense_pages_t zip_mode_sense_pages_default = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x5a, 0x00, 0x50, 0x20 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2f] = { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f } } +}; -static const mode_sense_pages_t zip_250_mode_sense_pages_default = - // clang-format off -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - {GPMODE_FLEXIBLE_DISK_PAGE, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CACHING_PAGE, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; -// clang-format on +static const mode_sense_pages_t zip_250_mode_sense_pages_default = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0x00, 0x00, 0x00, 0x00 }, + [0x05] = { GPMODE_FLEXIBLE_DISK_PAGE, 0x1e, 0x80, 0x00, 0x40, 0x20, 0x02, 0x00, + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x7d, 0x00, 0x00 }, + [0x08] = { GPMODE_CACHING_PAGE, 0x0a, 0x04, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff }, + [0x2f] = { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } } +}; -static const mode_sense_pages_t zip_mode_sense_pages_default_scsi = - // clang-format off -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 22, 0, 0, 0, 0, 90, 0, 0x50, 0x20 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 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 }, - { 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 }, - { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f } -} }; -// clang-format on +static const mode_sense_pages_t zip_mode_sense_pages_default_scsi = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xc8, 0x16, 0x00, 0x00, 0x00, 0x00, + 0x5a, 0x00, 0x50, 0x20 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2f] = { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0xff, 0x0f } } +}; -static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi = - // clang-format off -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - {GPMODE_FLEXIBLE_DISK_PAGE, 0x1e, 0x80, 0, 0x40, 0x20, 2, 0, 0, 0xef, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0b, 0x7d, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CACHING_PAGE, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } -} }; -// clang-format on +static const mode_sense_pages_t zip_250_mode_sense_pages_default_scsi = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0xc8, 0x64, 0x00, 0x00, 0x00, 0x00 }, + [0x05] = { GPMODE_FLEXIBLE_DISK_PAGE, 0x1e, 0x80, 0x00, 0x40, 0x20, 0x02, 0x00, + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x7d, 0x00, 0x00 }, + [0x08] = { GPMODE_CACHING_PAGE, 0x0a, 0x04, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff }, + [0x2f] = { GPMODE_IOMEGA_PAGE, 0x04, 0x5c, 0x0f, 0x3c, 0x0f } } +}; -static const mode_sense_pages_t zip_mode_sense_pages_changeable = - // clang-format off -{ { - { 0, 0 }, +static const mode_sense_pages_t zip_mode_sense_pages_changeable = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, + 0x5a, 0xff, 0xff, 0xff }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2f] = { GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff } } +}; - { GPMODE_R_W_ERROR_PAGE, 0x0a, 0xFF, 0xFF, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 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 }, - { 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 }, - { GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff } -} }; -// clang-format on - -static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = - // clang-format off -{ { - { 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 0x06, 0xFF, 0xFF, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - {GPMODE_FLEXIBLE_DISK_PAGE, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CACHING_PAGE, 0x0a, 4, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff }, - { 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff } -} }; +static const mode_sense_pages_t zip_250_mode_sense_pages_changeable = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x05] = { GPMODE_FLEXIBLE_DISK_PAGE, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }, + [0x08] = { GPMODE_CACHING_PAGE, 0x0a, 0x04, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff }, + [0x2f] = { GPMODE_IOMEGA_PAGE, 0x04, 0xff, 0xff, 0xff, 0xff } } +}; // clang-format on static void zip_command_complete(zip_t *dev); @@ -445,32 +147,22 @@ static void zip_init(zip_t *dev); int zip_do_log = ENABLE_ZIP_LOG; static void -zip_log(const char *fmt, ...) +zip_log(void *priv, const char *fmt, ...) { va_list ap; if (zip_do_log) { va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define zip_log(fmt, ...) +# define zip_log(priv, fmt, ...) #endif -int -find_zip_for_channel(uint8_t channel) -{ - for (uint8_t i = 0; i < ZIP_NUM; i++) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && (zip_drives[i].ide_channel == channel)) - return i; - } - return 0xff; -} - static int -zip_load_abort(zip_t *dev) +zip_load_abort(const zip_t *dev) { if (dev->drv->fp) fclose(dev->drv->fp); @@ -481,104 +173,140 @@ zip_load_abort(zip_t *dev) } int -zip_load(zip_t *dev, char *fn) +image_is_zdi(const char *s) { - int size = 0; + return !strcasecmp(path_get_extension((char *) s), "ZDI"); +} - if (!dev->drv) { +int +zip_is_empty(const uint8_t id) +{ + const zip_t *dev = (const zip_t *) zip_drives[id].priv; + int ret = 0; + + if ((dev->drv == NULL) || (dev->drv->fp == NULL)) + ret = 1; + + return ret; +} + +void +zip_load(const zip_t *dev, const char *fn, const int skip_insert) +{ + const int was_empty = zip_is_empty(dev->id); + int ret = 0; + + if (dev->drv == NULL) zip_eject(dev->id); - return 0; - } + else { + const int is_zdi = image_is_zdi(fn); - dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); - if (!dev->drv->fp) { - if (!dev->drv->read_only) { - dev->drv->fp = plat_fopen(fn, "rb"); - if (dev->drv->fp) - dev->drv->read_only = 1; - else - return zip_load_abort(dev); - } else - return zip_load_abort(dev); - } + dev->drv->fp = plat_fopen(fn, dev->drv->read_only ? "rb" : "rb+"); + ret = 1; - fseek(dev->drv->fp, 0, SEEK_END); - size = ftell(dev->drv->fp); - - if ((size == ((ZIP_250_SECTORS << 9) + 0x1000)) || (size == ((ZIP_SECTORS << 9) + 0x1000))) { - /* This is a ZDI image. */ - size -= 0x1000; - dev->drv->base = 0x1000; - } else - dev->drv->base = 0; - - if (dev->drv->is_250) { - if ((size != (ZIP_250_SECTORS << 9)) && (size != (ZIP_SECTORS << 9))) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i or %i bytes\n", - ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); - return zip_load_abort(dev); + if (dev->drv->fp == NULL) { + if (!dev->drv->read_only) { + dev->drv->fp = plat_fopen(fn, "rb"); + if (dev->drv->fp == NULL) + ret = zip_load_abort(dev); + else + dev->drv->read_only = 1; + } else + ret = zip_load_abort(dev); } - } else { - if (size != (ZIP_SECTORS << 9)) { - zip_log("File is incorrect size for a ZIP image\nMust be exactly %i bytes\n", - ZIP_SECTORS << 9); - return zip_load_abort(dev); + + if (ret) { + fseek(dev->drv->fp, 0, SEEK_END); + int size = ftell(dev->drv->fp); + + if (is_zdi) { + /* This is a ZDI image. */ + size -= 0x1000; + dev->drv->base = 0x1000; + } else + dev->drv->base = 0; + + if (dev->drv->is_250) { + 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", + ZIP_250_SECTORS << 9, ZIP_SECTORS << 9); + ret = zip_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); + } + + if (ret) + dev->drv->medium_size = size >> 9; + } + + 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 " + "the file\n"); + + strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + /* + After using strncpy, dev->drv->image_path needs to be explicitly null + terminated to make gcc happy. + In the event strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) + (no null terminator) it is placed at the very end. Otherwise, it is placed + right after the string. + */ + const size_t term = strlen(dev->drv->image_path) == + sizeof(dev->drv->image_path) ? sizeof(dev->drv->image_path) - 1 : + strlen(dev->drv->image_path); + dev->drv->image_path[term] = '\0'; } } - dev->drv->medium_size = size >> 9; + if (ret && !skip_insert) { + /* Signal media change to the emulated machine. */ + zip_insert((zip_t *) dev); - if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) - fatal("zip_load(): Error seeking to the beginning of the file\n"); - - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); - // After using strncpy, dev->drv->image_path needs to be explicitly null terminated to make gcc happy. - // In the event strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) (no null terminator) - // it is placed at the very end. Otherwise, it is placed right after the string. - const size_t term = strlen(dev->drv->image_path) == sizeof(dev->drv->image_path) ? sizeof(dev->drv->image_path) - 1 : strlen(dev->drv->image_path); - dev->drv->image_path[term] = '\0'; - - return 1; + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + zip_insert((zip_t *) dev); + } } void -zip_disk_reload(zip_t *dev) +zip_disk_reload(const zip_t *dev) { - int ret = 0; - - if (strlen(dev->drv->prev_image_path) == 0) - return; - else - ret = zip_load(dev, dev->drv->prev_image_path); - - if (ret) - dev->unit_attention = 1; + if (strlen(dev->drv->prev_image_path) != 0) + (void) zip_load(dev, dev->drv->prev_image_path, 0); } -void -zip_disk_unload(zip_t *dev) +static void +zip_disk_unload(const zip_t *dev) { - if (dev->drv && dev->drv->fp) { + if ((dev->drv != NULL) && (dev->drv->fp != NULL)) { fclose(dev->drv->fp); dev->drv->fp = NULL; } } void -zip_disk_close(zip_t *dev) +zip_disk_close(const zip_t *dev) { - if (dev->drv && dev->drv->fp) { + if ((dev->drv != NULL) && (dev->drv->fp != NULL)) { zip_disk_unload(dev); - memcpy(dev->drv->prev_image_path, dev->drv->image_path, sizeof(dev->drv->prev_image_path)); + memcpy(dev->drv->prev_image_path, dev->drv->image_path, + sizeof(dev->drv->prev_image_path)); memset(dev->drv->image_path, 0, sizeof(dev->drv->image_path)); dev->drv->medium_size = 0; + + zip_insert((zip_t *) dev); } } static void -zip_set_callback(zip_t *dev) +zip_set_callback(const zip_t *dev) { if (dev->drv->bus_type != ZIP_BUS_SCSI) ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); @@ -587,54 +315,54 @@ zip_set_callback(zip_t *dev) static void zip_init(zip_t *dev) { - if (dev->id >= ZIP_NUM) - return; - - 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) - dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < ZIP_BUS_SCSI) - dev->drv->bus_mode |= 1; - zip_log("ZIP %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - if (dev->drv->bus_type < ZIP_BUS_SCSI) { - dev->tf->phase = 1; - dev->tf->request_length = 0xEB14; + if (dev->id < ZIP_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) + dev->drv->bus_mode |= 2; + if (dev->drv->bus_type < ZIP_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) { + 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; } - dev->tf->status = READY_STAT | DSC_STAT; - dev->tf->pos = 0; - dev->packet_status = PHASE_NONE; - zip_sense_key = zip_asc = zip_ascq = dev->unit_attention = 0; } static int -zip_supports_pio(zip_t *dev) +zip_supports_pio(const zip_t *dev) { return (dev->drv->bus_mode & 1); } static int -zip_supports_dma(zip_t *dev) +zip_supports_dma(const zip_t *dev) { return (dev->drv->bus_mode & 2); } /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -zip_current_mode(zip_t *dev) +zip_current_mode(const zip_t *dev) { if (!zip_supports_pio(dev) && !zip_supports_dma(dev)) return 0; if (zip_supports_pio(dev) && !zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive does not support DMA, setting to PIO\n", dev->id); + zip_log(dev->log, "Drive does not support DMA, setting to PIO\n"); return 1; } if (!zip_supports_pio(dev) && zip_supports_dma(dev)) return 2; if (zip_supports_pio(dev) && zip_supports_dma(dev)) { - zip_log("ZIP %i: Drive supports both, setting to %s\n", dev->id, + zip_log(dev->log, "Drive supports both, setting to %s\n", (dev->tf->features & 1) ? "DMA" : "PIO"); return (dev->tf->features & 1) ? 2 : 1; } @@ -645,8 +373,7 @@ zip_current_mode(zip_t *dev) static void zip_mode_sense_load(zip_t *dev) { - FILE *fp; - char fn[512]; + char fn[512] = { 0 }; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); if (dev->drv->is_250) { @@ -661,12 +388,11 @@ zip_mode_sense_load(zip_t *dev) memcpy(&dev->ms_pages_saved, &zip_mode_sense_pages_default, sizeof(mode_sense_pages_t)); } - memset(fn, 0, 512); if (dev->drv->bus_type == ZIP_BUS_SCSI) sprintf(fn, "scsi_zip_%02i_mode_sense_bin", dev->id); else sprintf(fn, "zip_%02i_mode_sense_bin", dev->id); - fp = plat_fopen(nvr_path(fn), "rb"); + FILE *fp = plat_fopen(nvr_path(fn), "rb"); if (fp) { /* Nothing to read, not used by ZIP. */ fclose(fp); @@ -674,31 +400,31 @@ zip_mode_sense_load(zip_t *dev) } static void -zip_mode_sense_save(zip_t *dev) +zip_mode_sense_save(const zip_t *dev) { - FILE *fp; - char fn[512]; + char fn[512] = { 0 }; - memset(fn, 0, 512); if (dev->drv->bus_type == ZIP_BUS_SCSI) sprintf(fn, "scsi_zip_%02i_mode_sense_bin", dev->id); else sprintf(fn, "zip_%02i_mode_sense_bin", dev->id); - fp = plat_fopen(nvr_path(fn), "wb"); + FILE *fp = plat_fopen(nvr_path(fn), "wb"); if (fp) { /* Nothing to write, not used by ZIP. */ fclose(fp); } } -/*SCSI Mode Sense 6/10*/ +/* SCSI Mode Sense 6/10. */ static uint8_t -zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) +zip_mode_sense_read(const zip_t *dev, const uint8_t pgctl, + const uint8_t page, const uint8_t pos) { - switch (page_control) { + switch (pgctl) { case 0: case 3: - if (dev->drv->is_250 && (page == 5) && (pos == 9) && (dev->drv->medium_size == ZIP_SECTORS)) + if (dev->drv->is_250 && (page == 5) && (pos == 9) && + (dev->drv->medium_size == ZIP_SECTORS)) return 0x60; return dev->ms_pages_saved.pages[page][pos]; case 1: @@ -729,18 +455,17 @@ zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) } static uint32_t -zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) +zip_mode_sense(const zip_t *dev, uint8_t *buf, uint32_t pos, + uint8_t page, const uint8_t block_descriptor_len) { - uint64_t pf; - uint8_t page_control = (page >> 6) & 3; + uint64_t pf; + const uint8_t pgctl = (page >> 6) & 3; if (dev->drv->is_250) pf = zip_250_mode_sense_page_flags; else pf = zip_mode_sense_page_flags; - uint8_t msplen; - page &= 0x3f; if (block_descriptor_len) { @@ -757,12 +482,12 @@ zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t blo for (uint8_t i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { if (pf & (1LL << ((uint64_t) page))) { - buf[pos++] = zip_mode_sense_read(dev, page_control, i, 0); - msplen = zip_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - zip_log("ZIP %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + 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); for (uint8_t j = 0; j < msplen; j++) - buf[pos++] = zip_mode_sense_read(dev, page_control, i, 2 + j); + buf[pos++] = zip_mode_sense_read(dev, pgctl, i, 2 + j); } } } @@ -778,7 +503,10 @@ zip_update_request_length(zip_t *dev, int len, int block_len) dev->max_transfer_len = dev->tf->request_length; - /* For media access commands, make sure the requested DRQ length matches the block length. */ + /* + For media access commands, make sure the requested DRQ length matches the + block length. + */ switch (dev->current_cdb[0]) { case 0x08: case 0x0a: @@ -789,8 +517,10 @@ zip_update_request_length(zip_t *dev, int len, int block_len) /* Round it to the nearest 2048 bytes. */ dev->max_transfer_len = (dev->max_transfer_len >> 9) << 9; - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ + /* + Make sure total length is not bigger than sum of the lengths of + all the requested blocks. + */ bt = (dev->requested_blocks * block_len); if (len > bt) len = bt; @@ -812,10 +542,16 @@ zip_update_request_length(zip_t *dev, int len, int block_len) dev->packet_len = len; break; } - /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ + /* + If the DRQ length is odd, and the total remaining length is bigger, + make sure it's even. + */ if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) dev->max_transfer_len &= 0xfffe; - /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ + /* + If the DRQ length is smaller or equal in size to the total remaining length, + set it to that. + */ if (!dev->max_transfer_len) dev->max_transfer_len = 65534; @@ -850,23 +586,22 @@ zip_bus_speed(zip_t *dev) static void zip_command_common(zip_t *dev) { - double bytes_per_second; - double period; - dev->tf->status = BUSY_STAT; dev->tf->phase = 1; dev->tf->pos = 0; if (dev->packet_status == PHASE_COMPLETE) dev->callback = 0.0; else { + double bytes_per_second; + if (dev->drv->bus_type == ZIP_BUS_SCSI) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return; } else bytes_per_second = zip_bus_speed(dev); - period = 1000000.0 / bytes_per_second; - dev->callback = period * (double) (dev->packet_len); + double period = 1000000.0 / bytes_per_second; + dev->callback = period * (double) (dev->packet_len); } zip_set_callback(dev); @@ -907,16 +642,20 @@ zip_command_write_dma(zip_t *dev) zip_command_common(dev); } -/* id = Current ZIP device ID; +/* + dev = Pointer to current ZIP 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). */ + direction = Transfer direction (0 = read from host, 1 = write to host). + */ static void -zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int direction) +zip_data_command_finish(zip_t *dev, int len, const int block_len, + const int alloc_len, const int direction) { - zip_log("ZIP %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->tf->request_length); + zip_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; if (alloc_len >= 0) { if (alloc_len < len) @@ -945,27 +684,26 @@ zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int d } } - zip_log("ZIP %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, - dev->tf->phase); + zip_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)) { zip_sense_key = zip_asc = zip_ascq = 0; + zip_info = 0x00000000; } static void -zip_set_phase(zip_t *dev, uint8_t phase) +zip_set_phase(const zip_t *dev, const uint8_t phase) { - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + 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) - return; - - scsi_devices[scsi_bus][scsi_id].phase = phase; + if (dev->drv->bus_type == ZIP_BUS_SCSI) + scsi_devices[scsi_bus][scsi_id].phase = phase; } static void @@ -973,8 +711,6 @@ zip_cmd_error(zip_t *dev) { zip_set_phase(dev, SCSI_PHASE_STATUS); dev->tf->error = ((zip_sense_key & 0xf) << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->tf->error |= MCR_ERR; dev->tf->status = READY_STAT | ERR_STAT; dev->tf->phase = 3; dev->tf->pos = 0; @@ -982,7 +718,8 @@ zip_cmd_error(zip_t *dev) dev->callback = 50.0 * ZIP_TIME; zip_set_callback(dev); ui_sb_update_icon(SB_ZIP | dev->id, 0); - zip_log("ZIP %i: [%02X] ERROR: %02X/%02X/%02X\n", dev->id, dev->current_cdb[0], zip_sense_key, zip_asc, zip_ascq); + zip_log(dev->log, "[%02X] ERROR: %02X/%02X/%02X\n", dev->current_cdb[0], zip_sense_key, + zip_asc, zip_ascq); } static void @@ -990,8 +727,6 @@ zip_unit_attention(zip_t *dev) { zip_set_phase(dev, SCSI_PHASE_STATUS); dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->tf->error |= MCR_ERR; dev->tf->status = READY_STAT | ERR_STAT; dev->tf->phase = 3; dev->tf->pos = 0; @@ -999,22 +734,22 @@ zip_unit_attention(zip_t *dev) dev->callback = 50.0 * ZIP_TIME; zip_set_callback(dev); ui_sb_update_icon(SB_ZIP | dev->id, 0); - zip_log("ZIP %i: UNIT ATTENTION\n", dev->id); + zip_log(dev->log, "UNIT ATTENTION\n", dev->id); } static void -zip_buf_alloc(zip_t *dev, uint32_t len) +zip_buf_alloc(zip_t *dev, const uint32_t len) { - zip_log("ZIP %i: Allocated buffer length: %i\n", dev->id, len); - if (!dev->buffer) + zip_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) { - if (dev->buffer) { - zip_log("ZIP %i: Freeing buffer...\n", dev->id); + if (dev->buffer != NULL) { + zip_log(dev->log, "ZIP %i: Freeing buffer...\n"); free(dev->buffer); dev->buffer = NULL; } @@ -1027,6 +762,10 @@ zip_bus_master_error(scsi_common_t *sc) zip_buf_free(dev); zip_sense_key = zip_asc = zip_ascq = 0; + zip_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); zip_cmd_error(dev); } @@ -1036,6 +775,7 @@ zip_not_ready(zip_t *dev) zip_sense_key = SENSE_NOT_READY; zip_asc = ASC_MEDIUM_NOT_PRESENT; zip_ascq = 0; + zip_info = 0x00000000; zip_cmd_error(dev); } @@ -1045,24 +785,56 @@ zip_write_protected(zip_t *dev) zip_sense_key = SENSE_UNIT_ATTENTION; zip_asc = ASC_WRITE_PROTECTED; zip_ascq = 0; + zip_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); zip_cmd_error(dev); } static void -zip_invalid_lun(zip_t *dev) +zip_write_error(zip_t *dev) +{ + zip_sense_key = SENSE_MEDIUM_ERROR; + zip_asc = ASC_WRITE_ERROR; + zip_ascq = 0; + zip_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + zip_cmd_error(dev); +} + +static void +zip_read_error(zip_t *dev) +{ + zip_sense_key = SENSE_MEDIUM_ERROR; + zip_asc = ASC_UNRECOVERED_READ_ERROR; + zip_ascq = 0; + zip_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + zip_cmd_error(dev); +} + +static void +zip_invalid_lun(zip_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); } static void -zip_illegal_opcode(zip_t *dev) +zip_illegal_opcode(zip_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); } @@ -1072,178 +844,244 @@ zip_lba_out_of_range(zip_t *dev) zip_sense_key = SENSE_ILLEGAL_REQUEST; zip_asc = ASC_LBA_OUT_OF_RANGE; zip_ascq = 0; + zip_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); zip_cmd_error(dev); } static void -zip_invalid_field(zip_t *dev) +zip_invalid_field(zip_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) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); zip_cmd_error(dev); dev->tf->status = 0x53; } static void -zip_invalid_field_pl(zip_t *dev) +zip_invalid_field_pl(zip_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) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); zip_cmd_error(dev); dev->tf->status = 0x53; } static void -zip_data_phase_error(zip_t *dev) +zip_data_phase_error(zip_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) | + ((info >> 16) << 8) | + ((info >> 8) << 16) | + ( info << 24); zip_cmd_error(dev); } static int -zip_blocks(zip_t *dev, int32_t *len, UNUSED(int first_batch), int out) +zip_blocks(zip_t *dev, int32_t *len, const int out) { - *len = 0; + int ret = 1; + *len = 0; - if (!dev->sector_len) { + if (!dev->sector_len) zip_command_complete(dev); - return -1; - } + else { + zip_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", + dev->requested_blocks, dev->sector_pos); - zip_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("ZIP %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); - zip_lba_out_of_range(dev); - return 0; - } - - *len = dev->requested_blocks << 9; - - for (int i = 0; i < dev->requested_blocks; i++) { - if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + (i << 9), SEEK_SET) == 1) - break; - - if (feof(dev->drv->fp)) - break; - - if (out) { - if (fwrite(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) - fatal("zip_blocks(): Error writing data\n"); + if (dev->sector_pos >= dev->drv->medium_size) { + zip_log(dev->log, "Trying to %s beyond the end of disk\n", + out ? "write" : "read"); + zip_lba_out_of_range(dev); } else { - if (fread(dev->buffer + (i << 9), 1, 512, dev->drv->fp) != 512) - fatal("zip_blocks(): Error reading data\n"); + *len = dev->requested_blocks << 9; + + for (int i = 0; i < dev->requested_blocks; i++) { + if (fseek(dev->drv->fp, dev->drv->base + (dev->sector_pos << 9) + + (i << 9), SEEK_SET) == -1) { + if (out) + zip_write_error(dev); + else + zip_read_error(dev); + ret = -1; + } else { + if (feof(dev->drv->fp)) + break; + + 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); + 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); + ret = -1; + } + } + + if (ret == -1) + break; + + dev->sector_pos++; + } + + if (ret == 1) { + zip_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" : + "Read", *len); + + dev->sector_len -= dev->requested_blocks; + } } } - zip_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); - - dev->sector_pos += dev->requested_blocks; - dev->sector_len -= dev->requested_blocks; - - return 1; + return ret; } void zip_insert(zip_t *dev) { - dev->unit_attention = 1; -} - -/*SCSI Sense Initialization*/ -void -zip_sense_code_ok(zip_t *dev) -{ - zip_sense_key = SENSE_NONE; - zip_asc = 0; - zip_ascq = 0; + 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"); + } else if (dev->transition) { + dev->unit_attention = 1; + /* Turn off the medium changed status. */ + dev->transition = 0; + zip_log(dev->log, "Media insert\n"); + } else { + dev->unit_attention = 0; + dev->transition = 1; + zip_log(dev->log, "Media transition\n"); + } + } } static int -zip_pre_execution_check(zip_t *dev, uint8_t *cdb) +zip_pre_execution_check(zip_t *dev, const uint8_t *cdb) { - int ready = 0; + int ready; - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - zip_log("ZIP %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, + 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", ((dev->tf->request_length >> 5) & 7)); - zip_invalid_lun(dev); + zip_invalid_lun(dev, cdb[1] >> 5); return 0; } if (!(zip_command_flags[cdb[0]] & IMPLEMENTED)) { - zip_log("ZIP %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == ZIP_BUS_SCSI) ? "SCSI" : "ATAPI"); + zip_log(dev->log, "Attempting to execute unknown command %02X over %s\n", + cdb[0], (dev->drv->bus_type == ZIP_BUS_SCSI) ? + "SCSI" : "ATAPI"); - zip_illegal_opcode(dev); + zip_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type < ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & SCSI_ONLY)) { - zip_log("ZIP %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - zip_illegal_opcode(dev); + 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 " + "over ATAPI\n", cdb[0]); + zip_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type == ZIP_BUS_SCSI) && (zip_command_flags[cdb[0]] & ATAPI_ONLY)) { - zip_log("ZIP %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - zip_illegal_opcode(dev); + 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 " + "over SCSI\n", cdb[0]); + zip_illegal_opcode(dev, cdb[0]); return 0; } - ready = (dev->drv->fp != NULL); + if (dev->transition) { + 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 the drive is not ready, there is no reason to keep the + ready = (dev->drv->fp != NULL); + } + } else + ready = (dev->drv->fp != NULL); + + /* + If the drive is not ready, there is no reason to keep the UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - if (!ready && dev->unit_attention) + disc changes. + */ + if (!ready && (dev->unit_attention > 0)) dev->unit_attention = 0; - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ + /* + If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. + */ if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ + /* + Only increment the unit attention phase if the command can + not pass through it. + */ if (!(zip_command_flags[cdb[0]] & ALLOW_UA)) { - /* zip_log("ZIP %i: Unit attention now 2\n", dev->id); */ - dev->unit_attention = 2; - zip_log("ZIP %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); + zip_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", + cdb[0]); zip_unit_attention(dev); return 0; } } else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* zip_log("ZIP %i: Unit attention now 0\n", dev->id); */ + zip_log(dev->log, "Unit attention now 0\n"); dev->unit_attention = 0; } } - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ + /* + Unless the command is REQUEST SENSE, clear the sense. This will *NOT* clear + the UNIT ATTENTION condition if it's set. + */ if (cdb[0] != GPCMD_REQUEST_SENSE) zip_sense_clear(dev, cdb[0]); - /* Next it's time for NOT READY. */ - if ((zip_command_flags[cdb[0]] & CHECK_READY) && !ready) { - zip_log("ZIP %i: Not ready (%02X)\n", dev->id, 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); return 0; } - zip_log("ZIP %i: Continuing with command %02X\n", dev->id, cdb[0]); - + zip_log(dev->log, "Continuing with command %02X\n", cdb[0]); return 1; } static void -zip_seek(zip_t *dev, uint32_t pos) +zip_seek(zip_t *dev, const uint32_t pos) { -#if 0 - zip_log("ZIP %i: Seek %08X\n", dev->id, pos); -#endif dev->sector_pos = pos; } @@ -1268,10 +1106,12 @@ zip_reset(scsi_common_t *sc) 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; } static void -zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) +zip_request_sense(zip_t *dev, uint8_t *buffer, const uint8_t alloc_length, const int desc) { /*Will return 18 bytes of 0*/ if (alloc_length != 0) { @@ -1285,7 +1125,9 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) } } - buffer[0] = desc ? 0x72 : 0x70; + buffer[0] = desc ? 0x72 : 0xf0; + if (!desc) + buffer[7] = 10; if (dev->unit_attention && (zip_sense_key == 0)) { buffer[desc ? 1 : 2] = SENSE_UNIT_ATTENTION; @@ -1293,7 +1135,8 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) buffer[desc ? 3 : 13] = 0; } - zip_log("ZIP %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); + zip_log(dev->log, "Reporting sense: %02X %02X %02X\n", buffer[2], + buffer[12], buffer[13]); if (buffer[desc ? 1 : 2] == SENSE_UNIT_ATTENTION) { /* If the last remaining sense is unit attention, clear @@ -1303,30 +1146,33 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) /* Clear the sense stuff as per the spec. */ zip_sense_clear(dev, GPCMD_REQUEST_SENSE); + + if (dev->transition) { + zip_log(dev->log, "ZIP_TRANSITION: zip_insert()\n"); + zip_insert((void *) dev); + } } static void -zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) +zip_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, const uint8_t alloc_length) { - zip_t *dev = (zip_t *) sc; - int ready = 0; - - ready = (dev->drv->fp != NULL); + zip_t *dev = (zip_t *) sc; + const int ready = (dev->drv->fp != NULL); if (!ready && 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. */ + /* + 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. + */ dev->unit_attention = 0; } /* Do *NOT* advance the unit attention phase. */ - zip_request_sense(dev, buffer, alloc_length, 0); } static void -zip_set_buf_len(zip_t *dev, int32_t *BufLen, int32_t *src_len) +zip_set_buf_len(const zip_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == ZIP_BUS_SCSI) { if (*BufLen == -1) @@ -1335,28 +1181,27 @@ zip_set_buf_len(zip_t *dev, int32_t *BufLen, int32_t *src_len) *BufLen = MIN(*src_len, *BufLen); *src_len = *BufLen; } - zip_log("ZIP %i: Actual transfer length: %i\n", dev->id, *BufLen); + zip_log(dev->log, "Actual transfer length: %i\n", *BufLen); } } static void -zip_command(scsi_common_t *sc, uint8_t *cdb) +zip_command(scsi_common_t *sc, const uint8_t *cdb) { - zip_t *dev = (zip_t *) sc; - int pos = 0; - int block_desc = 0; - int ret; - int32_t len; - int32_t max_len; - int32_t alloc_length; - uint32_t i = 0; - int size_idx; - int idx = 0; - unsigned preamble_len; - int32_t blen = 0; - int32_t *BufLen; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + 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; + uint32_t i; + unsigned preamble_len; + int32_t len; + int32_t max_len; + int32_t alloc_length; + int block_desc; + int size_idx; + int32_t * BufLen; if (dev->drv->bus_type == ZIP_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -1372,11 +1217,13 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - zip_log("ZIP %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], zip_sense_key, zip_asc, zip_ascq, dev->unit_attention); - zip_log("ZIP %i: Request length: %04X\n", dev->id, dev->tf->request_length); + zip_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); - zip_log("ZIP %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + zip_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]); } @@ -1385,14 +1232,17 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_set_phase(dev, SCSI_PHASE_STATUS); - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ + /* + 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) return; switch (cdb[0]) { case GPCMD_SEND_DIAGNOSTIC: if (!(cdb[1] & (1 << 2))) { - zip_invalid_field(dev); + zip_invalid_field(dev, cdb[1]); return; } fallthrough; @@ -1404,13 +1254,12 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; case GPCMD_FORMAT_UNIT: - if (dev->drv->read_only) { + if (dev->drv->read_only) zip_write_protected(dev); - return; + else { + zip_set_phase(dev, SCSI_PHASE_STATUS); + zip_command_complete(dev); } - - zip_set_phase(dev, SCSI_PHASE_STATUS); - zip_command_complete(dev); break; case GPCMD_IOMEGA_SENSE: @@ -1420,8 +1269,10 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_set_buf_len(dev, BufLen, &max_len); memset(dev->buffer, 0, 256); if (cdb[2] == 1) { - /* This page is related to disk health status - setting - this page to 0 makes disk health read as "marginal". */ + /* + This page is related to disk health status - setting + this page to 0 makes disk health read as "marginal". + */ dev->buffer[0] = 0x58; dev->buffer[1] = 0x00; for (i = 0x00; i < 0x58; i++) @@ -1437,7 +1288,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) for (i = 0x00; i < 0x27; i++) dev->buffer[i + 0x16] = 0x00; } else { - zip_invalid_field(dev); + zip_invalid_field(dev, cdb[2]); zip_buf_free(dev); return; } @@ -1451,9 +1302,11 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not - ready, a standalone REQUEST SENSE should forget about the not - ready, and report unit attention straight away. */ + /* + If there's a unit attention condition and there's a buffered not ready, a + standalone REQUEST SENSE should forget about the not ready, and report unit + attention straight away. + */ zip_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; @@ -1502,17 +1355,20 @@ zip_command(scsi_common_t *sc, 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("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + zip_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("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + 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); break; case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; @@ -1520,51 +1376,47 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; } - if (dev->sector_pos >= dev->drv->medium_size) { + if (dev->sector_pos >= dev->drv->medium_size) zip_lba_out_of_range(dev); - return; - } + else if (dev->sector_len) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; - if (!dev->sector_len) { + dev->packet_len = max_len * alloc_length; + zip_buf_alloc(dev, dev->packet_len); + + int ret = 0; + + if (dev->sector_len > 0) + ret = zip_blocks(dev, &alloc_length, 0); + + if (ret > 0) { + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + zip_data_command_finish(dev, alloc_length, 512, + alloc_length, 0); + + ui_sb_update_icon(SB_ZIP | dev->id, + dev->packet_status != PHASE_COMPLETE); + } else { + zip_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); + } + } else { zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ + /* zip_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * ZIP_TIME; zip_set_callback(dev); break; } - - max_len = dev->sector_len; - /* - If we're reading all blocks in one go for DMA, why not also for - PIO, it should NOT matter anyway, this step should be identical - and only the way the read dat is transferred to the host should - be different. - */ - dev->requested_blocks = max_len; - - dev->packet_len = max_len * alloc_length; - zip_buf_alloc(dev, dev->packet_len); - - ret = zip_blocks(dev, &alloc_length, 1, 0); - if (ret <= 0) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - zip_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - zip_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0); - - ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE); - return; + break; case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: @@ -1585,7 +1437,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) if (dev->drv->read_only) { zip_write_protected(dev); - return; + break; } switch (cdb[0]) { @@ -1605,15 +1457,19 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - zip_log("ZIP %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, dev->sector_pos); + 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); break; case GPCMD_VERIFY_12: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; @@ -1621,86 +1477,75 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; } - if (dev->sector_pos >= dev->drv->medium_size) { + if (dev->sector_pos >= dev->drv->medium_size) zip_lba_out_of_range(dev); - return; - } + if (dev->sector_len) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; - if (!dev->sector_len) { + dev->packet_len = max_len * alloc_length; + zip_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); + + zip_data_command_finish(dev, dev->packet_len, 512, + dev->packet_len, 1); + + ui_sb_update_icon(SB_ZIP | dev->id, + dev->packet_status != PHASE_COMPLETE); + } else { zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ + /* zip_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * ZIP_TIME; zip_set_callback(dev); - break; } - - max_len = dev->sector_len; - /* - If we're writing all blocks in one go for DMA, why not also for - PIO, it should NOT matter anyway, this step should be identical - and only the way the read dat is transferred to the host should - be different. - */ - dev->requested_blocks = max_len; - - dev->packet_len = max_len * alloc_length; - zip_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); - - zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - - ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE); - return; + break; case GPCMD_WRITE_SAME_10: alloc_length = 512; - if ((cdb[1] & 6) == 6) { - zip_invalid_field(dev); - return; + if ((cdb[1] & 6) == 6) + zip_invalid_field(dev, cdb[1]); + else { + if (dev->drv->read_only) + zip_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); + else if (dev->sector_len) { + zip_buf_alloc(dev, alloc_length); + zip_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); + + zip_data_command_finish(dev, 512, 512, + alloc_length, 1); + + ui_sb_update_icon(SB_ZIP | dev->id, + dev->packet_status != PHASE_COMPLETE); + } else { + zip_set_phase(dev, SCSI_PHASE_STATUS); + /* zip_log(dev->log, "All done - callback set\n"); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * ZIP_TIME; + zip_set_callback(dev); + } + } } - - if (dev->drv->read_only) { - zip_write_protected(dev); - return; - } - - 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); - return; - } - - if (!dev->sector_len) { - zip_set_phase(dev, SCSI_PHASE_STATUS); - /* zip_log("ZIP %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * ZIP_TIME; - zip_set_callback(dev); - break; - } - - zip_buf_alloc(dev, alloc_length); - zip_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); - - zip_data_command_finish(dev, 512, 512, alloc_length, 1); - - ui_sb_update_icon(SB_ZIP | dev->id, dev->packet_status != PHASE_COMPLETE); - return; + break; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: @@ -1719,40 +1564,41 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) zip_buf_alloc(dev, 65536); } - if (!(zip_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - zip_invalid_field(dev); - zip_buf_free(dev); - return; - } + if (zip_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f))) { + memset(dev->buffer, 0, len); + alloc_length = len; - memset(dev->buffer, 0, len); - alloc_length = len; - - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = zip_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 = MIN(len, alloc_length); - dev->buffer[0] = (len - 2) >> 8; - dev->buffer[1] = (len - 2) & 255; - dev->buffer[2] = 0; - if (block_desc) { - dev->buffer[6] = 0; - dev->buffer[7] = 8; + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = zip_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 = MIN(len, alloc_length); + dev->buffer[0] = (len - 2) >> 8; + dev->buffer[1] = (len - 2) & 255; + dev->buffer[2] = 0; + if (block_desc) { + dev->buffer[6] = 0; + dev->buffer[7] = 8; + } } + + zip_set_buf_len(dev, BufLen, &len); + + zip_log(dev->log, "Reading mode page: %02X...\n", cdb[2]); + + zip_data_command_finish(dev, len, len, alloc_length, 0); + } else { + zip_invalid_field(dev, cdb[2]); + zip_buf_free(dev); } - - zip_set_buf_len(dev, BufLen, &len); - - zip_log("ZIP %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - - zip_data_command_finish(dev, len, len, alloc_length, 0); - return; + break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -1825,7 +1671,7 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) break; case 0x83: if (idx + 24 > max_len) { - zip_data_phase_error(dev); + zip_data_phase_error(dev, cdb[2]); zip_buf_free(dev); return; } @@ -1843,19 +1689,21 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) dev->buffer[idx++] = 0x01; dev->buffer[idx++] = 0x00; dev->buffer[idx++] = 68; - ide_padstr8(dev->buffer + idx, 8, "IOMEGA "); /* Vendor */ + /* Vendor */ + ide_padstr8(dev->buffer + idx, 8, "IOMEGA "); idx += 8; + /* Product */ if (dev->drv->is_250) - ide_padstr8(dev->buffer + idx, 40, "ZIP 250 "); /* Product */ + ide_padstr8(dev->buffer + idx, 40, "ZIP 250 "); else - ide_padstr8(dev->buffer + idx, 40, "ZIP 100 "); /* Product */ + ide_padstr8(dev->buffer + idx, 40, "ZIP 100 "); idx += 40; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Product */ + ide_padstr8(dev->buffer + idx, 20, "53R141"); idx += 20; break; default: - zip_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - zip_invalid_field(dev); + zip_log(dev->log, "INQUIRY: Invalid page: %02X\n", cdb[2]); + zip_invalid_field(dev, cdb[2]); zip_buf_free(dev); return; } @@ -1865,33 +1713,39 @@ zip_command(scsi_common_t *sc, uint8_t *cdb) memset(dev->buffer, 0, 8); if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) - dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + dev->buffer[0] = 0x7f; /* No physical device on this LUN */ else - dev->buffer[0] = 0x00; /*Hard disk*/ - dev->buffer[1] = 0x80; /*Removable*/ - dev->buffer[2] = (dev->drv->bus_type == ZIP_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + 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; #if 0 dev->buffer[4] = 31; #endif dev->buffer[4] = 0; if (dev->drv->bus_type == ZIP_BUS_SCSI) { - dev->buffer[6] = 1; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ + 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 */ + ide_padstr8(dev->buffer + 8, 8, "IOMEGA "); /* Vendor */ if (dev->drv->is_250) { - ide_padstr8(dev->buffer + 16, 16, "ZIP 250 "); /* Product */ - ide_padstr8(dev->buffer + 32, 4, "42.S"); /* Revision */ + /* Product */ + ide_padstr8(dev->buffer + 16, 16, "ZIP 250 "); + /* Revision */ + ide_padstr8(dev->buffer + 32, 4, "42.S"); + /* Date? */ if (max_len >= 44) - ide_padstr8(dev->buffer + 36, 8, "08/08/01"); /* Date? */ + 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 { - ide_padstr8(dev->buffer + 16, 16, "ZIP 100 "); /* Product */ - ide_padstr8(dev->buffer + 32, 4, "E.08"); /* Revision */ + /* Product */ + ide_padstr8(dev->buffer + 16, 16, "ZIP 100 "); + /* Revision */ + ide_padstr8(dev->buffer + 32, 4, "E.08"); } idx = 36; @@ -1943,7 +1797,8 @@ atapi_out: zip_buf_alloc(dev, 8); - max_len = dev->drv->medium_size - 1; /* IMPORTANT: What's returned is the last LBA block. */ + /* IMPORTANT: What's returned is the last LBA block. */ + max_len = dev->drv->medium_size - 1; memset(dev->buffer, 0, 8); dev->buffer[0] = (max_len >> 24) & 0xff; dev->buffer[1] = (max_len >> 16) & 0xff; @@ -2032,12 +1887,13 @@ atapi_out: break; default: - zip_illegal_opcode(dev); + zip_illegal_opcode(dev, cdb[0]); break; } #if 0 - zip_log("ZIP %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, dev->tf->request_length); + zip_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)) @@ -2057,29 +1913,16 @@ zip_command_stop(scsi_common_t *sc) static uint8_t zip_phase_data_out(scsi_common_t *sc) { - zip_t *dev = (zip_t *) sc; - + zip_t *dev = (zip_t *) sc; + int len = 0; + uint8_t error = 0; + uint32_t last_to_write; + uint32_t i; uint16_t block_desc_len; uint16_t pos; uint16_t param_list_len; - - uint8_t error = 0; - uint8_t page; - uint8_t page_len; - - uint32_t i = 0; - - uint8_t hdr_len; - uint8_t val; - uint8_t old_val; - uint8_t ch; - - uint32_t last_to_write = 0; - uint32_t c; - uint32_t h; - uint32_t s; - - int len = 0; + uint8_t hdr_len; + uint8_t val; switch (dev->current_cdb[0]) { case GPCMD_VERIFY_6: @@ -2092,7 +1935,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, 1); + zip_blocks(dev, &len, 1); break; case GPCMD_WRITE_SAME_10: if (!dev->current_cdb[7] && !dev->current_cdb[8]) { @@ -2108,23 +1951,26 @@ zip_phase_data_out(scsi_common_t *sc) 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) */ - s = (i % 2048); - h = ((i - s) / 2048) % 1; - c = ((i - s) / 2048) / 1; - dev->buffer[0] = (c >> 16) & 0xff; - dev->buffer[1] = (c >> 8) & 0xff; - dev->buffer[2] = c & 0xff; - dev->buffer[3] = h & 0xff; - dev->buffer[4] = (s >> 24) & 0xff; - dev->buffer[5] = (s >> 16) & 0xff; - dev->buffer[6] = (s >> 8) & 0xff; - dev->buffer[7] = s & 0xff; + const uint32_t s = (i % 2048); + const uint32_t h = ((i - s) / 2048) % 1; + const uint32_t c = ((i - s) / 2048) / 1; + dev->buffer[0] = (c >> 16) & 0xff; + dev->buffer[1] = (c >> 8) & 0xff; + dev->buffer[2] = c & 0xff; + dev->buffer[3] = h & 0xff; + dev->buffer[4] = (s >> 24) & 0xff; + dev->buffer[5] = (s >> 16) & 0xff; + dev->buffer[6] = (s >> 8) & 0xff; + dev->buffer[7] = s & 0xff; } - if (fseek(dev->drv->fp, dev->drv->base + (i << 9), SEEK_SET) == -1) - fatal("zip_phase_data_out(): Error seeking\n"); + if (fseek(dev->drv->fp, dev->drv->base + (i << 9), + SEEK_SET) == -1) + log_fatal(dev->log, "zip_phase_data_out(): Error seeking\n"); if (fwrite(dev->buffer, 1, 512, dev->drv->fp) != 512) - fatal("zip_phase_data_out(): Error writing data\n"); + log_fatal(dev->log, "zip_phase_data_out(): Error writing data\n"); } + + fflush(dev->drv->fp); break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -2155,27 +2001,27 @@ zip_phase_data_out(scsi_common_t *sc) while (1) { if (pos >= param_list_len) { - zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id); + zip_log(dev->log, "Buffer has only block descriptor\n"); break; } - page = dev->buffer[pos] & 0x3F; - page_len = dev->buffer[pos + 1]; + const uint8_t page = dev->buffer[pos] & 0x3f; + const uint8_t page_len = dev->buffer[pos + 1]; pos += 2; if (!(zip_mode_sense_page_flags & (1LL << ((uint64_t) page)))) error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; + else for (i = 0; i < page_len; i++) { + const uint8_t old_val = dev->ms_pages_saved.pages[page][i + 2]; + const uint8_t ch = zip_mode_sense_pages_changeable.pages[page][i + 2]; + val = dev->buffer[pos + i]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else { + error |= 1; + zip_invalid_field_pl(dev, val); } } } @@ -2195,7 +2041,6 @@ zip_phase_data_out(scsi_common_t *sc) if (error) { zip_buf_free(dev); - zip_invalid_field_pl(dev); return 0; } break; @@ -2217,7 +2062,7 @@ zip_global_init(void) } static int -zip_get_max(int ide_has_dma, int type) +zip_get_max(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -2241,7 +2086,7 @@ zip_get_max(int ide_has_dma, int type) } static int -zip_get_timings(int ide_has_dma, int type) +zip_get_timings(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -2264,39 +2109,43 @@ zip_get_timings(int ide_has_dma, int type) } static void -zip_100_identify(ide_t *ide) +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(ide_t *ide, int ide_has_dma) +zip_250_identify(const ide_t *ide, const int ide_has_dma) { - ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); /* Model */ + /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), "42.S", 8); + /* Model */ + ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); if (ide_has_dma) { - ide->buffer[80] = 0x70; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-6*/ - ide->buffer[81] = 0x19; /*Maximum ATA revision supported : ATA/ATAPI-6 T13 1410D revision 3a*/ + 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 -zip_identify(ide_t *ide, int ide_has_dma) +zip_identify(const ide_t *ide, const int ide_has_dma) { - const zip_t *zip; + const zip_t *zip = (zip_t *) ide->sc; - zip = (zip_t *) ide->sc; - - /* ATAPI device, direct-access device, removable media, interrupt DRQ: + /* + ATAPI device, direct-access device, removable media, interrupt DRQ: Using (2 << 5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive - as a LS-120. */ + as a LS-120. + */ ide->buffer[0] = 0x8000 | (0 << 8) | 0x80 | (1 << 5); - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide->buffer[49] = 0x200; /* LBA supported */ + /* 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); @@ -2305,30 +2154,32 @@ zip_identify(ide_t *ide, int ide_has_dma) } static void -zip_drive_reset(int c) +zip_drive_reset(const int c) { - zip_t *dev; - scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = zip_drives[c].scsi_device_id & 0x0f; + 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 (!zip_drives[c].priv) { - zip_drives[c].priv = (zip_t *) malloc(sizeof(zip_t)); - memset(zip_drives[c].priv, 0, sizeof(zip_t)); + 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; + + char n[1024] = { 0 }; + + sprintf(n, "ZIP %i", c + 1); + dev->log = log_open(n); } - dev = (zip_t *) zip_drives[c].priv; + zip_t *dev = (zip_t *) zip_drives[c].priv; dev->id = c; dev->cur_lun = SCSI_LUN_USE_CDB; if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - if (!dev->tf) + if (dev->tf == NULL) dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); /* SCSI ZIP, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + scsi_device_t *sd = &scsi_devices[scsi_bus][scsi_id]; sd->sc = (scsi_common_t *) dev; sd->command = zip_command; @@ -2339,7 +2190,7 @@ zip_drive_reset(int c) sd->type = SCSI_REMOVABLE_DISK; } else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) { /* ATAPI CD-ROM, attach to the IDE bus. */ - id = ide_get_drive(zip_drives[c].ide_channel); + ide_t *id = ide_get_drive(zip_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. */ @@ -2366,17 +2217,12 @@ zip_drive_reset(int c) void zip_hard_reset(void) { - zip_t *dev; - uint8_t scsi_id; - uint8_t scsi_bus; - 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)) { - zip_log("ZIP hard_reset drive=%d\n", c); if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = zip_drives[c].scsi_device_id & 0x0f; + 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; /* Make sure to ignore any SCSI ZIP drive that has an out of range SCSI bus. */ if (scsi_bus >= SCSI_BUS_MAX) @@ -2393,7 +2239,9 @@ zip_hard_reset(void) zip_drive_reset(c); - dev = (zip_t *) zip_drives[c].priv; + zip_t *dev = (zip_t *) zip_drives[c].priv; + + zip_log(dev->log, "ZIP hard_reset drive=%d\n", c); if (dev->tf == NULL) continue; @@ -2404,14 +2252,16 @@ zip_hard_reset(void) zip_init(dev); if (strlen(zip_drives[c].image_path)) - zip_load(dev, zip_drives[c].image_path); + zip_load(dev, zip_drives[c].image_path, 0); zip_mode_sense_load(dev); if (zip_drives[c].bus_type == ZIP_BUS_SCSI) - zip_log("SCSI ZIP drive %i attached to SCSI ID %i\n", c, zip_drives[c].scsi_device_id); + 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("ATAPI ZIP drive %i attached to IDE channel %i\n", c, zip_drives[c].ide_channel); + zip_log(dev->log, "ATAPI ZIP drive %i attached to IDE channel %i\n", + c, zip_drives[c].ide_channel); } } } @@ -2419,19 +2269,15 @@ zip_hard_reset(void) void zip_close(void) { - zip_t *dev; - uint8_t scsi_bus; - uint8_t scsi_id; - for (uint8_t c = 0; c < ZIP_NUM; c++) { if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - scsi_bus = (zip_drives[c].scsi_device_id >> 4) & 0x0f; - scsi_id = zip_drives[c].scsi_device_id & 0x0f; + 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; memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); } - dev = (zip_t *) zip_drives[c].priv; + zip_t *dev = (zip_t *) zip_drives[c].priv; if (dev) { zip_disk_unload(dev); @@ -2439,6 +2285,13 @@ zip_close(void) if (dev->tf) free(dev->tf); + if (dev->log != NULL) { + zip_log(dev->log, "Log closed\n"); + + log_close(dev->log); + dev->log = NULL; + } + free(dev); zip_drives[c].priv = NULL; } diff --git a/src/dma.c b/src/dma.c index 8bf60cdc8..4edeb39f8 100644 --- a/src/dma.c +++ b/src/dma.c @@ -665,6 +665,19 @@ dma_ps2_read(uint16_t addr, UNUSED(void *priv)) temp = dma_c->arb_level; break; + case 9: /*Set DMA mask*/ + dma_m |= (1 << dma_ps2.xfr_channel); + break; + + case 0xa: /*Reset DMA mask*/ + dma_m &= ~(1 << dma_ps2.xfr_channel); + break; + + case 0xb: + if (!(dma_m & (1 << dma_ps2.xfr_channel))) + dma_ps2_run(dma_ps2.xfr_channel); + break; + default: fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); } @@ -767,6 +780,19 @@ dma_ps2_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) dma_c->arb_level = val; break; + case 9: /*Set DMA mask*/ + dma_m |= (1 << dma_ps2.xfr_channel); + break; + + case 0xa: /*Reset DMA mask*/ + dma_m &= ~(1 << dma_ps2.xfr_channel); + break; + + case 0xb: + if (!(dma_m & (1 << dma_ps2.xfr_channel))) + dma_ps2_run(dma_ps2.xfr_channel); + break; + default: fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); } @@ -814,8 +840,6 @@ dma16_read(uint16_t addr, UNUSED(void *priv)) case 7: /*Count registers*/ dma_wp[1] ^= 1; count = dma[channel].cc/* + 1*/; - // if (count > dma[channel].cb) - // count = 0x0000; if (dma_wp[1]) ret = count & 0xff; else diff --git a/src/fifo.c b/src/fifo.c index f51809fd8..8afb5640f 100644 --- a/src/fifo.c +++ b/src/fifo.c @@ -10,7 +10,7 @@ * * Authors: Miran Grca, * - * Copyright 2023 Miran Grca. + * Copyright 2023-2025 Miran Grca. */ #include #include @@ -84,6 +84,31 @@ fifo_write(uint8_t val, void *priv) } } +void +fifo_write_tagged(uint8_t tag, uint8_t val, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = fifo->d_overrun = 0; + + if (fifo->full) + fifo->overrun = 1; + else { + fifo->buf[fifo->end] = val; + fifo->tag[fifo->end] = tag; + fifo->end = (fifo->end + 1) % fifo->len; + + if (fifo->end == fifo->start) + fifo->full = 1; + + fifo->empty = 0; + + if (fifo_get_count(fifo) >= fifo->trigger_len) + fifo->ready = 1; + } +} + void fifo_write_evt(uint8_t val, void *priv) { @@ -122,6 +147,45 @@ fifo_write_evt(uint8_t val, void *priv) } } +void +fifo_write_evt_tagged(uint8_t tag, uint8_t val, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = fifo->d_overrun = 0; + + if (fifo->full) { + fifo->d_overrun = (fifo->overrun != 1); + fifo->overrun = 1; + if (fifo->d_overrun && (fifo->d_overrun_evt != NULL)) + fifo->d_overrun_evt(fifo->priv); + } else { + fifo->buf[fifo->end] = val; + fifo->tag[fifo->end] = tag; + fifo->end = (fifo->end + 1) % fifo->len; + + if (fifo->end == fifo->start) { + fifo->d_full = (fifo->full != 1); + fifo->full = 1; + if (fifo->d_full && (fifo->d_full_evt != NULL)) + fifo->d_full_evt(fifo->priv); + } + + fifo->d_empty = (fifo->empty != 0); + fifo->empty = 0; + if (fifo->d_empty && (fifo->d_empty_evt != NULL)) + fifo->d_empty_evt(fifo->priv); + + if (fifo_get_count(fifo) >= fifo->trigger_len) { + fifo->d_ready = (fifo->ready != 1); + fifo->ready = 1; + if (fifo->d_ready && (fifo->d_ready_evt != NULL)) + fifo->d_ready_evt(fifo->priv); + } + } +} + uint8_t fifo_read(void *priv) { @@ -148,6 +212,35 @@ fifo_read(void *priv) return ret; } +uint8_t +fifo_read_tagged(uint8_t *tag, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + uint8_t ret = 0x00; + int count; + + if (!fifo->empty) { + ret = fifo->buf[fifo->start]; + *tag = fifo->tag[fifo->start]; + + fifo->start = (fifo->start + 1) % fifo->len; + + fifo->full = 0; + + count = fifo_get_count(fifo); + + if (count < fifo->trigger_len) { + fifo->ready = 0; + + if (count == 0) + fifo->empty = 1; + } + } else + *tag = 0x00; + + return ret; +} + uint8_t fifo_read_evt(void *priv) { @@ -187,6 +280,48 @@ fifo_read_evt(void *priv) return ret; } +uint8_t +fifo_read_evt_tagged(uint8_t *tag, void *priv) +{ + fifo_t *fifo = (fifo_t *) priv; + uint8_t ret = 0x00; + int count; + + fifo->d_full = fifo->d_empty = 0; + fifo->d_ready = 0; + + if (!fifo->empty) { + ret = fifo->buf[fifo->start]; + *tag = fifo->tag[fifo->start]; + + fifo->start = (fifo->start + 1) % fifo->len; + + fifo->d_full = (fifo->full != 0); + fifo->full = 0; + if (fifo->d_full && (fifo->d_full_evt != NULL)) + fifo->d_full_evt(fifo->priv); + + count = fifo_get_count(fifo); + + if (count < fifo->trigger_len) { + fifo->d_ready = (fifo->ready != 0); + fifo->ready = 0; + if (fifo->d_ready && (fifo->d_ready_evt != NULL)) + fifo->d_ready_evt(fifo->priv); + + if (count == 0) { + fifo->d_empty = (fifo->empty != 1); + fifo->empty = 1; + if (fifo->d_empty && (fifo->d_empty_evt != NULL)) + fifo->d_empty_evt(fifo->priv); + } + } + } else + *tag = 0x00; + + return ret; +} + void fifo_clear_overrun(void *priv) { diff --git a/src/floppy/CMakeLists.txt b/src/floppy/CMakeLists.txt index 5aea98714..c16ca06f4 100644 --- a/src/floppy/CMakeLists.txt +++ b/src/floppy/CMakeLists.txt @@ -9,13 +9,29 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_monster.c fdc_pii15xb.c - fdi2raw.c fdd_common.c fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_pcjs.c - fdd_mfm.c fdd_td0.c) +add_library(fdd OBJECT + fdd.c + fdc.c + fdc_compaticard.c + fdc_magitronic.c + fdc_monster.c + fdc_pii15xb.c + fdi2raw.c + fdd_common.c + fdd_86f.c + fdd_fdi.c + fdd_imd.c + fdd_img.c + fdd_pcjs.c + fdd_mfm.c + fdd_td0.c +) add_subdirectory(lzw) target_link_libraries(86Box lzw) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index f317fd948..75c2c10af 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -103,15 +103,18 @@ typedef const struct { static fdc_cards_t fdc_cards[] = { // clang-format off - { &device_none }, - { &device_internal }, - { &fdc_xt_device }, - { &fdc_at_device }, - { &fdc_b215_device }, - { &fdc_pii151b_device }, - { &fdc_pii158b_device }, - { &fdc_monster_device }, - { NULL } + { &device_none }, + { &device_internal }, + { &fdc_b215_device }, + { &fdc_pii151b_device }, + { &fdc_pii158b_device }, + { &fdc_compaticard_i_device }, + { &fdc_compaticard_ii_device }, +#if 0 + { &fdc_compaticard_iv_device }, +#endif + { &fdc_monster_device }, + { NULL } // clang-format on }; @@ -177,15 +180,13 @@ fdc_ctrl_reset(void *priv) { fdc_t *fdc = (fdc_t *) priv; - fdc->stat = 0x80; + 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->flags & FDC_FLAG_AT)) - fdc->rate = 2; } sector_id_t @@ -612,9 +613,11 @@ fdc_io_command_phase1(fdc_t *fdc, int out) ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 1); fdc->stat = out ? 0x10 : 0x50; - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) + if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) { fdc->stat |= 0x20; - else + if (out) + fdc->stat |= 0x80; + } else dma_set_drq(fdc->dma_ch, 1); } @@ -652,13 +655,31 @@ fdc_sis(fdc_t *fdc) fdc->paramstogo = 2; } +static void +fdc_soft_reset(fdc_t *fdc) +{ + if (fdc->power_down) { + timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); + fdc->interrupt = -5; + } else { + timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); + fdc->interrupt = -1; + + fdc->perp &= 0xfc; + + for (int i = 0; i < FDD_NUM; i++) + ui_sb_update_icon(SB_FLOPPY | i, 0); + + fdc_ctrl_reset(fdc); + } +} + static void fdc_write(uint16_t addr, uint8_t val, void *priv) { fdc_t *fdc = (fdc_t *) priv; int drive; - int i; int drive_num; fdc_log("Write FDC %04X %02X\n", addr, val); @@ -682,7 +703,6 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->interrupt = -1; ui_sb_update_icon(SB_FLOPPY | 0, 0); fdc_ctrl_reset(fdc); - fdd_changed[0] = 1; } if (!fdd_get_flags(0)) val &= 0xfe; @@ -699,24 +719,10 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->stat = 0x00; fdc->pnum = fdc->ptot = 0; } - if ((val & 4) && !(fdc->dor & 4)) { - if (fdc->power_down) { - timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); - fdc->interrupt = -5; - } else { - timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; - - fdc->perp &= 0xfc; - - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); - - fdc_ctrl_reset(fdc); - } - } + if ((val & 4) && !(fdc->dor & 4)) + fdc_soft_reset(fdc); /* We can now simplify this since each motor now spins separately. */ - for (i = 0; i < FDD_NUM; i++) { + for (int i = 0; i < FDD_NUM; i++) { drive_num = real_drive(fdc, i); if ((!fdd_get_flags(drive_num)) || (drive_num >= FDD_NUM)) val &= ~(0x10 << drive_num); @@ -749,28 +755,14 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) } } return; - case 4: + case 4: /* DSR */ if (!(fdc->flags & FDC_FLAG_NO_DSR_RESET)) { if (!(val & 0x80)) { timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); fdc->interrupt = -6; } - if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) { - if (fdc->power_down) { - timer_set_delay_u64(&fdc->timer, 1000 * TIMER_USEC); - fdc->interrupt = -5; - } else { - timer_set_delay_u64(&fdc->timer, 8 * TIMER_USEC); - fdc->interrupt = -1; - - fdc->perp &= 0xfc; - - for (i = 0; i < FDD_NUM; i++) - ui_sb_update_icon(SB_FLOPPY | i, 0); - - fdc_ctrl_reset(fdc); - } - } + if (fdc->power_down || ((val & 0x80) && !(fdc->dsr & 0x80))) + fdc_soft_reset(fdc); } fdc->dsr = val; return; @@ -1231,7 +1223,7 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) if (!(fdc->flags & FDC_FLAG_TOSHIBA) && !(fdc->flags & FDC_FLAG_AT) && !(fdc->flags & FDC_FLAG_UMC)) return; fdc->rate = val & 0x03; - if (fdc->flags & FDC_FLAG_PS1) + if (fdc->flags & FDC_FLAG_PS2) fdc->noprec = !!(val & 0x04); return; @@ -1251,23 +1243,43 @@ fdc_read(uint16_t addr, void *priv) if (!fdc->power_down || ((addr & 7) == 2)) switch (addr & 7) { case 0: /* STA */ - if (fdc->flags & FDC_FLAG_PS1) { + if (fdc->flags & FDC_FLAG_PS2) { drive = real_drive(fdc, fdc->dor & 3); ret = 0x00; /* TODO: Bit 2: INDEX (best return always 0 as it goes by very fast) */ - if (fdc->seek_dir) /* nDIRECTION */ + if (fdc->seek_dir) /* nDIRECTION */ ret |= 0x01; - if (writeprot[drive]) /* WRITEPROT */ + if (writeprot[drive]) /* WRITEPROT */ ret |= 0x02; - if (!fdd_get_head(drive)) /* nHDSEL */ + if (!fdd_get_head(drive)) /* nHDSEL */ ret |= 0x08; - if (fdd_track0(drive)) /* TRK0 */ + if (fdd_track0(drive)) /* TRK0 */ ret |= 0x10; - if (fdc->step) /* STEP */ + if (fdc->step) /* STEP */ ret |= 0x20; - if (dma_get_drq(fdc->dma_ch)) /* DRQ */ + if (dma_get_drq(fdc->dma_ch)) /* DRQ */ + ret |= 0x40; + if (fdc->fintr || fdc->reset_stat) /* INTR */ + ret |= 0x80; + } else if (fdc->flags & FDC_FLAG_PS2_MCA) { + drive = real_drive(fdc, fdc->dor & 3); + ret = 0x04; + /* TODO: + Bit 2: nINDEX (best return always 1 as it goes by very fast) + */ + if (!fdc->seek_dir) /* DIRECTION */ + ret |= 0x01; + if (!writeprot[drive]) /* nWRITEPROT */ + ret |= 0x02; + if (fdd_get_head(drive)) /* HDSEL */ + ret |= 0x08; + if (!fdd_track0(drive)) /* nTRK0 */ + ret |= 0x10; + if (fdc->step) /* STEP */ + ret |= 0x20; + if (!fdd_get_type(1)) /* -Drive 2 Installed */ ret |= 0x40; if (fdc->fintr || fdc->reset_stat) /* INTR */ ret |= 0x80; @@ -1295,14 +1307,12 @@ fdc_read(uint16_t addr, void *priv) ret = 0xff; break; case 1: /* STB */ - if (fdc->flags & FDC_FLAG_PS1) { + if (fdc->flags & FDC_FLAG_PS2) { drive = real_drive(fdc, fdc->dor & 3); ret = 0x00; - /* -Drive 2 Installed */ - if (!fdd_get_type(1)) + if (!fdd_get_type(1)) /* -Drive 2 Installed */ ret |= 0x80; - /* -Drive Select 1,0 */ - switch (drive) { + switch (drive) { /* -Drive Select 1,0 */ case 0: ret |= 0x43; break; @@ -1319,19 +1329,12 @@ fdc_read(uint16_t addr, void *priv) default: break; } - } - else if (fdc->flags & FDC_FLAG_PS2) { - /* Status Register B (PS/2, PS/55) */ - /* | 1 | 1 | DS0 | WD TOGGLE | RD TOGGLE | WE | MOT EN1 | MOT EN0 | */ - ret = 0xc0; - if (motoron[0]) /* Bit 0: MOT EN0 */ - ret |= 1; - if (motoron[1]) /* Bit 1: MOT EN1 */ - ret |= 2; - if(real_drive(fdc, fdc->dor & 3) == 0) /* Bit 5: Drive Select 0 */ - ret |= 0x20; - } - else { + } else if (fdc->flags & FDC_FLAG_PS2_MCA) { + drive = real_drive(fdc, fdc->dor & 3); + ret = 0xc0; + ret |= (fdc->dor & 0x01) << 5; /* Drive Select 0 */ + ret |= (fdc->dor & 0x30) >> 4; /* Motor Select 1, 0 */ + } else { if (is486 || !fdc->enable_3f1) ret = 0xff; else { @@ -1339,19 +1342,12 @@ fdc_read(uint16_t addr, void *priv) drive = real_drive(fdc, fdc->dor & 1); ret = !fdd_is_dd(drive) ? ((fdc->dor & 1) ? 2 : 1) : 0; } else { - ret = 0x70; - + /* TODO: What is this and what is it used for? + It's almost identical to the PS/2 MCA mode. */ drive = real_drive(fdc, fdc->dor & 3); - - if (drive) - ret &= ~0x40; - else - ret &= ~0x20; - - if (fdc->dor & 0x10) - ret |= 1; - if (fdc->dor & 0x20) - ret |= 2; + ret = 0x70; + ret &= ~(drive ? 0x40 : 0x20); + ret |= (fdc->dor & 0x30) >> 4; /* Motor Select 1, 0 */ } } } @@ -1361,7 +1357,8 @@ fdc_read(uint16_t addr, void *priv) break; case 3: drive = real_drive(fdc, fdc->dor & 3); - if (fdc->flags & FDC_FLAG_PS1) { + /* TODO: FDC_FLAG_PS2_TDR? */ + if ((fdc->flags & FDC_FLAG_PS2) || (fdc->flags & FDC_FLAG_PS2_MCA)) { /* PS/1 Model 2121 seems return drive type in port * 0x3f3, despite the 82077AA fdc_t not implementing * this. This is presumably implemented outside the @@ -1433,7 +1430,7 @@ fdc_read(uint16_t addr, void *priv) case 7: /*Disk change*/ drive = real_drive(fdc, fdc->dor & 3); - if (fdc->flags & FDC_FLAG_PS1) { + if (fdc->flags & FDC_FLAG_PS2) { if (fdc->dor & (0x10 << drive)) { ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x00 : 0x80; ret |= (fdc->dor & 0x08); @@ -1441,18 +1438,15 @@ fdc_read(uint16_t addr, void *priv) ret |= (fdc->rate & 0x03); } else ret = 0x00; - } - else if (fdc->flags & FDC_FLAG_PS2) { - /* Digital Input Register (PS/2, PS/55) */ - /* | DSKCHG | 1 | 1 | 1 | 1 | DRATE1 | DRATE0 | nHDEN | */ - ret = 0x78; - ret |= (fdc->rate & 0x03) << 1; - if (fdc->rate == 1 || fdc->rate == 2) - ret |= 0x01; - if (fdc->dor & (0x10 << drive)) - ret |= (fdd_changed[drive] || drive_empty[drive]) ? 0x80 : 0x00; - } - else { + } else if (fdc->flags & FDC_FLAG_PS2_MCA) { + if (fdc->dor & (0x10 << drive)) { + ret = (fdd_changed[drive] || drive_empty[drive]) ? 0x80 : 0x00; + ret |= ((fdc->rate & 0x03) << 1); + ret |= fdc_get_densel(fdc, drive); + ret |= 0x78; + } else + ret = 0xf9; + } else { if (fdc->dor & (0x10 << drive)) { if ((drive == 1) && (fdc->flags & FDC_FLAG_TOSHIBA)) ret = 0x00; @@ -1484,7 +1478,7 @@ static void fdc_poll_common_finish(fdc_t *fdc, int compare, int st5) { fdc_int(fdc, 1); - if (!(fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2))) + if (!(fdc->flags & FDC_FLAG_FINTR)) fdc->fintr = 0; fdc->stat = 0xD0; fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive; @@ -1786,7 +1780,7 @@ fdc_callback(void *priv) } else { fdc->interrupt = -2; fdc_int(fdc, 1); - if (!(fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2))) + if (!(fdc->flags & FDC_FLAG_FINTR)) fdc->fintr = 0; fdc->stat = 0xD0; fdc->st0 = fdc->res[4] = (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->drive; @@ -1878,7 +1872,7 @@ fdc_error(fdc_t *fdc, int st5, int st6) timer_disable(&fdc->timer); fdc_int(fdc, 1); - if (!(fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2))) + if (!(fdc->flags & FDC_FLAG_FINTR)) fdc->fintr = 0; fdc->stat = 0xD0; fdc->st0 = fdc->res[4] = 0x40 | (fdd_get_head(real_drive(fdc, fdc->drive)) ? 4 : 0) | fdc->rw_drive; @@ -2287,7 +2281,7 @@ fdc_reset(void *priv) fdc->enable_3f1 = 1; fdc_update_enh_mode(fdc, 0); - if (fdc->flags & (FDC_FLAG_PS1 | FDC_FLAG_PS2)) + if (fdc->flags & FDC_FLAG_DENSEL_INVERT) fdc_update_densel_polarity(fdc, 0); else fdc_update_densel_polarity(fdc, 1); @@ -2334,6 +2328,9 @@ fdc_reset(void *priv) fdc_ctrl_reset(fdc); + if (!(fdc->flags & FDC_FLAG_AT)) + fdc->rate = 2; + fdc->max_track = (fdc->flags & FDC_FLAG_MORE_TRACKS) ? 85 : 79; fdc_remove(fdc); @@ -2371,8 +2368,7 @@ fdc_close(void *priv) static void * fdc_init(const device_t *info) { - fdc_t *fdc = (fdc_t *) malloc(sizeof(fdc_t)); - memset(fdc, 0, sizeof(fdc_t)); + fdc_t *fdc = (fdc_t *) calloc(1, sizeof(fdc_t)); fdc->flags = info->local; @@ -2428,7 +2424,7 @@ const device_t fdc_xt_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2442,7 +2438,7 @@ const device_t fdc_xt_sec_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2456,7 +2452,7 @@ const device_t fdc_xt_ter_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2470,7 +2466,7 @@ const device_t fdc_xt_qua_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2484,7 +2480,7 @@ const device_t fdc_xt_t1x00_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2498,7 +2494,7 @@ const device_t fdc_xt_amstrad_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2512,7 +2508,21 @@ const device_t fdc_xt_tandy_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t fdc_xt_umc_um8398_device = { + .name = "PC/XT Floppy Drive Controller (UMC UM8398)", + .internal_name = "fdc_xt_umc_um8398", + .flags = 0, + .local = FDC_FLAG_UMC, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2526,7 +2536,7 @@ const device_t fdc_pcjr_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2540,7 +2550,7 @@ const device_t fdc_at_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2554,7 +2564,7 @@ const device_t fdc_at_sec_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2568,7 +2578,7 @@ const device_t fdc_at_ter_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2582,7 +2592,7 @@ const device_t fdc_at_qua_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2596,35 +2606,7 @@ const device_t fdc_at_actlow_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc_at_ps1_device = { - .name = "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)", - .internal_name = "fdc_at_ps1", - .flags = 0, - .local = FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1, - .init = fdc_init, - .close = fdc_close, - .reset = fdc_reset, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t fdc_at_ps1_2121_device = { - .name = "PC/AT Floppy Drive Controller (PS/1, PS/2 ISA)", - .internal_name = "fdc_at_ps1", - .flags = 0, - .local = FDC_FLAG_NO_DSR_RESET | FDC_FLAG_DISKCHG_ACTLOW | FDC_FLAG_AT | FDC_FLAG_PS1, - .init = fdc_init, - .close = fdc_close, - .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2652,7 +2634,7 @@ const device_t fdc_at_smc_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2666,7 +2648,7 @@ const device_t fdc_at_ali_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2680,7 +2662,7 @@ const device_t fdc_at_winbond_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2694,35 +2676,51 @@ const device_t fdc_at_nsc_device = { .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; -const device_t fdc_dp8473_device = { - .name = "NS DP8473 Floppy Drive Controller", - .internal_name = "fdc_dp8473", +const device_t fdc_at_nsc_dp8473_device = { + .name = "PC/AT Floppy Drive Controller (NSC DP8473)", + .internal_name = "fdc_at_nsc_dp8473", .flags = 0, .local = FDC_FLAG_AT | FDC_FLAG_NEC | FDC_FLAG_NO_DSR_RESET, .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; -const device_t fdc_um8398_device = { - .name = "UMC UM8398 Floppy Drive Controller", - .internal_name = "fdc_um8398", +const device_t fdc_ps2_device = { + .name = "PS/2 Model 25/30 Floppy Drive Controller", + .internal_name = "fdc_ps2", .flags = 0, - .local = FDC_FLAG_UMC, + .local = FDC_FLAG_FINTR | FDC_FLAG_DENSEL_INVERT | FDC_FLAG_NO_DSR_RESET | FDC_FLAG_DISKCHG_ACTLOW | + FDC_FLAG_AT | FDC_FLAG_PS2, .init = fdc_init, .close = fdc_close, .reset = fdc_reset, - { .available = NULL }, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t fdc_ps2_mca_device = { + .name = "PS/2 MCA Floppy Drive Controller", + .internal_name = "fdc_ps2_mca", + .flags = 0, + .local = FDC_FLAG_FINTR | FDC_FLAG_DENSEL_INVERT | FDC_FLAG_NO_DSR_RESET | FDC_FLAG_AT | + FDC_FLAG_PS2_MCA, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/floppy/fdc_compaticard.c b/src/floppy/fdc_compaticard.c new file mode 100644 index 000000000..741105927 --- /dev/null +++ b/src/floppy/fdc_compaticard.c @@ -0,0 +1,368 @@ +/* + * 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 Micro Solutions CompatiCard I/II/IV. + * + * Authors: Jasmine Iwanek, + * + * Copyright 2022-2025 Jasmine Iwanek. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/machine.h> +#include <86box/timer.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/plat_unused.h> + +#define DEVICE_COMPATICARD_I 0 +#define DEVICE_COMPATICARD_II 1 +#define DEVICE_COMPATICARD_IV 2 + +#define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff) +#define ROM_COMPATICARD_IV "roms/floppy/compaticard/ccivbios1.05.bin" + +#define CR_2_MASK 0x2f /* 00101111b */ + +typedef struct compaticard_s { + rom_t bios_rom; + fdc_t *fdc; + /* + * 7 - Reserved - Set to 0 + * 6 - Reserved - Set to 0 + * 5 - Programmable Pin 2 Logic I sets Pin 2 low (TODO) + * 4 - Reserved - Set to 0 + * 3-0 - Data Transfer Rate Select (TODO) + * 0000---250 Kbps + * 0001-300 Kbps + * 1111-500 Kbps + */ + uint8_t cr_2; +} compaticard_t; + +static void +compaticard_out(UNUSED(uint16_t port), uint8_t val, void *priv) +{ + compaticard_t *dev = (compaticard_t *) priv; + + dev->cr_2 = (val & CR_2_MASK); +} + +static uint8_t +compaticard_in(UNUSED(uint16_t port), void *priv) +{ + compaticard_t *dev = (compaticard_t *) priv; + uint8_t ret = (dev->cr_2 &CR_2_MASK); + + return ret; +} + +static void +compaticard_close(void *priv) +{ + compaticard_t *dev = (compaticard_t *) priv; + + free(dev); +} + +static void * +compaticard_init(const device_t *info) +{ + compaticard_t *dev = calloc(1, sizeof(compaticard_t)); + uint16_t base_addr = device_get_config_hex16("base"); + uint8_t irq = 6; + uint8_t dma = 2; + uint16_t cr2_addr = 0x7f2; // Control Register 2 + + // CompatiCard II & IV have configurable IRQ and DMA + if (info->local >= DEVICE_COMPATICARD_II) { + irq = device_get_config_int("irq"); + dma = device_get_config_int("dma"); + } + + // Only on CompatiCard IV + if ((info->local == DEVICE_COMPATICARD_IV) && (BIOS_ADDR != 0)) + rom_init(&dev->bios_rom, ROM_COMPATICARD_IV, BIOS_ADDR, 0x2000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL); + + // TODO: Make this neater + switch (base_addr) { + case FDC_SECONDARY_ADDR: + cr2_addr = 0x772; + if (info->local == DEVICE_COMPATICARD_IV) + dev->fdc = device_add(&fdc_at_sec_device); + else + dev->fdc = device_add(&fdc_xt_sec_device); + break; + + case FDC_TERTIARY_ADDR: + cr2_addr = 0x762; + if (info->local == DEVICE_COMPATICARD_IV) + dev->fdc = device_add(&fdc_at_ter_device); + else + dev->fdc = device_add(&fdc_xt_ter_device); + break; + + case FDC_QUATERNARY_ADDR: + cr2_addr = 0x7e2; + if (info->local == DEVICE_COMPATICARD_IV) + dev->fdc = device_add(&fdc_at_qua_device); + else + dev->fdc = device_add(&fdc_xt_qua_device); + break; + + default: + if (info->local == DEVICE_COMPATICARD_IV) + dev->fdc = device_add(&fdc_at_device); + else + dev->fdc = device_add(&fdc_xt_device); + break; + } + + fdc_set_irq(dev->fdc, irq); + fdc_set_dma_ch(dev->fdc, dma); + + io_sethandler(cr2_addr, 0x0001, + compaticard_in, NULL, NULL, + compaticard_out, NULL, NULL, + dev); + + return dev; +} + +static int compaticard_iv_available(void) +{ + return rom_present(ROM_COMPATICARD_IV); +} + +static const device_config_t compaticard_i_config[] = { +// clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x3f0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x3f0", .value = 0x3f0 }, + { .description = "0x370", .value = 0x370 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + +static const device_config_t compaticard_ii_config[] = { +// clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x3f0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x3f0", .value = 0x3f0 }, + { .description = "0x370", .value = 0x370 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 6, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 6", .value = 6 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 2", .value = 2 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + +static const device_config_t compaticard_iv_config[] = { +// clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x3f0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x3f0", .value = 0x3f0 }, + { .description = "0x370", .value = 0x370 }, + { .description = "0x360", .value = 0x360 }, + { .description = "0x3e0", .value = 0x3e0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 6, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 6", .value = 6 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 2", .value = 2 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS Address:", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xce000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "CE00H", .value = 0xce000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DE00H", .value = 0xde000 }, + { .description = "E000H", .value = 0xe0000 }, + { .description = "E800H", .value = 0xe8000 }, + { .description = "EE00H", .value = 0xee000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#if 0 + { + .name = "autoboot_enabled", + .description = "Enable Autoboot", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, +#endif + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + +const device_t fdc_compaticard_i_device = { + .name = "Micro Solutions CompatiCard I", + .internal_name = "compaticard_i", + .flags = DEVICE_ISA, + .local = 0, + .init = compaticard_init, + .close = compaticard_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = compaticard_i_config +}; + +const device_t fdc_compaticard_ii_device = { + .name = "Micro Solutions CompatiCard II", + .internal_name = "compaticard_ii", + .flags = DEVICE_ISA, + .local = 1, + .init = compaticard_init, + .close = compaticard_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = compaticard_ii_config +}; + +const device_t fdc_compaticard_iv_device = { + .name = "Micro Solutions CompatiCard IV", + .internal_name = "compaticard_iv", + .flags = DEVICE_ISA, + .local = 2, + .init = compaticard_init, + .close = compaticard_close, + .reset = NULL, + .available = compaticard_iv_available, + .speed_changed = NULL, + .force_redraw = NULL, + .config = compaticard_iv_config +}; diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index 084ce8c81..17e556e0f 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -90,12 +90,11 @@ b215_close(void *priv) static void * b215_init(UNUSED(const device_t *info)) { - b215_t *dev = (b215_t *) malloc(sizeof(b215_t)); - memset(dev, 0, sizeof(b215_t)); + b215_t *dev = (b215_t *) calloc(1, sizeof(b215_t)); rom_init(&dev->rom, ROM_B215, ROM_ADDR, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - dev->fdc_controller = device_add(&fdc_um8398_device); + dev->fdc_controller = device_add(&fdc_xt_umc_um8398_device); io_sethandler(FDC_PRIMARY_ADDR, 1, b215_read, NULL, NULL, NULL, NULL, NULL, dev); return dev; @@ -110,18 +109,19 @@ b215_available(void) static const device_config_t b215_config[] = { // clang-format off { - .name = "bios_addr", - .description = "BIOS Address:", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xca000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xca000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "CA00H", .value = 0xca000 }, { .description = "CC00H", .value = 0xcc000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -135,7 +135,7 @@ const device_t fdc_b215_device = { .init = b215_init, .close = b215_close, .reset = NULL, - { .available = b215_available }, + .available = b215_available, .speed_changed = NULL, .force_redraw = NULL, .config = b215_config diff --git a/src/floppy/fdc_monster.c b/src/floppy/fdc_monster.c index 504254ee0..1b0e2fbac 100644 --- a/src/floppy/fdc_monster.c +++ b/src/floppy/fdc_monster.c @@ -13,7 +13,7 @@ * Authors: Jasmine Iwanek, * Miran Grca, * - * Copyright 2022-2024 Jasmine Iwanek. + * Copyright 2022-2025 Jasmine Iwanek. * Copyright 2024 Miran Grca. */ #include @@ -165,82 +165,61 @@ static const device_config_t monster_fdc_config[] = { // clang-format off #if 0 { - .name = "sec_enabled", - .description = "Enable Secondary Controller", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "sec_enabled", + .description = "Enable Secondary Controller", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "sec_irq", - .description = "Secondary Controller IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 6", - .value = 6 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .name = "sec_irq", + .description = "Secondary Controller IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 6, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 6", .value = 6 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "sec_dma", - .description = "Secondary Controller DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 2", - .value = 2 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .name = "sec_dma", + .description = "Secondary Controller DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 2", .value = 2 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, #endif { - .name = "bios_addr", - .description = "BIOS Address:", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0 }, { .description = "C000H", .value = 0xc0000 }, { .description = "C800H", .value = 0xc8000 }, @@ -249,30 +228,36 @@ static const device_config_t monster_fdc_config[] = { { .description = "E000H", .value = 0xe0000 }, { .description = "E800H", .value = 0xe8000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, #if 0 { - .name = "bios_size", - .description = "BIOS Size:", - .type = CONFIG_HEX20, - .default_string = "32", - .default_int = 0xc8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_size", + .description = "BIOS Size:", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 32, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "8K", .value = 8 }, { .description = "32K", .value = 32 }, { .description = "" } - } + }, + .bios = { { 0 } } }, #endif { - .name = "rom_writes_enabled", - .description = "Enable BIOS extension ROM Writes", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 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 } // clang-format on @@ -286,7 +271,7 @@ const device_t fdc_monster_device = { .init = monster_fdc_init, .close = monster_fdc_close, .reset = NULL, - { .available = monster_fdc_available }, + .available = monster_fdc_available, .speed_changed = NULL, .force_redraw = NULL, .config = monster_fdc_config diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c index 5fd38d250..4e6a8367c 100644 --- a/src/floppy/fdc_pii15xb.c +++ b/src/floppy/fdc_pii15xb.c @@ -75,7 +75,7 @@ MiniMicro 4 also won't work with the XT FDC which the Zilog claims to be. #include <86box/fdc_ext.h> #define DTK_VARIANT ((info->local == 158) ? ROM_PII_158B : ROM_PII_151B) -#define DTK_CHIP ((info->local == 158) ? &fdc_xt_device : &fdc_dp8473_device) +#define DTK_CHIP ((info->local == 158) ? &fdc_xt_device : &fdc_at_nsc_dp8473_device) #define BIOS_ADDR (uint32_t)(device_get_config_hex20("bios_addr") & 0x000fffff) #define ROM_PII_151B "roms/floppy/dtk/pii-151b.rom" #define ROM_PII_158B "roms/floppy/dtk/pii-158b.rom" @@ -97,8 +97,7 @@ pii_init(const device_t *info) { pii_t *dev; - dev = (pii_t *) malloc(sizeof(pii_t)); - memset(dev, 0, sizeof(pii_t)); + dev = (pii_t *) calloc(1, sizeof(pii_t)); if (BIOS_ADDR != 0) rom_init(&dev->bios_rom, DTK_VARIANT, BIOS_ADDR, 0x2000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL); @@ -123,20 +122,21 @@ pii_158_available(void) static const device_config_t pii_config[] = { // clang-format off { - .name = "bios_addr", - .description = "BIOS Address:", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xce000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xce000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0 }, { .description = "CA00H", .value = 0xca000 }, { .description = "CC00H", .value = 0xcc000 }, { .description = "CE00H", .value = 0xce000 }, { .description = "" } - } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -150,7 +150,7 @@ const device_t fdc_pii151b_device = { .init = pii_init, .close = pii_close, .reset = NULL, - { .available = pii_151b_available }, + .available = pii_151b_available, .speed_changed = NULL, .force_redraw = NULL, .config = pii_config @@ -164,7 +164,7 @@ const device_t fdc_pii158b_device = { .init = pii_init, .close = pii_close, .reset = NULL, - { .available = pii_158_available }, + .available = pii_158_available, .speed_changed = NULL, .force_redraw = NULL, .config = pii_config diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 81edcc8b8..f0a32df75 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -26,6 +26,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/timer.h> +#include <86box/machine.h> #include <86box/path.h> #include <86box/plat.h> #include <86box/ui.h> @@ -99,10 +100,10 @@ d86f_handler_t d86f_handler[FDD_NUM]; static const struct { - char *ext; - void (*load)(int drive, char *fn); - void (*close)(int drive); - int size; + const char *ext; + void (*load)(int drive, char *fn); + void (*close)(int drive); + int size; } loaders[] = { { "001", img_load, img_close, -1}, { "002", img_load, img_close, -1}, @@ -153,20 +154,16 @@ static const struct { { 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" }, /* 5.25" QD */ { 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" }, - /* 5.25" HD PS/2 */ - { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" }, /* 5.25" HD */ - { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" }, + { 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_PS2, "5.25\" 1.2M", "525_2hd" }, /* 5.25" HD Dual RPM */ { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" }, /* 3.5" 1DD */ { 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" }, /* 3.5" DD, Equivalent to TEAC FD-235F */ { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" }, - /* 3.5" HD PS/2 */ - { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" }, /* 3.5" HD, Equivalent to TEAC FD-235HF */ - { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" }, + { 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_PS2, "3.5\" 1.44M", "35_2hd" }, /* TODO: 3.5" DD, Equivalent to TEAC FD-235GF */ // { 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.25M", "35_2hd_2mode" }, /* 3.5" HD PC-98 */ @@ -214,10 +211,19 @@ fdd_get_internal_name(int type) int fdd_get_from_internal_name(char *s) { - int c = 0; + 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, s)) + if (!strcmp((char *) drive_types[c].internal_name, n)) return c; c++; } @@ -282,11 +288,32 @@ fdd_current_track(int drive) return fdd[drive].track; } +static int +fdd_type_invert_densel(int type) +{ + int ret; + + if (drive_types[type].flags & FLAG_PS2) + ret = (!!strstr(machine_getname(), "PS/1")) || (!!strstr(machine_getname(), "PS/2")); + else + ret = drive_types[type].flags & FLAG_INVERT_DENSEL; + + return ret; +} + +static int +fdd_invert_densel(int drive) +{ + int ret = fdd_type_invert_densel(fdd[drive].type); + + return ret; +} + void fdd_set_densel(int densel) { for (uint8_t i = 0; i < FDD_NUM; i++) { - if (drive_types[fdd[i].type].flags & FLAG_INVERT_DENSEL) + if (fdd_invert_densel(i)) fdd[i].densel = densel ^ 1; else fdd[i].densel = densel; @@ -302,7 +329,7 @@ fdd_getrpm(int drive) hole = fdd_hole(drive); densel = fdd[drive].densel; - if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL) + if (fdd_invert_densel(drive)) densel ^= 1; if (!(drive_types[fdd[drive].type].flags & FLAG_RPM_360)) @@ -340,10 +367,9 @@ fdd_doublestep_40(int drive) void fdd_set_type(int drive, int type) { - int old_type = fdd[drive].type; - fdd[drive].type = type; - if ((drive_types[old_type].flags ^ drive_types[type].flags) & FLAG_INVERT_DENSEL) + if (fdd_type_invert_densel(fdd[drive].type) != fdd_type_invert_densel(type)) fdd[drive].densel ^= 1; + fdd[drive].type = type; } int diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 35ddbb1dd..140e87899 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -628,10 +628,12 @@ d86f_get_array_size(int drive, int side, int words) int hole; int rm; int ssd; + int mpc; rm = d86f_get_rpm_mode(drive); ssd = d86f_get_speed_shift_dir(drive); - hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; + hole = (d86f_handler[drive].disk_flags(drive) >> 1) & 3; + mpc = (d86f_handler[drive].disk_flags(drive) >> 13) & 1; if (!rm && ssd) /* Special case - extra bit cells size specifies entire array size. */ array_size = 0; @@ -703,13 +705,20 @@ d86f_get_array_size(int drive, int side, int words) array_size <<= 4; array_size += d86f_handler[drive].extra_bit_cells(drive, side); - if (array_size & 15) - array_size = (array_size >> 4) + 1; - else - array_size = (array_size >> 4); + if (mpc && !words) { + if (array_size & 7) + array_size = (array_size >> 3) + 1; + else + array_size = (array_size >> 3); + } else { + if (array_size & 15) + array_size = (array_size >> 4) + 1; + else + array_size = (array_size >> 4); - if (!words) - array_size <<= 1; + if (!words) + array_size <<= 1; + } return array_size; } @@ -1098,9 +1107,9 @@ d86f_get_bit(int drive, int side) /* In some cases, misindentification occurs so we need to make sure the surface data array is not not NULL. */ if (d86f_has_surface_desc(drive) && dev->track_surface_data[side]) { - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) surface_data = dev->track_surface_data[side][track_word] & 0xFF; - } else { + else { surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; surface_data |= (dev->track_surface_data[side][track_word] >> 8); } @@ -1150,9 +1159,9 @@ d86f_put_bit(int drive, int side, int bit) } if (d86f_has_surface_desc(drive)) { - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) surface_data = dev->track_surface_data[side][track_word] & 0xFF; - } else { + else { surface_data = (dev->track_surface_data[side][track_word] & 0xFF) << 8; surface_data |= (dev->track_surface_data[side][track_word] >> 8); } @@ -1177,9 +1186,9 @@ d86f_put_bit(int drive, int side, int bit) surface_data &= ~(1 << track_bit); surface_data |= (surface_bit << track_bit); - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) dev->track_surface_data[side][track_word] = surface_data; - } else { + else { dev->track_surface_data[side][track_word] = (surface_data & 0xFF) << 8; dev->track_surface_data[side][track_word] |= (surface_data >> 8); } @@ -1191,9 +1200,9 @@ d86f_put_bit(int drive, int side, int bit) encoded_data &= ~(1 << track_bit); encoded_data |= (current_bit << track_bit); - if (d86f_reverse_bytes(drive)) { + if (d86f_reverse_bytes(drive)) d86f_handler[drive].encoded_data(drive, side)[track_word] = encoded_data; - } else { + else { d86f_handler[drive].encoded_data(drive, side)[track_word] = (encoded_data & 0xFF) << 8; d86f_handler[drive].encoded_data(drive, side)[track_word] |= (encoded_data >> 8); } @@ -1833,7 +1842,6 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 uint16_t mask_data; uint16_t mask_surface; uint16_t mask_hole; - uint16_t mask_fuzzy; decoded_t dbyte; decoded_t dpbyte; @@ -1846,6 +1854,7 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 if (type == 0) { /* Byte write. */ encoded_byte = d86f_encode_byte(drive, 0, dbyte, dpbyte); + dev->preceding_bit[side] = encoded_byte & 1; if (!d86f_reverse_bytes(drive)) { mask_data = encoded_byte >> 8; encoded_byte &= 0xFF; @@ -1855,6 +1864,7 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 } else { /* Word write. */ encoded_byte = byte; + dev->preceding_bit[side] = (encoded_byte >> 8) & 1; if (d86f_reverse_bytes(drive)) { mask_data = encoded_byte >> 8; encoded_byte &= 0xFF; @@ -1863,16 +1873,19 @@ d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint3 } } - dev->preceding_bit[side] = encoded_byte & 1; - if (d86f_has_surface_desc(drive)) { - mask_data = dev->track_encoded_data[side][pos] ^= 0xFFFF; + /* Inverted track data, clear bits are now set. */ + mask_data = ~dev->track_encoded_data[side][pos]; + /* Surface data. */ mask_surface = dev->track_surface_data[side][pos]; - mask_hole = (mask_surface & mask_data) ^ 0xFFFF; /* This will retain bits that are both fuzzy and 0, therefore physical holes. */ - encoded_byte &= mask_hole; /* Filter out physical hole bits from the encoded data. */ - mask_data ^= 0xFFFF; /* Invert back so bits 1 are 1 again. */ - mask_fuzzy = (mask_surface & mask_data) ^ 0xFFFF; /* All fuzzy bits are 0. */ - dev->track_surface_data[side][pos] &= mask_fuzzy; /* Remove fuzzy bits (but not hole bits) from the surface mask, making them regular again. */ + + /* Hole = surface & ~data, so holes are one. */ + mask_hole = mask_surface & mask_data; + /* Hole bits are ones again, set the surface data to that. */ + dev->track_surface_data[side][pos] = mask_hole; + + /* Force the data of any hole to zero. */ + encoded_byte &= ~mask_hole; } dev->track_encoded_data[side][pos] = encoded_byte; @@ -2718,8 +2731,7 @@ d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t uint16_t datadam_mfm = 0x4A55; if (fdd_get_turbo(drive) && (dev->version == 0x0063)) { - s = (sector_t *) malloc(sizeof(sector_t)); - memset(s, 0, sizeof(sector_t)); + s = (sector_t *) calloc(1, sizeof(sector_t)); s->c = id_buf[0]; s->h = id_buf[1]; s->r = id_buf[2]; @@ -2865,22 +2877,22 @@ d86f_construct_encoded_buffer(int drive, int side) /* Source image has surface description data, so we have some more handling to do. */ src1_fuzm = src1[i] & src1_s[i]; src2_fuzm = src2[i] & src2_s[i]; - dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or - the other or both. */ - src1_holm = src1[i] | (src1_s[i] ^ 0xffff); - src2_holm = src2[i] | (src2_s[i] ^ 0xffff); - dst_holm = (src1_holm & src2_holm) ^ 0xffff; /* The bits that remain set are holes in both. */ - dst_neim = (dst_fuzm | dst_holm) ^ 0xffff; /* The bits that remain set are those that are neither - fuzzy nor are holes in both. */ + dst_fuzm = src1_fuzm | src2_fuzm; /* The bits that remain set are fuzzy in either one or + the other or both. */ + src1_holm = ~src1[i] & src1_s[i]; + src2_holm = ~src2[i] & src2_s[i]; + dst_holm = src1_holm & src2_holm; /* The bits that remain set are holes in both. */ + dst_neim = ~(dst_fuzm | dst_holm); /* The bits that remain set are those that are neither + fuzzy nor are holes in both. */ src1_d = src1[i] & dst_neim; src2_d = src2[i] & dst_neim; - dst_s[i] = (dst_neim ^ 0xffff); /* The set bits are those that are either fuzzy or are - holes in both. */ - dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and - Source 2. */ - dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set - but data bit clear). */ + dst_s[i] = ~dst_neim; /* The set bits are those that are either fuzzy or are + holes in both. */ + dst[i] = (src1_d | src2_d); /* Initial data is remaining data from Source 1 and + Source 2. */ + dst[i] |= dst_fuzm; /* Add to it the fuzzy bytes (holes have surface bit set + but data bit clear). */ } else { /* No surface data, the handling is much simpler - a simple OR. */ dst[i] = src1[i] | src2[i]; @@ -2898,6 +2910,7 @@ d86f_decompose_encoded_buffer(int drive, int side) uint16_t temp2; uint32_t len; const uint16_t *dst = dev->track_encoded_data[side]; + const uint16_t *dst_s = dev->track_surface_data[side]; uint16_t *src1 = dev->thin_track_encoded_data[0][side]; uint16_t *src1_s = dev->thin_track_surface_data[0][side]; uint16_t *src2 = dev->thin_track_encoded_data[1][side]; @@ -2909,15 +2922,15 @@ d86f_decompose_encoded_buffer(int drive, int side) if (d86f_has_surface_desc(drive)) { /* Source image has surface description data, so we have some more handling to do. We need hole masks for both buffers. Holes have data bit clear and surface bit set. */ - temp = src1[i] & (src1_s[i] ^ 0xffff); - temp2 = src2[i] & (src2_s[i] ^ 0xffff); - src1[i] = dst[i] & temp; - src1_s[i] = temp ^ 0xffff; - src2[i] = dst[i] & temp2; - src2_s[i] = temp2 ^ 0xffff; - } else { + src1_s[i] = src2_s[i] = dst_s[i]; /* Write the new holes and weak bits. */ + temp = ~src1[i] & src1_s[i]; /* Bits that are clear in data and set in surface are holes. */ + temp2 = ~src2[i] & src2_s[i]; /* Bits that are clear in data and set in surface are holes. */ + src1[i] = dst[i] & ~temp; /* Make sure the holes' bits are cleared in the decomposed buffer. */ + src1_s[i] |= temp; /* Make sure the holes' bits are set in the decomposed surface. */ + src2[i] = dst[i] & ~temp2; /* Make sure the holes' bits are cleared in the decomposed buffer. */ + src2_s[i] |= temp2; /* Make sure the holes' bits are set in the decomposed surface. */ + } else src1[i] = src2[i] = dst[i]; - } } } @@ -3213,6 +3226,8 @@ d86f_writeback(int drive) free(dev->filebuf); } #endif + + fflush(dev->fp); } void @@ -3544,9 +3559,9 @@ d86f_load(int drive, char *fn) writeprot[drive] = 1; } - if (ui_writeprot[drive]) { + if (ui_writeprot[drive]) writeprot[drive] = 1; - } + fwriteprot[drive] = writeprot[drive]; fseek(dev->fp, 0, SEEK_END); @@ -3905,8 +3920,7 @@ d86f_setup(int drive) d86f_t *dev; /* Allocate a drive structure. */ - dev = (d86f_t *) malloc(sizeof(d86f_t)); - memset(dev, 0x00, sizeof(d86f_t)); + dev = (d86f_t *) calloc(1, sizeof(d86f_t)); dev->state = STATE_IDLE; dev->last_side_sector[0] = NULL; diff --git a/src/floppy/fdd_fdi.c b/src/floppy/fdd_fdi.c index f14bf2cd4..97b6441a0 100644 --- a/src/floppy/fdd_fdi.c +++ b/src/floppy/fdd_fdi.c @@ -316,15 +316,13 @@ fdi_load(int drive, char *fn) writeprot[drive] = fwriteprot[drive] = 1; /* Allocate a drive block. */ - dev = (fdi_t *) malloc(sizeof(fdi_t)); + dev = (fdi_t *) calloc(1, sizeof(fdi_t)); if (dev == NULL) { memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); return; } - memset(dev, 0x00, sizeof(fdi_t)); - d86f_unregister(drive); dev->fp = plat_fopen(fn, "rb"); diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index fd6c59d01..7994530ed 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -549,6 +549,8 @@ imd_writeback(int drive) } } } + + fflush(dev->fp); } static uint8_t @@ -633,8 +635,7 @@ imd_load(int drive, char *fn) writeprot[drive] = 0; /* Allocate a drive block. */ - dev = (imd_t *) malloc(sizeof(imd_t)); - memset(dev, 0x00, sizeof(imd_t)); + dev = (imd_t *) calloc(1, sizeof(imd_t)); dev->fp = plat_fopen(fn, "rb+"); if (dev->fp == NULL) { diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index 404cbf9fa..30e0212cd 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -431,6 +431,8 @@ write_back(int drive) if (fwrite(dev->track_data[side], 1, size, dev->fp) != size) fatal("IMG write_back(): Error writing data\n"); } + + fflush(dev->fp); } static uint16_t @@ -679,8 +681,7 @@ img_load(int drive, char *fn) writeprot[drive] = 0; /* Allocate a drive block. */ - dev = (img_t *) malloc(sizeof(img_t)); - memset(dev, 0x00, sizeof(img_t)); + dev = (img_t *) calloc(1, sizeof(img_t)); dev->fp = plat_fopen(fn, "rb+"); if (dev->fp == NULL) { @@ -1073,9 +1074,14 @@ jump_if_fdf: dev->sectors = 19; dev->tracks = 80; } else if (size <= 1638400) { /*HD 1024 sector*/ +#ifdef SYNTH_FORMAT dev->sectors = 10; - dev->tracks = 80; dev->sector_size = 3; +#else + /* Prefer 20 512-byte sectors per track, used by the OpenStep 4.0 Pre-Release 1 boot disk. */ + dev->sectors = 20; +#endif + dev->tracks = 80; } else if (size <= 1720320) { /*DMF (Windows 95) */ dev->sectors = 21; dev->tracks = 80; @@ -1086,9 +1092,14 @@ jump_if_fdf: dev->sectors = 21; dev->tracks = 82; } else if (size <= 1802240) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; +#ifdef SYNTH_FORMAT + dev->sectors = 11; dev->sector_size = 3; +#else + /* Prefer 22 512-byte sectors per track. */ + dev->sectors = 22; +#endif + dev->tracks = 80; } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ dev->sectors = 23; dev->tracks = 80; @@ -1108,12 +1119,12 @@ jump_if_fdf: dev->sectors = 42; dev->tracks = 80; #if 0 - } else if (size <= 3440640) { /*HD 1024 sector*/ + } else if (size <= 3440640) { /*ED 1024 sector*/ dev->sectors = 21; dev->tracks = 80; dev->sector_size = 3; #endif - } else if (size <= 3604480) { /*HD 1024 sector*/ + } else if (size <= 3604480) { /*ED 1024 sector*/ dev->sectors = 22; dev->tracks = 80; dev->sector_size = 3; diff --git a/src/floppy/fdd_mfm.c b/src/floppy/fdd_mfm.c index a332d25c9..87da4e08b 100644 --- a/src/floppy/fdd_mfm.c +++ b/src/floppy/fdd_mfm.c @@ -396,8 +396,7 @@ mfm_load(int drive, char *fn) writeprot[drive] = fwriteprot[drive] = 1; /* Allocate a drive block. */ - dev = (mfm_t *) malloc(sizeof(mfm_t)); - memset(dev, 0x00, sizeof(mfm_t)); + dev = (mfm_t *) calloc(1, sizeof(mfm_t)); dev->fp = plat_fopen(fn, "rb"); if (dev->fp == NULL) { diff --git a/src/floppy/fdd_pcjs.c b/src/floppy/fdd_pcjs.c index b7b3cc69d..6f69042b0 100644 --- a/src/floppy/fdd_pcjs.c +++ b/src/floppy/fdd_pcjs.c @@ -20,7 +20,11 @@ #include #include #include +#ifndef _MSC_VER #include +#else +#include +#endif #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/timer.h> @@ -465,7 +469,7 @@ track_flags(int drive) } static void -set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) +set_sector(int drive, int side, uint8_t c, UNUSED(uint8_t h), uint8_t r, UNUSED(uint8_t n)) { pcjs_t *dev = images[drive]; @@ -613,8 +617,7 @@ pcjs_load(int drive, char *fn) d86f_unregister(drive); /* Allocate a drive block */ - dev = (pcjs_t *) malloc(sizeof(pcjs_t)); - memset(dev, 0x00, sizeof(pcjs_t)); + dev = (pcjs_t *) calloc(1, sizeof(pcjs_t)); /* Open the image file, read-only */ dev->fp = plat_fopen(fn, "rb"); diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 0bf4b1c71..f5882158b 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -1214,8 +1214,7 @@ td0_load(int drive, char *fn) writeprot[drive] = 1; - dev = (td0_t *) malloc(sizeof(td0_t)); - memset(dev, 0x00, sizeof(td0_t)); + dev = (td0_t *) calloc(1, sizeof(td0_t)); td0[drive] = dev; dev->fp = plat_fopen(fn, "rb"); diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 83dcd4836..6b44a2236 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -9,9 +9,16 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(game OBJECT gameport.c joystick_standard.c - joystick_ch_flightstick_pro.c joystick_sw_pad.c joystick_tm_fcs.c) +add_library(game OBJECT + gameport.c + joystick_standard.c + joystick_ch_flightstick_pro.c + joystick_sw_pad.c + joystick_tm_fcs.c +) diff --git a/src/game/gameport.c b/src/game/gameport.c index 58d9a446f..90986a655 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -8,15 +8,15 @@ * * Implementation of a generic Game Port. * - * - * * Authors: Miran Grca, * Sarah Walker, * RichardG, + * Jasmine Iwanek, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2022 Miran Grca. * Copyright 2008-2018 Sarah Walker. * Copyright 2021 RichardG. + * Copyright 2021-2025 Jasmine Iwanek. */ #include #include @@ -33,6 +33,12 @@ #include <86box/gameport.h> #include <86box/plat_unused.h> +device_t game_ports[GAMEPORT_MAX]; + +typedef struct { + const device_t *device; +} GAMEPORT; + typedef struct g_axis_t { pc_timer_t timer; int axis_nr; @@ -46,6 +52,11 @@ typedef struct _gameport_ { struct _gameport_ *next; } gameport_t; +typedef struct _tmacm_ { + struct gameport_t *port1; + struct gameport_t *port2; +} tmacm_t; + typedef struct _joystick_instance_ { uint8_t state; g_axis_t axis[4]; @@ -77,21 +88,21 @@ static const joystick_if_t joystick_none = { static const struct { const joystick_if_t *joystick; } joysticks[] = { - { &joystick_none }, - { &joystick_2axis_2button }, - { &joystick_2axis_4button }, - { &joystick_2axis_6button }, - { &joystick_2axis_8button }, - { &joystick_3axis_2button }, - { &joystick_3axis_4button }, - { &joystick_4axis_4button }, + { &joystick_none }, + { &joystick_2axis_2button }, + { &joystick_2axis_4button }, + { &joystick_2axis_6button }, + { &joystick_2axis_8button }, + { &joystick_3axis_2button }, + { &joystick_3axis_4button }, + { &joystick_4axis_4button }, { &joystick_ch_flightstick_pro }, - { &joystick_sw_pad }, - { &joystick_tm_fcs }, - { NULL } + { &joystick_sw_pad }, + { &joystick_tm_fcs }, + { NULL } }; -static joystick_instance_t *joystick_instance = NULL; +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) */ @@ -273,10 +284,10 @@ gameport_update_joystick_type(void) gameport_add(standalone_gameport_type); /* Reset the joystick interface. */ - if (joystick_instance) { - joystick_instance->intf->close(joystick_instance->dat); - joystick_instance->intf = joysticks[joystick_type].joystick; - joystick_instance->dat = joystick_instance->intf->init(); + if (joystick_instance[0]) { + joystick_instance[0]->intf->close(joystick_instance[0]->dat); + joystick_instance[0]->intf = joysticks[joystick_type].joystick; + joystick_instance[0]->dat = joystick_instance[0]->intf->init(); } } @@ -355,36 +366,32 @@ gameport_add(const device_t *gameport_type) static void * gameport_init(const device_t *info) { - gameport_t *dev = NULL; - - dev = malloc(sizeof(gameport_t)); - memset(dev, 0x00, sizeof(gameport_t)); + gameport_t *dev = calloc(1, sizeof(gameport_t)); /* Allocate global instance. */ - if (!joystick_instance && joystick_type) { - joystick_instance = malloc(sizeof(joystick_instance_t)); - memset(joystick_instance, 0x00, sizeof(joystick_instance_t)); + if (!joystick_instance[0] && joystick_type) { + joystick_instance[0] = calloc(1, sizeof(joystick_instance_t)); - joystick_instance->axis[0].joystick = joystick_instance; - joystick_instance->axis[1].joystick = joystick_instance; - joystick_instance->axis[2].joystick = joystick_instance; - joystick_instance->axis[3].joystick = joystick_instance; + 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]; - joystick_instance->axis[0].axis_nr = 0; - joystick_instance->axis[1].axis_nr = 1; - joystick_instance->axis[2].axis_nr = 2; - joystick_instance->axis[3].axis_nr = 3; + 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; - timer_add(&joystick_instance->axis[0].timer, timer_over, &joystick_instance->axis[0], 0); - timer_add(&joystick_instance->axis[1].timer, timer_over, &joystick_instance->axis[1], 0); - timer_add(&joystick_instance->axis[2].timer, timer_over, &joystick_instance->axis[2], 0); - timer_add(&joystick_instance->axis[3].timer, timer_over, &joystick_instance->axis[3], 0); + 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); - joystick_instance->intf = joysticks[joystick_type].joystick; - joystick_instance->dat = joystick_instance->intf->init(); + joystick_instance[0]->intf = joysticks[joystick_type].joystick; + joystick_instance[0]->dat = joystick_instance[0]->intf->init(); } - dev->joystick = joystick_instance; + dev->joystick = joystick_instance[0]; /* Map game port to the default address. Not applicable on PnP-only ports. */ dev->len = (info->local >> 16) & 0xff; @@ -400,25 +407,24 @@ gameport_init(const device_t *info) static void * tmacm_init(UNUSED(const device_t *info)) { - uint16_t port = 0x0000; - gameport_t *dev = NULL; + uint16_t port = 0x0000; + tmacm_t *dev = NULL; - dev = malloc(sizeof(gameport_t)); - memset(dev, 0x00, sizeof(gameport_t)); + dev = calloc(1, sizeof(tmacm_t)); port = (uint16_t) device_get_config_hex16("port1_addr"); switch (port) { case 0x201: - dev = gameport_add(&gameport_201_device); + dev->port1 = gameport_add(&gameport_201_device); break; case 0x203: - dev = gameport_add(&gameport_203_device); + dev->port1 = gameport_add(&gameport_203_device); break; case 0x205: - dev = gameport_add(&gameport_205_device); + dev->port1 = gameport_add(&gameport_205_device); break; case 0x207: - dev = gameport_add(&gameport_207_device); + dev->port1 = gameport_add(&gameport_207_device); break; default: break; @@ -427,16 +433,16 @@ tmacm_init(UNUSED(const device_t *info)) port = (uint16_t) device_get_config_hex16("port2_addr"); switch (port) { case 0x209: - dev = gameport_add(&gameport_209_device); + dev->port2 = gameport_add(&gameport_209_device); break; case 0x20b: - dev = gameport_add(&gameport_20b_device); + dev->port2 = gameport_add(&gameport_20b_device); break; case 0x20d: - dev = gameport_add(&gameport_20d_device); + dev->port2 = gameport_add(&gameport_20d_device); break; case 0x20f: - dev = gameport_add(&gameport_20f_device); + dev->port2 = gameport_add(&gameport_20f_device); break; default: break; @@ -454,11 +460,11 @@ gameport_close(void *priv) gameport_remap(dev, 0); /* Free the global instance here, if it wasn't already freed. */ - if (joystick_instance) { - joystick_instance->intf->close(joystick_instance->dat); + if (joystick_instance[0]) { + joystick_instance[0]->intf->close(joystick_instance[0]->dat); - free(joystick_instance); - joystick_instance = NULL; + free(joystick_instance[0]); + joystick_instance[0] = NULL; } free(dev); @@ -468,11 +474,11 @@ const device_t gameport_device = { .name = "Game port", .internal_name = "gameport", .flags = 0, - .local = 0x080200, + .local = GAMEPORT_8ADDR | 0x0200, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -482,11 +488,11 @@ const device_t gameport_201_device = { .name = "Game port (Port 201h only)", .internal_name = "gameport_201", .flags = 0, - .local = 0x010201, + .local = GAMEPORT_1ADDR | 0x0201, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -496,11 +502,11 @@ const device_t gameport_203_device = { .name = "Game port (Port 203h only)", .internal_name = "gameport_203", .flags = 0, - .local = 0x010203, + .local = GAMEPORT_1ADDR | 0x0203, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -510,11 +516,11 @@ const device_t gameport_205_device = { .name = "Game port (Port 205h only)", .internal_name = "gameport_205", .flags = 0, - .local = 0x010205, + .local = GAMEPORT_1ADDR | 0x0205, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -524,11 +530,11 @@ const device_t gameport_207_device = { .name = "Game port (Port 207h only)", .internal_name = "gameport_207", .flags = 0, - .local = 0x010207, + .local = GAMEPORT_1ADDR | 0x0207, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -538,11 +544,11 @@ const device_t gameport_208_device = { .name = "Game port (Port 208h-20fh)", .internal_name = "gameport_208", .flags = 0, - .local = 0x080208, + .local = GAMEPORT_8ADDR | 0x0208, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -552,11 +558,11 @@ const device_t gameport_209_device = { .name = "Game port (Port 209h only)", .internal_name = "gameport_209", .flags = 0, - .local = 0x010209, + .local = GAMEPORT_1ADDR | 0x0209, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -566,11 +572,11 @@ const device_t gameport_20b_device = { .name = "Game port (Port 20Bh only)", .internal_name = "gameport_20b", .flags = 0, - .local = 0x01020B, + .local = GAMEPORT_1ADDR | 0x020B, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -580,11 +586,11 @@ const device_t gameport_20d_device = { .name = "Game port (Port 20Dh only)", .internal_name = "gameport_20d", .flags = 0, - .local = 0x01020D, + .local = GAMEPORT_1ADDR | 0x020D, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -594,11 +600,11 @@ const device_t gameport_20f_device = { .name = "Game port (Port 20Fh only)", .internal_name = "gameport_20f", .flags = 0, - .local = 0x01020F, + .local = GAMEPORT_1ADDR | 0x020F, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -607,40 +613,42 @@ const device_t gameport_20f_device = { static const device_config_t tmacm_config[] = { // clang-format off { - .name = "port1_addr", - .description = "Port 1 Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0201, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "port1_addr", + .description = "Port 1 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0201, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "201h", .value = 0x0201 }, { .description = "203h", .value = 0x0203 }, { .description = "205h", .value = 0x0205 }, { .description = "207h", .value = 0x0207 }, { .description = "Disabled", .value = 0x0000 }, - { "" } - } + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "port2_addr", - .description = "Port 2 Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0209, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "port2_addr", + .description = "Port 2 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0209, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "209h", .value = 0x0209 }, { .description = "20Bh", .value = 0x020B }, { .description = "20Dh", .value = 0x020D }, { .description = "20Fh", .value = 0x020F }, { .description = "Disabled", .value = 0x0000 }, - { "" } - } + { .description = "" } + }, + .bios = { { 0 } } }, - { "", "", -1 } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -652,7 +660,7 @@ const device_t gameport_tm_acm_device = { .init = tmacm_init, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = tmacm_config @@ -662,11 +670,25 @@ const device_t gameport_pnp_device = { .name = "Game port (Plug and Play only)", .internal_name = "gameport_pnp", .flags = 0, - .local = 0x080000, + .local = GAMEPORT_8ADDR, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t gameport_pnp_1io_device = { + .name = "Game port (Plug and Play only, 1 I/O port)", + .internal_name = "gameport_pnp_1io", + .flags = 0, + .local = GAMEPORT_1ADDR, + .init = gameport_init, + .close = gameport_close, + .reset = NULL, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -676,11 +698,11 @@ const device_t gameport_pnp_6io_device = { .name = "Game port (Plug and Play only, 6 I/O ports)", .internal_name = "gameport_pnp_6io", .flags = 0, - .local = 0x060000, + .local = GAMEPORT_6ADDR, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -690,11 +712,11 @@ const device_t gameport_sio_device = { .name = "Game port (Super I/O)", .internal_name = "gameport_sio", .flags = 0, - .local = 0x1080000, + .local = GAMEPORT_SIO | GAMEPORT_8ADDR, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -704,12 +726,72 @@ const device_t gameport_sio_1io_device = { .name = "Game port (Super I/O, 1 I/O port)", .internal_name = "gameport_sio", .flags = 0, - .local = 0x1010000, + .local = GAMEPORT_SIO | GAMEPORT_1ADDR, .init = gameport_init, .close = gameport_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; + +static const GAMEPORT gameports[] = { + { &device_none }, + { &device_internal }, + { &gameport_device }, + { &gameport_208_device }, + { &gameport_pnp_device }, + { &gameport_tm_acm_device }, + { NULL } + // clang-format on +}; + +/* UI */ +int +gameport_available(int port) +{ + if (gameports[port].device) + return (device_available(gameports[port].device)); + + return 1; +} + +/* UI */ +const device_t * +gameports_getdevice(int port) +{ + return (gameports[port].device); +} + +/* UI */ +int +gameport_has_config(int port) +{ + if (!gameports[port].device) + return 0; + + return (device_has_config(gameports[port].device) ? 1 : 0); +} + +/* UI */ +const char * +gameport_get_internal_name(int port) +{ + return device_get_internal_name(gameports[port].device); +} + +/* UI */ +int +gameport_get_from_internal_name(const char *str) +{ + int c = 0; + + while (gameports[c].device != NULL) { + if (!strcmp(gameports[c].device->internal_name, str)) + return c; + c++; + } + + return 0; +} diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 8ca51d531..6aaaa5dc5 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -62,23 +62,23 @@ ch_flightstick_pro_read(UNUSED(void *priv)) { uint8_t ret = 0xf0; - if (JOYSTICK_PRESENT(0)) { - if (joystick_state[0].button[0]) + if (JOYSTICK_PRESENT(0, 0)) { + if (joystick_state[0][0].button[0]) ret &= ~0x10; - if (joystick_state[0].button[1]) + if (joystick_state[0][0].button[1]) ret &= ~0x20; - if (joystick_state[0].button[2]) + if (joystick_state[0][0].button[2]) ret &= ~0x40; - if (joystick_state[0].button[3]) + if (joystick_state[0][0].button[3]) ret &= ~0x80; - if (joystick_state[0].pov[0] != -1) { - if (joystick_state[0].pov[0] > 315 || joystick_state[0].pov[0] < 45) + if (joystick_state[0][0].pov[0] != -1) { + if (joystick_state[0][0].pov[0] > 315 || joystick_state[0][0].pov[0] < 45) ret &= ~0xf0; - else if (joystick_state[0].pov[0] >= 45 && joystick_state[0].pov[0] < 135) + else if (joystick_state[0][0].pov[0] >= 45 && joystick_state[0][0].pov[0] < 135) ret &= ~0xb0; - else if (joystick_state[0].pov[0] >= 135 && joystick_state[0].pov[0] < 225) + else if (joystick_state[0][0].pov[0] >= 135 && joystick_state[0][0].pov[0] < 225) ret &= ~0x70; - else if (joystick_state[0].pov[0] >= 225 && joystick_state[0].pov[0] < 315) + else if (joystick_state[0][0].pov[0] >= 225 && joystick_state[0][0].pov[0] < 315) ret &= ~0x30; } } @@ -95,18 +95,18 @@ ch_flightstick_pro_write(UNUSED(void *priv)) static int ch_flightstick_pro_read_axis(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: return 0; case 3: - return joystick_state[0].axis[2]; + return joystick_state[0][0].axis[2]; default: return 0; } diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index 1d1568738..122d2c65f 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -62,17 +62,13 @@ joystick_standard_read(UNUSED(void *priv)) { uint8_t ret = 0xf0; - if (JOYSTICK_PRESENT(0)) { - if (joystick_state[0].button[0]) - ret &= ~0x10; - if (joystick_state[0].button[1]) - ret &= ~0x20; - } - if (JOYSTICK_PRESENT(1)) { - if (joystick_state[1].button[0]) - ret &= ~0x40; - if (joystick_state[1].button[1]) - ret &= ~0x80; + for (int js = 0; js < 2; js++) { + if (JOYSTICK_PRESENT(0, js)) { + if (joystick_state[0][js].button[0]) + ret &= ~0x10; + if (joystick_state[0][js].button[1]) + ret &= ~0x20; + } } return ret; @@ -83,14 +79,14 @@ joystick_standard_read_4button(UNUSED(void *priv)) { uint8_t ret = 0xf0; - if (JOYSTICK_PRESENT(0)) { - if (joystick_state[0].button[0]) + if (JOYSTICK_PRESENT(0, 0)) { + if (joystick_state[0][0].button[0]) ret &= ~0x10; - if (joystick_state[0].button[1]) + if (joystick_state[0][0].button[1]) ret &= ~0x20; - if (joystick_state[0].button[2]) + if (joystick_state[0][0].button[2]) ret &= ~0x40; - if (joystick_state[0].button[3]) + if (joystick_state[0][0].button[3]) ret &= ~0x80; } @@ -108,21 +104,21 @@ joystick_standard_read_axis(UNUSED(void *priv), int axis) { switch (axis) { case 0: - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: - if (!JOYSTICK_PRESENT(1)) + if (!JOYSTICK_PRESENT(0, 1)) return AXIS_NOT_PRESENT; - return joystick_state[1].axis[0]; + return joystick_state[0][1].axis[0]; case 3: - if (!JOYSTICK_PRESENT(1)) + if (!JOYSTICK_PRESENT(0, 1)) return AXIS_NOT_PRESENT; - return joystick_state[1].axis[1]; + return joystick_state[0][1].axis[1]; default: return 0; } @@ -131,18 +127,16 @@ joystick_standard_read_axis(UNUSED(void *priv), int axis) static int joystick_standard_read_axis_4button(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: - return 0; case 3: - return 0; default: return 0; } @@ -151,18 +145,17 @@ joystick_standard_read_axis_4button(UNUSED(void *priv), int axis) static int joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: - return joystick_state[0].axis[2]; + return joystick_state[0][0].axis[2]; case 3: - return 0; default: return 0; } @@ -171,18 +164,18 @@ joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis) static int joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: - return joystick_state[0].axis[2]; + return joystick_state[0][0].axis[2]; case 3: - return joystick_state[0].axis[3]; + return joystick_state[0][0].axis[3]; default: return 0; } @@ -191,18 +184,18 @@ joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis) static int joystick_standard_read_axis_6button(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: - return joystick_state[0].button[4] ? -32767 : 32768; + return joystick_state[0][0].button[4] ? -32767 : 32768; case 3: - return joystick_state[0].button[5] ? -32767 : 32768; + return joystick_state[0][0].button[5] ? -32767 : 32768; default: return 0; } @@ -210,24 +203,24 @@ joystick_standard_read_axis_6button(UNUSED(void *priv), int axis) static int joystick_standard_read_axis_8button(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: - if (joystick_state[0].button[4]) + if (joystick_state[0][0].button[4]) return -32767; - if (joystick_state[0].button[6]) + if (joystick_state[0][0].button[6]) return 32768; return 0; case 3: - if (joystick_state[0].button[5]) + if (joystick_state[0][0].button[5]) return -32767; - if (joystick_state[0].button[7]) + if (joystick_state[0][0].button[7]) return 32768; return 0; default: diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index cab008d0a..bfdc0e025 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -119,8 +119,7 @@ sw_parity(uint16_t data) static void * sw_init(void) { - sw_data *sw = (sw_data *) malloc(sizeof(sw_data)); - memset(sw, 0, sizeof(sw_data)); + sw_data *sw = (sw_data *) calloc(1, sizeof(sw_data)); timer_add(&sw->poll_timer, sw_timer_over, sw, 0); timer_add(&sw->trigger_timer, sw_trigger_timer_over, sw, 0); @@ -142,7 +141,7 @@ sw_read(void *priv) sw_data *sw = (sw_data *) priv; uint8_t temp = 0; - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return 0xff; if (timer_is_enabled(&sw->poll_timer)) { @@ -168,7 +167,7 @@ sw_write(void *priv) sw_data *sw = (sw_data *) priv; int64_t time_since_last = timer_get_remaining_us(&sw->trigger_timer); - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return; if (!sw->poll_left) { @@ -191,24 +190,24 @@ sw_write(void *priv) sw->poll_data = 1; } - for (uint8_t c = 0; c < 4; c++) { + for (uint8_t js = 0; js < 4; js++) { uint16_t data = 0x3fff; - if (!JOYSTICK_PRESENT(c)) + if (!JOYSTICK_PRESENT(0, js)) break; - if (joystick_state[c].axis[1] < -16383) + if (joystick_state[0][js].axis[1] < -16383) data &= ~1; - if (joystick_state[c].axis[1] > 16383) + if (joystick_state[0][js].axis[1] > 16383) data &= ~2; - if (joystick_state[c].axis[0] > 16383) + if (joystick_state[0][js].axis[0] > 16383) data &= ~4; - if (joystick_state[c].axis[0] < -16383) + if (joystick_state[0][js].axis[0] < -16383) data &= ~8; - for (uint8_t b = 0; b < 10; b++) { - if (joystick_state[c].button[b]) - data &= ~(1 << (b + 4)); + for (uint8_t button_nr = 0; button_nr < 10; button_nr++) { + if (joystick_state[0][js].button[button_nr]) + data &= ~(1 << (button_nr + 4)); } if (sw_parity(data)) @@ -216,10 +215,10 @@ sw_write(void *priv) if (sw->poll_mode) { sw->poll_left += 5; - sw->poll_data |= (data << (c * 15 + 3)); + sw->poll_data |= (data << (js * 15 + 3)); } else { sw->poll_left += 15; - sw->poll_data |= (data << (c * 15 + 1)); + sw->poll_data |= (data << (js * 15 + 1)); } } } @@ -231,7 +230,7 @@ sw_write(void *priv) static int sw_read_axis(UNUSED(void *priv), UNUSED(int axis)) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; return 0; /*No analogue support on Sidewinder game pad*/ diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index f5c1e64e6..4440b039e 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -62,14 +62,14 @@ tm_fcs_read(UNUSED(void *priv)) { uint8_t ret = 0xf0; - if (JOYSTICK_PRESENT(0)) { - if (joystick_state[0].button[0]) + if (JOYSTICK_PRESENT(0, 0)) { + if (joystick_state[0][0].button[0]) ret &= ~0x10; - if (joystick_state[0].button[1]) + if (joystick_state[0][0].button[1]) ret &= ~0x20; - if (joystick_state[0].button[2]) + if (joystick_state[0][0].button[2]) ret &= ~0x40; - if (joystick_state[0].button[3]) + if (joystick_state[0][0].button[3]) ret &= ~0x80; } @@ -85,26 +85,26 @@ tm_fcs_write(UNUSED(void *priv)) static int tm_fcs_read_axis(UNUSED(void *priv), int axis) { - if (!JOYSTICK_PRESENT(0)) + if (!JOYSTICK_PRESENT(0, 0)) return AXIS_NOT_PRESENT; switch (axis) { case 0: - return joystick_state[0].axis[0]; + return joystick_state[0][0].axis[0]; case 1: - return joystick_state[0].axis[1]; + return joystick_state[0][0].axis[1]; case 2: return 0; case 3: - if (joystick_state[0].pov[0] == -1) + if (joystick_state[0][0].pov[0] == -1) return 32767; - if (joystick_state[0].pov[0] > 315 || joystick_state[0].pov[0] < 45) + if (joystick_state[0][0].pov[0] > 315 || joystick_state[0][0].pov[0] < 45) return -32768; - if (joystick_state[0].pov[0] >= 45 && joystick_state[0].pov[0] < 135) + if (joystick_state[0][0].pov[0] >= 45 && joystick_state[0][0].pov[0] < 135) return -16384; - if (joystick_state[0].pov[0] >= 135 && joystick_state[0].pov[0] < 225) + if (joystick_state[0][0].pov[0] >= 135 && joystick_state[0][0].pov[0] < 225) return 0; - if (joystick_state[0].pov[0] >= 225 && joystick_state[0].pov[0] < 315) + if (joystick_state[0][0].pov[0] >= 225 && joystick_state[0][0].pov[0] < 315) return 16384; return 0; default: diff --git a/src/gdbstub.c b/src/gdbstub.c index 900f40dab..42e1fc46d 100644 --- a/src/gdbstub.c +++ b/src/gdbstub.c @@ -1513,6 +1513,7 @@ gdbstub_client_thread(void *priv) case '$': /* packet start */ /* Wait for any existing packets to be processed. */ thread_wait_event(client->processed_event, -1); + thread_set_event(client->processed_event); client->packet_pos = 0; break; @@ -1530,6 +1531,7 @@ gdbstub_client_thread(void *priv) case 0x03: /* break */ /* Wait for any existing packets to be processed. */ thread_wait_event(client->processed_event, -1); + thread_set_event(client->processed_event); /* Break immediately. */ gdbstub_log("GDB Stub: Break requested\n"); @@ -1539,6 +1541,7 @@ gdbstub_client_thread(void *priv) default: /* Wait for any existing packets to be processed, just in case. */ thread_wait_event(client->processed_event, -1); + thread_set_event(client->processed_event); if (client->packet_pos < (sizeof(client->packet) - 1)) { /* Append byte to the packet. */ diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index d21bba49c..e4e5ecae1 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -8,14 +8,14 @@ * * Main include file for the application. * - * - * * Authors: Miran Grca, * Fred N. van Kempen, + * Jasmine Iwanek, * * Copyright 2016-2020 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. * Copyright 2021 Laci bá' + * Copyright 2021-2025 Jasmine Iwanek. */ #ifndef EMU_86BOX_H #define EMU_86BOX_H @@ -33,7 +33,7 @@ #define SCREENSHOT_PATH "screenshots" /* Recently used images */ -#define MAX_PREV_IMAGES 4 +#define MAX_PREV_IMAGES 10 #define MAX_IMAGE_PATH_LEN 2048 /* Max UUID Length */ @@ -131,6 +131,7 @@ extern int bugger_enabled; /* (C) enable ISAbugger */ extern int novell_keycard_enabled; /* (C) enable Novell NetWare 2.x key card emulation. */ 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 isartc_type; /* (C) enable ISA RTC card */ extern int sound_is_float; /* (C) sound uses FP values */ @@ -154,6 +155,7 @@ extern int enable_discord; /* (C) enable Discord integration */ 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 hard_reset_pending; extern int fixed_size_x; extern int fixed_size_y; extern int do_auto_pause; /* (C) Auto-pause the emulator on focus loss */ @@ -165,6 +167,7 @@ extern _Atomic double mouse_y_error; /* Mouse error accumulator - Y */ #endif extern int pit_mode; /* (C) force setting PIT mode */ extern int fm_driver; /* (C) select FM sound driver */ +extern int hook_enabled; /* (C) Keyboard hook is enabled */ /* Keyboard variables for future key combination redefinition. */ extern uint16_t key_prefix_1_1; @@ -186,12 +189,17 @@ extern int config_changed; /* config has changed */ /* Function prototypes. */ #ifdef HAVE_STDARG_H -extern void pclog_ex(const char *fmt, va_list); -extern void fatal_ex(const char *fmt, va_list); +extern void pclog_ex(const char *fmt, va_list ap); +extern void fatal_ex(const char *fmt, va_list ap); #endif extern void pclog_toggle_suppr(void); +#ifdef _MSC_VER +extern void pclog(const char *fmt, ...); +extern void fatal(const char *fmt, ...); +#else extern void pclog(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern void fatal(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +#endif extern void set_screen_size(int x, int y); extern void set_screen_size_monitor(int x, int y, int monitor_index); extern void reset_screen_size(void); diff --git a/src/include/86box/access_bus.h b/src/include/86box/access_bus.h new file mode 100644 index 000000000..333a1d4a5 --- /dev/null +++ b/src/include/86box/access_bus.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. + * + * Definitions for the ACPI emulation. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2020-2025 Miran Grca. + */ +#ifndef ACCESS_BUS_H +#define ACCESS_BUS_H + +#define AB_RST 0x80 + +typedef struct access_bus_t { + uint8_t control; + uint8_t status; + uint8_t own_addr; + uint8_t data; + uint8_t clock; + uint8_t enable; + uint16_t base; +} access_bus_t; + +extern const device_t access_bus_device; + +/* Functions */ +extern void access_bus_handler(access_bus_t *dev, uint8_t enable, uint16_t base); + +#endif /*ACCESS_BUS_H*/ diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index 78183d137..37c846d59 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -35,6 +35,8 @@ * USA. */ +#ifndef __NetBSD__ + #ifndef BSWAP_H #define BSWAP_H @@ -131,12 +133,12 @@ bswap64s(uint64_t *s) return endian##_bswap(v, size); \ } \ \ - static __inline void endian##size##_to_cpus(type *p) \ + static __inline void endian##size##_to_cpus(UNUSED(type *p)) \ { \ endian##_bswaps(p, size) \ } \ \ - static __inline void cpu_to_##endian##size##s(type *p) \ + static __inline void cpu_to_##endian##size##s(UNUSED(type *p)) \ { \ endian##_bswaps(p, size) \ } \ @@ -239,3 +241,5 @@ cpu_to_be32wu(uint32_t *p, uint32_t v) #undef be_bswaps #endif /*BSWAP_H*/ + +#endif diff --git a/src/include/86box/cartridge.h b/src/include/86box/cartridge.h index 2fa0a9358..2b0662703 100644 --- a/src/include/86box/cartridge.h +++ b/src/include/86box/cartridge.h @@ -21,7 +21,10 @@ extern "C" { #endif +#define CART_IMAGE_HISTORY 10 + extern char cart_fns[2][512]; +extern char *cart_image_history[2][CART_IMAGE_HISTORY]; extern void cart_load(int drive, char *fn); extern void cart_close(int drive); diff --git a/src/include/86box/cassette.h b/src/include/86box/cassette.h index 3706ca632..168d82099 100644 --- a/src/include/86box/cassette.h +++ b/src/include/86box/cassette.h @@ -153,10 +153,13 @@ void pc_cas_print_state(const pc_cassette_t *cas); void pc_cas_clock(pc_cassette_t *cas, unsigned long cnt); void pc_cas_advance(pc_cassette_t *cas); +#define CASSETTE_IMAGE_HISTORY 10 + extern pc_cassette_t *cassette; extern char cassette_fname[512]; extern char cassette_mode[512]; +extern char * cassette_image_history[CASSETTE_IMAGE_HISTORY]; extern unsigned long cassette_pos; extern unsigned long cassette_srate; extern int cassette_enable; diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index b97693560..7c028d7d6 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -15,30 +15,40 @@ #ifndef EMU_CDROM_H #define EMU_CDROM_H +#ifndef EMU_VERSION_H +#include <86box/version.h> +#endif + #define CDROM_NUM 8 #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 -#define CD_STATUS_PAUSED 2 -#define CD_STATUS_PLAYING 3 -#define CD_STATUS_STOPPED 4 -#define CD_STATUS_PLAYING_COMPLETED 5 +#define CD_STATUS_DVD 2 +#define CD_STATUS_PAUSED 4 +#define CD_STATUS_PLAYING 5 +#define CD_STATUS_STOPPED 6 +#define CD_STATUS_PLAYING_COMPLETED 7 +#define CD_STATUS_HAS_AUDIO 4 +#define CD_STATUS_MASK 7 /* Medium changed flag. */ +#define CD_STATUS_TRANSITION 0x40 #define CD_STATUS_MEDIUM_CHANGED 0x80 +#define CD_TRACK_UNK_DATA 0x04 +#define CD_TRACK_NORMAL 0x00 #define CD_TRACK_AUDIO 0x08 +#define CD_TRACK_CDI 0x10 +#define CD_TRACK_XA 0x20 +#define CD_TRACK_MODE_MASK 0x30 #define CD_TRACK_MODE2 0x04 - -#define CD_READ_DATA 0 -#define CD_READ_AUDIO 1 -#define CD_READ_RAW 2 +#define CD_TRACK_MODE2_MASK 0x07 #define CD_TOC_NORMAL 0 #define CD_TOC_SESSION 1 #define CD_TOC_RAW 2 -#define CD_IMAGE_HISTORY 4 +#define CD_IMAGE_HISTORY 10 #define BUF_SIZE 32768 @@ -46,7 +56,34 @@ /* This is so that if/when this is changed to something else, changing this one define will be enough. */ -#define CDROM_EMPTY !dev->host_drive +#define CDROM_EMPTY !dev->host_drive + +#define DVD_LAYER_0_SECTORS 0x00210558ULL + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 + +#define FRAMES_TO_MSF(f, M, S, F) \ + { \ + uint64_t value = f; \ + *(F) = (value % CD_FPS) & 0xff; \ + value /= CD_FPS; \ + *(S) = (value % 60) & 0xff; \ + value /= 60; \ + *(M) = value & 0xff; \ + } +#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F)) + +typedef struct SMSF { + uint16_t min; + uint8_t sec; + uint8_t fr; +} TMSF; #ifdef __cplusplus extern "C" { @@ -60,115 +97,125 @@ enum { CDROM_BUS_USB = 8 }; -enum -{ - CDROM_TYPE_86BOX_100, - CDROM_TYPE_AZT_CDA46802I_115, - CDROM_TYPE_BTC_BCD36XH_U10, - CDROM_TYPE_GOLDSTAR_CRD_8160B_314, - CDROM_TYPE_HITACHI_CDR_8130_0020, - CDROM_TYPE_KENWOOD_UCR_421_208E, - CDROM_TYPE_MATSHITA_587_7S13, - CDROM_TYPE_MATSHITA_588_LS15, - CDROM_TYPE_MATSHITA_571_10e, - CDROM_TYPE_MATSHITA_572_10j, - CDROM_TYPE_MITSUMI_FX4820T_D02A, - CDROM_TYPE_NEC_260_100, - CDROM_TYPE_NEC_260_101, - CDROM_TYPE_NEC_273_420, - CDROM_TYPE_NEC_280_105, - CDROM_TYPE_NEC_280_308, - CDROM_TYPE_PHILIPS_PCA403CD_U31P, - CDROM_TYPE_SONY_CDU76_10i, - CDROM_TYPE_SONY_CDU311_30h, - CDROM_TYPE_TOSHIBA_5302TA_0305, - CDROM_TYPE_TOSHIBA_5702B_TA70, - CDROM_TYPE_CHINON_CDS431_H42, - CDROM_TYPE_DEC_RRD45_0436, - CDROM_TYPE_MATSHITA_501_10b, - CDROM_TYPE_NEC_25_10a, - CDROM_TYPE_NEC_38_103, - CDROM_TYPE_NEC_75_103, - CDROM_TYPE_NEC_77_106, - CDROM_TYPE_NEC_211_100, - CDROM_TYPE_NEC_464_105, - CDROM_TYPE_SONY_CDU541_10i, - CDROM_TYPE_SONY_CDU561_18k, - CDROM_TYPE_SONY_CDU76S_100, - CDROM_TYPE_PHILIPS_CDD2600_107, - CDROM_TYPE_PIONEER_DRM604X_2403, - CDROM_TYPE_PLEXTOR_PX32TS_103, - CDROM_TYPE_TEAC_CD50_100, - CDROM_TYPE_TEAC_R55S_10R, - CDROM_TYPE_TEXEL_DMXX24_100, - CDROM_TYPE_TOSHIBA_XM_3433, - CDROM_TYPE_TOSHIBA_XM3201B_3232, - CDROM_TYPE_TOSHIBA_XM3301TA_0272, - CDROM_TYPE_TOSHIBA_XM5701TA_3136, - CDROM_TYPE_TOSHIBA_SDM1401_1008, - CDROM_TYPES_NUM -}; - -#define KNOWN_CDROM_DRIVE_TYPES CDROM_TYPES_NUM #define BUS_TYPE_IDE CDROM_BUS_ATAPI #define BUS_TYPE_SCSI CDROM_BUS_SCSI #define BUS_TYPE_BOTH -2 #define BUS_TYPE_NONE -1 -static const struct -{ - const char vendor[9]; - const char model[17]; - const char revision[5]; - const char *name; - const char *internal_name; - const int bus_type; +#define CDV EMU_VERSION_EX + +static const struct cdrom_drive_types_s { + const char vendor[9]; + const char model[17]; + const char revision[5]; + 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 transfer_max[4]; } cdrom_drive_types[] = { - { "86BOX", "CD-ROM", "1.00", "86BOX CD-ROM 1.00", "86BOX_CD-ROM_1.00", BUS_TYPE_BOTH }, - { "AZT", "CDA46802I", "1.15", "AZT CDA46802I 1.15", "AZT_CDA46802I_1.15", BUS_TYPE_IDE }, - { "BTC", "CD-ROM BCD36XH", "U1.0", "BTC CD-ROM BCD36XH U1.0", "BTC_CD-ROM_BCD36XH_U1.0", BUS_TYPE_IDE }, - { "GOLDSTAR", "CRD-8160B", "3.14", "GOLDSTAR CRD-8160B 3.14", "GOLDSTAR_CRD-8160B_3.14", BUS_TYPE_IDE }, - { "HITACHI", "CDR-8130", "0020", "HITACHI CDR-8130 0020", "HITACHI_CDR-8130_0020", BUS_TYPE_IDE }, - { "KENWOOD", "CD-ROM UCR-421", "208E", "KENWOOD CD-ROM UCR-421 208E", "KENWOOD_CD-ROM_UCR-421_208E", BUS_TYPE_IDE }, - { "MATSHITA", "CD-ROM CR-587", "7S13", "MATSHITA CD-ROM CR-587 7S13", "MATSHITA_CD-ROM_CR-587_7S13", BUS_TYPE_IDE }, - { "MATSHITA", "CD-ROM CR-588", "LS15", "MATSHITA CD-ROM CR-588 LS15", "MATSHITA_CD-ROM_CR-588_LS15", BUS_TYPE_IDE }, - { "MATSHITA", "CR-571", "1.0e", "MATSHITA CR-571 1.0e", "MATSHITA_CR-571_1.0e", BUS_TYPE_IDE }, - { "MATSHITA", "CR-572", "1.0j", "MATSHITA CR-572 1.0j", "MATSHITA_CR-572_1.0j", BUS_TYPE_IDE }, - { "MITSUMI", "CRMC-FX4820T", "D02A", "MITSUMI CRMC-FX4820T D02A", "MITSUMI_CRMC-FX4820T_D02A", BUS_TYPE_IDE }, - { "NEC", "CD-ROM DRIVE:260", "1.00", "NEC CD-ROM DRIVE:260 1.00", "NEC_CD-ROM_DRIVE260_1.00", BUS_TYPE_IDE }, - { "NEC", "CD-ROM DRIVE:260", "1.01", "NEC CD-ROM DRIVE:260 1.01", "NEC_CD-ROM_DRIVE260_1.01", BUS_TYPE_IDE }, - { "NEC", "CD-ROM DRIVE:273", "4.20", "NEC CD-ROM DRIVE:273 4.20", "NEC_CD-ROM_DRIVE273_4.20", BUS_TYPE_IDE }, - { "NEC", "CD-ROM DRIVE:280", "1.05", "NEC CD-ROM DRIVE:280 1.05", "NEC_CD-ROM_DRIVE280_1.05", BUS_TYPE_IDE }, - { "NEC", "CD-ROM DRIVE:280", "3.08", "NEC CD-ROM DRIVE:280 3.08", "NEC_CD-ROM_DRIVE280_3.08", BUS_TYPE_IDE }, - { "PHILIPS", "CD-ROM PCA403CD", "U31P", "PHILIPS CD-ROM PCA403CD U31P", "PHILIPS_CD-ROM_PCA403CD_U31P", BUS_TYPE_IDE }, - { "SONY", "CD-ROM CDU76", "1.0i", "SONY CD-ROM CDU76 1.0i", "SONY_CD-ROM_CDU76_1.0i", BUS_TYPE_IDE }, - { "SONY", "CD-ROM CDU311", "3.0h", "SONY CD-ROM CDU311 3.0h", "SONY_CD-ROM_CDU311_3.0h", BUS_TYPE_IDE }, - { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "TOSHIBA CD-ROM XM-5302TA 0305", "TOSHIBA_CD-ROM_XM-5302TA_0305", BUS_TYPE_IDE }, - { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "TOSHIBA CD-ROM XM-5702B TA70", "TOSHIBA_CD-ROM_XM-5702B_TA70", BUS_TYPE_IDE }, - { "CHINON", "CD-ROM CDS-431", "H42 ", "CHINON CD-ROM CDS-431 H42", "CHINON_CD-ROM_CDS-431_H42", BUS_TYPE_SCSI }, - { "DEC", "RRD45 (C) DEC", "0436", "DEC RRD45 0436", "DEC_RRD45_0436", BUS_TYPE_SCSI }, - { "MATSHITA", "CD-ROM CR-501", "1.0b", "MATSHITA CD-ROM CR-501 1.0b", "MATSHITA_CD-ROM_CR-501_1.0b", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:25", "1.0a", "NEC CD-ROM DRIVE:25 1.0a", "NEC_CD-ROM_DRIVE25_1.0a", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:38", "1.00", "NEC CD-ROM DRIVE:38 1.00", "NEC_CD-ROM_DRIVE38_1.00", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:75", "1.03", "NEC CD-ROM DRIVE:75 1.03", "NEC_CD-ROM_DRIVE75_1.03", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:77", "1.06", "NEC CD-ROM DRIVE:77 1.06", "NEC_CD-ROM_DRIVE77_1.06", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:211", "1.00", "NEC CD-ROM DRIVE:211 1.00", "NEC_CD-ROM_DRIVE211_1.00", BUS_TYPE_SCSI }, - { "NEC", "CD-ROM DRIVE:464", "1.05", "NEC CD-ROM DRIVE:464 1.05", "NEC_CD-ROM_DRIVE464_1.05", BUS_TYPE_SCSI }, - { "SONY", "CD-ROM CDU-541", "1.0i", "SONY CD-ROM CDU-541 1.0i", "SONY_CD-ROM_CDU-541_1.0i", BUS_TYPE_SCSI }, - { "SONY", "CD-ROM CDU-561", "1.8k", "SONY CD-ROM CDU-561 1.8k", "SONY_CD-ROM_CDU-561_1.8k", BUS_TYPE_SCSI }, - { "SONY", "CD-ROM CDU-76S", "1.00", "SONY CD-ROM CDU-76S 1.00", "SONY_CD-ROM_CDU-76S_1.00", BUS_TYPE_SCSI }, - { "PHILIPS", "CDD2600", "1.07", "PHILIPS CDD2600 1.07", "PHILIPS_CDD2600_1.07", BUS_TYPE_SCSI }, - { "PIONEER", "CD-ROM DRM-604X", "2403", "PIONEER CD-ROM DRM-604X 2403", "PIONEER_CD-ROM_DRM-604X_2403", BUS_TYPE_SCSI }, - { "PLEXTOR", "CD-ROM PX-32TS", "1.03", "PLEXTOR CD-ROM PX-32TS 1.03", "PLEXTOR_CD-ROM_PX-32TS_1.03", BUS_TYPE_SCSI }, - { "TEAC", "CD 50", "1.00", "TEAC CD 50 1.00", "TEAC_CD_50_1.00", BUS_TYPE_SCSI }, - { "TEAC", "CD-ROM R55S", "1.0R", "TEAC CD-ROM R55S 1.0R", "TEAC_CD-ROM_R55S_1.0R", BUS_TYPE_SCSI }, - { "TEXEL", "CD-ROM DM-XX24", "1.00", "TEXEL CD-ROM DM-XX24 1.00", "TEXEL_CD-ROM_DM-XX24_1.00", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM DRIVE:XM", "3433", "TOSHIBA CD-ROM DRIVE:XM 3433", "TOSHIBA_CD-ROM_DRIVEXM_3433", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM XM-3201B", "3232", "TOSHIBA CD-ROM XM-3201B 3232", "TOSHIBA_CD-ROM_XM-3201B_3232", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM XM-3301TA", "0272", "TOSHIBA CD-ROM XM-3301TA 0272", "TOSHIBA_CD-ROM_XM-3301TA_0272", BUS_TYPE_SCSI }, - { "TOSHIBA", "CD-ROM XM-5701TA", "3136", "TOSHIBA CD-ROM XM-5701TA 3136", "TOSHIBA_CD-ROM_XM-5701TA_3136", BUS_TYPE_SCSI }, - { "TOSHIBA", "DVD-ROM SD-M1401", "1008", "TOSHIBA DVD-ROM SD-M1401 1008", "TOSHIBA_DVD-ROM_SD-M1401_1008", BUS_TYPE_SCSI }, - { "", "", "", "", "", BUS_TYPE_NONE }, + { EMU_NAME, "86B_CD", CDV, "86cd", BUS_TYPE_BOTH, 2, -1, 36, 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 } }, + /* 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 } }, + /* 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 } }, + /* + 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* 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 } }, + /* + 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. */ + /* + 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 } } }; /* To shut up the GCC compilers. */ @@ -194,129 +241,201 @@ typedef struct track_info_t { uint8_t f; } track_info_t; +typedef struct raw_track_info_t { + uint8_t session; + uint8_t adr_ctl; + uint8_t tno; + uint8_t point; + uint8_t m; + uint8_t s; + uint8_t f; + uint8_t zero; + uint8_t pm; + uint8_t ps; + uint8_t pf; +} raw_track_info_t; + /* Define the various CD-ROM drive operations (ops). */ typedef struct cdrom_ops_t { - void (*get_tracks)(struct cdrom *dev, int *first, int *last); - void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti); - void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); - int (*is_track_pre)(struct cdrom *dev, uint32_t lba); - int (*sector_size)(struct cdrom *dev, uint32_t lba); - int (*read_sector)(struct cdrom *dev, int type, uint8_t *b, uint32_t lba); - int (*track_type)(struct cdrom *dev, uint32_t lba); - int (*ext_medium_changed)(struct cdrom *dev); - void (*exit)(struct cdrom *dev); + int (*get_track_info)(const void *local, const uint32_t track, + const int end, track_info_t *ti); + void (*get_raw_track_info)(const void *local, int *num, + uint8_t *rti); + int (*is_track_pre)(const void *local, const uint32_t sector); + int (*read_sector)(const void *local, uint8_t *buffer, + const uint32_t sector); + uint8_t (*get_track_type)(const void *local, const uint32_t sector); + uint32_t (*get_last_block)(const void *local); + int (*read_dvd_structure)(const void *local, const uint8_t layer, + const uint8_t format, uint8_t *buffer, + uint32_t *info); + int (*is_dvd)(const void *local); + int (*has_audio)(const void *local); + int (*is_empty)(const void *local); + void (*close)(void *local); + void (*load)(const void *local); } cdrom_ops_t; typedef struct cdrom { - uint8_t id; + uint8_t id; union { - uint8_t res; - uint8_t res0; /* Reserved for other ID's. */ - uint8_t res1; - uint8_t ide_channel; - uint8_t scsi_device_id; + uint8_t res; + uint8_t res0; /* Reserved for other ID's. */ + uint8_t res1; + uint8_t ide_channel; + uint8_t scsi_device_id; }; - uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ - uint8_t bus_mode; /* Bit 0 = PIO suported; - Bit 1 = DMA supportd. */ - uint8_t cd_status; /* Struct variable reserved for - media status. */ - uint8_t speed; - uint8_t cur_speed; + uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + uint8_t cd_status; /* Struct variable reserved for + media status. */ + uint8_t speed; + uint8_t cur_speed; - void *priv; + void * priv; - char image_path[1024]; - char prev_image_path[1024]; + char image_path[1024]; + char prev_image_path[1024]; - char *image_history[CD_IMAGE_HISTORY]; + char * image_history[CD_IMAGE_HISTORY]; - uint32_t sound_on; - uint32_t cdrom_capacity; - uint32_t seek_pos; - uint32_t seek_diff; - uint32_t cd_end; - uint32_t type; + uint32_t sound_on; + uint32_t cdrom_capacity; + uint32_t seek_pos; + uint32_t seek_diff; + uint32_t cd_end; + uint32_t type; + uint32_t sector_size; - int cd_buflen; - int audio_op; - int audio_muted_soft; - int sony_msf; + int cd_buflen; + int audio_op; + int audio_muted_soft; + int sony_msf; + int real_speed; + int is_early; + int is_nec; + + uint32_t inv_field; const cdrom_ops_t *ops; - void *image; + void * local; + void * log; - void (*insert)(void *priv); - void (*close)(void *priv); - uint32_t (*get_volume)(void *p, int channel); - uint32_t (*get_channel)(void *p, int channel); + void (*insert)(void *priv); + void (*close)(void *priv); + uint32_t (*get_volume)(void *p, int channel); + uint32_t (*get_channel)(void *p, int channel); - int16_t cd_buffer[BUF_SIZE]; + int16_t cd_buffer[BUF_SIZE]; + + uint8_t subch_buffer[96]; + + int cdrom_sector_size; + + /* Needs some extra breathing space in case of overflows. */ + uint8_t raw_buffer[4096]; + uint8_t extra_buffer[296]; } cdrom_t; extern cdrom_t cdrom[CDROM_NUM]; -extern char *cdrom_getname(int type); +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -extern char *cdrom_get_internal_name(int type); -extern int cdrom_get_from_internal_name(char *s); -extern void cdrom_set_type(int model, int type); -extern int cdrom_get_type(int model); +static __inline int +bin2bcd(int x) +{ + return (x % 10) | ((x / 10) << 4); +} -extern int cdrom_lba_to_msf_accurate(int lba); -extern double cdrom_seek_time(cdrom_t *dev); -extern void cdrom_stop(cdrom_t *dev); -extern int cdrom_is_pre(cdrom_t *dev, uint32_t lba); -extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len); -extern uint8_t cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf); -extern uint8_t cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit); -extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit); -extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos); -extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type); -extern void cdrom_audio_pause_resume(cdrom_t *dev, uint8_t resume); -extern uint8_t cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type); -extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b); -extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf); -extern uint8_t cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf); -extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf); -extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b); -extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); -extern int cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, - unsigned char start_track, int msf, int max_len); -extern int cdrom_read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf, int max_len); -extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf); -extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode); -extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len); -extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, - int cdrom_sector_type, int cdrom_sector_flags, int *len, uint8_t vendor_type); -extern uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type); +static __inline int +bcd2bin(int x) +{ + return (x >> 4) * 10 + (x & 0x0f); +} -extern void cdrom_seek(cdrom_t *dev, uint32_t pos, uint8_t vendor_type); +extern char *cdrom_get_vendor(const int type); +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_generic(const int type); +extern int cdrom_has_date(const int type); +extern int cdrom_is_sony(const int type); +extern int cdrom_is_caddy(const int type); +extern int cdrom_get_speed(const int type); +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_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); +extern int cdrom_get_from_internal_name(const char *s); +/* TODO: Configuration migration, remove when no longer needed. */ +extern int cdrom_get_from_name(const char *s); +extern void cdrom_set_type(const int model, const int type); +extern int cdrom_get_type(const int model); -extern void cdrom_close_handler(uint8_t id); -extern void cdrom_insert(uint8_t id); -extern void cdrom_eject(uint8_t id); -extern void cdrom_reload(uint8_t id); +extern int cdrom_lba_to_msf_accurate(const int lba); +extern double cdrom_seek_time(const cdrom_t *dev); +extern void cdrom_stop(cdrom_t *dev); +extern void cdrom_seek(cdrom_t *dev, const uint32_t pos, const uint8_t vendor_type); +extern int cdrom_is_pre(const cdrom_t *dev, const uint32_t lba); -extern int cdrom_image_open(cdrom_t *dev, const char *fn); -extern void cdrom_image_close(cdrom_t *dev); +extern int cdrom_audio_callback(cdrom_t *dev, int16_t *output, const int len); +extern uint8_t cdrom_audio_play(cdrom_t *dev, const uint32_t pos, const uint32_t len, const int ismsf); +extern uint8_t cdrom_audio_track_search(cdrom_t *dev, const uint32_t pos, + const int type, const uint8_t playbit); +extern uint8_t cdrom_audio_track_search_pioneer(cdrom_t *dev, const uint32_t pos, const uint8_t playbit); +extern uint8_t cdrom_audio_play_pioneer(cdrom_t *dev, const uint32_t pos); +extern uint8_t cdrom_audio_play_toshiba(cdrom_t *dev, const uint32_t pos, const int type); +extern uint8_t cdrom_audio_scan(cdrom_t *dev, const uint32_t pos, const int type); +extern void cdrom_audio_pause_resume(cdrom_t *dev, const uint8_t resume); -extern int cdrom_ioctl_open(cdrom_t *dev, const char *drv); -extern void cdrom_ioctl_close(cdrom_t *dev); +extern uint8_t cdrom_get_current_status(const cdrom_t *dev); +extern void cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, const int msf); +extern void cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, const int msf); +extern uint8_t cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b); +extern uint8_t cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, const int msf); +extern void cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b); +extern uint8_t cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b); +extern int cdrom_read_toc(const cdrom_t *dev, uint8_t *b, const int type, + const uint8_t start_track, const int msf, const int max_len); +extern int cdrom_read_toc_sony(const cdrom_t *dev, uint8_t *b, const uint8_t start_track, + const int msf, const int max_len); +#ifdef USE_CDROM_MITSUMI +extern void cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf); +extern void cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode); +extern uint8_t cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len); +#endif +extern uint8_t cdrom_read_disc_info_toc(cdrom_t *dev, uint8_t *b, + const uint8_t track, const int type); +extern int cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int ismsf, + int cdrom_sector_type, const int cdrom_sector_flags, + int *len, const uint8_t vendor_type); +extern int cdrom_read_dvd_structure(const cdrom_t *dev, const uint8_t layer, const uint8_t format, + uint8_t *buffer, uint32_t *info); +extern void cdrom_read_disc_information(const cdrom_t *dev, uint8_t *buffer); +extern int cdrom_read_track_information(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer); +extern void cdrom_set_empty(cdrom_t *dev); +extern void cdrom_update_status(cdrom_t *dev); +extern int cdrom_load(cdrom_t *dev, const char *fn, const int skip_insert); -extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, - int number_of_blocks); - -extern int find_cdrom_for_scsi_id(uint8_t scsi_id); - -extern void cdrom_close(void); -extern void cdrom_global_init(void); -extern void cdrom_global_reset(void); -extern void cdrom_hard_reset(void); -extern void scsi_cdrom_drive_reset(int c); +extern void cdrom_global_init(void); +extern void cdrom_hard_reset(void); +extern void cdrom_close(void); +extern void cdrom_insert(const uint8_t id); +extern void cdrom_exit(const uint8_t id); +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); #ifdef __cplusplus } diff --git a/src/include/86box/cdrom_image.h b/src/include/86box/cdrom_image.h index c848af50d..84dd66f37 100644 --- a/src/include/86box/cdrom_image.h +++ b/src/include/86box/cdrom_image.h @@ -6,35 +6,33 @@ * * This file is part of the 86Box distribution. * - * CD-ROM image file handling module header, translated to C - * from cdrom_dosbox.h. + * CD-ROM image file handling module header. * - * Authors: RichardG, - * Miran Grca, + * Authors: Miran Grca, + * RichardG, + * Cacodemon345 * - * Copyright 2016-2022 RichardG. - * Copyright 2016-2022 Miran Grca. + * Copyright 2016-2025 Miran Grca. + * Copyright 2016-2025 RichardG. + * Copyright 2024-2025 Cacodemon345. */ #ifndef CDROM_IMAGE_H #define CDROM_IMAGE_H -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ +/* Track file struct. */ +typedef struct track_file_t { + int (*read)(void *priv, uint8_t *buffer, uint64_t seek, size_t count); + uint64_t (*get_length)(void *priv); + void (*close)(void *priv); -#ifdef __cplusplus -extern "C" { -#endif + char fn[260]; + FILE *fp; + void *priv; + void *log; -extern int image_open(uint8_t id, wchar_t *fn); -extern void image_reset(uint8_t id); + int motorola; +} track_file_t; -extern void image_close(uint8_t id); - -void update_status_bar_icon_state(int tag, int state); -extern void cdrom_set_null_handler(uint8_t id); - -#ifdef __cplusplus -} -#endif +extern void * image_open(cdrom_t *dev, const char *path); #endif /*CDROM_IMAGE_H*/ diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h deleted file mode 100644 index cf4fe95c3..000000000 --- a/src/include/86box/cdrom_image_backend.h +++ /dev/null @@ -1,107 +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. - * - * CD-ROM image file handling module header , translated to C - * from cdrom_dosbox.h. - * - * Authors: Miran Grca, - * Fred N. van Kempen, - * The DOSBox Team, - * - * Copyright 2016-2020 Miran Grca. - * Copyright 2017-2020 Fred N. van Kempen. - * Copyright 2002-2020 The DOSBox Team. - */ -#ifndef CDROM_IMAGE_BACKEND_H -#define CDROM_IMAGE_BACKEND_H - -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 - -#define DATA_TRACK 0x14 -#define AUDIO_TRACK 0x10 - -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M, S, F) \ - { \ - uint64_t value = f; \ - *(F) = (value % CD_FPS) & 0xff; \ - value /= CD_FPS; \ - *(S) = (value % 60) & 0xff; \ - value /= 60; \ - *(M) = value & 0xff; \ - } -#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F)) - -typedef struct SMSF { - uint16_t min; - uint8_t sec; - uint8_t fr; -} TMSF; - -/* Track file struct. */ -typedef struct track_file_t { - int (*read)(void *priv, uint8_t *buffer, uint64_t seek, size_t count); - uint64_t (*get_length)(void *priv); - void (*close)(void *priv); - - char fn[260]; - FILE *fp; - void *priv; - - int motorola; -} track_file_t; - -typedef struct track_t { - int number; - int track_number; - int attr; - int sector_size; - int mode2; - int form; - int pre; - int noskip; /* Do not skip by 8 bytes.*/ - uint64_t start; - uint64_t length; - uint64_t skip; - track_file_t *file; -} track_t; - -typedef struct cd_img_t { - int tracks_num; - track_t *tracks; -} cd_img_t; - -/* Binary file functions. */ -extern void cdi_close(cd_img_t *cdi); -extern int cdi_set_device(cd_img_t *cdi, const char *path); -extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out); -extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out); -extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track); -extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num, TMSF *start, uint8_t *attr); -extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num, uint32_t *start, uint8_t *attr); -extern int cdi_get_track(cd_img_t *cdi, uint32_t sector); -extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); -extern int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector); -extern int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num); -extern int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector); -extern int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector); -extern int cdi_is_mode2(cd_img_t *cdi, uint32_t sector); -extern int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector); -extern int cdi_load_iso(cd_img_t *cdi, const char *filename); -extern int cdi_load_cue(cd_img_t *cdi, const char *cuefile); -extern int cdi_has_data_track(cd_img_t *cdi); -extern int cdi_has_audio_track(cd_img_t *cdi); - -/* Virtual ISO functions. */ -extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count); -extern uint64_t viso_get_length(void *priv); -extern void viso_close(void *priv); -extern track_file_t *viso_init(const char *dirname, int *error); - -#endif /*CDROM_IMAGE_BACKEND_H*/ diff --git a/src/include/86box/cdrom_image_viso.h b/src/include/86box/cdrom_image_viso.h new file mode 100644 index 000000000..19f0e1de0 --- /dev/null +++ b/src/include/86box/cdrom_image_viso.h @@ -0,0 +1,26 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CD-ROM image file handling module header. + * + * Authors: RichardG, + * Miran Grca, + * + * Copyright 2016-2025 RichardG. + * Copyright 2016-2025 Miran Grca. + */ +#ifndef CDROM_IMAGE_VISO_H +#define CDROM_IMAGE_VISO_H + +/* Virtual ISO functions. */ +extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count); +extern uint64_t viso_get_length(void *priv); +extern void viso_close(void *priv); +extern track_file_t *viso_init(const uint8_t id, const char *dirname, int *error); + +#endif /*CDROM_IMAGE_VISO_H*/ diff --git a/src/include/86box/cdrom_interface.h b/src/include/86box/cdrom_interface.h index 081f758f6..ba4d0581b 100644 --- a/src/include/86box/cdrom_interface.h +++ b/src/include/86box/cdrom_interface.h @@ -21,11 +21,13 @@ extern int cdrom_interface_current; extern void cdrom_interface_reset(void); -extern const char *cdrom_interface_get_internal_name(int cdinterface); -extern int cdrom_interface_get_from_internal_name(char *s); -extern int cdrom_interface_has_config(int cdinterface); -extern const device_t *cdrom_interface_get_device(int cdinterface); -extern int cdrom_interface_get_flags(int cdinterface); -extern int cdrom_interface_available(int cdinterface); +const char *cdrom_interface_get_internal_name(const int cdinterface); +extern int cdrom_interface_get_from_internal_name(const char *s); +#ifdef EMU_DEVICE_H +extern const device_t *cdrom_interface_get_device(const int cdinterface); +#endif +extern int cdrom_interface_has_config(const int cdinterface); +extern int cdrom_interface_get_flags(const int cdinterface); +extern int cdrom_interface_available(const int cdinterface); #endif /*EMU_CDROM_INTERFACE_H*/ diff --git a/src/include/86box/cdrom_ioctl.h b/src/include/86box/cdrom_ioctl.h deleted file mode 100644 index 5fc157615..000000000 --- a/src/include/86box/cdrom_ioctl.h +++ /dev/null @@ -1,32 +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. - * - * CD-ROM image file handling module header, translated to C - * from cdrom_dosbox.h. - * - * Authors: RichardG, - * Miran Grca, - * - * Copyright 2016-2022 RichardG. - * Copyright 2016-2022 Miran Grca. - */ -#ifndef CDROM_IOCTL_H -#define CDROM_IOCTL_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /*CDROM_IOCTL_H*/ diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 90647da9a..e47bb489f 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -195,7 +195,7 @@ 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; -#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +#ifdef USE_OLIVETTI extern const device_t olivetti_eva_device; -#endif +#endif /* USE_OLIVETTI */ #endif /*EMU_CHIPSET_H*/ diff --git a/src/include/86box/config.h b/src/include/86box/config.h index a043fb22a..693f38ab7 100644 --- a/src/include/86box/config.h +++ b/src/include/86box/config.h @@ -8,16 +8,16 @@ * * Configuration file handler header. * - * - * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * Overdoze, + * Jasmine Iwanek, * * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. * Copyright 2017 Fred N. van Kempen. + * Copyright 2021-2025 Jasmine Iwanek. */ #ifndef EMU_CONFIG_H #define EMU_CONFIG_H @@ -111,6 +111,7 @@ typedef struct config_t { # ifdef USE_SERIAL_DEVICES char serial_devices[SERIAL_MAX][32]; /* Serial device names */ # endif + char gameport_devices[GAMEPORT_MAX][32]; /* gameport device names */ /* Other peripherals category */ int fdc_current[FDC_MAX]; /* Floppy disk controller type */ diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 67a30b1c8..1c3ef1ef3 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -18,7 +18,7 @@ * Copyright 2016-2019 Miran Grca. * Copyright 2008-2019 Sarah Walker. * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. + * 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 @@ -79,29 +79,33 @@ // #define CONFIG_STANDALONE 257 /* not available on the on-board variant */ enum { - DEVICE_PCJR = 2, /* requires an IBM PCjr */ - DEVICE_XTKBC = 4, /* requires an XT-compatible keyboard controller */ - DEVICE_AT = 8, /* requires an AT-compatible system */ - DEVICE_ATKBC = 0x10, /* requires an AT-compatible keyboard controller */ - DEVICE_PS2 = 0x20, /* requires a PS/1 or PS/2 system */ - DEVICE_ISA = 0x40, /* requires the ISA bus */ - DEVICE_CBUS = 0x80, /* requires the C-BUS bus */ - DEVICE_PCMCIA = 0x100, /* requires the PCMCIA bus */ - DEVICE_MCA = 0x200, /* requires the MCA bus */ - DEVICE_HIL = 0x400, /* requires the HP HIL bus */ - DEVICE_EISA = 0x800, /* requires the EISA bus */ - DEVICE_AT32 = 0x1000, /* requires the Mylex AT/32 local bus */ - DEVICE_OLB = 0x2000, /* requires the OPTi local bus */ - DEVICE_VLB = 0x4000, /* requires the VLB bus */ - DEVICE_PCI = 0x8000, /* requires the PCI bus */ - DEVICE_CARDBUS = 0x10000, /* requires the CardBus bus */ - DEVICE_USB = 0x20000, /* requires the USB bus */ - DEVICE_AGP = 0x40000, /* requires the AGP bus */ - DEVICE_AC97 = 0x80000, /* requires the AC'97 bus */ - DEVICE_COM = 0x100000, /* requires a serial port */ - DEVICE_LPT = 0x200000, /* requires a parallel port */ - DEVICE_KBC = 0x400000, /* is a keyboard controller */ - DEVICE_SOFTRESET = 0x800000, /* requires to be reset on soft reset */ + DEVICE_SIDECAR = 2, /* requires an IBM PCjr */ + DEVICE_ISA = 4, /* requires the ISA bus */ + DEVICE_XT_KBC = 8, /* requires an XT-compatible keyboard controller */ + DEVICE_CBUS = 0x10, /* requires the C-BUS bus */ + DEVICE_ISA16 = 0x20, /* requires an AT-compatible system */ + DEVICE_AT_KBC = 0x40, /* requires an AT-compatible keyboard controller */ + DEVICE_MCA = 0x80, /* requires the MCA bus */ + DEVICE_MCA32 = 0x100, /* requires the MCA bus */ + DEVICE_PS2_KBC = 0x200, /* requires a PS/1 or PS/2 system */ + DEVICE_PCMCIA = 0x400, /* requires the PCMCIA bus */ + DEVICE_HIL = 0x800, /* requires the HP HIL bus */ + DEVICE_EISA = 0x1000, /* requires the EISA bus */ + DEVICE_AT32 = 0x2000, /* requires the Mylex AT/32 local bus */ + DEVICE_OLB = 0x4000, /* requires the OPTi local bus */ + DEVICE_VLB = 0x8000, /* requires the VLB bus */ + DEVICE_PCI = 0x10000, /* requires the PCI bus */ + DEVICE_CARDBUS = 0x20000, /* requires the CardBus bus */ + DEVICE_USB = 0x40000, /* requires the USB bus */ + DEVICE_AGP = 0x80000, /* requires the AGP bus */ + DEVICE_AC97 = 0x100000, /* requires the AC'97 bus */ + DEVICE_BUS = 0x1fffff, /* requires a machine bus */ + + DEVICE_COM = 0x200000, /* requires a serial port */ + DEVICE_LPT = 0x400000, /* requires a parallel port */ + + DEVICE_KBC = 0x800000, /* is a keyboard controller */ + DEVICE_SOFTRESET = 0x1000000, /* requires to be reset on soft reset */ DEVICE_ONBOARD = 0x40000000, /* is on-board */ DEVICE_PIT = 0x80000000, /* device is a PIT */ @@ -118,16 +122,6 @@ enum { #define BIOS_INTERLEAVED_INVERT 8 #define BIOS_HIGH_BIT_INVERT 16 -#define device_common_config_t \ - const char *name; \ - const char *description; \ - int type; \ - const char *default_string; \ - int default_int; \ - const char *file_filter; \ - const device_config_spinner_t spinner; \ - const device_config_selection_t selection[32] - typedef struct device_config_selection_t { const char *description; int value; @@ -139,10 +133,6 @@ typedef struct device_config_spinner_t { int16_t step; } device_config_spinner_t; -typedef struct _device_dep_config_ { - device_common_config_t; -} device_dep_config_t; - typedef struct device_config_bios_t { const char *name; const char *internal_name; @@ -153,15 +143,18 @@ typedef struct device_config_bios_t { void *dev1; void *dev2; const char *files[9]; - /* Configuration options that depend on the device variant. - To prevent excessive nesting, there is no CONFIG_BIOS - option a dep_config struct */ - const device_dep_config_t *dep_config; } device_config_bios_t; typedef struct _device_config_ { - device_common_config_t; - const device_config_bios_t bios[32]; + const char *name; + const char *description; + int type; + const char *default_string; + int default_int; + const char *file_filter; + const device_config_spinner_t spinner; + const device_config_selection_t selection[32]; + const device_config_bios_t bios[32]; } device_config_t; typedef struct _device_ { @@ -176,10 +169,7 @@ typedef struct _device_ { }; void (*close)(void *priv); void (*reset)(void *priv); - union { - int (*available)(void); - int (*poll)(void *priv); - }; + int (*available)(void); void (*speed_changed)(void *priv); void (*force_redraw)(void *priv); @@ -197,12 +187,12 @@ extern "C" { #endif extern void device_init(void); -extern void device_set_context(device_context_t *c, const device_t *dev, int inst); +extern void device_set_context(device_context_t *ctx, const device_t *dev, int inst); extern void device_context(const device_t *dev); extern void device_context_inst(const device_t *dev, int inst); extern void device_context_restore(void); -extern void *device_add(const device_t *d); -extern void *device_add_linked(const device_t *d, void *priv); +extern void *device_add(const device_t *dev); +extern void *device_add_linked(const device_t *dev, void *priv); extern void *device_add_params(const device_t *dev, void *params); extern void device_add_ex(const device_t *dev, void *priv); extern void device_add_ex_params(const device_t *dev, void *priv, void *params); @@ -216,34 +206,33 @@ extern void device_reset_all(uint32_t match_flags); extern void *device_find_first_priv(uint32_t match_flags); extern void *device_get_priv(const device_t *dev); extern int device_available(const device_t *dev); -extern int device_poll(const device_t *dev); extern void device_speed_changed(void); extern void device_force_redraw(void); extern void device_get_name(const device_t *dev, int bus, char *name); extern int device_has_config(const device_t *dev); extern const char *device_get_bios_file(const device_t *dev, const char *internal_name, int file_no); -extern int device_is_valid(const device_t *, int m); +extern int device_is_valid(const device_t *, int mch); extern const device_t* device_context_get_device(void); extern int device_get_config_int(const char *name); -extern int device_get_config_int_ex(const char *s, int dflt_int); +extern int device_get_config_int_ex(const char *str, int def); extern int device_get_config_hex16(const char *name); extern int device_get_config_hex20(const char *name); -extern int device_get_config_mac(const char *name, int dflt_int); -extern void device_set_config_int(const char *s, int val); -extern void device_set_config_hex16(const char *s, int val); -extern void device_set_config_hex20(const char *s, int val); -extern void device_set_config_mac(const char *s, int val); +extern int device_get_config_mac(const char *name, int def); +extern void device_set_config_int(const char *str, int val); +extern void device_set_config_hex16(const char *str, int val); +extern void device_set_config_hex20(const char *str, int val); +extern void device_set_config_mac(const char *str, int val); extern const char *device_get_config_string(const char *name); extern int device_get_instance(void); #define device_get_config_bios device_get_config_string extern const char *device_get_internal_name(const device_t *dev); -extern int machine_get_config_int(char *s); -extern char *machine_get_config_string(char *s); +extern int machine_get_config_int(char *str); +extern const char *machine_get_config_string(char *str); 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 0c2e5ce06..2d17380d0 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -41,21 +41,23 @@ #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_PS1 0x08 /* PS/1, PS/2 ISA */ -#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ -#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ -#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ -#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ -#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ -#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ -#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ -#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ -#define FDC_FLAG_NO_DSR_RESET 0x1000 /* Has no DSR reset */ -#define FDC_FLAG_NEC 0x2000 /* Is NEC upd765-compatible */ -#define FDC_FLAG_PS2 0x4000 /* PS/2, PS/55 */ -#define FDC_FLAG_SEC 0x10000 /* Is Secondary */ -#define FDC_FLAG_TER 0x20000 /* Is Tertiary */ -#define FDC_FLAG_QUA 0x40000 /* Is Quaternary */ +#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 */ typedef struct fdc_t { uint8_t dor; @@ -245,21 +247,20 @@ extern const device_t fdc_xt_qua_device; extern const device_t fdc_xt_t1x00_device; extern const device_t fdc_xt_tandy_device; extern const device_t fdc_xt_amstrad_device; +extern const device_t fdc_xt_umc_um8398_device; extern const device_t fdc_pcjr_device; extern const device_t fdc_at_device; 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_ps1_device; -extern const device_t fdc_at_ps1_2121_device; -extern const device_t fdc_at_ps2_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; extern const device_t fdc_at_nsc_device; -extern const device_t fdc_dp8473_device; -extern const device_t fdc_um8398_device; +extern const device_t fdc_at_nsc_dp8473_device; +extern const device_t fdc_ps2_device; +extern const device_t fdc_ps2_mca_device; #endif #endif /*EMU_FDC_H*/ diff --git a/src/include/86box/fdc_ext.h b/src/include/86box/fdc_ext.h index 4b33ed7a1..e6348139b 100644 --- a/src/include/86box/fdc_ext.h +++ b/src/include/86box/fdc_ext.h @@ -34,6 +34,10 @@ extern const device_t fdc_b215_device; extern const device_t fdc_pii151b_device; extern const device_t fdc_pii158b_device; +extern const device_t fdc_compaticard_i_device; +extern const device_t fdc_compaticard_ii_device; +extern const device_t fdc_compaticard_iv_device; + extern const device_t fdc_monster_device; extern void fdc_card_init(void); diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index 0331f4fcc..ff9315f1d 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -22,7 +22,7 @@ #define EMU_FDD_H #define FDD_NUM 4 -#define FLOPPY_IMAGE_HISTORY 4 +#define FLOPPY_IMAGE_HISTORY 10 #define SEEK_RECALIBRATE -999 #ifdef __cplusplus diff --git a/src/include/86box/fdd_86f.h b/src/include/86box/fdd_86f.h index cc8035965..de7bb7dcb 100644 --- a/src/include/86box/fdd_86f.h +++ b/src/include/86box/fdd_86f.h @@ -8,13 +8,11 @@ * * Definitions for the 86F floppy image format. * - * - * * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2016-2019 Miran Grca. - * Copyright 2018-2019 Fred N. van Kempen. + * Copyright 2016-2025 Miran Grca. + * Copyright 2018-2025 Fred N. van Kempen. */ #ifndef EMU_FLOPPY_86F_H #define EMU_FLOPPY_86F_H diff --git a/src/include/86box/fifo.h b/src/include/86box/fifo.h index f87f932e0..f8f07d9b5 100644 --- a/src/include/86box/fifo.h +++ b/src/include/86box/fifo.h @@ -1,6 +1,3 @@ -#ifndef FIFO_H -#define FIFO_H - /* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM @@ -13,8 +10,11 @@ * * Authors: Miran Grca, * - * Copyright 2023 Miran Grca. + * Copyright 2023-2025 Miran Grca. */ +#ifndef FIFO_H +#define FIFO_H + #define FIFO(size) \ typedef struct { \ int start; \ @@ -37,6 +37,7 @@ void (*d_full_evt)(void *); \ void (*d_ready_evt)(void *); \ \ + uint8_t tag[64]; \ uint8_t buf[size]; \ } fifo## size ##_t; @@ -50,9 +51,13 @@ FIFO(64) extern int fifo_get_count(void *priv); extern void fifo_write(uint8_t val, void *priv); +extern void fifo_write_tagged(uint8_t tag, uint8_t val, void *priv); extern void fifo_write_evt(uint8_t val, void *priv); +extern void fifo_write_evt_tagged(uint8_t tag, uint8_t val, void *priv); extern uint8_t fifo_read(void *priv); +extern uint8_t fifo_read_tagged(uint8_t *tag, void *priv); extern uint8_t fifo_read_evt(void *priv); +extern uint8_t fifo_read_evt_tagged(uint8_t *tag, void *priv); extern void fifo_clear_overrun(void *priv); extern int fifo_get_full(void *priv); extern int fifo_get_d_full(void *priv); diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index d9c702394..c5fc1d192 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -8,19 +8,21 @@ * * Definitions for the generic game port handlers. * - * - * * Authors: Miran Grca, * Sarah Walker, * RichardG, + * Jasmine Iwanek, * - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2022 Miran Grca. * Copyright 2008-2018 Sarah Walker. * Copyright 2021 RichardG. + * Copyright 2021-2025 Jasmine Iwanek. */ #ifndef EMU_GAMEPORT_H #define EMU_GAMEPORT_H +#define GAMEPORT_MAX 2 + #define MAX_PLAT_JOYSTICKS 8 #define MAX_JOYSTICKS 4 @@ -43,8 +45,11 @@ #define AXIS_NOT_PRESENT -99999 -#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) +#define JOYSTICK_PRESENT(gp, js) (joystick_state[gp][js].plat_joystick_nr != 0) +#define GAMEPORT_1ADDR 0x010000 +#define GAMEPORT_6ADDR 0x060000 +#define GAMEPORT_8ADDR 0x080000 #define GAMEPORT_SIO 0x1000000 typedef struct plat_joystick_t { @@ -105,10 +110,20 @@ typedef struct joystick_if_t { const char *pov_names[MAX_JOY_POVS]; } joystick_if_t; +extern device_t game_ports[GAMEPORT_MAX]; + #ifdef __cplusplus extern "C" { #endif +extern int gameport_available(int port); +#ifdef EMU_DEVICE_H +extern const device_t *gameport_getdevice(int port); +#endif +extern int gameport_has_config(int port); +extern const char *gameport_get_internal_name(int port); +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_201_device; @@ -122,6 +137,7 @@ extern const device_t gameport_20d_device; extern const device_t gameport_20f_device; extern const device_t gameport_tm_acm_device; extern const device_t gameport_pnp_device; +extern const device_t gameport_pnp_1io_device; extern const device_t gameport_pnp_6io_device; extern const device_t gameport_sio_device; extern const device_t gameport_sio_1io_device; @@ -130,7 +146,7 @@ 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[MAX_JOYSTICKS]; +extern joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; extern int joysticks_present; extern int joystick_type; @@ -167,6 +183,15 @@ extern const joystick_if_t joystick_ch_flightstick_pro; extern const joystick_if_t joystick_sw_pad; extern const joystick_if_t joystick_tm_fcs; + +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 + #ifdef __cplusplus } #endif diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 734cdf37a..7f91fd61b 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -13,7 +13,7 @@ * Authors: Miran Grca, * Fred N. van Kempen, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ #ifndef EMU_HDC_H @@ -22,11 +22,6 @@ #define MFM_NUM 2 /* 2 drives per controller supported */ #define ESDI_NUM 2 /* 2 drives per controller supported */ #define XTA_NUM 2 /* 2 drives per controller supported */ -#define IDE_NUM 10 /* 8 drives per AT IDE + 2 for XT IDE */ -#define ATAPI_NUM 8 /* 8 drives per AT IDE */ -#define SCSI_NUM 16 /* theoretically the controller can have at \ - * least 7 devices, with each device being \ - * able to support 8 units, but hey... */ /* Controller types. */ #define HDC_NONE 0 @@ -56,11 +51,13 @@ extern const device_t esdi_ps2_device; /* esdi_mca */ extern const device_t esdi_integrated_device; /* esdi_mca */ extern const device_t ide_isa_device; /* isa_ide */ +extern const device_t ide_isa_sec_device; /* isa_ide sec*/ extern const device_t ide_isa_2ch_device; /* isa_ide_2ch */ -extern const device_t ide_isa_2ch_opt_device; /* isa_ide_2ch_opt */ extern const device_t ide_vlb_device; /* vlb_ide */ +extern const device_t ide_vlb_sec_device; /* vlb_ide sec */ extern const device_t ide_vlb_2ch_device; /* vlb_ide_2ch */ extern const device_t ide_pci_device; /* pci_ide */ +extern const device_t ide_pci_sec_device; /* pci_ide sec */ extern const device_t ide_pci_2ch_device; /* pci_ide_2ch */ extern const device_t ide_ali1489_device; /* ALi M1489 */ @@ -90,6 +87,7 @@ extern const device_t ide_w83769f_vlb_device; /* Winbond W8376 extern const device_t ide_w83769f_vlb_34_device; /* Winbond W83769F VLB (Port 34h) */ extern const device_t ide_w83769f_pci_device; /* Winbond W83769F PCI */ extern const device_t ide_w83769f_pci_34_device; /* Winbond W83769F PCI (Port 34h) */ +extern const device_t ide_w83769f_pci_single_channel_device; /* Winbond W83769F PCI (Only primary channel) */ extern const device_t ide_ter_device; extern const device_t ide_ter_pnp_device; diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 9094f7f00..6af4d92e6 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -19,20 +19,23 @@ #ifndef EMU_IDE_H #define EMU_IDE_H +#define IDE_NUM 10 /* 8 drives per AT IDE + 2 for XT IDE */ +#define ATAPI_NUM 10 /* 8 drives per AT IDE + 2 for XT IDE */ + #define IDE_BUS_MAX 4 #define IDE_CHAN_MAX 2 -#define HDC_PRIMARY_BASE 0x01F0 -#define HDC_PRIMARY_SIDE 0x03F6 +#define HDC_PRIMARY_BASE 0x01f0 +#define HDC_PRIMARY_SIDE 0x03f6 #define HDC_PRIMARY_IRQ 14 #define HDC_SECONDARY_BASE 0x0170 #define HDC_SECONDARY_SIDE 0x0376 #define HDC_SECONDARY_IRQ 15 -#define HDC_TERTIARY_BASE 0x01E8 -#define HDC_TERTIARY_SIDE 0x03EE +#define HDC_TERTIARY_BASE 0x01e8 +#define HDC_TERTIARY_SIDE 0x03ee #define HDC_TERTIARY_IRQ 11 #define HDC_QUATERNARY_BASE 0x0168 -#define HDC_QUATERNARY_SIDE 0x036E +#define HDC_QUATERNARY_SIDE 0x036e #define HDC_QUATERNARY_IRQ 10 enum { @@ -121,11 +124,11 @@ typedef struct ide_s { double pending_delay; #ifdef SCSI_DEVICE_H - int (*get_max)(int ide_has_dma, int type); - int (*get_timings)(int ide_has_dma, int type); - void (*identify)(struct ide_s *ide, int ide_has_dma); - void (*stop)(scsi_common_t *sc); - void (*packet_command)(scsi_common_t *sc, uint8_t *cdb); + int (*get_max)(const struct ide_s *ide, const int ide_has_dma, const int type); + int (*get_timings)(const struct ide_s *ide, const int ide_has_dma, const int type); + void (*identify)(const struct ide_s *ide, const int ide_has_dma); + void (*stop)(const scsi_common_t *sc); + void (*packet_command)(scsi_common_t *sc, const uint8_t *cdb); void (*device_reset)(scsi_common_t *sc); uint8_t (*phase_data_out)(scsi_common_t *sc); void (*command_stop)(scsi_common_t *sc); @@ -142,10 +145,8 @@ typedef struct ide_s { #endif } ide_t; -#ifdef EMU_HDC_H extern ide_t *ide_drives[IDE_NUM]; #endif -#endif /* Type: 0 = PIO, diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 89a6cf1ff..b80c21c13 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -90,6 +90,7 @@ enum { typedef struct hdd_preset_t { const char *name; const char *internal_name; + const char *model; uint32_t zones; uint32_t avg_spt; uint32_t heads; @@ -147,7 +148,7 @@ typedef struct hard_disk_t { uint8_t ide_channel; uint8_t scsi_id; }; - uint8_t bus; + uint8_t bus_type; uint8_t bus_mode; /* Bit 0 = PIO suported; Bit 1 = DMA supportd. */ uint8_t wp; /* Disk has been mounted READ-ONLY */ @@ -165,6 +166,7 @@ typedef struct hard_disk_t { uint32_t spt; uint32_t hpc; /* Physical geometry parameters */ uint32_t tracks; + const char *model; hdd_zone_t zones[HDD_MAX_ZONES]; uint32_t num_zones; @@ -197,12 +199,12 @@ extern int hdd_is_valid(int c); extern void hdd_image_init(void); extern int hdd_image_load(int id); -extern void hdd_image_seek(uint8_t id, uint32_t sector); -extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); +extern int hdd_image_seek(uint8_t id, uint32_t sector); +extern int hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); extern int hdd_image_read_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); -extern void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); +extern int hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); extern int hdd_image_write_ex(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); -extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count); +extern int hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count); extern int hdd_image_zero_ex(uint8_t id, uint32_t sector, uint32_t count); extern uint32_t hdd_image_get_last_sector(uint8_t id); extern uint32_t hdd_image_get_pos(uint8_t id); diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index eec64990e..ec5c05775 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -15,7 +15,7 @@ * Fred N. van Kempen, * * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2025 Miran Grca. * Copyright 2017-2019 Fred N. van Kempen. */ @@ -197,6 +197,8 @@ extern "C" { extern uint8_t keyboard_mode; extern int keyboard_scan; +extern uint16_t scancode_map[768]; + extern void (*keyboard_send)(uint16_t val); extern void kbd_adddata_process(uint16_t val, void (*adddata)(uint16_t val)); @@ -222,34 +224,34 @@ 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; -# if defined(DEV_BRANCH) && defined(USE_LASERXT) +# ifdef USE_LASERXT extern const device_t keyboard_xt_lxt3_device; -# endif /*defined(DEV_BRANCH) && defined(USE_LASERXT) */ +# 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_siemens_device; extern const device_t keyboard_at_ami_device; +extern const device_t keyboard_at_compaq_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_at_olivetti_device; -extern const device_t keyboard_at_ncr_device; -extern const device_t keyboard_at_compaq_device; extern const device_t keyboard_ps2_device; extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; extern const device_t keyboard_ps2_xi8088_device; extern const device_t keyboard_ps2_ami_device; extern const device_t keyboard_ps2_holtek_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_olivetti_device; -extern const device_t keyboard_ps2_phoenix_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; @@ -288,6 +290,9 @@ 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); extern atkbc_dev_t *kbc_at_dev_init(uint8_t inst); +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +extern uint16_t convert_scan_code(uint16_t scan_code); #ifdef __cplusplus } diff --git a/src/include/86box/log.h b/src/include/86box/log.h index 9d3568069..a37bdec4f 100644 --- a/src/include/86box/log.h +++ b/src/include/86box/log.h @@ -6,42 +6,42 @@ * * This file is part of the 86Box distribution. * - * Main include file for the application. - * - * + * New logging system handler header. * * Authors: Miran Grca, * Fred N. van Kempen, + * Connor Hyde, * - * Copyright 2021 Miran Grca. - * Copyright 2021 Fred N. van Kempen. + * Copyright 2021-25 Miran Grca. + * Copyright 2021-25 Fred N. van Kempen. + * Copyright 2025 Connor Hyde. */ #ifndef EMU_LOG_H #define EMU_LOG_H -#ifndef RELEASE_BUILD - # ifdef __cplusplus extern "C" { # endif +#define LOG_SIZE_BUFFER 1024 /* Log size buffer */ +#define LOG_SIZE_BUFFER_CYCLIC_LINES 32 /* Cyclic log size buffer (number of lines that should be cehcked) */ +#define LOG_MINIMUM_REPEAT_ORDER 4 /* Minimum repeat size */ + /* Function prototypes. */ extern void log_set_suppr_seen(void *priv, int suppr_seen); extern void log_set_dev_name(void *priv, char *dev_name); -# ifdef HAVE_STDARG_H +#ifndef RELEASE_BUILD extern void log_out(void *priv, const char *fmt, va_list); +extern void log_out_cyclic(void* priv, const char *fmt, va_list); +#endif /*RELEASE_BUILD*/ extern void log_fatal(void *priv, const char *fmt, ...); -# endif -extern void *log_open(char *dev_name); +extern void *log_open(const char *dev_name); +extern void *log_open_cyclic(const char *dev_name); extern void log_close(void *priv); # ifdef __cplusplus } # endif -#else -# define log_fatal(priv, fmt, ...) fatal(fmt, ...) -#endif /*RELEASE_BUILD*/ - #endif /*EMU_LOG_H*/ diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 4e95b64c3..674d6340f 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -31,33 +31,33 @@ typedef struct lpt_device_t { } lpt_device_t; extern void lpt_init(void); -extern void lpt_port_init(int i, uint16_t port); +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_init(a) lpt_port_init(0, a) +#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_init(a) lpt_port_init(1, a) +#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_init(a) lpt_port_init(2, a) +#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_init(a) lpt_port_init(3, a) +#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_init(a) lpt_port_init(4, a) +#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_init(a) lpt_port_init(5, a) +#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 diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 3efb5a8e8..690d867db 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -23,26 +23,25 @@ #define EMU_MACHINE_H /* Machine feature flags. */ -#define MACHINE_BUS_NONE 0x00000000 /* sys has no bus */ +#define MACHINE_BUS_NONE 0x00000000 /* sys has no bus */ /* Feature flags for BUS'es. */ -#define MACHINE_BUS_ISA 0x00000001 /* sys has ISA bus */ -#define MACHINE_BUS_CASSETTE 0x00000002 /* sys has cassette port */ -#define MACHINE_BUS_CARTRIDGE 0x00000004 /* sys has two cartridge bays */ -#define MACHINE_BUS_PCJR 0x00000008 /* sys has PCjr sidecar bus */ -#define MACHINE_BUS_DM_KBC 0x00000010 /* system has keyboard controller that supports - both XT and AT keyboards */ +#define MACHINE_BUS_CASSETTE 0x00000001 /* sys has cassette port */ +#define MACHINE_BUS_SIDECAR 0x00000002 /* sys has PCjr sidecar bus */ +#define MACHINE_BUS_ISA 0x00000004 /* sys has ISA bus */ +#define MACHINE_BUS_XT_KBD 0x00000008 /* sys has an XT keyboard port */ +#define MACHINE_BUS_CBUS 0x00000010 /* sys has C-BUS bus */ #define MACHINE_BUS_ISA16 0x00000020 /* sys has ISA16 bus - PC/AT architecture */ -#define MACHINE_BUS_CBUS 0x00000040 /* sys has C-BUS bus */ -#define MACHINE_BUS_PCMCIA 0x00000080 /* sys has PCMCIA bus */ -#define MACHINE_BUS_PS2_LATCH 0x00000100 /* system has PS/2 keyboard controller IRQ latch */ +#define MACHINE_BUS_AT_KBD 0x00000040 /* sys has an AT keyboard port */ +#define MACHINE_BUS_MCA 0x00000080 /* sys has MCA bus */ +#define MACHINE_BUS_MCA32 0x00000100 /* sys has MCA32 bus */ #define MACHINE_BUS_PS2_PORTS 0x00000200 /* system has PS/2 keyboard and mouse ports */ -#define MACHINE_BUS_PS2 (MACHINE_BUS_PS2_LATCH | MACHINE_BUS_PS2_PORTS) -#define MACHINE_BUS_HIL 0x00000400 /* system has HP HIL keyboard and mouse ports */ -#define MACHINE_BUS_EISA 0x00000800 /* sys has EISA bus */ -#define MACHINE_BUS_AT32 0x00001000 /* sys has Mylex AT/32 local bus */ -#define MACHINE_BUS_OLB 0x00002000 /* sys has OPTi local bus */ -#define MACHINE_BUS_VLB 0x00004000 /* sys has VL bus */ -#define MACHINE_BUS_MCA 0x00008000 /* sys has MCA bus */ +#define MACHINE_BUS_PS2 MACHINE_BUS_PS2_PORTS +#define MACHINE_BUS_PCMCIA 0x00000400 /* sys has PCMCIA bus */ +#define MACHINE_BUS_HIL 0x00000800 /* system has HP HIL keyboard and mouse ports */ +#define MACHINE_BUS_EISA 0x00001000 /* sys has EISA bus */ +#define MACHINE_BUS_AT32 0x00002000 /* sys has Mylex AT/32 local bus */ +#define MACHINE_BUS_OLB 0x00004000 /* sys has OPTi local bus */ +#define MACHINE_BUS_VLB 0x00008000 /* sys has VL bus */ #define MACHINE_BUS_PCI 0x00010000 /* sys has PCI bus */ #define MACHINE_BUS_CARDBUS 0x00020000 /* sys has CardBus bus */ #define MACHINE_BUS_USB 0x00040000 /* sys has USB bus */ @@ -50,7 +49,6 @@ #define MACHINE_BUS_AC97 0x00100000 /* sys has AC97 bus (ACR/AMR/CNR slot) */ /* Aliases. */ #define MACHINE_CASSETTE (MACHINE_BUS_CASSETTE) /* sys has cassette port */ -#define MACHINE_CARTRIDGE (MACHINE_BUS_CARTRIDGE) /* sys has two cartridge bays */ /* Combined flags. */ #define MACHINE_PC (MACHINE_BUS_ISA) /* sys is PC/XT-compatible (ISA) */ #define MACHINE_AT (MACHINE_BUS_ISA | MACHINE_BUS_ISA16) /* sys is AT-compatible (ISA + ISA16) */ @@ -69,18 +67,18 @@ #define MACHINE_AGP (MACHINE_BUS_AGP | MACHINE_PCI) /* sys is AT-compatible with AGP */ #define MACHINE_AGP98 (MACHINE_BUS_AGP | MACHINE_PCI98) /* sys is NEC PC-98x1 series with AGP (did that even exist?) */ -#define MACHINE_PC5150 (MACHINE_PC | MACHINE_CASSETTE) /* sys is IBM PC 5150 */ -#define MACHINE_PCJR (MACHINE_PC | MACHINE_CASSETTE | MACHINE_CARTRIDGE) /* sys is PCjr */ -#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */ -#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */ -#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */ -#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */ -#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */ -#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */ -#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */ -#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */ -#define MACHINE_PS2_PCIONLY (MACHINE_PS2_NOISA & ~MACHINE_BUS_AGP) /* sys is PCI PS/2 without ISA */ -#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */ +#define MACHINE_PC5150 (MACHINE_PC | MACHINE_CASSETTE) /* sys is IBM PC 5150 */ +#define MACHINE_PCJR (MACHINE_PC | MACHINE_CASSETTE | MACHINE_BUS_SIDECAR) /* sys is PCjr */ +#define MACHINE_PS2 (MACHINE_AT | MACHINE_BUS_PS2) /* sys is PS/2 */ +#define MACHINE_PS2_MCA (MACHINE_MCA | MACHINE_BUS_PS2) /* sys is MCA PS/2 */ +#define MACHINE_PS2_VLB (MACHINE_VLB | MACHINE_BUS_PS2) /* sys is VLB PS/2 */ +#define MACHINE_PS2_PCI (MACHINE_PCI | MACHINE_BUS_PS2) /* sys is PCI PS/2 */ +#define MACHINE_PS2_PCIV (MACHINE_PCIV | MACHINE_BUS_PS2) /* sys is VLB/PCI PS/2 */ +#define MACHINE_PS2_AGP (MACHINE_AGP | MACHINE_BUS_PS2) /* sys is AGP PS/2 */ +#define MACHINE_PS2_A97 (MACHINE_PS2_AGP | MACHINE_BUS_AC97) /* sys is AGP/AC97 PS/2 */ +#define MACHINE_PS2_NOISA (MACHINE_PS2_AGP & ~MACHINE_AT) /* sys is AGP PS/2 without ISA */ +#define MACHINE_PS2_PCIONLY (MACHINE_PS2_NOISA & ~MACHINE_BUS_AGP) /* sys is PCI PS/2 without ISA */ +#define MACHINE_PS2_NOI97 (MACHINE_PS2_A97 & ~MACHINE_AT) /* sys is AGP/AC97 PS/2 without ISA */ /* Feature flags for miscellaneous internal devices. */ #define MACHINE_FLAGS_NONE 0x00000000 /* sys has no int devices */ #define MACHINE_SOFTFLOAT_ONLY 0x00000001 /* sys requires SoftFloat FPU */ @@ -93,7 +91,8 @@ #define MACHINE_LPT_PRI 0x00000080 /* sys has int pri LPT */ #define MACHINE_LPT_SEC 0x00000100 /* sys has int sec LPT */ #define MACHINE_LPT_TER 0x00000200 /* sys has int ter LPT */ -#define MACHINE_LPT_QUA 0x00000400 /* sys has int qua LPT */ +#define MACHINE_PS2_KBC 0x00000400 /* 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 */ @@ -106,7 +105,7 @@ #define MACHINE_APM 0x00080000 /* sys has APM */ #define MACHINE_ACPI 0x00100000 /* sys has ACPI */ #define MACHINE_HWM 0x00200000 /* sys has hw monitor */ -#define MACHINE_COREBOOT 0x00400000 /* sys has coreboot BIOS */ +#define MACHINE_CARTRIDGE 0x00400000 /* sys has cartridge bays */ /* Feature flags for internal storage controllers. */ #define MACHINE_MFM 0x00800000 /* sys has int MFM/RLL */ #define MACHINE_XTA 0x01000000 /* sys has int XTA */ @@ -173,20 +172,21 @@ enum { MACHINE_TYPE_486 = 8, MACHINE_TYPE_486_S2 = 9, MACHINE_TYPE_486_S3 = 10, - MACHINE_TYPE_486_MISC = 11, - MACHINE_TYPE_SOCKET4 = 12, - MACHINE_TYPE_SOCKET5 = 13, - MACHINE_TYPE_SOCKET7_3V = 14, - MACHINE_TYPE_SOCKET7 = 15, - MACHINE_TYPE_SOCKETS7 = 16, - MACHINE_TYPE_SOCKET8 = 17, - MACHINE_TYPE_SLOT1 = 18, - MACHINE_TYPE_SLOT1_2 = 19, - MACHINE_TYPE_SLOT1_370 = 20, - MACHINE_TYPE_SLOT2 = 21, - MACHINE_TYPE_SOCKET370 = 22, - MACHINE_TYPE_MISC = 23, - MACHINE_TYPE_MAX = 24 + MACHINE_TYPE_486_S3_PCI = 11, + MACHINE_TYPE_486_MISC = 12, + MACHINE_TYPE_SOCKET4 = 13, + MACHINE_TYPE_SOCKET5 = 14, + MACHINE_TYPE_SOCKET7_3V = 15, + MACHINE_TYPE_SOCKET7 = 16, + MACHINE_TYPE_SOCKETS7 = 17, + MACHINE_TYPE_SOCKET8 = 18, + MACHINE_TYPE_SLOT1 = 19, + MACHINE_TYPE_SLOT1_2 = 20, + MACHINE_TYPE_SLOT1_370 = 21, + MACHINE_TYPE_SLOT2 = 22, + MACHINE_TYPE_SOCKET370 = 23, + MACHINE_TYPE_MISC = 24, + MACHINE_TYPE_MAX = 25 }; enum { @@ -320,27 +320,29 @@ typedef struct _machine_ { int ram_granularity; int nvrmask; #ifdef EMU_DEVICE_H - const device_t *kbc_device; + const device_t *kbc_device; #else - void *kbc_device; + void *kbc_device; #endif /* EMU_DEVICE_H */ - uint8_t kbc_p1; - uint32_t gpio; - uint32_t gpio_acpi; + uintptr_t kbc_params; + /* Bits 23-16: XOR mask, bits 15-8: OR mask, bits 7-0: AND mask. */ + uint32_t kbc_p1; + uint32_t gpio; + uint32_t gpio_acpi; #ifdef EMU_DEVICE_H - const device_t *device; - const device_t *fdc_device; - const device_t *sio_device; - const device_t *vid_device; - const device_t *snd_device; - const device_t *net_device; + const device_t *device; + const device_t *fdc_device; + const device_t *sio_device; + const device_t *vid_device; + const device_t *snd_device; + const device_t *net_device; #else - void *device; - void *fdc_device; - void *sio_device; - void *vid_device; - void *snd_device; - void *net_device; + void *device; + void *fdc_device; + void *sio_device; + void *vid_device; + void *snd_device; + void *net_device; #endif } machine_t; @@ -358,6 +360,7 @@ extern int machine_available(int m); extern const char *machine_getname(void); extern const char *machine_getname_ex(int m); extern const char *machine_get_internal_name(void); +extern const char *machine_get_nvr_name(void); extern int machine_get_machine_from_internal_name(const char *s); extern void machine_init(void); #ifdef EMU_DEVICE_H @@ -370,6 +373,7 @@ extern const device_t *machine_get_snd_device(int m); extern const device_t *machine_get_net_device(int m); #endif extern const char *machine_get_internal_name_ex(int m); +extern const char *machine_get_nvr_name_ex(int m); extern int machine_get_nvrmask(int m); extern int machine_has_flags(int m, int flags); extern int machine_has_bus(int m, int bus_flags); @@ -437,9 +441,9 @@ extern int machine_at_ibmxt286_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 -#if defined(DEV_BRANCH) && defined(USE_OPEN_AT) +#ifdef USE_OPEN_AT extern int machine_at_openat_init(const machine_t *); -#endif +#endif /* USE_OPEN_AT */ /* m_at_286_386sx.c */ extern int machine_at_tg286m_init(const machine_t *); @@ -450,6 +454,7 @@ extern int machine_at_mr286_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 *); extern int machine_at_quadt386sx_init(const machine_t *); @@ -468,9 +473,9 @@ extern int machine_at_deskmaster286_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_3302_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +#ifdef USE_OLIVETTI extern int machine_at_m290_init(const machine_t *); -#endif +#endif /* USE_OLIVETTI */ extern int machine_at_shuttle386sx_init(const machine_t *); extern int machine_at_adi386sx_init(const machine_t *); @@ -593,6 +598,7 @@ extern int machine_at_pcm5330_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 *); extern int machine_at_atc1415_init(const machine_t *); extern int machine_at_actionpc2600_init(const machine_t *); extern int machine_at_actiontower8400_init(const machine_t *); @@ -631,9 +637,11 @@ extern int machine_at_valuepointp60_init(const machine_t *); extern int machine_at_revenge_init(const machine_t *); extern int machine_at_586is_init(const machine_t *); extern int machine_at_pb520r_init(const machine_t *); +extern int machine_at_m5pi_init(const machine_t *); extern int machine_at_excalibur_init(const machine_t *); +extern int machine_at_globalyst330_p5_init(const machine_t *); extern int machine_at_p5vl_init(const machine_t *); extern int machine_at_excaliburpci2_init(const machine_t *); @@ -643,6 +651,7 @@ extern int machine_at_p5sp4_init(const machine_t *); extern int machine_at_plato_init(const machine_t *); extern int machine_at_dellplato_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); +extern int machine_at_p54np4_init(const machine_t *); extern int machine_at_586ip_init(const machine_t *); extern int machine_at_tek932_init(const machine_t *); @@ -687,7 +696,7 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); -extern int machine_at_gw2kte_init(const machine_t *); +extern int machine_at_gw2kma_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); extern int machine_at_pc140_6260_init(const machine_t *); @@ -722,13 +731,14 @@ extern int machine_at_pb680_init(const machine_t *); extern int machine_at_pb810_init(const machine_t *); extern int machine_at_mb520n_init(const machine_t *); extern int machine_at_i430vx_init(const machine_t *); +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 *); -#if defined(DEV_BRANCH) && defined(USE_AN430TX) +#ifdef USE_AN430TX extern int machine_at_an430tx_init(const machine_t *); -#endif +#endif /* USE_AN430TX */ extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_thunderbolt_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); @@ -740,6 +750,7 @@ extern int machine_at_tomahawk_init(const machine_t *); extern int machine_at_ficva502_init(const machine_t *); extern int machine_at_ficpa2012_init(const machine_t *); +extern int machine_at_via809ds_init(const machine_t *); extern int machine_at_r534f_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); @@ -802,6 +813,7 @@ extern int machine_at_p2bls_init(const machine_t *); extern int machine_at_lgibmx7g_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_bf6_init(const machine_t *); +extern int machine_at_bx6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_atc6310bxii_init(const machine_t *); extern int machine_at_686bx_init(const machine_t *); @@ -841,6 +853,7 @@ extern int machine_at_6via90ap_init(const machine_t *); extern int machine_at_s1857_init(const machine_t *); extern int machine_at_p6bap_init(const machine_t *); extern int machine_at_p6bat_init(const machine_t *); +extern int machine_at_prosignias31x_bx_init(const machine_t *); /* m_at_misc.c */ extern int machine_at_vpc2007_init(const machine_t *); @@ -848,6 +861,9 @@ extern int machine_at_vpc2007_init(const machine_t *); /* m_at_t3100e.c */ extern int machine_at_t3100e_init(const machine_t *); +/* m_at_grid.c */ +extern int machine_at_grid1520_init(const machine_t *); + /* m_elt.c */ extern int machine_elt_init(const machine_t *); @@ -910,6 +926,7 @@ extern int machine_xt86_init(const machine_t *); extern int machine_xt_americxt_init(const machine_t *); extern int machine_xt_amixt_init(const machine_t *); +extern int machine_xt_ataripc3_init(const machine_t *); extern int machine_xt_dtk_init(const machine_t *); extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_openxt_init(const machine_t *); @@ -937,16 +954,17 @@ extern int machine_xt_iskra3104_init(const machine_t *); extern int machine_xt_pravetz16_imko4_init(const machine_t *); extern int machine_xt_pravetz16s_cpu12p_init(const machine_t *); extern int machine_xt_micoms_xl7turbo_init(const machine_t *); +extern int machine_xt_maz1016_init(const machine_t *); /* m_xt_compaq.c */ extern int machine_xt_compaq_deskpro_init(const machine_t *); extern int machine_xt_compaq_portable_init(const machine_t *); /* m_xt_laserxt.c */ -#if defined(DEV_BRANCH) && defined(USE_LASERXT) +#ifdef USE_LASERXT extern int machine_xt_laserxt_init(const machine_t *); extern int machine_xt_lxt3_init(const machine_t *); -#endif +#endif /* USE_LASERXT */ /* m_xt_philips.c */ extern int machine_xt_p3105_init(const machine_t *); diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 3c0e0aee0..19a331925 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -179,6 +179,7 @@ typedef struct _mem_mapping_ { uint32_t base; uint32_t size; + uint32_t base_ignore; uint32_t mask; uint8_t (*read_b)(uint32_t addr, void *priv); @@ -400,6 +401,7 @@ extern void mem_mapping_set_p(mem_mapping_t *, void *priv); extern void mem_mapping_set_addr(mem_mapping_t *, uint32_t base, uint32_t size); +extern void mem_mapping_set_base_ignore(mem_mapping_t *, uint32_t base_ignore); extern void mem_mapping_set_exec(mem_mapping_t *, uint8_t *exec); extern void mem_mapping_set_mask(mem_mapping_t *, uint32_t mask); extern void mem_mapping_disable(mem_mapping_t *); @@ -446,6 +448,7 @@ extern void mem_flush_write_page(uint32_t addr, uint32_t virt); extern void mem_reset_page_blocks(void); extern void flushmmucache(void); +extern void flushmmucache_pc(void); extern void flushmmucache_nopc(void); extern void mem_debug_check_addr(uint32_t addr, int write); @@ -457,7 +460,9 @@ extern void mem_init(void); extern void mem_close(void); extern void mem_reset(void); extern void mem_remap_top_ex(int kb, uint32_t start); +extern void mem_remap_top_ex_nomid(int kb, uint32_t start); extern void mem_remap_top(int kb); +extern void mem_remap_top_nomid(int kb); extern void umc_smram_recalc(uint32_t start, int set); diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index 57a20ae5c..3a41c2cb5 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -104,18 +104,18 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #ifdef EMU_DEVICE_H extern const device_t rtmidi_output_device; extern const device_t rtmidi_input_device; -# if defined(DEV_BRANCH) && defined(USE_OPL4ML) +# ifdef USE_OPL4ML extern const device_t opl4_midi_device; -# endif +# endif /* USE_OPL4ML */ # ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; -# endif +# endif /* USE_FLUIDSYNTH */ # ifdef USE_MUNT extern const device_t mt32_old_device; extern const device_t mt32_new_device; extern const device_t cm32l_device; extern const device_t cm32ln_device; -# endif +# endif /* USE_MUNT */ #endif #endif /*EMU_SOUND_MIDI_H*/ diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 5d4b723f3..1df16c3fe 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -9,13 +9,13 @@ * Implementation of a generic Magneto-Optical Disk drive * commands, for both ATAPI and SCSI usage. * - * - * * Authors: Natalia Portillo - * Fred N. van Kempen, * Miran Grca, + * Fred N. van Kempen, * - * Copyright 2020 Miran Grca. + * Copyright 2020-2025 Natalia Portillo. + * Copyright 2020-2025 Miran Grca. + * Copyright 2020-2025 Fred N. van Kempen */ #ifndef EMU_MO_H @@ -27,7 +27,7 @@ #define MO_TIME 10.0 -#define MO_IMAGE_HISTORY 4 +#define MO_IMAGE_HISTORY 10 typedef struct mo_type_t { uint32_t sectors; @@ -91,98 +91,87 @@ enum { }; typedef struct mo_drive_t { - uint8_t id; + uint8_t id; union { - uint8_t res; - uint8_t res0; /* Reserved for other ID's. */ - uint8_t res1; - uint8_t ide_channel; - uint8_t scsi_device_id; + uint8_t 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; + 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; + FILE * fp; + void * priv; - char image_path[1024]; - char prev_image_path[1024]; + char image_path[1024]; + char prev_image_path[1024]; - char *image_history[MO_IMAGE_HISTORY]; - - uint32_t type; - uint32_t medium_size; - uint32_t base; - uint16_t sector_size; + char * image_history[MO_IMAGE_HISTORY]; + uint32_t type; + uint32_t medium_size; + uint32_t base; + uint16_t sector_size; } 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 - uint8_t *buffer; - uint8_t atapi_cdb[16]; - uint8_t current_cdb[16]; - uint8_t sense[256]; + void * log; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif + uint8_t * 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; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; - uint16_t max_transfer_len; - uint16_t pad2; + uint16_t max_transfer_len; + uint16_t pad2; - int requested_blocks; - int packet_status; - int total_length; - int do_page_save; - int unit_attention; - int request_pos; - int old_len; - int pad3; + 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 sector_pos; + uint32_t sector_len; + uint32_t packet_len; - double callback; + double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } mo_t; -extern mo_t *mo[MO_NUM]; -extern mo_drive_t mo_drives[MO_NUM]; -#if 0 -extern uint8_t atapi_mo_drives[8]; -extern uint8_t scsi_mo_drives[16]; -#endif +extern mo_drive_t mo_drives[MO_NUM]; #define mo_sense_error dev->sense[0] #define mo_sense_key dev->sense[2] +#define mo_info *(uint32_t *) &(dev->sense[3]) #define mo_asc dev->sense[12] #define mo_ascq dev->sense[13] @@ -190,15 +179,16 @@ extern uint8_t scsi_mo_drives[16]; extern "C" { #endif -extern void mo_disk_close(mo_t *dev); -extern void mo_disk_reload(mo_t *dev); +extern void mo_disk_close(const mo_t *dev); +extern void mo_disk_reload(const mo_t *dev); extern void mo_insert(mo_t *dev); extern void mo_global_init(void); extern void mo_hard_reset(void); extern void mo_reset(scsi_common_t *sc); -extern int mo_load(mo_t *dev, char *fn); +extern int mo_is_empty(const uint8_t id); +extern void mo_load(const mo_t *dev, const char *fn, const int skip_insert); extern void mo_close(void); #ifdef __cplusplus diff --git a/src/include/86box/mouse.h b/src/include/86box/mouse.h index 810d62293..bbe78413b 100644 --- a/src/include/86box/mouse.h +++ b/src/include/86box/mouse.h @@ -71,8 +71,10 @@ extern const device_t mouse_mssystems_device; extern const device_t mouse_msserial_device; extern const device_t mouse_ltserial_device; extern const device_t mouse_ps2_device; +# ifdef USE_WACOM extern const device_t mouse_wacom_device; extern const device_t mouse_wacom_artpad_device; +# endif extern const device_t mouse_mtouch_device; #endif diff --git a/src/include/86box/net_ne2000.h b/src/include/86box/net_ne2000.h index cb17ef8b1..ecf2612b5 100644 --- a/src/include/86box/net_ne2000.h +++ b/src/include/86box/net_ne2000.h @@ -44,7 +44,7 @@ enum { NE2K_NE2000_COMPAT = 4, /* 16-bit ISA NE2000-Compatible */ NE2K_NE2000_COMPAT_8BIT = 5, /* 8-bit ISA NE2000-Compatible, like: https://github.com/skiselev/isa8_eth */ NE2K_ETHERNEXT_MC = 6, /* 16-bit MCA EtherNext/MC */ - NE2K_RTL8019AS = 7, /* 16-bit ISA PnP Realtek 8019AS */ + NE2K_RTL8019AS_PNP = 7, /* 16-bit ISA PnP Realtek 8019AS */ NE2K_DE220P = 8, /* 16-bit ISA PnP D-Link DE-220P */ NE2K_RTL8029AS = 9, /* 32-bit PCI Realtek 8029AS */ /* Check nic_init() if adding items after this point. */ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index fa6408790..2140d62dd 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -213,7 +213,7 @@ extern const device_t ne2000_device; extern const device_t ne2000_compat_device; extern const device_t ne2000_compat_8bit_device; extern const device_t ethernext_mc_device; -extern const device_t rtl8019as_device; +extern const device_t rtl8019as_pnp_device; extern const device_t de220p_device; extern const device_t rtl8029as_device; diff --git a/src/include/86box/nv/vid_nv_rivatimer.h b/src/include/86box/nv/vid_nv_rivatimer.h new file mode 100644 index 000000000..59f6cfebf --- /dev/null +++ b/src/include/86box/nv/vid_nv_rivatimer.h @@ -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. + * + * Fast, high-frequency, guest CPU-independent timer for Riva emulation. + * + * + * Authors: Connor Hyde, I need a better email address ;^) + * + * Copyright 2024-2025 starfrost + */ + +/* +RivaTimer + +This is a fast, high-frequency, guest CPU-independent timer. + +The main 86box timer is dependent on the TSC (time-stamp counter) register of the emulated CPU core. +This is fine for most purposes and has advantages in the fields of synchronisation and integrates neatly with +the clock dividers of the PC architecture, but in the case of the RIVA 128 it does not particularly suffice +(although it can be made to work with various techniques) since the clock source on the RIVA 128 is on the board itself +and the GPU has several different clocks that control different parts of the GPU (e.g., PTIMER runs on the memory clock but the core gpu is using the pixel clock). + +As faster graphics cards that offload more and more of the 3D graphics pipeline are emulated in the future, more and more work needs to be done by the emulator and +issues of synchronisation with a host CPU will simply make that work harder. Some features that are required for + +Architecture Brand Name 3D Features +NV1 (1995) NV1 Some weird URBS rectangle crap but feature set generally similar to nv3 but a bit worse +NV3 (1997) RIVA 128 (ZX) Triangle setup, edge-slope calculations, edge interpolation, span-slope calculations, span interpolation (Color-buffer, z-buffer, texture mapping, filtering) +NV4 (1998) RIVA TNT NV3 + 2x1 pixel pipelines + 32-bit colour + larger textures + trilinear + more ram (16mb) +NV5 (1999) RIVA TNT2 NV4 + higher clock speed +NV10 (1999) GeForce 256 NV5 + initial geometry transformation + lighting (8x lights) + MPEG-2 motion compensation + 4x1 pixel pipelines +NV15 (2000) GeForce 2 NV10 + First attempt at programmability + 4x2 pixel pipelines +NV20 (2001) GeForce 3 Programmable shaders! + +As you can see, the performance basically exponentially increases over a period of only 4 years. + +So I decided to create this timer that is completely separate from the CPU Core. +*/ + +#pragma once +#include +#include +#include +#include +#include <86box/86box.h> + +#ifdef _WIN32 +#include +// Linux & MacOS should have the same API since OSX 10.12 +#else +#include +#endif + +typedef struct rivatimer_s +{ + struct rivatimer_s* prev; // Previous Rivatimer + double period; // Period in uS before firing + double value; // The current value of the rivatimer + bool running; // Is this RivaTimer running? + struct rivatimer_s* next; // Next RivaTimer + void (*callback)(double real_time); // Callback to call on fire + #ifdef _WIN32 + LARGE_INTEGER starting_time; // Starting time. + #else + struct timespec starting_time; // Starting time. + #endif + double time; // Accumulated time in uS. +} rivatimer_t; + +void rivatimer_init(void); // Initialise the Rivatimer. +rivatimer_t* rivatimer_create(double period, void (*callback)(double real_time)); +void rivatimer_destroy(rivatimer_t* rivatimer_ptr); + +void rivatimer_update_all(void); +void rivatimer_start(rivatimer_t* rivatimer_ptr); +void rivatimer_stop(rivatimer_t* rivatimer_ptr); +double rivatimer_get_time(rivatimer_t* rivatimer_ptr); +void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)(double real_time)); +void rivatimer_set_period(rivatimer_t* rivatimer_ptr, double period); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 85e0954f0..0f7d22172 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -60,6 +60,7 @@ #define TIME_SYNC_ENABLED 1 #define TIME_SYNC_UTC 2 +#ifdef _TIMER_H_ /* Define a generic RTC/NVRAM device. */ typedef struct _nvr_ { char *fn; /* pathname of image file */ @@ -104,8 +105,6 @@ extern const device_t elt_nvr_device; extern void rtc_tick(void); extern void nvr_init(nvr_t *); -extern char *nvr_path(char *str); -extern FILE *nvr_fopen(char *str, char *mode); extern int nvr_load(void); extern void nvr_close(void); extern void nvr_set_ven_save(void (*ven_save)(void)); @@ -114,8 +113,8 @@ extern int nvr_save(void); extern int nvr_is_leap(int year); extern int nvr_get_days(int month, int year); extern void nvr_time_sync(void); -extern void nvr_time_get(struct tm *); -extern void nvr_time_set(struct tm *); +extern void nvr_time_get(void *priv); +extern void nvr_time_set(void *priv); extern void nvr_reg_write(uint16_t reg, uint8_t val, void *priv); extern void nvr_at_handler(int set, uint16_t base, nvr_t *nvr); @@ -132,5 +131,9 @@ extern void nvr_irq_set(int irq, nvr_t *nvr); extern void nvr_smi_enable(int enable, nvr_t *nvr); extern uint8_t nvr_smi_status(nvr_t *nvr); extern void nvr_smi_status_clear(nvr_t *nvr); +#endif + +extern char *nvr_path(char *str); +extern FILE *nvr_fopen(char *str, char *mode); #endif /*EMU_NVR_H*/ diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index 4a310ab44..f39f6ba51 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/Ctrl+End to release mouse" */ - STRING_MOUSE_RELEASE_MMB, /* "Press F8+F12/Ctrl+End or middle button to release mouse" */ + STRING_MOUSE_RELEASE, /* "Press F8+F12 to release mouse" */ + STRING_MOUSE_RELEASE_MMB, /* "Press F8+F12 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" */ @@ -47,6 +47,7 @@ enum { STRING_HW_NOT_AVAILABLE_MACHINE, /* "Machine \"%hs\" is not available..." */ STRING_HW_NOT_AVAILABLE_VIDEO, /* "Video card \"%hs\" is not available..." */ STRING_HW_NOT_AVAILABLE_VIDEO2, /* "Video card #2 \"%hs\" is not available..." */ + STRING_HW_NOT_AVAILABLE_DEVICE, /* "Device \"%hs\" is not available..." */ STRING_MONITOR_SLEEP, /* "Monitor in sleep mode" */ STRING_GHOSTPCL_ERROR_TITLE, /* "Unable to initialize GhostPCL" */ STRING_GHOSTPCL_ERROR_DESC /* "gpcl6dll32.dll/gpcl6dll64.dll/libgpcl6 is required..." */ @@ -187,9 +188,6 @@ extern void zip_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); -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); -extern void ioctl_close(uint8_t id); /* Other stuff. */ extern void startblit(void); diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h deleted file mode 100644 index 8e81f9459..000000000 --- a/src/include/86box/plat_cdrom.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for platform specific serial to host passthrough. - * - * - * Authors: Andreas J. Reichel , - * Jasmine Iwanek - * - * Copyright 2021 Andreas J. Reichel. - * Copyright 2021-2022 Jasmine Iwanek. - */ - -#ifndef PLAT_CDROM_H -#define PLAT_CDROM_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 - -#define DATA_TRACK 0x14 -#define AUDIO_TRACK 0x10 - -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M, S, F) \ - { \ - uint64_t value = f; \ - *(F) = (value % CD_FPS) & 0xff; \ - value /= CD_FPS; \ - *(S) = (value % 60) & 0xff; \ - value /= 60; \ - *(M) = value & 0xff; \ - } -#define MSF_TO_FRAMES(M, S, F) ((M) *60 * CD_FPS + (S) *CD_FPS + (F)) - -typedef struct SMSF { - uint16_t min; - uint8_t sec; - uint8_t fr; -} TMSF; - -extern int plat_cdrom_is_track_audio(uint32_t sector); -extern int plat_cdrom_is_track_pre(uint32_t sector); -extern uint32_t plat_cdrom_get_last_block(void); -extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); -extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); -extern int plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); -extern int plat_cdrom_get_sector_size(uint32_t sector); -extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); -extern void plat_cdrom_eject(void); -extern void plat_cdrom_close(void); -extern int plat_cdrom_set_drive(const char *drv); -extern int plat_cdrom_ext_medium_changed(void); -extern uint32_t plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/include/86box/plat_cdrom_ioctl.h b/src/include/86box/plat_cdrom_ioctl.h new file mode 100644 index 000000000..471222134 --- /dev/null +++ b/src/include/86box/plat_cdrom_ioctl.h @@ -0,0 +1,34 @@ +/* + * 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 platform specific serial to host passthrough. + * + * + * Authors: Andreas J. Reichel , + * Jasmine Iwanek + * + * Copyright 2021 Andreas J. Reichel. + * Copyright 2021-2022 Jasmine Iwanek. + */ + +#ifndef PLAT_CDROM_IOCTL_H +#define PLAT_CDROM_IOCTL_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void * ioctl_open(cdrom_t *dev, const char *drv); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/86box/scsi.h b/src/include/86box/scsi.h index 32ad1f912..84a4a608e 100644 --- a/src/include/86box/scsi.h +++ b/src/include/86box/scsi.h @@ -29,15 +29,21 @@ #define SCSI_ID_MAX 16 /* 16 on wide buses */ #define SCSI_LUN_MAX 8 /* always 8 */ -extern int scsi_card_current[SCSI_CARD_MAX]; +extern int scsi_card_current[SCSI_CARD_MAX]; -extern int scsi_card_available(int card); +extern void scsi_reset(void); +extern uint8_t scsi_get_bus(void); + +extern int scsi_card_available(int card); #ifdef EMU_DEVICE_H extern const device_t *scsi_card_getdevice(int card); #endif -extern int scsi_card_has_config(int card); -extern const char *scsi_card_get_internal_name(int card); -extern int scsi_card_get_from_internal_name(char *s); -extern void scsi_card_init(void); +extern int scsi_card_has_config(int card); +extern const char *scsi_card_get_internal_name(int card); +extern int scsi_card_get_from_internal_name(char *s); +extern void scsi_card_init(void); + +extern void scsi_bus_set_speed(uint8_t bus, double speed); +extern double scsi_bus_get_speed(uint8_t bus); #endif /*EMU_SCSI_H*/ diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index dec537429..bc2d4c8bd 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -26,55 +26,56 @@ typedef struct scsi_cdrom_t { /* Common block. */ mode_sense_pages_t ms_pages_saved; - cdrom_t * drv; + cdrom_t * drv; #ifdef EMU_IDE_H - ide_tf_t *tf; + ide_tf_t * tf; #else - void * tf; + void * tf; #endif - uint8_t *buffer; - uint8_t atapi_cdb[16]; - uint8_t current_cdb[16]; - uint8_t sense[256]; + void * log; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif + uint8_t * buffer; + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + uint8_t sense[256]; - uint8_t id; - uint8_t cur_lun; - uint8_t early; - uint8_t pad1; + uint8_t id; + uint8_t cur_lun; + uint8_t early; + uint8_t sector_type; - uint16_t max_transfer_len; - uint16_t pad2; + uint16_t max_transfer_len; + uint16_t sector_flags; - int requested_blocks; - int packet_status; - int total_length; - int do_page_save; - int unit_attention; - int request_pos; - int old_len; - int media_status; + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int media_status; - uint32_t sector_pos; - uint32_t sector_len; - uint32_t packet_len; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; - double callback; + double callback; + + int is_sony; + int use_cdb_9; + + uint8_t ven_cmd_is_data[256]; - mode_sense_pages_t ms_pages_saved_sony; mode_sense_pages_t ms_drive_status_pages_saved; - int sony_vendor; + + uint64_t ms_page_flags; + + mode_sense_pages_t ms_pages_default; + mode_sense_pages_t ms_pages_changeable; + + uint8_t (*ven_cmd)(void *sc, const uint8_t *cdb, int32_t *BufLen); } scsi_cdrom_t; #endif @@ -82,10 +83,12 @@ extern scsi_cdrom_t *scsi_cdrom[CDROM_NUM]; #define scsi_cdrom_sense_error dev->sense[0] #define scsi_cdrom_sense_key dev->sense[2] +#define scsi_cdrom_info *(uint32_t *) &(dev->sense[3]) #define scsi_cdrom_asc dev->sense[12] #define scsi_cdrom_ascq dev->sense[13] #define scsi_cdrom_drive cdrom_drives[id].host_drive extern void scsi_cdrom_reset(scsi_common_t *sc); +extern void scsi_cdrom_drive_reset(const int c); #endif /*EMU_SCSI_CDROM_H*/ diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 64d3bc853..ffe042481 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -21,6 +21,7 @@ #define SCSI_DEVICE_H /* Configuration. */ +#define SCSI_NUM (SCSI_BUS_MAX * SCSI_ID_MAX) #define SCSI_LUN_USE_CDB 0xff @@ -53,8 +54,8 @@ #define GPCMD_SEEK_6 0x0b #define GPCMD_IOMEGA_SET_PROTECTION_MODE 0x0c #define GPCMD_IOMEGA_EJECT 0x0d /* ATAPI only? */ -#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command */ -#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command */ +#define GPCMD_NO_OPERATION_TOSHIBA 0x0d /* Toshiba Vendor Unique command. */ +#define GPCMD_NO_OPERATION_NEC 0x0d /* NEC Vendor Unique command. */ #define GPCMD_INQUIRY 0x12 #define GPCMD_VERIFY_6 0x13 #define GPCMD_MODE_SELECT_6 0x15 @@ -66,7 +67,7 @@ #define GPCMD_PREVENT_REMOVAL 0x1e #define GPCMD_READ_FORMAT_CAPACITIES 0x23 #define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_UNKNOWN_CHINON 0x26 /*Chinon Vendor Unique command*/ +#define GPCMD_UNKNOWN_CHINON 0x26 /* Chinon Vendor Unique command. */ #define GPCMD_READ_10 0x28 #define GPCMD_READ_GENERATION 0x29 #define GPCMD_WRITE_10 0x2a @@ -100,43 +101,54 @@ #define GPCMD_WRITE_AND_VERIFY_12 0xae #define GPCMD_VERIFY_12 0xaf #define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 +#define GPCMD_READ_CD_OLD 0xb8 /* Should be equivalent to 0xbe */ #define GPCMD_READ_CD_MSF 0xb9 #define GPCMD_AUDIO_SCAN 0xba #define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc +#define GPCMD_PLAY_CD 0xbc /* At some point, this was READ CD, according to the + ATAPI specification */ #define GPCMD_MECHANISM_STATUS 0xbd #define GPCMD_READ_CD 0xbe #define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to 86Box. */ #define GPCMD_EJECT_CHINON 0xc0 /* Chinon Vendor Unique command */ #define GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA 0xc0 /* Toshiba Vendor Unique command */ -#define GPCMD_UNKNOWN_SONY 0xc0 /* Sony Vendor Unique command */ +#define GPCMD_SET_ADDRESS_FORMAT_SONY 0xc0 /* Sony Vendor Unique command */ +#define GPCMD_MAGAZINE_EJECT_PIONEER 0xc0 /* Pioneer Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TOSHIBA 0xc1 /* Toshiba Vendor Unique command */ #define GPCMD_READ_TOC_SONY 0xc1 /* Sony Vendor Unique command */ +#define GPCMD_READ_TOC_PIONEER 0xc1 /* Pioneer Vendor Unique command */ #define GPCMD_PAUSE_RESUME_ALT 0xc2 #define GPCMD_READ_SUBCHANNEL_MATSUSHITA 0xc2 /* Matsushita Vendor Unique command */ #define GPCMD_READ_SUBCHANNEL_SONY 0xc2 /* Sony Vendor Unique command */ #define GPCMD_STILL_TOSHIBA 0xc2 /* Toshiba Vendor Unique command */ +#define GPCMD_READ_SUBCODEQ_PIONEER 0xc2 /* Pioneer Vendor Unique command */ #define GPCMD_READ_TOC_MATSUSHITA 0xc3 /* Matsushita Vendor Unique command */ #define GPCMD_READ_HEADER_SONY 0xc3 /* Sony Vendor Unique command */ #define GPCMD_SET_STOP_TIME_TOSHIBA 0xc3 /* Toshiba Vendor Unique command */ #define GPCMD_READ_HEADER_MATSUSHITA 0xc4 /* Matsushita Vendor Unique command */ -#define GPCMD_PLAYBACK_STATUS_TOSHIBA 0xc4 /* Sony Vendor Unique command */ +#define GPCMD_PLAYBACK_STATUS_SONY 0xc4 /* Sony Vendor Unique command */ #define GPCMD_CADDY_EJECT_TOSHIBA 0xc4 /* Toshiba Vendor Unique command */ #define GPCMD_PAUSE_SONY 0xc5 /* Sony Vendor Unique command */ #define GPCMD_PLAY_AUDIO_MATSUSHITA 0xc5 /* Matsushita Vendor Unique command */ +#define GPCMD_UNKNOWN_SCSI2_NEC 0xc5 /* NEC Vendor Unique Command */ #define GPCMD_STOP_CHINON 0xc6 /* Chinon Vendor Unique command */ -#define GPCMD_PLAT_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ +#define GPCMD_PLAY_TRACK_SONY 0xc6 /* Sony Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA 0xc6 /* Toshiba Vendor Unique command */ #define GPCMD_PLAY_AUDIO_MSF_MATSUSHITA 0xc7 /* Matsushita Vendor Unique command*/ #define GPCMD_PLAY_MSF_SONY 0xc7 /* Sony Vendor Unique command*/ #define GPCMD_READ_DISC_INFORMATION_TOSHIBA 0xc7 /* Toshiba Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA 0xc8 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_SONY 0xc8 /* Sony Vendor Unique command */ -#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /*Matsushita Vendor Unique command */ +#define GPCMD_AUDIO_TRACK_SEARCH_PIONEER 0xc8 /* Pioneer Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA 0xc9 /* Matsushita Vendor Unique command */ #define GPCMD_PLAYBACK_CONTROL_SONY 0xc9 /* Sony Vendor Unique command */ +#define GPCMD_PLAY_AUDIO_PIONEER 0xc9 /* Pioneer Vendor Unique command */ +#define GPCMD_PAUSE_PIONEER 0xca /* Pioneer Vendor Unique command */ #define GPCMD_PAUSE_RESUME_MATSUSHITA 0xcb /* Matsushita Vendor Unique command */ +#define GPCMD_STOP_PIONEER 0xcb /* Pioneer Vendor Unique command */ +#define GPCMD_PLAYBACK_STATUS_PIONEER 0xcc /* Pioneer Vendor Unique command */ #define GPCMD_SCAN_PIONEER 0xcd /* Should be equivalent to 0xba */ +#define GPCMD_READ_CD_MSF_OLD 0xd5 /* Should be equivalent to 0xb9 */ #define GPCMD_AUDIO_TRACK_SEARCH_NEC 0xd8 /* NEC Vendor Unique command */ #define GPCMD_PLAY_AUDIO_NEC 0xd9 /* NEC Vendor Unique command */ #define GPCMD_STILL_NEC 0xda /* NEC Vendor Unique command */ @@ -145,6 +157,7 @@ #define GPCMD_CADDY_EJECT_NEC 0xdc /* NEC Vendor Unique command */ #define GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC 0xdd /* NEC Vendor Unique command */ #define GPCMD_READ_DISC_INFORMATION_NEC 0xde /* NEC Vendor Unique command */ +#define GPCMD_DRIVE_STATUS_PIONEER 0xe0 /* Pioneer Vendor Unique command */ #define GPCMD_PLAY_AUDIO_12_MATSUSHITA 0xe5 /* Matsushita Vendor Unique command */ #define GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA 0xe9 /* Matsushita Vendor Unique command */ @@ -189,6 +202,7 @@ /* SCSI Sense Keys */ #define SENSE_NONE 0 #define SENSE_NOT_READY 2 +#define SENSE_MEDIUM_ERROR 3 #define SENSE_ILLEGAL_REQUEST 5 #define SENSE_UNIT_ATTENTION 6 @@ -196,6 +210,8 @@ #define ASC_NONE 0x00 #define ASC_AUDIO_PLAY_OPERATION 0x00 #define ASC_NOT_READY 0x04 +#define ASC_WRITE_ERROR 0x0c +#define ASC_UNRECOVERED_READ_ERROR 0x11 #define ASC_ILLEGAL_OPCODE 0x20 #define ASC_LBA_OUT_OF_RANGE 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 @@ -203,7 +219,7 @@ #define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 #define ASC_WRITE_PROTECTED 0x27 #define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_CAPACITY_DATA_CHANGED 0x2A +#define ASC_CAPACITY_DATA_CHANGED 0x2a #define ASC_INCOMPATIBLE_FORMAT 0x30 #define ASC_MEDIUM_NOT_PRESENT 0x3a #define ASC_DATA_PHASE_ERROR 0x4b @@ -212,21 +228,18 @@ #define ASCQ_NONE 0x00 #define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01 #define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02 +#define ASCQ_CIRC_UNRECOVERED_ERROR 0x06 #define ASCQ_CAPACITY_DATA_CHANGED 0x09 #define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 #define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 #define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 -/* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). - Not that it means anything */ -#define CDROM_SPEED 706 /* 0x2C2 */ - -#define BUFFER_SIZE (256 * 1024) - -#define RW_DELAY (TIMER_USEC * 500) - /* Some generally useful CD-ROM information */ +#ifdef CONSERVATIVE_MAXIMUM #define CD_MINS 90 /* max. minutes per CD */ +#else +#define CD_MINS 100 /* max. minutes per CD - yes, 100-minute CD's in fact existed */ +#endif #define CD_SECS 60 /* seconds per minute */ #define CD_FRAMES 75 /* frames per second */ #define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */ @@ -260,6 +273,10 @@ /* Profile list from MMC-6 revision 1 table 91 */ #define MMC_PROFILE_NONE 0x0000 +#define MMC_PROFILE_REMOVABLE_DISK 0x0002 +#define MMC_PROFILE_MO 0x0003 +#define MMC_PROFILE_MO_WORM 0x0004 +#define MMC_PROFILE_AS_MO 0x0005 #define MMC_PROFILE_CD_ROM 0x0008 #define MMC_PROFILE_CD_R 0x0009 #define MMC_PROFILE_CD_RW 0x000A @@ -288,7 +305,6 @@ #define MMC_PROFILE_HDDVD_RW_DL 0x005A #define MMC_PROFILE_INVALID 0xFFFF -#define EARLY_ONLY 64 #define SCSI_ONLY 32 #define ATAPI_ONLY 16 #define IMPLEMENTED 8 @@ -296,8 +312,6 @@ #define CHECK_READY 2 #define ALLOW_UA 1 -#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) - #define MSG_COMMAND_COMPLETE 0x00 #define BUS_DBP 0x01 @@ -317,6 +331,20 @@ #define BUS_IDLE (1 << 31) +#define STATE_IDLE 0 +#define STATE_COMMAND 1 +#define STATE_DATAIN 2 +#define STATE_DATAOUT 3 +#define STATE_STATUS 4 +#define STATE_MESSAGEIN 5 +#define STATE_SELECT 6 +#define STATE_MESSAGEOUT 7 +#define STATE_MESSAGE_ID 8 + +#define PIO_TX_BUS 0 +#define DMA_IN_TX_BUS 1 +#define DMA_OUT_TX_BUS 2 + #define PHASE_IDLE 0x00 #define PHASE_COMMAND 0x01 #define PHASE_DATA_IN 0x02 @@ -341,7 +369,7 @@ #define MODE_SELECT_PHASE_PAGE 4 typedef struct mode_sense_pages_t { - uint8_t pages[0x40][0x40]; + uint8_t pages[0x40][0x40]; } mode_sense_pages_t; /* This is so we can access the common elements to all SCSI device structs @@ -349,70 +377,107 @@ typedef struct mode_sense_pages_t { typedef struct scsi_common_s { mode_sense_pages_t ms_pages_saved; - void * priv; + void * priv; #ifdef EMU_IDE_H - ide_tf_t *tf; + ide_tf_t * tf; #else - void * tf; + void * tf; #endif - uint8_t *temp_buffer; - uint8_t atapi_cdb[16]; /* This is atapi_cdb in ATAPI-supporting devices, - and pad in SCSI-only devices. */ - uint8_t current_cdb[16]; - uint8_t sense[256]; + void * log; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif + uint8_t * temp_buffer; + /* + This is atapi_cdb in ATAPI-supporting devices, + and pad in SCSI-only devices. + */ + 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; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; - uint16_t max_transfer_len; - uint16_t pad2; + 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 media_status; + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int old_len; + int media_status; - uint32_t sector_pos; - uint32_t sector_len; - uint32_t packet_len; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; - double callback; + double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } scsi_common_t; typedef struct scsi_device_t { - int32_t buffer_length; + int32_t buffer_length; - uint8_t status; - uint8_t phase; - uint16_t type; + uint8_t status; + uint8_t phase; - scsi_common_t *sc; + uint16_t type; - void (*command)(scsi_common_t *sc, uint8_t *cdb); - void (*request_sense)(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length); - void (*reset)(scsi_common_t *sc); - uint8_t (*phase_data_out)(scsi_common_t *sc); - void (*command_stop)(scsi_common_t *sc); + scsi_common_t * sc; + + void (*command)(scsi_common_t *sc, const uint8_t *cdb); + void (*request_sense)(scsi_common_t *sc, uint8_t *buffer, + uint8_t alloc_length); + void (*reset)(scsi_common_t *sc); + uint8_t (*phase_data_out)(scsi_common_t *sc); + void (*command_stop)(scsi_common_t *sc); } scsi_device_t; +typedef struct scsi_bus_t { + uint8_t data; + uint8_t msglun; + uint8_t data_wait; + uint8_t target_id; + uint8_t bus_device; + uint8_t pad; + uint8_t pad0; + uint8_t pad1; + + uint8_t command[16]; + uint8_t msgout[4]; + uint8_t pad2[4]; + + int tx_mode; + int clear_req; + int wait_data; + int wait_complete; + int bus_out; + int bus_in; + int command_pos; + int command_issued; + int data_pos; + int msgout_pos; + int is_msgout; + int state; + int dma_on_pio_enabled; + + uint32_t bus_phase; + + double period; + double speed; + double divider; + double multi; + + void *priv; + void (*timer)(void *priv, double period); +} scsi_bus_t; + /* These are based on the INQUIRY values. */ #define SCSI_NONE 0x0060 #define SCSI_FIXED_DISK 0x0000 @@ -423,15 +488,8 @@ typedef struct scsi_device_t { extern scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX]; #endif /* EMU_SCSI_H */ -extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); -extern int cdrom_LBAtoMSF_accurate(void); - -extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save); -extern int mode_select_terminate(int force); -extern int mode_select_write(uint8_t val); - -extern uint8_t *scsi_device_sense(scsi_device_t *dev); extern double scsi_device_get_callback(scsi_device_t *dev); +extern uint8_t *scsi_device_sense(scsi_device_t *dev); extern void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer, uint8_t alloc_length); extern void scsi_device_reset(scsi_device_t *dev); @@ -439,14 +497,16 @@ extern int scsi_device_present(scsi_device_t *dev); extern int scsi_device_valid(scsi_device_t *dev); extern int scsi_device_cdb_length(scsi_device_t *dev); extern void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb); -extern void scsi_device_command_phase1(scsi_device_t *dev); extern void scsi_device_command_stop(scsi_device_t *dev); +extern void scsi_device_command_phase1(scsi_device_t *dev); extern void scsi_device_identify(scsi_device_t *dev, uint8_t lun); extern void scsi_device_close_all(void); extern void scsi_device_init(void); extern void scsi_reset(void); extern uint8_t scsi_get_bus(void); +extern int scsi_bus_read(scsi_bus_t *scsi_bus); +extern void scsi_bus_update(scsi_bus_t *scsi_bus, int bus); extern void scsi_bus_set_speed(uint8_t bus, double speed); extern double scsi_bus_get_speed(uint8_t bus); diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index eb4dc69a4..7099b836a 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -19,51 +19,44 @@ typedef struct scsi_disk_t { mode_sense_pages_t ms_pages_saved; - hard_disk_t *drv; + hard_disk_t * drv; #ifdef EMU_IDE_H - ide_tf_t * tf; + ide_tf_t * tf; #else - void * tf; + void * tf; #endif - uint8_t *temp_buffer; - uint8_t atapi_cdb[16]; - uint8_t current_cdb[16]; - uint8_t sense[256]; + void * log; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif + uint8_t * temp_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; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; - uint16_t max_transfer_len; - uint16_t pad2; + 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 pad6; - int pad7; + int requested_blocks; + int packet_status; + int total_length; + int do_page_save; + int unit_attention; + int request_pos; + int pad6; + int pad7; - uint32_t sector_pos; - uint32_t sector_len; - uint32_t packet_len; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t packet_len; - double callback; + double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } scsi_disk_t; extern scsi_disk_t *scsi_disk[HDD_NUM]; diff --git a/src/include/86box/scsi_ncr5380.h b/src/include/86box/scsi_ncr5380.h index 55692075b..5a43ba76a 100644 --- a/src/include/86box/scsi_ncr5380.h +++ b/src/include/86box/scsi_ncr5380.h @@ -44,6 +44,9 @@ #define ICR_ACK 0x10 #define ICR_ARB_LOST 0x20 #define ICR_ARB_IN_PROGRESS 0x40 +#define ICR_RST 0x80 +#define ICR_PHASE 0x9e +#define ICR_WRITE 0x9f #define MODE_ARBITRATE 0x01 #define MODE_DMA 0x02 @@ -63,69 +66,34 @@ #define TCR_REQ 0x08 #define TCR_LAST_BYTE_SENT 0x80 - -#define STATE_IDLE 0 -#define STATE_COMMAND 1 -#define STATE_DATAIN 2 -#define STATE_DATAOUT 3 -#define STATE_STATUS 4 -#define STATE_MESSAGEIN 5 -#define STATE_SELECT 6 -#define STATE_MESSAGEOUT 7 -#define STATE_MESSAGE_ID 8 - -#define DMA_IDLE 0 -#define DMA_SEND 1 -#define DMA_INITIATOR_RECEIVE 2 - typedef struct ncr_t { uint8_t icr; uint8_t mode; uint8_t tcr; - uint8_t data_wait; uint8_t isr; uint8_t output_data; - uint8_t target_id; uint8_t tx_data; - uint8_t msglun; uint8_t irq_state; + uint8_t isr_reg; - uint8_t command[20]; - uint8_t msgout[4]; uint8_t bus; - int msgout_pos; - int is_msgout; - - int dma_mode; - int cur_bus; - int bus_in; - int new_phase; - int state; - int clear_req; - int wait_data; - int wait_complete; - int command_pos; - int data_pos; - int irq; double period; void *priv; - void (*dma_mode_ext)(void *priv, void *ext_priv); + void (*dma_mode_ext)(void *priv, void *ext_priv, uint8_t val); int (*dma_send_ext)(void *priv, void *ext_priv); int (*dma_initiator_receive_ext)(void *priv, void *ext_priv); void (*timer)(void *ext_priv, double period); + + scsi_bus_t scsibus; } ncr_t; -extern int ncr5380_cmd_len[8]; - extern void ncr5380_irq(ncr_t *ncr, int set_irq); -extern void ncr5380_set_irq(ncr_t *ncr, int irq); +extern void ncr5380_set_irq(ncr_t *ncr, int irq); extern uint32_t ncr5380_get_bus_host(ncr_t *ncr); -extern void ncr5380_bus_read(ncr_t *ncr); -extern void ncr5380_bus_update(ncr_t *ncr, int bus); extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr); extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr); diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index a205c7cec..31c77ce5a 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -16,7 +16,7 @@ * Fred N. van Kempen, * * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. * Copyright 2017-2020 Fred N. van Kempen. */ @@ -137,6 +137,7 @@ extern serial_t *serial_attach_ex_2(int port, extern void serial_remove(serial_t *dev); extern void serial_set_type(serial_t *dev, int type); extern void serial_setup(serial_t *dev, uint16_t addr, uint8_t irq); +extern void serial_irq(serial_t *dev, uint8_t irq); extern void serial_clear_fifo(serial_t *dev); extern void serial_write_fifo(serial_t *dev, uint8_t dat); extern void serial_set_next_inst(int ni); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 7f40203b4..7fcb376b9 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -16,13 +16,20 @@ #ifndef EMU_SIO_H #define EMU_SIO_H -extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); - +/* ACC Micro */ extern const device_t acc3221_device; + +/* Acer / ALi */ extern const device_t ali5105_device; + extern const device_t ali5123_device; -extern const device_t f82c710_device; + +/* Chips & Technologies */ extern const device_t f82c606_device; + +extern const device_t f82c710_device; + +/* SM(S)C */ extern const device_t fdc37c651_device; extern const device_t fdc37c651_ide_device; extern const device_t fdc37c661_device; @@ -35,9 +42,12 @@ extern const device_t fdc37c665_ide_device; extern const device_t fdc37c665_ide_pri_device; extern const device_t fdc37c665_ide_sec_device; extern const device_t fdc37c666_device; -extern const device_t fdc37c67x_device; + extern const device_t fdc37c669_device; extern const device_t fdc37c669_370_device; + +extern const device_t fdc37c67x_device; + extern const device_t fdc37c931apm_device; extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; @@ -46,22 +56,23 @@ 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; + extern const device_t fdc37m60x_device; extern const device_t fdc37m60x_370_device; + +/* ITE */ extern const device_t it8661f_device; extern const device_t it8671f_device; extern const device_t i82091aa_device; extern const device_t i82091aa_398_device; extern const device_t i82091aa_ide_pri_device; extern const device_t i82091aa_ide_device; -extern const device_t pc87306_device; -extern const device_t pc87307_device; -extern const device_t pc87307_15c_device; -extern const device_t pc87307_both_device; -extern const device_t pc87309_device; -extern const device_t pc87309_15c_device; + +/* National Semiconductors */ extern const device_t pc87310_device; extern const device_t pc87310_ide_device; + +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; @@ -69,35 +80,66 @@ extern const device_t pc87332_398_device; 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; + +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; extern const device_t prime3b_ide_device; extern const device_t prime3c_device; extern const device_t prime3c_ide_device; + +/* IBM PS/1 */ extern const device_t ps1_m2133_sio; -#if defined(DEV_BRANCH) && defined(USE_SIO_DETECT) + +/* Super I/O Detect */ +#ifdef USE_SIO_DETECT extern const device_t sio_detect_device; -#endif +#endif /* USE_SIO_DETECT */ + +/* UMC */ extern const device_t um8663af_device; extern const device_t um8663af_ide_device; extern const device_t um8663af_sec_device; extern const device_t um8663bf_device; extern const device_t um8663bf_ide_device; extern const device_t um8663bf_sec_device; + extern const device_t um8669f_device; extern const device_t um8669f_ide_device; extern const device_t um8669f_ide_sec_device; + +/* VIA */ +extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); + extern const device_t via_vt82c686_sio_device; + +/* VLSI */ extern const device_t vl82c113_device; + +/* Winbond */ extern const device_t w83787f_88h_device; extern const device_t w83787f_device; extern const device_t w83787f_ide_device; extern const device_t w83787f_ide_en_device; extern const device_t w83787f_ide_sec_device; + extern const device_t w83877f_device; extern const device_t w83877f_president_device; extern const device_t w83877tf_device; extern const device_t w83877tf_acorp_device; + +#define TYPE_W83977EF 0x52F0 +#define TYPE_W83977F 0x9771 +#define TYPE_W83977TF 0x9773 +#define TYPE_W83977ATF 0x9774 + extern const device_t w83977f_device; extern const device_t w83977f_370_device; extern const device_t w83977tf_device; diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 319f9bf24..a7e38a6f8 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -16,7 +16,7 @@ * * Copyright 2008-2020 Sarah Walker. * Copyright 2018-2020 TheCollector1995. - * Copyright 2021 RichardG. + * Copyright 2021-2025 RichardG. */ #ifndef SOUND_AD1848_H @@ -26,8 +26,10 @@ enum { AD1848_TYPE_DEFAULT = 0, AD1848_TYPE_CS4248 = 1, AD1848_TYPE_CS4231 = 2, - AD1848_TYPE_CS4235 = 3, - AD1848_TYPE_CS4236 = 4 + AD1848_TYPE_CS4232 = 3, + AD1848_TYPE_CS4236 = 4, + AD1848_TYPE_CS4236B = 5, + AD1848_TYPE_CS4235 = 6 }; typedef struct ad1848_t { diff --git a/src/include/86box/snd_akm4531.h b/src/include/86box/snd_akm4531.h new file mode 100644 index 000000000..96f87b396 --- /dev/null +++ b/src/include/86box/snd_akm4531.h @@ -0,0 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Ensoniq AudioPCI family emulation. + * + * Authors: Cacodemon345 + * + * Copyright 2024-2025 Cacodemon345. + */ +struct akm4531_t +{ + unsigned char registers[256]; +}; + +typedef struct akm4531_t akm4531_t; + +double akm4531_apply_master_vol(unsigned short sample); \ No newline at end of file diff --git a/src/include/86box/snd_opl.h b/src/include/86box/snd_opl.h index 441e2a119..62c62e965 100644 --- a/src/include/86box/snd_opl.h +++ b/src/include/86box/snd_opl.h @@ -18,12 +18,35 @@ #define SOUND_OPL_H enum fm_type { - FM_YM3812 = 0, /* OPL2 */ - FM_YMF262 = 1, /* OPL3 */ - FM_YMF289B = 2, /* OPL3-L */ - FM_YMF278B = 3, /* OPL 4 */ - FM_ESFM = 4, /* ESFM */ - FM_MAX = 5 + FM_YM2149 = 0, /* SSG */ + FM_YM3526 = 1, /* OPL */ + FM_Y8950 = 2, /* MSX-Audio (OPL with ADPCM) */ + FM_YM3812 = 3, /* OPL2 */ + FM_YMF262 = 4, /* OPL3 */ + FM_YMF289B = 5, /* OPL3-L */ + FM_YMF278B = 6, /* OPL4 */ + FM_YM2413 = 7, /* OPLL */ + FM_YM2423 = 8, /* OPLL-X */ + FM_YMF281 = 9, /* OPLLP */ + FM_DS1001 = 10, /* Konami VRC7 MMC */ + FM_YM2151 = 11, /* OPM */ + FM_YM2203 = 12, /* OPN */ + FM_YM2608 = 13, /* OPNA */ + FM_YMF288 = 14, /* OPN3L */ + FM_YM2610 = 15, /* OPNB */ + FM_YM2610B = 16, /* OPNB2 */ + FM_YM2612 = 17, /* OPN2 */ + FM_YM3438 = 18, /* OPN2C */ + FM_YMF276 = 19, /* OPN2L */ + FM_YM2164 = 20, /* OPP */ + FM_YM3806 = 21, /* OPQ */ +#if 0 + FM_YMF271 = 22, /* OPX */ +#endif + FM_YM2414 = 23, /* OPZ */ + FM_ESFM = 24, /* ESFM */ + FM_OPL2BOARD = 25, /* OPL2Board (External Device) */ + FM_MAX = 26 }; enum fm_driver { @@ -47,17 +70,59 @@ extern uint8_t fm_driver_get(int chip_id, fm_drv_t *drv); extern const fm_drv_t nuked_opl_drv; extern const fm_drv_t ymfm_drv; extern const fm_drv_t esfmu_opl_drv; +extern const fm_drv_t ymfm_opl2board_drv; #ifdef EMU_DEVICE_H extern const device_t ym3812_nuked_device; extern const device_t ymf262_nuked_device; +extern const device_t ym2149_ymfm_device; + +/* OPL Series */ +extern const device_t ym3526_ymfm_device; +extern const device_t y8950_ymfm_device; extern const device_t ym3812_ymfm_device; extern const device_t ymf262_ymfm_device; extern const device_t ymf289b_ymfm_device; extern const device_t ymf278b_ymfm_device; +extern const device_t ym2413_ymfm_device; +extern const device_t ym2423_ymfm_device; +extern const device_t ymf281_ymfm_device; +extern const device_t ds1001_ymfm_device; + +/* OPM Series */ +extern const device_t ym2151_ymfm_device; + +/* OPN Series */ +extern const device_t ym2203_ymfm_device; +extern const device_t ym2608_ymfm_device; +extern const device_t ymf288_ymfm_device; +extern const device_t ym2610_ymfm_device; +extern const device_t ym2610b_ymfm_device; +extern const device_t ym2612_ymfm_device; +extern const device_t ym3438_ymfm_device; +extern const device_t ymf276_ymfm_device; + +/* OPP Series */ +extern const device_t ym2164_ymfm_device; + +/* OPQ Series */ +extern const device_t ym3806_ymfm_device; + +/* OPX Series */ +#if 0 +extern const device_t ymf271_ymfm_device; +#endif + +/* OPZ Series */ +extern const device_t ym2414_ymfm_device; extern const device_t esfm_esfmu_device; + +#ifdef USE_LIBSERIALPORT +extern const device_t ym_opl2board_device; +#endif + #endif #endif /*SOUND_OPL_H*/ diff --git a/src/include/86box/snd_resid.h b/src/include/86box/snd_resid.h index 4ddaf9b91..c7e97ac0f 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(void); +void *sid_init(uint8_t type); 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/snd_sb.h b/src/include/86box/snd_sb.h index 70fcff387..06fbbfa3b 100644 --- a/src/include/86box/snd_sb.h +++ b/src/include/86box/snd_sb.h @@ -11,9 +11,11 @@ * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, + * Jasmine Iwanek, * * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. */ #ifndef SOUND_SND_SB_H @@ -27,15 +29,19 @@ enum { SADLIB = 1, /* No DSP */ - SB1, /* DSP v1.05 */ - SB15, /* DSP v2.00 */ - SB2, /* DSP v2.01 - needed for high-speed DMA */ - SBPRO, /* DSP v3.00 */ - SBPRO2, /* DSP v3.02 + OPL3 */ - SB16, /* DSP v4.05 + OPL3 */ - SBAWE32, /* DSP v4.12 + OPL3 */ - SBAWE32PNP, /* DSP v4.13 + OPL3 */ - SBAWE64 /* DSP v4.16 + OPL3 */ + SB_DSP_105, /* DSP v1.05, Original CT1320 (Also known as CT1310) */ + SB_DSP_200, /* DSP v2.00 */ + SB_DSP_201, /* DSP v2.01 - needed for high-speed DMA, Seen on CT1350B with CT1336 */ + SB_DSP_202, /* DSP v2.02 - Seen on CT1350B with CT1336A */ + SBPRO_DSP_300, /* DSP v3.00 */ + SBPRO2_DSP_302, /* DSP v3.02 + OPL3 */ + SB16_DSP_404, /* DSP v4.05 + OPL3 */ + SB16_DSP_405, /* DSP v4.05 + OPL3 */ + SB16_DSP_406, /* DSP v4.06 + OPL3 */ + SB16_DSP_411, /* DSP v4.11 + OPL3 */ + SBAWE32_DSP_412, /* DSP v4.12 + OPL3 */ + SBAWE32_DSP_413, /* DSP v4.13 + OPL3 */ + SBAWE64_DSP_416 /* DSP v4.16 + OPL3 */ }; /* SB 2.0 CD version */ @@ -182,6 +188,7 @@ typedef struct sb_t { void *gameport; int pnp; + int has_ide; uint8_t pos_regs[8]; uint8_t pnp_rom[512]; @@ -195,6 +202,12 @@ typedef struct sb_t { void (*opl_mix)(void*, double*, double*); } sb_t; +typedef struct goldfinch_t { + emu8k_t emu8k; + + uint8_t pnp_rom[512]; +} goldfinch_t; + extern void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *priv); extern uint8_t sb_ct1345_mixer_read(uint16_t addr, void *priv); extern void sb_ct1345_mixer_reset(sb_t *sb); diff --git a/src/include/86box/snd_sn76489.h b/src/include/86box/snd_sn76489.h index 6e7399d54..81d9ad229 100644 --- a/src/include/86box/snd_sn76489.h +++ b/src/include/86box/snd_sn76489.h @@ -20,6 +20,9 @@ typedef struct sn76489_t { int freqhi[4]; int vol[4]; uint32_t shift; + uint32_t white_noise_tap_1; + uint32_t white_noise_tap_2; + uint32_t feedback_mask; uint8_t noise; int lasttone; uint8_t firstdat; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 9895e73d7..a30095c66 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -109,6 +109,8 @@ extern void givealbuffer_wt(const void *buf); extern void givealbuffer_cd(const void *buf); #define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base +#define sb_vibra16cl_onboard_relocate_base sb_vibra16s_onboard_relocate_base +#define sb_vibra16xv_onboard_relocate_base sb_vibra16s_onboard_relocate_base extern void sb_vibra16s_onboard_relocate_base(uint16_t new_addr, void *priv); #ifdef EMU_DEVICE_H @@ -143,26 +145,34 @@ extern const device_t sb_pro_v2_device; extern const device_t sb_pro_mcv_device; extern const device_t sb_pro_compat_device; extern const device_t sb_16_device; -extern const device_t sb_vibra16s_onboard_device; -extern const device_t sb_vibra16s_device; -extern const device_t sb_vibra16xv_device; extern const device_t sb_vibra16c_onboard_device; extern const device_t sb_vibra16c_device; +extern const device_t sb_vibra16cl_onboard_device; +extern const device_t sb_vibra16cl_device; +extern const device_t sb_vibra16s_onboard_device; +extern const device_t sb_vibra16s_device; +extern const device_t sb_vibra16xv_onboard_device; +extern const device_t sb_vibra16xv_device; extern const device_t sb_16_pnp_device; +extern const device_t sb_16_pnp_ide_device; extern const device_t sb_16_compat_device; extern const device_t sb_16_compat_nompu_device; extern const device_t sb_16_reply_mca_device; +extern const device_t sb_goldfinch_device; extern const device_t sb_32_pnp_device; extern const device_t sb_awe32_device; extern const device_t sb_awe32_pnp_device; extern const device_t sb_awe64_value_device; extern const device_t sb_awe64_device; +extern const device_t sb_awe64_ide_device; extern const device_t sb_awe64_gold_device; /* Crystal CS423x */ extern const device_t cs4235_device; extern const device_t cs4235_onboard_device; +extern const device_t cs4236_onboard_device; extern const device_t cs4236b_device; +extern const device_t cs4236b_onboard_device; extern const device_t cs4237b_device; extern const device_t cs4238b_device; @@ -177,6 +187,7 @@ extern const device_t ess_soundpiper_32_mca_device; extern const device_t ess_chipchat_16_mca_device; /* Ensoniq AudioPCI */ +extern const device_t es1370_device; extern const device_t es1371_device; extern const device_t es1371_onboard_device; extern const device_t es1373_device; @@ -192,6 +203,7 @@ extern const device_t ps1snd_device; /* Innovation SSI-2001 */ extern const device_t ssi2001_device; +extern const device_t entertainer_device; /* Pro Audio Spectrum Plus, 16, and 16D */ extern const device_t pasplus_device; @@ -209,6 +221,11 @@ extern const device_t tndy_device; extern const device_t wss_device; extern const device_t ncr_business_audio_device; +#ifdef USE_LIBSERIALPORT +/* External Audio device OPL2Board (Host Connected hardware)*/ +extern const device_t opl2board_device; +#endif + #endif #endif /*EMU_SOUND_H*/ diff --git a/src/include/86box/version.h.in b/src/include/86box/version.h.in index 5ebf7dba9..17c5b3068 100644 --- a/src/include/86box/version.h.in +++ b/src/include/86box/version.h.in @@ -14,6 +14,8 @@ * * Copyright 2020 Miran Grca. */ +#ifndef EMU_VERSION_H +#define EMU_VERSION_H #define _LSTR(s) L ## s #define LSTR(s) _LSTR(s) @@ -58,3 +60,5 @@ # define EMU_DOCS_URL "https://86box.readthedocs.io" #endif #define EMU_DOCS_URL_W LSTR(EMU_DOCS_URL) + +#endif /*EMU_VERSION_H*/ diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index def3f0f2b..57e98cc44 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -41,6 +41,10 @@ typedef union { typedef struct ibm8514_t { rom_t bios_rom; + rom_t bios_rom2; + mem_mapping_t bios_mapping; + uint8_t *rom1; + uint8_t *rom2; hwcursor8514_t hwcursor; hwcursor8514_t hwcursor_latch; uint8_t pos_regs[8]; @@ -50,7 +54,7 @@ typedef struct ibm8514_t { int type; int local; int bpp; - int on[2]; + int on; int accel_bpp; uint32_t vram_size; @@ -100,6 +104,8 @@ typedef struct ibm8514_t { uint16_t frgd_mix; uint16_t multifunc_cntl; uint16_t multifunc[16]; + uint16_t clip_right; + uint16_t clip_bottom; int16_t clip_left; int16_t clip_top; uint8_t pix_trans[2]; @@ -110,8 +116,6 @@ typedef struct ibm8514_t { int x3; int y1; int y2; - int sys_cnt; - int sys_cnt2; int temp_cnt; int16_t cx; int16_t cx_back; @@ -125,21 +129,16 @@ typedef struct ibm8514_t { int16_t err; uint32_t src; uint32_t dest; - uint32_t newsrc_blt; - uint32_t newdest_blt; - uint32_t newdest_in; - uint32_t newdest_out; - uint8_t *writemono; - uint8_t *nibbleset; int x_count; int xx_count; int y_count; int input; + int input2; int output; + int output2; - uint16_t cur_x_bit12; - uint16_t cur_y_bit12; int ssv_len; + int ssv_len_back; uint8_t ssv_dir; uint8_t ssv_draw; int odd_in; @@ -154,7 +153,6 @@ typedef struct ibm8514_t { } accel; uint16_t test; - int vendor_mode[2]; int h_blankstart; int h_blank_end_val; int hblankstart; @@ -203,18 +201,23 @@ typedef struct ibm8514_t { int hsync_width; int htotal; int hdisp; + int hdisp2; int hdisped; int sc; int vsyncstart; int vsyncwidth; int vtotal; int v_disp; + int v_disp2; int vdisp; + int vdisp2; int disp_cntl; int interlace; uint8_t subsys_cntl; uint8_t subsys_stat; + atomic_int fifo_idx; + atomic_int ext_fifo_idx; atomic_int force_busy; atomic_int force_busy2; @@ -225,6 +228,11 @@ typedef struct ibm8514_t { int ext_pitch; int ext_crt_pitch; int extensions; + int linear; + uint32_t vram_amount; + int vram_512k_8514; + int vendor_mode; + PALETTE _8514pal; latch8514_t latch; } ibm8514_t; diff --git a/src/include/86box/vid_8514a_device.h b/src/include/86box/vid_8514a_device.h new file mode 100644 index 000000000..b4102b17a --- /dev/null +++ b/src/include/86box/vid_8514a_device.h @@ -0,0 +1,25 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the 8514/A card from IBM for the MCA bus and + * generic ISA bus clones without vendor extensions. + * + * + * + * Authors: TheCollector1995 + * + * Copyright 2024 TheCollector1995. + */ +#ifndef VIDEO_8514A_DEVICE_H +#define VIDEO_8514A_DEVICE_H + +#ifdef EMU_DEVICE_H +extern const device_t ibm8514_mca_device; +extern const device_t gen8514_isa_device; +#endif +#endif /*VIDEO_XGA_DEVICE_H*/ diff --git a/src/include/86box/vid_ati_eeprom.h b/src/include/86box/vid_ati_eeprom.h index 99af36eda..c52b5bd4b 100644 --- a/src/include/86box/vid_ati_eeprom.h +++ b/src/include/86box/vid_ati_eeprom.h @@ -47,7 +47,8 @@ typedef struct ati_eeprom_t { } ati_eeprom_t; void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); -void ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn); +void ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn, int mca); +void ati_eeprom_load_mach8_vga(ati_eeprom_t *eeprom, char *fn); void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/src/include/86box/vid_ati_mach8.h b/src/include/86box/vid_ati_mach8.h index a25432920..849446def 100644 --- a/src/include/86box/vid_ati_mach8.h +++ b/src/include/86box/vid_ati_mach8.h @@ -41,8 +41,6 @@ typedef struct mach_t { int ramdac_type; int old_mode; - uint32_t memory; - uint16_t config1; uint16_t config2; @@ -73,9 +71,7 @@ typedef struct mach_t { uint8_t bank_r; uint16_t shadow_set; uint16_t shadow_cntl; - int ext_on[2]; - int extended_mode; - int compat_mode; + int override_resolution; struct { uint8_t line_idx; @@ -84,6 +80,12 @@ typedef struct mach_t { uint8_t patt_len; uint8_t pix_trans[2]; uint8_t eeprom_control; + uint8_t alu_bg_fn; + uint8_t alu_fg_fn; + uint16_t clip_left; + uint16_t clip_right; + uint16_t clip_top; + uint16_t clip_bottom; uint16_t dest_x_end; uint16_t dest_x_start; uint16_t dest_y_end; @@ -102,14 +104,14 @@ typedef struct mach_t { uint16_t ge_offset_hi; uint16_t linedraw_opt; uint16_t max_waitstates; - uint8_t patt_data_idx; - uint8_t patt_data[0x18]; uint16_t scan_to_x; uint16_t scratch0; uint16_t scratch1; uint16_t test; uint16_t pattern; uint16_t test2; + int patt_data_idx_reg; + int patt_data_idx; int src_y_dir; int cmd_type; int block_write_mono_pattern_enable; @@ -144,9 +146,8 @@ typedef struct mach_t { int stepx; int stepy; int src_stepx; - uint8_t color_pattern[16]; - uint8_t color_pattern_full[32]; - uint16_t color_pattern_word[8]; + uint8_t mono_pattern_normal[16]; + uint8_t color_pattern[32]; int mono_pattern[8][8]; uint32_t ge_offset; uint32_t crt_offset; diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index 5b6a2dea2..a503d12ba 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -31,6 +31,8 @@ typedef struct cga_t { uint8_t cgamode; uint8_t cgacol; + uint8_t lp_strobe; + int fontbase; int linepos; int displine; diff --git a/src/include/86box/vid_ogc.h b/src/include/86box/vid_ogc.h index 839769e69..efafb180e 100644 --- a/src/include/86box/vid_ogc.h +++ b/src/include/86box/vid_ogc.h @@ -23,6 +23,7 @@ typedef struct ogc_t { cga_t cga; + uint16_t ctrl_addr; /* unused in OGC, required for M19 video card structure idiom */ uint8_t ctrl_3dd; uint8_t ctrl_3de; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 72b755cf1..afff6e211 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -79,6 +79,7 @@ typedef struct svga_t { uint8_t fcr; uint8_t hblank_overscan; uint8_t vidsys_ena; + uint8_t sleep; int dac_addr; int dac_pos; @@ -87,6 +88,7 @@ typedef struct svga_t { int dac_b; int vtotal; int dispend; + int vdisp; int vsyncstart; int split; int vblankstart; @@ -170,9 +172,11 @@ typedef struct svga_t { pc_timer_t timer; pc_timer_t timer8514; + pc_timer_t timer_xga; double clock; double clock8514; + double clock_xga; double multiplier; @@ -185,6 +189,7 @@ typedef struct svga_t { void (*render)(struct svga_t *svga); void (*render8514)(struct svga_t *svga); + void (*render_xga)(struct svga_t *svga); void (*recalctimings_ex)(struct svga_t *svga); void (*video_out)(uint16_t addr, uint8_t val, void *priv); @@ -198,6 +203,14 @@ typedef struct svga_t { void (*vblank_start)(struct svga_t *svga); + void (*write)(uint32_t addr, uint8_t val, void *priv); + void (*writew)(uint32_t addr, uint16_t val, void *priv); + void (*writel)(uint32_t addr, uint32_t val, void *priv); + + uint8_t (*read)(uint32_t addr, void *priv); + uint16_t (*readw)(uint32_t addr, void *priv); + uint32_t (*readl)(uint32_t addr, void *priv); + void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr); float (*getclock)(int clock, void *priv); float (*getclock8514)(int clock, void *priv); @@ -299,8 +312,7 @@ typedef struct svga_t { void * xga; } svga_t; -extern int vga_on; - +extern void ibm8514_set_poll(svga_t *svga); extern void ibm8514_poll(void *priv); extern void ibm8514_recalctimings(svga_t *svga); extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); @@ -315,16 +327,21 @@ extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); -#ifdef ATI_8514_ULTRA +extern void ati8514_out(uint16_t addr, uint8_t val, void *priv); +extern uint8_t ati8514_in(uint16_t addr, void *priv); extern void ati8514_recalctimings(svga_t *svga); extern uint8_t ati8514_mca_read(int port, void *priv); extern void ati8514_mca_write(int port, uint8_t val, void *priv); extern void ati8514_pos_write(uint16_t port, uint8_t val, void *priv); extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); -#endif -extern void xga_poll(void *priv, svga_t *svga); -extern void xga_recalctimings(svga_t *svga); +extern void xga_write_test(uint32_t addr, uint8_t val, void *priv); +extern uint8_t xga_read_test(uint32_t addr, void *priv); +extern void xga_set_poll(svga_t *svga); +extern void xga_poll(void *priv); +extern void xga_recalctimings(svga_t *svga); + +extern uint32_t svga_decode_addr(svga_t *svga, uint32_t addr, int write); extern int svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), @@ -367,6 +384,8 @@ uint32_t svga_mask_addr(uint32_t addr, svga_t *svga); uint32_t svga_mask_changedaddr(uint32_t addr, svga_t *svga); void svga_doblit(int wx, int wy, svga_t *svga); +void svga_set_poll(svga_t *svga); +void svga_poll(void *priv); enum { RAMDAC_6BIT = 0, @@ -394,6 +413,9 @@ extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); extern float av9194_getclock(int clock, void *priv); +extern void bt481_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t bt481_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); + extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); extern uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); extern void bt48x_recalctimings(void *priv, svga_t *svga); @@ -450,6 +472,7 @@ extern const device_t att491_ramdac_device; extern const device_t att492_ramdac_device; extern const device_t att498_ramdac_device; extern const device_t av9194_device; +extern const device_t bt481_ramdac_device; extern const device_t bt484_ramdac_device; extern const device_t att20c504_ramdac_device; extern const device_t bt485_ramdac_device; diff --git a/src/include/86box/vid_vga.h b/src/include/86box/vid_vga.h index 62cee8e9f..26b5a7f71 100644 --- a/src/include/86box/vid_vga.h +++ b/src/include/86box/vid_vga.h @@ -28,10 +28,8 @@ typedef struct vga_t { rom_t bios_rom; } vga_t; -static video_timings_t timing_vga = { VIDEO_ISA, 8, 16, 32, 8, 16, 32 }; - -void vga_out(uint16_t addr, uint8_t val, void *priv); -uint8_t vga_in(uint16_t addr, void *priv); +extern void vga_out(uint16_t addr, uint8_t val, void *priv); +extern uint8_t vga_in(uint16_t addr, void *priv); void vga_disable(void* p); void vga_enable(void* p); diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index dc0ebce72..e8b7299f2 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -2157,6 +2157,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xc2); } + addbyte(0xf3); /*MOVQ XMM15(colbfog), XMM0 */ + addbyte(0x44); + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xf8); + if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ @@ -2580,17 +2586,17 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xef); addbyte(0xe4); break; - case AFUNC_ASATURATE: - addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/ + case AFUNC_ACOLORBEFOREFOG: + addbyte(0x66); /*PMULLW XMM4, XMM15(colbfog)*/ addbyte(0x41); addbyte(0x0f); addbyte(0xd5); - addbyte(0xe3); + addbyte(0xe7); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ addbyte(0x41); addbyte(0x0f); addbyte(0xfd); @@ -2610,6 +2616,7 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x71); addbyte(0xd4); addbyte(8); + break; } switch (src_afunc) { @@ -2762,7 +2769,36 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xef); addbyte(0xc0); break; - case AFUNC_ACOLORBEFOREFOG: + case AFUNC_ASATURATE: + addbyte(0x66); /*PMULLW XMM0, XMM11(minus_254)*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xd5); + addbyte(0xc3); + addbyte(0xf3); /*MOVQ XMM5, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xe8); + addbyte(0x66); /*PADDW XMM0, alookup[1*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xfd); + addbyte(0x42); + addbyte(8 * 2); + addbyte(0x66); /*PSRLW XMM5, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd5); + addbyte(8); + addbyte(0x66); /*PADDW XMM0, XMM5*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc5); + addbyte(0x66); /*PSRLW XMM0, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd0); + addbyte(8); break; } diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 96865ac6d..5ab63ec3a 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -408,6 +408,7 @@ typedef struct voodoo_t { atomic_int cmd_read; atomic_int cmd_written; atomic_int cmd_written_fifo; + atomic_int cmd_written_fifo_2; voodoo_params_t params_buffer[PARAM_SIZE]; atomic_int params_read_idx[4]; @@ -426,7 +427,20 @@ typedef struct voodoo_t { uint32_t cmdfifo_amax; int cmdfifo_holecount; - atomic_uint cmd_status; + uint32_t cmdfifo_base_2; + uint32_t cmdfifo_end_2; + uint32_t cmdfifo_size_2; + int cmdfifo_rp_2; + int cmdfifo_ret_addr_2; + int cmdfifo_in_sub_2; + atomic_int cmdfifo_depth_rd_2; + atomic_int cmdfifo_depth_wr_2; + atomic_int cmdfifo_enabled_2; + uint32_t cmdfifo_amin_2; + uint32_t cmdfifo_amax_2; + int cmdfifo_holecount_2; + + atomic_uint cmd_status, cmd_status_2; uint32_t sSetupMode; vert_t verts[4]; diff --git a/src/include/86box/vid_voodoo_regs.h b/src/include/86box/vid_voodoo_regs.h index f05029a8d..6aeb98bcc 100644 --- a/src/include/86box/vid_voodoo_regs.h +++ b/src/include/86box/vid_voodoo_regs.h @@ -338,17 +338,22 @@ enum { }; enum { - LFB_FORMAT_RGB565 = 0, - LFB_FORMAT_RGB555 = 1, - LFB_FORMAT_ARGB1555 = 2, - LFB_FORMAT_ARGB8888 = 5, - LFB_FORMAT_DEPTH = 15, - LFB_FORMAT_MASK = 15 + LFB_FORMAT_RGB565 = 0, + LFB_FORMAT_RGB555 = 1, + LFB_FORMAT_ARGB1555 = 2, + LFB_FORMAT_XRGB8888 = 4, + LFB_FORMAT_ARGB8888 = 5, + LFB_FORMAT_DEPTH_RGB565 = 12, + LFB_FORMAT_DEPTH_RGB555 = 13, + LFB_FORMAT_DEPTH_ARGB1555 = 14, + LFB_FORMAT_DEPTH = 15, + LFB_FORMAT_MASK = 15 }; enum { LFB_WRITE_COLOUR = 1, - LFB_WRITE_DEPTH = 2 + LFB_WRITE_DEPTH = 2, + LFB_WRITE_BOTH = 4 }; enum { diff --git a/src/include/86box/vid_voodoo_render.h b/src/include/86box/vid_voodoo_render.h index cd1962430..e88d21dd5 100644 --- a/src/include/86box/vid_voodoo_render.h +++ b/src/include/86box/vid_voodoo_render.h @@ -210,11 +210,10 @@ void voodoo_codegen_close(voodoo_t *voodoo); newdest_g = (dest_g * (255 - dest_a)) / 255; \ newdest_b = (dest_b * (255 - dest_a)) / 255; \ break; \ - case AFUNC_ASATURATE: \ - _a = MIN(src_a, 1 - dest_a); \ - newdest_r = (dest_r * _a) / 255; \ - newdest_g = (dest_g * _a) / 255; \ - newdest_b = (dest_b * _a) / 255; \ + case AFUNC_ACOLORBEFOREFOG: \ + newdest_r = (dest_r * colbfog_r) / 255; \ + newdest_g = (dest_g * colbfog_g) / 255; \ + newdest_b = (dest_b * colbfog_b) / 255; \ break; \ } \ \ @@ -254,8 +253,11 @@ void voodoo_codegen_close(voodoo_t *voodoo); src_g = (src_g * (255 - dest_a)) / 255; \ src_b = (src_b * (255 - dest_a)) / 255; \ break; \ - case AFUNC_ACOLORBEFOREFOG: \ - fatal("AFUNC_ACOLORBEFOREFOG\n"); \ + case AFUNC_ASATURATE: \ + _a = MIN(src_a, 255 - dest_a); \ + src_r = (dest_r * _a) / 255; \ + src_g = (dest_g * _a) / 255; \ + src_b = (dest_b * _a) / 255; \ break; \ } \ \ diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index e5248b309..b2001dba9 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -35,7 +35,7 @@ typedef struct xga_t { mem_mapping_t linear_mapping; mem_mapping_t video_mapping; rom_t bios_rom; - rom_t vga_bios_rom; + rom_t bios_rom2; xga_hwcursor_t hwcursor; xga_hwcursor_t hwcursor_latch; PALETTE extpal; @@ -47,6 +47,8 @@ typedef struct xga_t { uint8_t pos_regs[8]; uint8_t disp_addr; + uint8_t dac_mask; + uint8_t dac_status; uint8_t cfg_reg; uint8_t instance; uint8_t op_mode; @@ -85,6 +87,8 @@ typedef struct xga_t { 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; @@ -106,6 +110,10 @@ typedef struct xga_t { uint16_t old_pal_addr_idx; uint16_t sprite_pal_addr_idx_prefetch; + int dac_addr; + int dac_pos; + int dac_r; + int dac_g; int v_total; int dispend; int v_syncstart; @@ -143,6 +151,7 @@ typedef struct xga_t { int a5_test; int type; int bus; + int busy; uint32_t linear_base; uint32_t linear_size; @@ -161,6 +170,9 @@ typedef struct xga_t { uint32_t write_bank; uint32_t px_map_base; uint32_t pallook[512]; + uint32_t bios_diag; + + PALETTE xgapal; uint64_t dispontime; uint64_t dispofftime; @@ -228,8 +240,6 @@ typedef struct xga_t { uint16_t px_map_height[4]; uint32_t px_map_base[4]; } accel; - - int big_endian_linear; } xga_t; #endif /*VIDEO_XGA_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 3db41d2ab..7ad29838c 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -329,13 +329,14 @@ extern const device_t ati18800_device; /* ATi 28800 */ extern const device_t ati28800_device; +extern const device_t ati28800_wonder1024d_xl_plus_device; extern const device_t ati28800k_device; extern const device_t ati28800k_spc4620p_device; extern const device_t ati28800k_spc6033p_device; extern const device_t compaq_ati28800_device; -# if defined(DEV_BRANCH) && defined(USE_XL24) +# ifdef USE_XL24 extern const device_t ati28800_wonderxl24_device; -# endif +# endif /* USE_XL24 */ /* Bochs */ extern const device_t bochs_svga_device; @@ -451,7 +452,7 @@ extern const device_t mystique_220_device; extern const device_t millennium_ii_device; #ifdef USE_G100 extern const device_t productiva_g100_device; -#endif +#endif /* USE_G100 */ /* Oak OTI-0x7 */ extern const device_t oti037c_device; @@ -530,7 +531,9 @@ extern const device_t s3_trio64v2_dx_onboard_pci_device; /* S3 ViRGE */ extern const device_t s3_virge_325_pci_device; +extern const device_t s3_virge_325_onboard_pci_device; extern const device_t s3_diamond_stealth_2000_pci_device; +extern const device_t s3_mirocrystal_3d_pci_device; extern const device_t s3_diamond_stealth_3000_pci_device; extern const device_t s3_stb_velocity_3d_pci_device; extern const device_t s3_virge_375_pci_device; diff --git a/src/include/86box/zip.h b/src/include/86box/zip.h index a4a4c341f..06c6e8485 100644 --- a/src/include/86box/zip.h +++ b/src/include/86box/zip.h @@ -13,7 +13,7 @@ * * Authors: Miran Grca, * - * Copyright 2018-2019 Miran Grca. + * Copyright 2018-2025 Miran Grca. */ #ifndef EMU_ZIP_H @@ -29,7 +29,7 @@ #define ZIP_250_SECTORS (489532) -#define ZIP_IMAGE_HISTORY 4 +#define ZIP_IMAGE_HISTORY 10 enum { ZIP_BUS_DISABLED = 0, @@ -39,85 +39,79 @@ enum { }; typedef struct zip_drive_t { - uint8_t id; + uint8_t id; union { - uint8_t res; - uint8_t res0; /* Reserved for other ID's. */ - uint8_t res1; - uint8_t ide_channel; - uint8_t scsi_device_id; + uint8_t 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; + 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; + FILE * fp; + void * priv; - char image_path[1024]; - char prev_image_path[1024]; + char image_path[1024]; + char prev_image_path[1024]; - char *image_history[ZIP_IMAGE_HISTORY]; + char * image_history[ZIP_IMAGE_HISTORY]; - uint32_t is_250; - uint32_t medium_size; - uint32_t base; + 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; + zip_drive_t * drv; #ifdef EMU_IDE_H - ide_tf_t * tf; + ide_tf_t * tf; #else - void * tf; + void * tf; #endif - uint8_t *buffer; - uint8_t atapi_cdb[16]; - uint8_t current_cdb[16]; - uint8_t sense[256]; + void * log; -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t features; - uint8_t phase; - uint16_t request_length; - uint8_t status; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif + uint8_t * 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; + uint8_t id; + uint8_t cur_lun; + uint8_t pad0; + uint8_t pad1; - uint16_t max_transfer_len; - uint16_t pad2; + uint16_t max_transfer_len; + uint16_t pad2; - int requested_blocks; - int packet_status; - int total_length; - int do_page_save; - int unit_attention; - int request_pos; - int old_len; - int pad3; + 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 sector_pos; + uint32_t sector_len; + uint32_t packet_len; - double callback; + double callback; + + uint8_t (*ven_cmd)(void *sc, uint8_t *cdb, int32_t *BufLen); } zip_t; extern zip_t *zip[ZIP_NUM]; @@ -127,6 +121,7 @@ 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] @@ -134,15 +129,16 @@ extern uint8_t scsi_zip_drives[16]; extern "C" { #endif -extern void zip_disk_close(zip_t *dev); -extern void zip_disk_reload(zip_t *dev); +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_load(zip_t *dev, char *fn); +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 diff --git a/src/ini.c b/src/ini.c index 616245786..78c873758 100644 --- a/src/ini.c +++ b/src/ini.c @@ -181,7 +181,45 @@ delete_section_if_empty(list_t *head, section_t *section) if (section == NULL) return; - if (entries_num(section) == 0) { + int n = entries_num(section); + + if (n > 0) { + int i = 0; + entry_t *i_ent = (entry_t *) section->entry_head.next; + + while (i_ent != NULL) { + int i_nlen = strlen(i_ent->name); + entry_t* i_next = (entry_t *) i_ent->list.next; + + if (i_nlen > 0) { + int j = 0; + entry_t *j_ent = (entry_t *) section->entry_head.next; + + while (j_ent != NULL) { + int j_nlen = strlen(j_ent->name); + entry_t* j_next = (entry_t *) j_ent->list.next; + if (j_nlen > 0) { + if ((j != i) && (strcmp(j_ent->name, i_ent->name) > 0)) { + entry_t t_ent = { 0 }; + memcpy(&t_ent, j_ent, sizeof(entry_t)); + /* J: Contents of I, list of J */ + memcpy(j_ent->name, i_ent->name, sizeof(entry_t) - sizeof(i_ent->list)); + /* I: Contents of J, list of I */ + memcpy(i_ent->name, t_ent.name, sizeof(entry_t) - sizeof(i_ent->list)); + } + + j++; + } + + j_ent = (entry_t *) j_next; + } + + i++; + } + + i_ent = (entry_t *) i_next; + } + } else { list_delete(§ion->list, head); free(section); } diff --git a/src/io.c b/src/io.c index fd87089d0..27f8503b0 100644 --- a/src/io.c +++ b/src/io.c @@ -15,7 +15,7 @@ * Fred N. van Kempen, * * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -145,6 +145,8 @@ io_sethandler_common(uint16_t base, int size, q->next = NULL; io_last[base + c] = q; + + q = NULL; } } diff --git a/src/ioapic.c b/src/ioapic.c index c3939f249..ea0811f91 100644 --- a/src/ioapic.c +++ b/src/ioapic.c @@ -117,12 +117,12 @@ ioapic_init(UNUSED(const device_t *info)) const device_t ioapic_device = { .name = "I/O Advanced Programmable Interrupt Controller", .internal_name = "ioapic", - .flags = DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = ioapic_init, .close = ioapic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/log.c b/src/log.c index b5267d70b..c8dddf62e 100644 --- a/src/log.c +++ b/src/log.c @@ -6,18 +6,19 @@ * * This file is part of the 86Box distribution. * - * The handler of the new logging system. - * - * + * New logging system handler. * * Authors: Miran Grca, * Fred N. van Kempen, - * - * Copyright 2021 Miran Grca. - * Copyright 2021 Fred N. van Kempen. + * Connor Hyde, + * + * Copyright 2021-25 Miran Grca. + * Copyright 2021-25 Fred N. van Kempen. + * Copyright 2025 Connor Hyde. */ #include #include +#include #include #include #include @@ -34,15 +35,56 @@ #include <86box/version.h> #include <86box/log.h> -#ifndef RELEASE_BUILD typedef struct log_t { - char buff[1024]; - char *dev_name; - int seen; - int suppr_seen; + char buff[1024]; + char dev_name[1024]; + int seen; + int suppr_seen; + /* Cyclical log buffer. */ + char **cyclic_buff; + int32_t cyclic_last_line; + int32_t log_cycles; } log_t; -extern FILE *stdlog; /* file to log output to */ +/* File to log output to. */ +extern FILE *stdlog; +/* Functions only used in this translation unit. */ +void log_ensure_stdlog_open(void); + +void +log_set_dev_name(void *priv, char *dev_name) +{ + log_t *log = (log_t *) priv; + + memcpy(log->dev_name, dev_name, strlen(dev_name) + 1); +} + +static void +log_copy(log_t *log, char *dest, const char *src, size_t dest_size) +{ + memset(dest, 0x00, dest_size * sizeof(char)); + + if ((log != NULL) && strcmp(log->dev_name, "")) { + strcat(dest, log->dev_name); + strcat(dest, ": "); + } + + strcat(dest, src); +} + +#ifndef RELEASE_BUILD +void +log_ensure_stdlog_open(void) +{ + if (stdlog == NULL) { + if (log_path[0] != '\0') { + stdlog = plat_fopen(log_path, "w"); + if (stdlog == NULL) + stdlog = stdout; + } else + stdlog = stdout; + } +} void log_set_suppr_seen(void *priv, int suppr_seen) @@ -52,31 +94,12 @@ log_set_suppr_seen(void *priv, int suppr_seen) log->suppr_seen = suppr_seen; } -void -log_set_dev_name(void *priv, char *dev_name) -{ - log_t *log = (log_t *) priv; - - log->dev_name = dev_name; -} - -static void -log_copy(log_t *log, char *dest, const char *src, size_t dest_size) -{ - memset(dest, 0x00, dest_size * sizeof(char)); - if (log && log->dev_name && strcmp(log->dev_name, "")) { - strcat(dest, log->dev_name); - strcat(dest, ": "); - } - strcat(dest, src); -} - /* - * Log something to the logfile or stdout. - * - * To avoid excessively-large logfiles because some - * module repeatedly logs, we keep track of what is - * being logged, and catch repeating entries. + Log something to the logfile or stdout. + + To avoid excessively-large logfiles because some + module repeatedly logs, we keep track of what is + being logged, and catch repeating entries. */ void log_out(void *priv, const char *fmt, va_list ap) @@ -86,37 +109,165 @@ log_out(void *priv, const char *fmt, va_list ap) char fmt2[1024]; if (log == NULL) - return; + pclog("WARNING: Logging called with a NULL log pointer\n"); + else if (fmt == NULL) + pclog("WARNING: Logging called with a NULL format pointer\n"); + else if (fmt[0] != '\0') { + log_ensure_stdlog_open(); - if (strcmp(fmt, "") == 0) - return; - - if (stdlog == NULL) { - if (log_path[0] != '\0') { - stdlog = plat_fopen(log_path, "w"); - if (stdlog == NULL) - stdlog = stdout; - } else - stdlog = stdout; - } - - vsprintf(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); + vsprintf(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); + } + log->seen = 0; + strcpy(log->buff, temp); + log_copy(log, fmt2, temp, 1024); + fprintf(stdlog, fmt2, ap); } - log->seen = 0; - strcpy(log->buff, temp); - log_copy(log, fmt2, temp, 1024); - fprintf(stdlog, fmt2, ap); - } - fflush(stdlog); + fflush(stdlog); + } } +/* + Starfrost, 7-8 January 2025: + + For RIVA 128 emulation I needed a way to suppress logging if a repeated + pattern of the same set of lines were found. + + Implements a version of the Rabin-Karp algorithm: + https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm . +*/ +void +log_out_cyclic(void* priv, const char* fmt, va_list ap) +{ + /* Get our new logging system instance. */ + log_t* log = (log_t*) priv; + + /* Does the log actually exist? */ + if (log == NULL) + pclog("WARNING: Cyclical logging called with a NULL log pointer\n"); + else if (log->cyclic_buff == NULL) + pclog("WARNING: Cyclical logging called with a non-cyclic log\n"); + else if (fmt == NULL) + pclog("WARNING: Cyclical logging called with a NULL format pointer\n"); + /* Is the string empty? */ + else if (fmt[0] != '\0') { + /* Ensure stdlog is open. */ + log_ensure_stdlog_open(); + + char temp[LOG_SIZE_BUFFER] = {0}; + + log->cyclic_last_line %= LOG_SIZE_BUFFER_CYCLIC_LINES; + + vsprintf(temp, fmt, ap); + + log_copy(log, log->cyclic_buff[log->cyclic_last_line], temp, + LOG_SIZE_BUFFER); + + uint32_t hashes[LOG_SIZE_BUFFER_CYCLIC_LINES] = {0}; + + /* Random numbers. */ + uint32_t base = 257; + uint32_t mod = 1000000007; + + uint32_t repeat_order = 0; + bool is_cycle = false; + + /* Compute the set of hashes for the current log buffer. */ + for (int32_t log_line = 0; log_line < LOG_SIZE_BUFFER_CYCLIC_LINES; + log_line++) { + if (log->cyclic_buff[log_line][0] == '\0') + continue; /* Skip. */ + + for (int32_t log_line_char = 0; log_line_char < LOG_SIZE_BUFFER; + log_line_char++) + hashes[log_line] = hashes[log_line] * base + + log->cyclic_buff[log_line][log_line_char] % mod; + } + + /* + Now see if there are real cycles. + We implement a minimum repeat size. + */ + for (int32_t check_size = LOG_MINIMUM_REPEAT_ORDER; + check_size < LOG_SIZE_BUFFER_CYCLIC_LINES / 2; check_size++) { + /* + TODO: Log what we need for cycle 1. + TODO: Command line option that lets us turn off this behaviour. + */ + for (int32_t log_line_to_check = 0; log_line_to_check < check_size; + log_line_to_check++) { + if (hashes[log_line_to_check] == + hashes[(log_line_to_check + check_size) % + LOG_SIZE_BUFFER_CYCLIC_LINES]) { + repeat_order = check_size; + break; + } + } + + is_cycle = (repeat_order != 0); + + /* If there still is a cycle, break. */ + if (is_cycle) + break; + + } + + if (is_cycle) { + if (log->cyclic_last_line % repeat_order == 0) { + log->log_cycles++; + + if (log->log_cycles == 1) { + /* + 'Replay' the last few log entries so they actually + show up. + + TODO: Is this right? + */ + + for (uint32_t index = log->cyclic_last_line - 1; + index > (log->cyclic_last_line - repeat_order); + index--) { + /* *Very important* to prevent out of bounds index. */ + uint32_t real_index = index % + LOG_SIZE_BUFFER_CYCLIC_LINES; + log_copy(log, temp, log->cyclic_buff[real_index], + LOG_SIZE_BUFFER); + + fprintf(stdlog, "%s", log->cyclic_buff[real_index]); + } + + /* Restore the original line. */ + log_copy(log, temp, + log->cyclic_buff[log->cyclic_last_line], + LOG_SIZE_BUFFER); + + /* Allow normal logging. */ + fprintf(stdlog, "%s", temp); + } + + if (log->log_cycles > 1 && log->log_cycles < 100) + fprintf(stdlog, "***** Cyclical Log Repeat of Order %d " + "#%d *****\n", repeat_order, log->log_cycles); + else if (log->log_cycles == 100) + fprintf(stdlog, "Logged the same cycle 100 times... " + "Silence until something interesting happens\n"); + } + } else { + log->log_cycles = 0; + fprintf(stdlog, "%s", temp); + } + + log->cyclic_last_line++; + } +} +#endif + void log_fatal(void *priv, const char *fmt, ...) { @@ -128,6 +279,13 @@ log_fatal(void *priv, const char *fmt, ...) if (log == NULL) return; + if (log->cyclic_buff != NULL) { + for (int i = 0; i < LOG_SIZE_BUFFER_CYCLIC_LINES; i++) + if (log->cyclic_buff[i] != NULL) + free(log->cyclic_buff[i]); + free(log->cyclic_buff); + } + va_start(ap, fmt); log_copy(log, fmt2, fmt, 1024); vsprintf(temp, fmt2, ap); @@ -136,19 +294,42 @@ log_fatal(void *priv, const char *fmt, ...) exit(-1); } -void * -log_open(char *dev_name) +static void * +log_open_common(const char *dev_name, const int cyclic) { - log_t *log = malloc(sizeof(log_t)); + log_t *log = calloc(1, sizeof(log_t)); - memset(log, 0, sizeof(log_t)); - - log->dev_name = dev_name; + memcpy(log->dev_name, dev_name, strlen(dev_name) + 1); log->suppr_seen = 1; + log->cyclic_last_line = 0; + log->log_cycles = 0; + + if (cyclic) { + log->cyclic_buff = calloc(LOG_SIZE_BUFFER_CYCLIC_LINES, + sizeof(char *)); + for (int i = 0; i < LOG_SIZE_BUFFER_CYCLIC_LINES; i++) + log->cyclic_buff[i] = calloc(LOG_SIZE_BUFFER, sizeof(char)); + } return (void *) log; } +void * +log_open(const char *dev_name) +{ + return log_open_common(dev_name, 0); +} + +/* + This is so that not all logs get the 32k cyclical buffer + they may not need. + */ +void * +log_open_cyclic(const char *dev_name) +{ + return log_open_common(dev_name, 1); +} + void log_close(void *priv) { @@ -156,4 +337,3 @@ log_close(void *priv) free(log); } -#endif diff --git a/src/lpt.c b/src/lpt.c index 3f1c5eb7b..26174d96b 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -219,14 +219,14 @@ lpt_init(void) lpt_ports[i].enable_irq = 0x10; if (lpt_ports[i].enabled) { - lpt_port_init(i, default_ports[i]); + lpt_port_setup(i, default_ports[i]); lpt_port_irq(i, default_irqs[i]); } } } void -lpt_port_init(int i, uint16_t port) +lpt_port_setup(int i, uint16_t port) { if (lpt_ports[i].enabled) { if (lpt_ports[i].addr != 0xffff) diff --git a/src/mac/CMakeLists.txt b/src/mac/CMakeLists.txt index bbdf1d5d5..0562ca01d 100644 --- a/src/mac/CMakeLists.txt +++ b/src/mac/CMakeLists.txt @@ -11,10 +11,12 @@ # Authors: dob205, # Jerome Vernet # David Hrdlička, +# Jasmine Iwanek, # # Copyright 2021 dob205. # Copyright 2021 Jerome Vernet. # Copyright 2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # # Pick the bundle icon depending on the release channel diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index ecc374e66..ff6a66801 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -9,20 +9,52 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c +add_library(mch OBJECT + machine.c + machine_table.c + m_xt.c + m_xt_compaq.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_europc.c m_elt.c m_xt_olivetti.c m_tandy.c m_v86p.c - m_at.c m_at_commodore.c - m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c - m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c - m_at_socket4.c m_at_socket5.c m_at_socket7_3v.c m_at_socket7.c - m_at_sockets7.c m_at_socket8.c m_at_slot1.c m_at_slot2.c m_at_socket370.c - m_at_misc.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_europc.c + m_elt.c + m_xt_olivetti.c + m_tandy.c + m_v86p.c + m_at.c + 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 + m_ps2_mca.c + m_at_compaq.c + m_at_286_386sx.c + m_at_386dx_486.c + m_at_socket4.c + m_at_socket5.c + m_at_socket7_3v.c + m_at_socket7.c + m_at_sockets7.c + m_at_socket8.c + m_at_slot1.c + m_at_slot2.c + m_at_socket370.c + m_at_misc.c +) if(AN430TX) target_compile_definitions(mch PRIVATE USE_AN430TX) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 530362b89..3dba578bd 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -619,8 +619,7 @@ vid_init_1512(amstrad_t *ams) amsvid_t *vid; /* Allocate a video controller block. */ - vid = (amsvid_t *) malloc(sizeof(amsvid_t)); - memset(vid, 0x00, sizeof(amsvid_t)); + vid = (amsvid_t *) calloc(1, sizeof(amsvid_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_pc1512); @@ -726,7 +725,7 @@ const device_t vid_1512_device = { .init = NULL, .close = vid_close_1512, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_change_1512, .force_redraw = NULL, .config = vid_1512_config @@ -823,8 +822,7 @@ vid_init_1640(amstrad_t *ams) amsvid_t *vid; /* Allocate a video controller block. */ - vid = (amsvid_t *) malloc(sizeof(amsvid_t)); - memset(vid, 0x00, sizeof(amsvid_t)); + vid = (amsvid_t *) calloc(1, sizeof(amsvid_t)); rom_init(&vid->bios_rom, "roms/machines/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); @@ -906,7 +904,7 @@ const device_t vid_1640_device = { .init = NULL, .close = vid_close_1640, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed_1640, .force_redraw = NULL, .config = vid_1640_config @@ -1620,8 +1618,7 @@ vid_init_200(amstrad_t *ams) mda_t *mda; /* Allocate a video controller block. */ - vid = (amsvid_t *) malloc(sizeof(amsvid_t)); - memset(vid, 0x00, sizeof(amsvid_t)); + vid = (amsvid_t *) calloc(1, sizeof(amsvid_t)); vid->emulation = device_get_config_int("video_emulation"); @@ -1831,7 +1828,7 @@ const device_t vid_200_device = { .init = NULL, .close = vid_close_200, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed_200, .force_redraw = NULL, .config = vid_200_config @@ -1931,7 +1928,7 @@ const device_t vid_ppc512_device = { .init = NULL, .close = vid_close_200, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed_200, .force_redraw = NULL, .config = vid_ppc512_config @@ -1965,7 +1962,7 @@ const device_t vid_pc2086_device = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = vid_pc2086_config @@ -1999,7 +1996,7 @@ const device_t vid_pc3086_device = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = vid_pc3086_config @@ -2870,8 +2867,7 @@ machine_amstrad_init(const machine_t *model, int type) { amstrad_t *ams; - ams = (amstrad_t *) malloc(sizeof(amstrad_t)); - memset(ams, 0x00, sizeof(amstrad_t)); + ams = (amstrad_t *) calloc(1, sizeof(amstrad_t)); ams->type = type; amstrad_latch = 0x80000000; diff --git a/src/machine/m_at.c b/src/machine/m_at.c index 6343af4dc..3f5e88011 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -13,10 +13,12 @@ * Authors: Fred N. van Kempen, * Miran Grca, * Sarah Walker, + * Jasmine Iwanek, * * Copyright 2017-2020 Fred N. van Kempen. * Copyright 2016-2020 Miran Grca. * Copyright 2008-2020 Sarah Walker. + * Copyright 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 @@ -36,7 +38,6 @@ * Boston, MA 02111-1307 * USA. */ - #include #include #include @@ -53,6 +54,7 @@ #include <86box/fdc_ext.h> #include <86box/nvr.h> #include <86box/gameport.h> +#include <86box/ibm_5161.h> #include <86box/keyboard.h> #include <86box/lpt.h> #include <86box/rom.h> @@ -149,20 +151,81 @@ machine_at_ps2_ide_init(const machine_t *model) device_add(&ide_isa_device); } +static const device_config_t ibmat_config[] = { + // clang-format off + { + .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", "" } }, + + { .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", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmat_device = { + .name = " IBM AT Devices", + .internal_name = "ibmat_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmat_config +}; + int machine_at_ibm_init(const machine_t *model) { - int ret; + int ret = 0; + uint8_t enable_5161; + const char *fn[2]; - ret = bios_load_interleaved("roms/machines/ibmat/62x0820.u27", - "roms/machines/ibmat/62x0821.u47", - 0x000f0000, 65536, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + fn[0] = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + fn[1] = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); + ret = bios_load_interleaved(fn[0], fn[1], 0x000f0000, 65536, 0); + device_context_restore(); if (bios_only || !ret) return ret; machine_at_ibm_common_init(model); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -218,10 +281,41 @@ machine_at_ibmatpx_init(const machine_t *model) return ret; } +static const device_config_t ibmxt286_config[] = { + // clang-format off + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmxt286_device = { + .name = "IBM XT Model 286 Devices", + .internal_name = "ibmxt286_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt286_config +}; + int machine_at_ibmxt286_init(const machine_t *model) { - int ret; + int ret; + uint8_t enable_5161; + + device_context(model->device); + enable_5161 = machine_get_config_int("enable_5161"); + device_context_restore(); ret = bios_load_interleaved("roms/machines/ibmxt286/bios_5162_21apr86_u34_78x7460_27256.bin", "roms/machines/ibmxt286/bios_5162_21apr86_u35_78x7461_27256.bin", @@ -232,6 +326,9 @@ machine_at_ibmxt286_init(const machine_t *model) machine_at_ibm_common_init(model); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -275,7 +372,7 @@ machine_at_wellamerastar_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_OPEN_AT) +#ifdef USE_OPEN_AT int machine_at_openat_init(const machine_t *model) { @@ -291,4 +388,4 @@ machine_at_openat_init(const machine_t *model) return ret; } -#endif +#endif /* USE_OPEN_AT */ diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 4632e00df..cb2a04d07 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -66,7 +66,7 @@ machine_at_mr286_init(const machine_t *model) } static void -machine_at_headland_common_init(int type) +machine_at_headland_common_init(const machine_t *model, int type) { device_add(&keyboard_at_ami_device); @@ -94,7 +94,7 @@ machine_at_tg286m_init(const machine_t *model) machine_at_common_ide_init(model); - machine_at_headland_common_init(1); + machine_at_headland_common_init(model, 1); return ret; } @@ -115,7 +115,7 @@ machine_at_ama932j_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(&oti067_ama932j_device); - machine_at_headland_common_init(2); + machine_at_headland_common_init(model, 2); device_add(&ali5105_device); @@ -212,6 +212,33 @@ machine_at_neat_ami_init(const machine_t *model) return ret; } +// TODO +// Onboard Paradise PVGA1A-JK VGA Graphics +// Data Technology Corporation DTC7187 RLL Controller (Optional) +int +machine_at_ataripc4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN", + "roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&neat_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&keyboard_at_ami_device); + + return ret; +} + int machine_at_px286_init(const machine_t *model) { @@ -728,7 +755,7 @@ machine_at_acer100t_init(const machine_t *model) device_add(&ali1409_device); if (gfxcard[0] == VID_INTERNAL) - device_add(&oti077_acer100t_device); + device_add(&oti077_acer100t_device); device_add(&ali5105_device); @@ -770,7 +797,8 @@ machine_at_sbc350a_init(const machine_t *model) machine_at_common_init(model); device_add(&ali1217_device); - device_add(&fdc37c665_ide_device); + device_add(&ide_isa_device); + device_add(&fdc37c665_ide_pri_device); device_add(&keyboard_ps2_ami_device); return ret; @@ -965,7 +993,7 @@ machine_at_pc916sx_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +#ifdef USE_OLIVETTI int machine_at_m290_init(const machine_t *model) { @@ -988,4 +1016,4 @@ machine_at_m290_init(const machine_t *model) return ret; } -#endif +#endif /* USE_OLIVETTI */ diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 6b0ffae50..19c4b535e 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -48,7 +48,9 @@ #include <86box/hwm.h> #include <86box/machine.h> #include <86box/plat_unused.h> +#include <86box/sound.h> +/* 386DX */ int machine_at_acc386_init(const machine_t *model) { @@ -251,7 +253,7 @@ machine_at_ecs386v_init(const machine_t *model) int ret; ret = bios_load_linear("roms/machines/ecs386v/PANDA_386V.BIN", - 0x000f0000, 65536, 0); + 0x000f0000, 65536, 0); if (bios_only || !ret) return ret; @@ -683,14 +685,57 @@ machine_at_403tg_d_mr_init(const machine_t *model) return ret; } +static const device_config_t pb450_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pci10a", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "PCI 1.0A", .internal_name = "pb450" /*"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, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pb450/PNP11A.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pb450_device = { + .name = "Packard Bell PB450 Devices", + .internal_name = "pb450_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pb450_config +}; + int machine_at_pb450_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/pb450/OPTI802.bin", - 0x000e0000, 131072, 0); + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + if (bios_only || !ret) return ret; @@ -790,7 +835,7 @@ machine_at_mvi486_init(const machine_t *model) machine_at_common_init(model); - device_add(&opti895_device); + device_add(&opti495_device); device_add(&keyboard_at_device); device_add(&pc87311_ide_device); @@ -837,7 +882,7 @@ machine_at_vli486sv2g_init(const machine_t *model) return ret; machine_at_sis_85c471_common_init(model); - device_add(&keyboard_at_ami_device); + device_add(&keyboard_ps2_ami_device); return ret; } @@ -914,7 +959,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_ps2_ami_device); + device_add(&keyboard_at_ami_device); device_add(&sio_device); device_add(&intel_flash_bxt_ami_device); @@ -1352,7 +1397,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_ps2_ami_pci_device); /* Uses the AMIKEY KBC */ + device_add(&keyboard_at_ami_device); /* Uses the AMIKEY KBC */ device_add(&sio_device); device_add(&fdc37c663_ide_device); device_add(&sst_flash_29ee010_device); @@ -1368,7 +1413,7 @@ machine_at_amis76_init(const machine_t *model) { int ret; - ret = bios_load_linear_inverted("roms/machines/s76p/S76P.ROM", + ret = bios_load_linear_inverted("roms/machines/s76p/S76P.ROM", 0x000e0000, 131072, 0); if (bios_only || !ret) @@ -1962,6 +2007,48 @@ machine_at_hot433a_init(const machine_t *model) return ret; } +int +machine_at_pl4600c_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/pl4600c/SST29EE010.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); /* Slot 01 */ + pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); /* Slot 02 */ + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x12, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); /* Onboard */ + pci_register_slot(0x13, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard */ + + + device_add(&umc_hb4_device); + device_add(&umc_8886af_device); + device_add(&um8663af_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_ps2_ami_pci_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(&gd5430_onboard_pci_device); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&ess_1688_device); + + if (fdc_current[0] == FDC_INTERNAL){ + fdd_set_turbo(0, 1); + fdd_set_turbo(1, 1); + } + + return ret; +} + int machine_at_atc1415_init(const machine_t *model) { diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index 0b45fe60c..b9615c064 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -64,13 +64,13 @@ cbm_io_write(UNUSED(uint16_t port), uint8_t val, UNUSED(void *priv)) switch (val & 3) { case 1: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 2: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 3: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 0ac541e90..904122bad 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -629,8 +629,7 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self) static void * compaq_plasma_init(UNUSED(const device_t *info)) { - compaq_plasma_t *self = malloc(sizeof(compaq_plasma_t)); - memset(self, 0, sizeof(compaq_plasma_t)); + 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) @@ -714,7 +713,7 @@ const device_t compaq_plasma_device = { .init = compaq_plasma_init, .close = compaq_plasma_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = compaq_plasma_speed_changed, .force_redraw = NULL, .config = compaq_plasma_config diff --git a/src/machine/m_at_grid.c b/src/machine/m_at_grid.c new file mode 100644 index 000000000..03b7288b9 --- /dev/null +++ b/src/machine/m_at_grid.c @@ -0,0 +1,355 @@ +/* + * 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 GRiD GRiDcase 1520 + * + * The GRiDcase 1520 is a 286-based portable. + * These are HDDs supported by GRiD1520 (and probably other 15XX) BIOS + * "CP3022",5 + * "CP3024",5, 615,4,17 BIOS table type 2 + * "CP344",6, + * "CP3044",9, 980,5,17 BIOS table type 17 + * "CP3042",9 + * "CP3104",7, 776,8,33 extended type 224 (separate entry outside BIOS table) + * The only way to run unpatched BIOS is to run exactly that (or larger) + * geometry and report model name correctly in response to IDENTYIFY command. + * Alternatively you can use RomBuster to patch the BIOS. + * https://classicbits.net/coding-and-software/my-software/rombuster/ + */ +#include +#include +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/fdc_ext.h> +#include <86box/io.h> +#include <86box/keyboard.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/vid_cga.h> +#include <86box/plat_unused.h> + +#define GRID_APPROM_SELECT 0x440 +#define GRID_APPROM_ENABLE 0x405 + +/* +approm mapping regs? +XXX_7FA equ 7FAh +XXX_7F8 equ 7F8h +XXX_7F9 equ 7F9h +XXX_BD0 equ 0BD0h +XXX_BD1 equ 0BD1h +*/ + +#define GRID_EMS_PAGE_0 0x0258 +#define GRID_EMS_PAGE_1 0x4258 +#define GRID_EMS_PAGE_2 0x8258 +#define GRID_EMS_PAGE_3 0xC258 +#define GRID_TURBO 0x416 +#define GRID_UNUSED_424 0x424 +#define GRID_426 0x426 +#define GRID_HIGH_ENABLE 0xFFF +#define GRID_ROM_SUBSYSTEM 0x6F8 + +// EMS window +#define GRID_EMS_BASE 0xE0000 +#define GRID_EMS_PAGE_SIZE 0x4000 +#define GRID_EMS_PAGE_MASK 0x3FFF +#define GRID_EMS_PAGE_SHIFT 14 +// physical base of extended memory +#define GRID_EXTENDED_BASE 0xA0000 +#define GRID_1M 0x100000 + +typedef struct { + uint8_t grid_unknown; + uint8_t grid_unused_424; + uint8_t grid_426; + uint8_t grid_high_enable; + uint8_t grid_ems_page[4]; + mem_mapping_t grid_ems_mapping[4]; + uint8_t grid_turbo; + uint8_t grid_rom_enable; + uint8_t grid_rom_select; +} grid_t; + + +static uint32_t get_grid_ems_paddr(grid_t *dev, uint32_t addr) { + uint32_t slot = (addr >> GRID_EMS_PAGE_SHIFT) & 0x3; + uint32_t paddr = addr; + + if (dev->grid_ems_page[slot] & 0x80) + paddr = GRID_EXTENDED_BASE + ((uint32_t)(dev->grid_ems_page[slot] & 0x7F) << GRID_EMS_PAGE_SHIFT) + (addr & GRID_EMS_PAGE_MASK); + + return paddr; +} + +static void grid_ems_mem_write8(uint32_t addr, uint8_t val, void *priv) { + grid_t *dev = (grid_t *) priv; + + addr = get_grid_ems_paddr(dev, addr); + + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +static uint8_t grid_ems_mem_read8(uint32_t addr, void *priv) { + grid_t *dev = (grid_t *) priv; + uint8_t val = 0xFF; + + addr = get_grid_ems_paddr(dev, addr); + + if (addr < (mem_size << 10)) + val = ram[addr]; + + return val; +} + +static void grid_ems_mem_write16(uint32_t addr, uint16_t val, void *priv) { + grid_t *dev = (grid_t *) priv; + + addr = get_grid_ems_paddr(dev, addr); + + if (addr < (mem_size << 10)) + *(uint16_t *)&(ram[addr]) = val; +} + +static uint16_t grid_ems_mem_read16(uint32_t addr, void *priv) { + grid_t *dev = (grid_t *) priv; + uint16_t val = 0xFFFF; + + addr = get_grid_ems_paddr(dev, addr); + + if (addr < (mem_size << 10)) + val = *(uint16_t *)&(ram[addr]); + + return val; +} + +static void grid_ems_update_mapping(grid_t *dev, uint32_t slot) { + uint32_t vaddr = GRID_EMS_BASE + (slot << GRID_EMS_PAGE_SHIFT); + if (dev->grid_ems_page[slot] & 0x80) { + uint32_t paddr; + mem_mapping_enable(&dev->grid_ems_mapping[slot]); + paddr = get_grid_ems_paddr(dev, vaddr); + mem_mapping_set_exec(&dev->grid_ems_mapping[slot], ram + paddr); + } else { + mem_mapping_disable(&dev->grid_ems_mapping[slot]); + } +} + +static void grid_io_write(uint16_t port, uint8_t val, void *priv) { + grid_t *dev = (grid_t *) priv; + + switch (port) { + case GRID_426: + dev->grid_426 = val; + break; + case GRID_UNUSED_424: + dev->grid_unused_424 = val; + break; + case GRID_ROM_SUBSYSTEM: + case GRID_ROM_SUBSYSTEM+1: + case GRID_ROM_SUBSYSTEM+2: + case GRID_ROM_SUBSYSTEM+3: + case GRID_ROM_SUBSYSTEM+4: + case GRID_ROM_SUBSYSTEM+5: + case GRID_ROM_SUBSYSTEM+6: + case GRID_ROM_SUBSYSTEM+7: + break; + case GRID_APPROM_SELECT: + dev->grid_rom_select = val; + break; + case GRID_APPROM_ENABLE: + dev->grid_rom_enable = val; + break; + case GRID_TURBO: + if ((dev->grid_turbo ^ val) & 1) { + dev->grid_turbo = val; + if (dev->grid_turbo) + cpu_dynamic_switch(cpu); + else + cpu_dynamic_switch(0); /* 286/6 */ + } + break; + case GRID_EMS_PAGE_0: + case GRID_EMS_PAGE_1: + case GRID_EMS_PAGE_2: + case GRID_EMS_PAGE_3: { + uint32_t slot = (port >> 14) & 0x3; + if (dev->grid_ems_page[slot] == val) + break; // no change + + dev->grid_ems_page[slot] = val; + if (dev->grid_high_enable & 0x1) + break; // XMS is enabled + grid_ems_update_mapping(dev, slot); + + flushmmucache(); + break; + } + case GRID_HIGH_ENABLE: { + if (((val ^ dev->grid_high_enable) & 0x1) == 0) + break; // no change + dev->grid_high_enable = val; + if (dev->grid_high_enable & 0x1) { + for (uint8_t i = 0; i < 4; i++) + mem_mapping_disable(&dev->grid_ems_mapping[i]); + mem_mapping_enable(&ram_high_mapping); + } else { + mem_mapping_disable(&ram_high_mapping); + for (uint8_t i = 0; i < 4; i++) + grid_ems_update_mapping(dev, i); + } + flushmmucache(); + break; + } + default: + break; + } +} + +static uint8_t grid_io_read(uint16_t port, void *priv) { + grid_t *dev = (grid_t *) priv; + + switch (port) { + case GRID_426: + return dev->grid_426; + break; + case GRID_UNUSED_424: + return dev->grid_unused_424; + break; + case GRID_ROM_SUBSYSTEM: + return 0x99; + break; + case GRID_ROM_SUBSYSTEM+1: + case GRID_ROM_SUBSYSTEM+2: + case GRID_ROM_SUBSYSTEM+3: + case GRID_ROM_SUBSYSTEM+4: + case GRID_ROM_SUBSYSTEM+5: + case GRID_ROM_SUBSYSTEM+6: + case GRID_ROM_SUBSYSTEM+7: + break; + case GRID_APPROM_SELECT: + return dev->grid_rom_select; + case GRID_APPROM_ENABLE: + return dev->grid_rom_enable; + case GRID_TURBO: + return dev->grid_turbo; + case GRID_HIGH_ENABLE: + return dev->grid_high_enable; + case GRID_EMS_PAGE_0: + case GRID_EMS_PAGE_1: + case GRID_EMS_PAGE_2: + case GRID_EMS_PAGE_3: { + uint32_t slot = (port >> 14) & 0x3; + + return dev->grid_ems_page[slot]; + } + default: + break; + } + + return 0xff; +} + +static void * +grid_init(UNUSED(const device_t *info)) +{ + grid_t *dev = calloc(1, sizeof(grid_t)); + + io_sethandler(GRID_ROM_SUBSYSTEM, 0x0008, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_UNUSED_424, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_426, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_APPROM_SELECT, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_APPROM_ENABLE, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_TURBO, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + dev->grid_turbo = 0x1; + + io_sethandler(GRID_HIGH_ENABLE, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_EMS_PAGE_0, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_EMS_PAGE_1, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_EMS_PAGE_2, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + io_sethandler(GRID_EMS_PAGE_3, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev); + + dev->grid_high_enable = 1; + for (uint8_t slot = 0; slot < 4; slot++) { + dev->grid_ems_page[slot] = 0; + mem_mapping_add(&dev->grid_ems_mapping[slot], GRID_EMS_BASE + (slot << GRID_EMS_PAGE_SHIFT), GRID_EMS_PAGE_SIZE, grid_ems_mem_read8, grid_ems_mem_read16, NULL, + grid_ems_mem_write8, grid_ems_mem_write16, NULL, ram + GRID_EXTENDED_BASE + (slot << GRID_EMS_PAGE_SHIFT), MEM_MAPPING_EXTERNAL, dev); + mem_mapping_disable(&dev->grid_ems_mapping[slot]); + } + flushmmucache(); + return dev; +} + +static void grid_close(void *priv) { + grid_t *dev = (grid_t *) priv; + + free(dev); +} + +static void grid_reset(void *priv) { + grid_t *dev = (grid_t *) priv; + + dev->grid_high_enable = 1; + mem_mapping_enable(&ram_high_mapping); + dev->grid_turbo = 0x1; + for (uint8_t slot = 0; slot < 4; slot++) { + dev->grid_ems_page[slot] = 0; + mem_mapping_disable(&dev->grid_ems_mapping[slot]); + } + flushmmucache(); + dev->grid_unknown = 0; + dev->grid_unused_424 = 0; + dev->grid_426 = 0; + dev->grid_rom_enable = 0; + dev->grid_rom_select = 0; +} + +const device_t grid_device = { + .name = "GRiDcase 1520 chipset", + .internal_name = "grid1520", + .flags = 0, + .local = 0, + .init = grid_init, + .close = grid_close, + .reset = grid_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +int machine_at_grid1520_init(const machine_t *model) { + int ret = 0; + + ret = bios_load_linear("roms/machines/grid1520/grid1520_891025.rom", + 0x000f8000, 0x8000, 0); + if (bios_only || !ret) + return ret; + + machine_at_common_ide_init(model); + mem_remap_top(384); + + device_add(&keyboard_at_device); + // for now just select CGA with amber monitor + //device_add(&cga_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&grid_device); + + return ret; +} diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index a870d4c59..a3ff921e3 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -359,6 +359,37 @@ machine_at_bf6_init(const machine_t *model) return ret; } +int +machine_at_bx6_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/bx6/BX6_EG.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&keyboard_ps2_pci_device); + device_add(&w83977f_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + + return ret; +} + int machine_at_ax6bc_init(const machine_t *model) { @@ -408,11 +439,10 @@ machine_at_atc6310bxii_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); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0C, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); - pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&slc90e66_device); diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 6d7b8c710..9be2d45b8 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -74,6 +74,46 @@ machine_at_s370slm_init(const machine_t *model) return ret; } +int +machine_at_prosignias31x_bx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/prosignias31x_bx/p6bxt-ap-092600.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0a, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0d, PCI_CARD_SOUND, 4, 3, 2, 1); /* assumed */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&w83977ef_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&winbond_flash_w29c020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 256); + device_add(&gl520sm_2d_device); /* fans: CPU, Chassis; temperature: System */ + hwm_values.temperatures[0] += 2; /* System offset */ + hwm_values.temperatures[1] += 2; /* CPU offset */ + hwm_values.voltages[0] = 3300; /* Vcore and 3.3V are swapped */ + hwm_values.voltages[2] = hwm_get_vcore(); + + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(&cmi8738_onboard_device); + + return ret; +} + int machine_at_s1857_init(const machine_t *model) { diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index e39ab87be..78df5b0cb 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -126,7 +126,6 @@ machine_at_p5mp3_init(const machine_t *model) return ret; machine_at_common_init(model); - 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); @@ -296,7 +295,7 @@ machine_at_award_common_init(const machine_t *model) if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&keyboard_at_ami_device); device_add(&sio_zb_device); device_add(&intel_flash_bxt_device); } @@ -355,6 +354,67 @@ machine_at_pb520r_init(const machine_t *model) return ret; } +int +machine_at_m5pi_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_inverted("roms/machines/m5pi/M5PI10R.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_IDE, 0, 0, 0, 0); + pci_register_slot(0x0f, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0c, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0b, PCI_CARD_NORMAL, 3, 4, 1, 2); + 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(&ide_w83769f_pci_single_channel_device); + device_add(&fdc37c665_ide_sec_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +int +machine_at_globalyst330_p5_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/globalyst330_p5/MiTAC_PB5500C_v1.02_120794_ATT.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x10, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 5, 6, 7, 8); + pci_register_slot(0x13, PCI_CARD_NORMAL, 9, 10, 11, 12); + pci_register_slot(0x14, PCI_CARD_NORMAL, 13, 14, 15, 16); + + device_add(&opti5x7_pci_device); + device_add(&opti822_device); + device_add(&sst_flash_29ee010_device); + device_add(&keyboard_at_ami_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_excalibur_init(const machine_t *model) { diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index a5ab30c42..b6e82301b 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -97,6 +97,36 @@ machine_at_ambradp90_init(const machine_t *model) return ret; } +int +machine_at_p54np4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/p54np4/asus-642accdebcb75833703472.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 03 = Slot 1 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 04 = Slot 2 */ + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ + pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 06 = Slot 4 */ + pci_register_slot(0x07, PCI_CARD_SCSI, 1, 2, 3, 4); /* 07 = SCSI */ + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430nx_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c665_ide_pri_device); + device_add(&ncr53c810_onboard_pci_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_586ip_init(const machine_t *model) { diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 12cec1357..14b641540 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -58,10 +58,6 @@ machine_at_acerv35n_init(const machine_t *model) return ret; machine_at_common_init_ex(model, 2); - /* Yes, it's called amstrad_mega_pc_nvr_device, but it's basically the - standard AT NVR, just initialized to 0x00's (perhaps that should be the - default behavior?). */ - device_add(&amstrad_megapc_nvr_device); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -824,6 +820,39 @@ machine_at_i430vx_init(const machine_t *model) return ret; } +int +machine_at_gw2kte_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/gw2kte/1008CY1T.BIO", + "roms/machines/gw2kte/1008CY1T.BI1", + "roms/machines/gw2kte/1008CY1T.BI2", + "roms/machines/gw2kte/1008CY1T.BI3", + "roms/machines/gw2kte/1008CY1T.RCV", + 0x3a000, 128); + + 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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_ma23c_init(const machine_t *model) { @@ -935,7 +964,7 @@ machine_at_tx97_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_AN430TX) +#ifdef USE_AN430TX int machine_at_an430tx_init(const machine_t *model) { @@ -979,7 +1008,7 @@ machine_at_an430tx_init(const machine_t *model) return ret; } -#endif +#endif /* USE_AN430TX */ int machine_at_ym430tx_init(const machine_t *model) @@ -1242,6 +1271,38 @@ machine_at_ficpa2012_init(const machine_t *model) return ret; } +int +machine_at_via809ds_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/via809ds/v30422sg.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); /* assumed */ + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&via_vp3_device); + device_add(&via_vt82c586b_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c669_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); + + return ret; +} + int machine_at_r534f_init(const machine_t *model) { diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index c36fade86..40ae221a0 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -671,15 +671,15 @@ machine_at_p5vxb_init(const machine_t *model) } int -machine_at_gw2kte_init(const machine_t *model) +machine_at_gw2kma_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined2("roms/machines/gw2kte/1008CY1T.BIO", - "roms/machines/gw2kte/1008CY1T.BI1", - "roms/machines/gw2kte/1008CY1T.BI2", - "roms/machines/gw2kte/1008CY1T.BI3", - "roms/machines/gw2kte/1008CY1T.RCV", + ret = bios_load_linear_combined2("roms/machines/gw2kma/1007DQ0T.BIO", + "roms/machines/gw2kma/1007DQ0T.BI1", + "roms/machines/gw2kma/1007DQ0T.BI2", + "roms/machines/gw2kma/1007DQ0T.BI3", + "roms/machines/gw2kma/1007DQ0T.RCV", 0x3a000, 128); if (bios_only || !ret) @@ -689,7 +689,6 @@ machine_at_gw2kte_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(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 8c2688c1a..935a26fb2 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -256,6 +256,9 @@ machine_at_vs440fx_init(const machine_t *model) device_add(&intel_flash_bxt_ami_device); + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(machine_get_snd_device(machine)); + return ret; } @@ -290,6 +293,9 @@ machine_at_gw2kvenus_init(const machine_t *model) device_add(&intel_flash_bxt_ami_device); + if (sound_card_current[0] == SOUND_INTERNAL) + device_add(machine_get_snd_device(machine)); + return ret; } @@ -324,10 +330,10 @@ machine_at_ap440fx_init(const machine_t *model) device_add(&intel_flash_bxt_ami_device); if (sound_card_current[0] == SOUND_INTERNAL) - device_add(&cs4236b_device); + device_add(machine_get_snd_device(machine)); if (gfxcard[0] == VID_INTERNAL) - device_add(&s3_virge_375_onboard_pci_device); + device_add(machine_get_vid_device(machine)); return ret; } diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index fe6983733..0360b5650 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -263,7 +263,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(&w83877tf_device); + device_add(&w83877tf_acorp_device); device_add(&sst_flash_39sf010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); diff --git a/src/machine/m_at_t3100e.c b/src/machine/m_at_t3100e.c index 357f012f2..3c83b0cce 100644 --- a/src/machine/m_at_t3100e.c +++ b/src/machine/m_at_t3100e.c @@ -850,6 +850,9 @@ machine_at_t3100e_init(const machine_t *model) NULL, MEM_MAPPING_INTERNAL, &t3100e_ems); mem_mapping_disable(&t3100e_ems.upper_mapping); + if (mem_size < (16384 - 448)) + mem_set_mem_state_both(mem_size * 1024, 384 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + device_add(&t3100e_device); return ret; diff --git a/src/machine/m_at_t3100e_vid.c b/src/machine/m_at_t3100e_vid.c index 50c9ec05a..c827a05e5 100644 --- a/src/machine/m_at_t3100e_vid.c +++ b/src/machine/m_at_t3100e_vid.c @@ -655,8 +655,7 @@ t3100e_recalcattrs(t3100e_t *t3100e) void * t3100e_init(UNUSED(const device_t *info)) { - t3100e_t *t3100e = malloc(sizeof(t3100e_t)); - memset(t3100e, 0, sizeof(t3100e_t)); + t3100e_t *t3100e = calloc(1, sizeof(t3100e_t)); loadfont("roms/machines/t3100e/t3100e_font.bin", 5); cga_init(&t3100e->cga); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_t3100e); @@ -711,7 +710,7 @@ const device_t t3100e_device = { .init = t3100e_init, .close = t3100e_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = t3100e_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 42034e2f6..b98a1f51e 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -703,7 +703,7 @@ const device_t europc_device = { .init = europc_boot, .close = europc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = europc_config diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 9ac4ff631..ca9e72fca 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -96,6 +96,7 @@ typedef struct pcjr_t { int firstline; int lastline; int composite; + int apply_hd; /* Keyboard Controller stuff. */ int latched; @@ -107,6 +108,525 @@ typedef struct pcjr_t { pc_timer_t send_delay_timer; } pcjr_t; +/*PCjr keyboard has no escape scancodes, and no scancodes beyond 54 + Map right alt to 54h (FN) */ +const scancode scancode_pcjr[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 = { 0 }, .brk = { 0 } }, /* 054 */ + { .mk = { 0 }, .brk = { 0 } }, /* 055 */ + { .mk = { 0x55, 0 }, .brk = { 0xd5, 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 = { 0 }, .brk = { 0 } }, /* 05c */ + { .mk = { 0 }, .brk = { 0 } }, /* 05d */ + { .mk = { 0 }, .brk = { 0 } }, /* 05e */ + { .mk = { 0 }, .brk = { 0 } }, /* 05f */ + { .mk = { 0 }, .brk = { 0 } }, /* 060 */ + { .mk = { 0 }, .brk = { 0 } }, /* 061 */ + { .mk = { 0 }, .brk = { 0 } }, /* 062 */ + { .mk = { 0 }, .brk = { 0 } }, /* 063 */ + { .mk = { 0 }, .brk = { 0 } }, /* 064 */ + { .mk = { 0 }, .brk = { 0 } }, /* 065 */ + { .mk = { 0 }, .brk = { 0 } }, /* 066 */ + { .mk = { 0 }, .brk = { 0 } }, /* 067 */ + { .mk = { 0 }, .brk = { 0 } }, /* 068 */ + { .mk = { 0 }, .brk = { 0 } }, /* 069 */ + { .mk = { 0 }, .brk = { 0 } }, /* 06a */ + { .mk = { 0 }, .brk = { 0 } }, /* 06b */ + { .mk = { 0 }, .brk = { 0 } }, /* 06c */ + { .mk = { 0 }, .brk = { 0 } }, /* 06d */ + { .mk = { 0 }, .brk = { 0 } }, /* 06e */ + { .mk = { 0 }, .brk = { 0 } }, /* 06f */ + { .mk = { 0 }, .brk = { 0 } }, /* 070 */ + { .mk = { 0 }, .brk = { 0 } }, /* 071 */ + { .mk = { 0 }, .brk = { 0 } }, /* 072 */ + { .mk = { 0 }, .brk = { 0 } }, /* 073 */ + { .mk = { 0 }, .brk = { 0 } }, /* 074 */ + { .mk = { 0 }, .brk = { 0 } }, /* 075 */ + { .mk = { 0 }, .brk = { 0 } }, /* 076 */ + { .mk = { 0 }, .brk = { 0 } }, /* 077 */ + { .mk = { 0 }, .brk = { 0 } }, /* 078 */ + { .mk = { 0 }, .brk = { 0 } }, /* 079 */ + { .mk = { 0 }, .brk = { 0 } }, /* 07a */ + { .mk = { 0 }, .brk = { 0 } }, /* 07b */ + { .mk = { 0 }, .brk = { 0 } }, /* 07c */ + { .mk = { 0 }, .brk = { 0 } }, /* 07d */ + { .mk = { 0 }, .brk = { 0 } }, /* 07e */ + { .mk = { 0 }, .brk = { 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 = { 0 }, .brk = { 0 } }, /* 0f1 */ + { .mk = { 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 = { 0x54, 0 }, .brk = { 0xd4, 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 = { 0 }, .brk = { 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 +}; + static video_timings_t timing_dram = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*No additional waitstates*/ static uint8_t crtcmask[32] = { @@ -301,7 +821,7 @@ vid_get_h_overscan_delta(pcjr_t *pcjr) coef = 8; break; case 0x12: /*160x200x16*/ - def = 0x2b; + def = 0x2c; /* I'm going to assume a datasheet erratum here. */ coef = 16; break; case 0x03: /*640x200x4*/ @@ -341,20 +861,12 @@ vid_get_h_overscan_delta(pcjr_t *pcjr) static void vid_blit_h_overscan(pcjr_t *pcjr) { - int cols; + 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; - int y = (pcjr->lastline << 1) + 16; - int ho_s = vid_get_h_overscan_size(pcjr); - - if (pcjr->dispon) - cols = (pcjr->array[2] & 0xf) + 16; - else { - if (pcjr->array[3] & 4) - cols = (pcjr->array[2] & 0xf) + 16; - else - cols = pcjr->array[0 + 16] + 16; - } if (pcjr->array[0] & 1) x = (pcjr->crtc[1] << 3) + ho_s; @@ -362,14 +874,14 @@ vid_blit_h_overscan(pcjr_t *pcjr) x = (pcjr->crtc[1] << 4) + ho_s; for (i = 0; i < 16; i++) { - hline(buffer32, 0, i, x, cols); + 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[i]); + 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, i); + video_process_8(x, y0 + i); video_process_8(x, y + i); } } @@ -443,16 +955,16 @@ vid_poll(void *priv) 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]) + 16] + 16; + 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]) + 16] + 16; + 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]) + 16] + 16; + 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]) + 16] + 16; + pcjr->array[(dat & pcjr->array[1] & 0x0f) + 16] + 16; } break; case 0x12: /*160x200x16*/ @@ -493,7 +1005,7 @@ vid_poll(void *priv) 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]) + 16] + 16; + pcjr->array[(chr & pcjr->array[1] & 0x0f) + 16] + 16; dat <<= 1; } } @@ -505,13 +1017,13 @@ vid_poll(void *priv) 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]) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16; + 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]) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; + 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++) @@ -537,13 +1049,13 @@ vid_poll(void *priv) 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]) + 16] + 16; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16] + 16; + 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]) + 16] + 16; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16] + 16; + 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) @@ -727,9 +1239,12 @@ vid_poll(void *priv) if (enable_overscan) { video_blit_memtoscreen(0, pcjr->firstline << 1, xsize, actual_ys + 32); - } else { + } 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); } } @@ -923,6 +1438,34 @@ speed_changed(void *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(); +} + void pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv)) { @@ -951,6 +1494,13 @@ static const device_config_t pcjr_config[] = { { .description = "" } } }, + { + .name = "apply_hd", + .description = "Apply overscan deltas", + .type = CONFIG_BINARY, + .default_string = "", + .default_int = 1 + }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -963,7 +1513,7 @@ const device_t pcjr_device = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = speed_changed, .force_redraw = NULL, .config = pcjr_config @@ -972,7 +1522,6 @@ const device_t pcjr_device = { int machine_pcjr_init(UNUSED(const machine_t *model)) { - int display_type; pcjr_t *pcjr; int ret; @@ -983,15 +1532,7 @@ machine_pcjr_init(UNUSED(const machine_t *model)) if (bios_only || !ret) return ret; - pcjr = malloc(sizeof(pcjr_t)); - memset(pcjr, 0x00, sizeof(pcjr_t)); - pcjr->memctrl = -1; - if (mem_size < 128) - pcjr->memctrl &= ~0x24; - display_type = machine_get_config_int("display_type"); - pcjr->composite = (display_type != PCJR_RGB); - overscan_x = 256; - overscan_y = 32; + pcjr = calloc(1, sizeof(pcjr_t)); pic_init_pcjr(); pit_common_init(0, pit_irq0_timer_pcjr, NULL); @@ -1001,16 +1542,10 @@ machine_pcjr_init(UNUSED(const machine_t *model)) /* Initialize the video controller. */ video_reset(gfxcard[0]); loadfont("roms/video/mda/mda.rom", 0); - 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); - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); + device_context(&pcjr_device); + pcjr_vid_init(pcjr); + device_context_restore(); device_add_ex(&pcjr_device, pcjr); - cga_palette = 0; - cgapal_rebuild(); /* Initialize the keyboard. */ keyboard_scan = 1; @@ -1020,7 +1555,7 @@ machine_pcjr_init(UNUSED(const machine_t *model)) io_sethandler(0x00a0, 8, kbd_read, NULL, NULL, kbd_write, NULL, NULL, pcjr); timer_add(&pcjr->send_delay_timer, kbd_poll, pcjr, 1); - keyboard_set_table(scancode_xt); + keyboard_set_table(scancode_pcjr); keyboard_send = kbd_adddata_ex; /* Technically it's the SN76496N, but the SN76489 is identical to the SN76496N. */ diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index a6a16d65c..130481394 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -146,13 +146,13 @@ ps1_write(uint16_t port, uint8_t val, void *priv) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 1: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 2: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: @@ -252,7 +252,7 @@ static const device_config_t ps1_2011_config[] = { .default_string = "english_us", .default_int = 0, .file_filter = "", - .spinner = { 0 }, /*W1*/ + .spinner = { 0 }, .bios = { { .name = "English (US)", .internal_name = "english_us", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ibmps1es/FC0000_US.BIN", "" } }, @@ -287,7 +287,7 @@ const device_t ps1_2011_device = { .init = NULL, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = &ps1_2011_config[0] @@ -299,8 +299,7 @@ ps1_setup(int model) ps1_t *ps; void *priv; - ps = (ps1_t *) malloc(sizeof(ps1_t)); - memset(ps, 0x00, sizeof(ps1_t)); + ps = (ps1_t *) calloc(1, sizeof(ps1_t)); ps->model = model; io_sethandler(0x0091, 1, @@ -317,12 +316,14 @@ ps1_setup(int model) ps->uart = device_add_inst(&ns16450_device, 1); lpt1_remove(); - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); mem_remap_top(384); device_add(&ps_nvr_device); + device_add(&fdc_ps2_device); + if (model == 2011) { if (!strcmp("english_us", device_get_config_bios("bios_language"))) { /* US English */ @@ -350,8 +351,6 @@ ps1_setup(int model) device_add(&ps1snd_device); - device_add(&fdc_at_ps1_device); - /* Enable the builtin HDC. */ if (hdc_current[0] == HDC_INTERNAL) { priv = device_add(&ps1_hdc_device); @@ -378,8 +377,6 @@ ps1_setup(int model) if (gfxcard[0] == VID_INTERNAL) device_add(&ibm_ps1_2121_device); - device_add(&fdc_at_ps1_2121_device); - device_add(&ide_isa_device); device_add(&ps1snd_device); diff --git a/src/machine/m_ps1_hdc.c b/src/machine/m_ps1_hdc.c index f35879458..18792ded7 100644 --- a/src/machine/m_ps1_hdc.c +++ b/src/machine/m_ps1_hdc.c @@ -462,7 +462,6 @@ static const geom_t ibm_type_table[] = { // clang-format on }; -#define ENABLE_PS1_HDC_LOG 1 #ifdef ENABLE_PS1_HDC_LOG int ps1_hdc_do_log = ENABLE_PS1_HDC_LOG; @@ -721,7 +720,9 @@ hdc_callback(void *priv) off64_t addr; int no_data = 0; int val; +#ifdef ENABLE_PS1_HDC_LOG uint8_t cmd = ccb->cmd & 0x0f; +#endif /* Clear the SSB error bits. */ dev->ssb.track_0 = 0; @@ -1296,8 +1297,7 @@ ps1_hdc_init(UNUSED(const device_t *info)) int c; /* Allocate and initialize device block. */ - dev = malloc(sizeof(hdc_t)); - memset(dev, 0x00, sizeof(hdc_t)); + dev = calloc(1, sizeof(hdc_t)); /* Set up controller parameters for PS/1 2011. */ dev->base = 0x0320; @@ -1310,7 +1310,7 @@ ps1_hdc_init(UNUSED(const device_t *info)) /* Load any disks for this device class. */ c = 0; for (uint8_t i = 0; i < HDD_NUM; i++) { - if ((hdd[i].bus == HDD_BUS_XTA) && (hdd[i].xta_channel < 1)) { + if ((hdd[i].bus_type == HDD_BUS_XTA) && (hdd[i].xta_channel < 1)) { drive = &dev->drives[hdd[i].xta_channel]; if (!hdd_image_load(i)) { @@ -1380,12 +1380,12 @@ ps1_hdc_close(void *priv) const device_t ps1_hdc_device = { .name = "PS/1 2011 Fixed Disk Controller", .internal_name = "ps1_hdc", - .flags = DEVICE_ISA | DEVICE_PS2, + .flags = DEVICE_ISA, .local = 0, .init = ps1_hdc_init, .close = ps1_hdc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 2887cca20..8a2760f15 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -64,13 +64,13 @@ ps2_write(uint16_t port, uint8_t val, void *priv) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 1: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 2: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: @@ -151,8 +151,7 @@ ps2_isa_setup(int model, int cpu_type) ps2_isa_t *ps2; void *priv; - ps2 = (ps2_isa_t *) malloc(sizeof(ps2_isa_t)); - memset(ps2, 0x00, sizeof(ps2_isa_t)); + ps2 = (ps2_isa_t *) calloc(1, sizeof(ps2_isa_t)); ps2->model = model; ps2->cpu_type = cpu_type; @@ -168,7 +167,7 @@ ps2_isa_setup(int model, int cpu_type) ps2->uart = device_add_inst(&ns16450_device, 1); lpt1_remove(); - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); device_add(&port_92_device); @@ -176,7 +175,7 @@ ps2_isa_setup(int model, int cpu_type) device_add(&ps_nvr_device); - device_add(&fdc_at_ps1_device); + device_add(&fdc_ps2_device); /* Enable the builtin HDC. */ if (hdc_current[0] == HDC_INTERNAL) { diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 103badf61..c355ba4b2 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -478,13 +478,13 @@ model_50_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 1: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 2: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: @@ -610,13 +610,13 @@ model_55sx_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 1: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 2: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: @@ -669,13 +669,13 @@ model_70_type3_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 1: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 2: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: @@ -723,13 +723,13 @@ model_80_write(uint16_t port, uint8_t val) if (val & 0x10) { switch ((val >> 5) & 3) { case 0: - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); break; case 1: - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); break; case 2: - lpt1_init(LPT2_ADDR); + lpt1_setup(LPT2_ADDR); break; default: @@ -1031,7 +1031,7 @@ ps2_mca_board_common_init(void) ps2.setup = 0xff; - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); } static uint8_t @@ -1657,7 +1657,7 @@ machine_ps2_common_init(const machine_t *model) machine_common_init(model); if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_ps2_device); + device_add(&fdc_ps2_mca_device); dma16_init(); ps2_dma_init(); diff --git a/src/machine/m_tandy.c b/src/machine/m_tandy.c index c5de74824..7072c5e78 100644 --- a/src/machine/m_tandy.c +++ b/src/machine/m_tandy.c @@ -27,6 +27,7 @@ #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> @@ -83,6 +84,7 @@ typedef struct t1kvid_t { uint32_t b8000_mask; uint32_t b8000_limit; uint8_t planar_ctrl; + uint8_t lp_strobe; int linepos; int displine; @@ -717,8 +719,13 @@ recalc_timings(tandy_t *dev) double _dispofftime; double disptime; - disptime = vid->crtc[0] + 1; - _dispontime = vid->crtc[1]; + 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; @@ -764,6 +771,15 @@ recalc_address_sl(tandy_t *dev) } } +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) { @@ -794,7 +810,10 @@ vid_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -807,6 +826,18 @@ vid_out(uint16_t addr, uint8_t val, void *priv) 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; @@ -843,7 +874,7 @@ static uint8_t vid_in(uint16_t addr, void *priv) { const tandy_t *dev = (tandy_t *) priv; - const t1kvid_t *vid = dev->vid; + t1kvid_t *vid = dev->vid; uint8_t ret = 0xff; if ((addr >= 0x3d0) && (addr <= 0x3d7)) @@ -862,6 +893,18 @@ vid_in(uint16_t addr, void *priv) 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; } @@ -1215,6 +1258,7 @@ vid_poll(void *priv) 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; @@ -1315,14 +1359,12 @@ vid_init(tandy_t *dev) int display_type; t1kvid_t *vid; - vid = malloc(sizeof(t1kvid_t)); - memset(vid, 0x00, sizeof(t1kvid_t)); + vid = calloc(1, sizeof(t1kvid_t)); vid->memctrl = -1; - dev->vid = vid; video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); - display_type = machine_get_config_int("display_type"); + display_type = device_get_config_int("display_type"); vid->composite = (display_type != TANDY_RGB); cga_comp_init(1); @@ -1335,11 +1377,14 @@ vid_init(tandy_t *dev) 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[] = { @@ -1370,7 +1415,7 @@ const device_t vid_device = { .init = NULL, .close = vid_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed, .force_redraw = NULL, .config = vid_config @@ -1384,7 +1429,7 @@ const device_t vid_device_hx = { .init = NULL, .close = vid_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed, .force_redraw = NULL, .config = vid_config @@ -1398,7 +1443,7 @@ const device_t vid_device_sl = { .init = NULL, .close = vid_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed, .force_redraw = NULL, .config = NULL @@ -1494,8 +1539,7 @@ eep_init(const device_t *info) t1keep_t *eep; FILE *fp = NULL; - eep = (t1keep_t *) malloc(sizeof(t1keep_t)); - memset(eep, 0x00, sizeof(t1keep_t)); + eep = (t1keep_t *) calloc(1, sizeof(t1keep_t)); switch (info->local) { case TYPE_TANDY1000HX: @@ -1546,7 +1590,7 @@ static const device_t eep_1000hx_device = { .init = eep_init, .close = eep_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1560,7 +1604,7 @@ static const device_t eep_1000sl2_device = { .init = eep_init, .close = eep_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1761,9 +1805,11 @@ 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_restore(); device_add_ex(&vid_device, dev); - device_add(&sn76489_device); + device_add((type == TYPE_TANDY1000SX) ? &ncr8496_device : &sn76489_device); break; case TYPE_TANDY1000HX: @@ -1771,8 +1817,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_add_ex(&vid_device, dev); + device_context_restore(); + device_add_ex(&vid_device_hx, dev); device_add(&ncr8496_device); device_add(&eep_1000hx_device); break; @@ -1782,7 +1830,9 @@ 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_restore(); device_add_ex(&vid_device_sl, dev); device_add(&pssj_device); device_add(&eep_1000sl2_device); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index c11968d33..9f232ac95 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -1,3 +1,25 @@ +/* + * 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. + * + * Standard PC/AT implementation. + * + * + * + * Authors: Fred N. van Kempen, + * Miran Grca, + * Sarah Walker, + * Jasmine Iwanek, + * + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2025 Jasmine Iwanek. + */ #include #include #include @@ -19,6 +41,7 @@ #include <86box/machine.h> #include <86box/chipset.h> #include <86box/port_6x.h> +#include <86box/video.h> extern const device_t vendex_xt_rtc_onboard_device; @@ -36,22 +59,101 @@ machine_xt_common_init(const machine_t *model, int fixed_floppy) standalone_gameport_type = &gameport_device; } +static const device_config_t ibmpc_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ibm5150_5700671", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "5700671 (10/19/81)", .internal_name = "ibm5150_5700671", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc/BIOS_IBM5150_19OCT81_5700671_U33.BIN", "" } }, + { .name = "5700051 (04/24/81)", .internal_name = "ibm5150_5700051", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc/BIOS_IBM5150_24APR81_5700051_U33.BIN", "" } }, + + // GlaBIOS for IBM PC + { .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_8P.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_VP.ROM", "" } }, + + // The following are Diagnostic ROMs. + { .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", "" } }, + { .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 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "enable_basic", + .description = "IBM Cassette Basic", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmpc_device = { + .name = "IBM PC (1981) Device", + .internal_name = "ibmpc_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmpc_config +}; + int machine_pc_init(const machine_t *model) { - int ret; + int ret = 0; + int ret2; + uint8_t enable_5161; + uint8_t enable_basic; + const char *fn; - ret = bios_load_linear("roms/machines/ibmpc/BIOS_5150_24APR81_U33.BIN", - 0x000fe000, 40960, 0); - if (ret) { - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin", - 0x000f6000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin", - 0x000f8000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U31 - 5700035.bin", - 0x000fa000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U32 - 5700043.bin", - 0x000fc000, 8192, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + 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, 40960, 0); + device_context_restore(); + + if (enable_basic && ret) { + ret2 = bios_load_aux_linear("roms/machines/ibmpc/ibm-basic-1.00.rom", + 0x000f6000, 32768, 0); + if (!ret2) { + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U29 - 5700019.bin", + 0x000f6000, 8192, 0); + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U30 - 5700027.bin", + 0x000f8000, 8192, 0); + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U31 - 5700035.bin", + 0x000fa000, 8192, 0); + bios_load_aux_linear("roms/machines/ibmpc/IBM 5150 - Cassette BASIC version C1.00 - U32 - 5700043.bin", + 0x000fc000, 8192, 0); + } } if (bios_only || !ret) @@ -61,28 +163,105 @@ machine_pc_init(const machine_t *model) machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } +static const device_config_t ibmpc82_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ibm5150_1501476", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "1501476 (10/27/82)", .internal_name = "ibm5150_1501476", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_27OCT82_1501476_U33.BIN", "" } }, + { .name = "5000024 (08/16/82)", .internal_name = "ibm5150_5000024", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 40960, .files = { "roms/machines/ibmpc82/BIOS_5150_16AUG82_5000024_U33.BIN", "" } }, + + // GlaBIOS for IBM PC + { .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_8P.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_VP.ROM", "" } }, + + // The following are Diagnostic ROMs. + { .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", "" } }, + { .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 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "enable_basic", + .description = "IBM Cassette Basic", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmpc82_device = { + .name = "IBM PC (1982) Devices", + .internal_name = "ibmpc82_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmpc82_config +}; + int machine_pc82_init(const machine_t *model) { - int ret; - int ret2; + int ret = 0; + int ret2; + uint8_t enable_5161; + uint8_t enable_basic; + const char *fn; - ret = bios_load_linear("roms/machines/ibmpc82/pc102782.bin", - 0x000fe000, 40960, 0); - if (ret) { + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + 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, 40960, 0); + device_context_restore(); + + if (enable_basic && ret) { ret2 = bios_load_aux_linear("roms/machines/ibmpc82/ibm-basic-1.10.rom", 0x000f6000, 32768, 0); if (!ret2) { - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.f6", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U29 - 5000019.bin", 0x000f6000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.f8", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U30 - 5000021.bin", 0x000f8000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.fa", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U31 - 5000022.bin", 0x000fa000, 8192, 0); - bios_load_aux_linear("roms/machines/ibmpc82/basicc11.fc", + bios_load_aux_linear("roms/machines/ibmpc82/IBM 5150 - Cassette BASIC version C1.10 - U32 - 5000023.bin", 0x000fc000, 8192, 0); } } @@ -91,40 +270,116 @@ machine_pc82_init(const machine_t *model) return ret; device_add(&keyboard_pc82_device); - device_add(&ibm_5161_device); machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } +static const device_config_t ibmxt_config[] = { + // clang-format off + { + .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 + // 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", "" } }, + + // 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 + { .files_no = 0 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "enable_basic", + .description = "IBM Cassette Basic", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmxt_device = { + .name = "IBM XT (1982) Device", + .internal_name = "ibmxt_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt_config +}; + int machine_xt_init(const machine_t *model) { - int ret; + int ret = 0; + uint8_t enable_5161; + uint8_t enable_basic; + const char *fn; - ret = bios_load_linear("roms/machines/ibmxt/xt.rom", - 0x000f0000, 65536, 0); - if (!ret) { - ret = bios_load_linear("roms/machines/ibmxt/1501512.u18", - 0x000fe000, 65536, 0x6000); - if (ret) { - bios_load_aux_linear("roms/machines/ibmxt/1501512.u18", - 0x000f8000, 24576, 0); - bios_load_aux_linear("roms/machines/ibmxt/5000027.u19", - 0x000f0000, 32768, 0); - } + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + 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); + + 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); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); + (void) bios_load_aux_linear(fn, 0x000f0000, 32768, 0); } + device_context_restore(); if (bios_only || !ret) return ret; - device_add(&keyboard_xt_device); - device_add(&ibm_5161_device); machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -146,28 +401,99 @@ machine_genxt_init(const machine_t *model) return ret; } +static const device_config_t ibmxt86_config[] = { + // clang-format off + { + .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 + // 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", "" } }, + + // 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 + { .files_no = 0 } + }, + }, + { + .name = "enable_5161", + .description = "IBM 5161 Expansion Unit", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ibmxt86_device = { + .name = "IBM XT (1986) Device", + .internal_name = "ibmxt86_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ibmxt86_config +}; + int machine_xt86_init(const machine_t *model) { - int ret; + int ret = 0; + uint8_t enable_5161; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + 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); - ret = bios_load_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", - 0x000fe000, 65536, 0x6000); if (ret) { - (void) bios_load_aux_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", - 0x000f8000, 24576, 0); - (void) bios_load_aux_linear("roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", - 0x000f0000, 32768, 0); + 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); } + device_context_restore(); if (bios_only || !ret) return ret; device_add(&keyboard_xt86_device); - device_add(&ibm_5161_device); machine_xt_common_init(model, 0); + if (enable_5161) + device_add(&ibm_5161_device); + return ret; } @@ -211,6 +537,31 @@ machine_xt_amixt_init(const machine_t *model) return ret; } +// TODO +// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions) +// RTC +// Adaptec ACB-2072 RLL Controller Card (Optional) +// Atari PCM1 Mouse Support +int +machine_xt_ataripc3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN", + 0x000f8000, 32768, 0); +#if 0 + ret = bios_load_linear("roms/machines/ataripc3/c101701-004 308.u61", + 0x000f8000, 0x8000, 0); +#endif + + if (bios_only || !ret) + return ret; + + machine_xt_clone_init(model, 0); + + return ret; +} + int machine_xt_znic_init(const machine_t *model) { @@ -243,13 +594,59 @@ machine_xt_dtk_init(const machine_t *model) return ret; } +static const device_config_t jukopc_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "jukost", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "Bios 2.30", .internal_name = "jukost", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { "roms/machines/jukopc/000o001.bin", "" } }, + // GlaBIOS for Juko ST + { .name = "GlaBIOS 0.2.5 (8088)", .internal_name = "glabios_025_8088", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { "roms/machines/glabios/GLABIOS_0.2.5_8S_2.ROM", "" } }, + { .name = "GlaBIOS 0.2.5 (V20)", .internal_name = "glabios_025_v20", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 8192, .files = { "roms/machines/glabios/GLABIOS_0.2.5_VS_2.ROM", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t jukopc_device = { + .name = "Juko ST Devices", + .internal_name = "jukopc_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = jukopc_config +}; + int machine_xt_jukopc_init(const machine_t *model) { - int ret; + int ret = 0; + const char *fn; - ret = bios_load_linear("roms/machines/jukopc/000o001.bin", - 0x000fe000, 8192, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 8192, 0); + device_context_restore(); if (bios_only || !ret) return ret; @@ -330,6 +727,35 @@ machine_xt_iskra3104_init(const machine_t *model) return ret; } +int +machine_xt_maz1016_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/maz1016/e1.bin", + "roms/machines/maz1016/e4.bin", + 0x000fc000, 49152, 0); + + if (ret) { + bios_load_aux_interleaved("roms/machines/maz1016/e2.bin", + "roms/machines/maz1016/e5.bin", + 0x000f8000, 16384, 0); + + bios_load_aux_interleaved("roms/machines/maz1016/e3.bin", + "roms/machines/maz1016/e6b.bin", + 0x000f4000, 16384, 0); + } + + if (bios_only || !ret) + return ret; + + loadfont("roms/machines/maz1016/crt-8.bin", 0); + + machine_xt_clone_init(model, 0); + + return ret; +} + int machine_xt_pravetz16_imko4_init(const machine_t *model) { @@ -493,18 +919,63 @@ machine_xt_pc500_init(const machine_t *model) return ret; } +static const device_config_t vendex_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "vendex", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "Bios 2.03C", .internal_name = "vendex", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 16384, .files = { "roms/machines/vendex/Vendex Turbo 888 XT - ROM BIOS - VER 2.03C.bin", "" } }, + // GlaBIOS for Juko ST + { .name = "GlaBIOS 0.2.5 (8088)", .internal_name = "glabios_025_8088", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 16384, .files = { "roms/machines/glabios/GLABIOS_0.2.5_8TV.ROM", "" } }, + { .name = "GlaBIOS 0.2.5 (V20)", .internal_name = "glabios_025_v20", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 16384, .files = { "roms/machines/glabios/GLABIOS_0.2.5_VTV.ROM", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t vendex_device = { + .name = "Vendex 888T Devices", + .internal_name = "vendex_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = vendex_config +}; + int machine_xt_vendex_init(const machine_t *model) { - int ret; + int ret = 0; + const char *fn; - ret = bios_load_linear("roms/machines/vendex/Vendex Turbo 888 XT - ROM BIOS - VER 2.03C.bin", - 0x000fc000, 16384, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fc000, 16384, 0); + device_context_restore(); if (bios_only || !ret) return ret; - /* On-board FDC cannot be disabled */ machine_xt_clone_init(model, 1); device_add(&vendex_xt_rtc_onboard_device); diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index ed1b3e26c..f8c0b6a19 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -59,7 +59,7 @@ machine_xt_compaq_deskpro_init(const machine_t *model) standalone_gameport_type = &gameport_device; lpt1_remove(); - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); return ret; } @@ -87,7 +87,7 @@ machine_xt_compaq_portable_init(const machine_t *model) device_add(&gameport_device); lpt1_remove(); - lpt1_init(LPT_MDA_ADDR); + lpt1_setup(LPT_MDA_ADDR); return ret; } diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index b13db6bf9..b6e4fb94a 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -2038,6 +2038,8 @@ m19_vid_init(m19_vid_t *vid) vid->ogc.mono_display = 0; else vid->ogc.mono_display = 1; + + vid->ogc.ctrl_addr = 0x3db; /* OGC emulation part end */ /* Plantronics emulation part begin*/ @@ -2073,7 +2075,7 @@ const device_t m24_kbd_device = { .init = NULL, .close = m24_kbd_close, .reset = m24_kbd_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2117,7 +2119,7 @@ const device_t m19_vid_device = { .init = NULL, .close = m19_vid_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = m19_vid_speed_changed, .force_redraw = NULL, .config = m19_vid_config @@ -2311,8 +2313,7 @@ machine_xt_m24_init(const machine_t *model) if (bios_only || !ret) return ret; - m24_kbd = (m24_kbd_t *) malloc(sizeof(m24_kbd_t)); - memset(m24_kbd, 0x00, sizeof(m24_kbd_t)); + m24_kbd = (m24_kbd_t *) calloc(1, sizeof(m24_kbd_t)); machine_common_init(model); @@ -2328,10 +2329,9 @@ machine_xt_m24_init(const machine_t *model) nmi_init(); /* Allocate an NVR for this machine. */ - nvr = (nvr_t *) malloc(sizeof(nvr_t)); + nvr = (nvr_t *) calloc(1, sizeof(nvr_t)); if (nvr == NULL) return 0; - memset(nvr, 0x00, sizeof(nvr_t)); mm58174_init(nvr, model->nvrmask + 1); @@ -2372,8 +2372,7 @@ machine_xt_m240_init(const machine_t *model) if (bios_only || !ret) return ret; - m24_kbd = (m24_kbd_t *) malloc(sizeof(m24_kbd_t)); - memset(m24_kbd, 0x00, sizeof(m24_kbd_t)); + m24_kbd = (m24_kbd_t *) calloc(1, sizeof(m24_kbd_t)); machine_common_init(model); @@ -2402,10 +2401,9 @@ machine_xt_m240_init(const machine_t *model) nmi_init(); /* Allocate an NVR for this machine. */ - nvr = (nvr_t *) malloc(sizeof(nvr_t)); + nvr = (nvr_t *) calloc(1, sizeof(nvr_t)); if (nvr == NULL) return 0; - memset(nvr, 0x00, sizeof(nvr_t)); mm58274_init(nvr, model->nvrmask + 1); @@ -2436,8 +2434,7 @@ machine_xt_m19_init(const machine_t *model) m19_vid_t *vid; /* Do not move memory allocation elsewhere. */ - vid = (m19_vid_t *) malloc(sizeof(m19_vid_t)); - memset(vid, 0x00, sizeof(m19_vid_t)); + vid = (m19_vid_t *) calloc(1, sizeof(m19_vid_t)); machine_common_init(model); diff --git a/src/machine/m_xt_philips.c b/src/machine/m_xt_philips.c index 1fc284a46..604ccebaf 100644 --- a/src/machine/m_xt_philips.c +++ b/src/machine/m_xt_philips.c @@ -142,7 +142,7 @@ const device_t philips_device = { .init = philips_init, .close = philips_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 4ec13b5c4..efad869e1 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -651,8 +651,7 @@ t1000_recalcattrs(t1000_t *t1000) static void * t1000_init(UNUSED(const device_t *info)) { - t1000_t *t1000 = malloc(sizeof(t1000_t)); - memset(t1000, 0, sizeof(t1000_t)); + t1000_t *t1000 = calloc(1, sizeof(t1000_t)); loadfont("roms/machines/t1000/t1000font.bin", 8); cga_init(&t1000->cga); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_t1000); @@ -741,7 +740,7 @@ const device_t t1000_video_device = { .init = t1000_init, .close = t1000_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = t1000_speed_changed, .force_redraw = NULL, .config = t1000_config @@ -755,7 +754,7 @@ const device_t t1200_video_device = { .init = t1000_init, .close = t1000_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = t1000_speed_changed, .force_redraw = NULL, .config = t1000_config diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index 8515ea27a..886c1be6e 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 = "64KB starting from 0xF0000", + .description = "64 kB starting from F0000", .value = 0 }, { - .description = "128KB starting from 0xE0000 (address MSB inverted, last 64KB first)", + .description = "128 kB starting from E0000 (address MSB inverted, last 64KB first)", .value = 1 } }, @@ -122,37 +122,37 @@ static const device_config_t xi8088_config[] = { }, { .name = "umb_c0000h_c7fff", - .description = "Map 0xc0000-0xc7fff as UMB", + .description = "Map C0000-C7FFF as UMB", .type = CONFIG_BINARY, .default_int = 0 }, { .name = "umb_c8000h_cffff", - .description = "Map 0xc8000-0xcffff as UMB", + .description = "Map C8000-CFFFF as UMB", .type = CONFIG_BINARY, .default_int = 0 }, { .name = "umb_d0000h_d7fff", - .description = "Map 0xd0000-0xd7fff as UMB", + .description = "Map D0000-D7FFF as UMB", .type = CONFIG_BINARY, .default_int = 0 }, { .name = "umb_d8000h_dffff", - .description = "Map 0xd8000-0xdffff as UMB", + .description = "Map D8000-DFFFF as UMB", .type = CONFIG_BINARY, .default_int = 0 }, { .name = "umb_e0000h_e7fff", - .description = "Map 0xe0000-0xe7fff as UMB", + .description = "Map E0000-E7FFF as UMB", .type = CONFIG_BINARY, .default_int = 0 }, { .name = "umb_e8000h_effff", - .description = "Map 0xe8000-0xeffff as UMB", + .description = "Map E8000-EFFFF as UMB", .type = CONFIG_BINARY, .default_int = 0 }, @@ -168,7 +168,7 @@ const device_t xi8088_device = { .init = xi8088_init, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = xi8088_config diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index f5e231772..6c5d556f2 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -73,8 +73,7 @@ zenith_scratchpad_init(UNUSED(const device_t *info)) { zenith_t *dev; - dev = (zenith_t *) malloc(sizeof(zenith_t)); - memset(dev, 0x00, sizeof(zenith_t)); + dev = (zenith_t *) calloc(1, sizeof(zenith_t)); dev->scratchpad_ram = malloc(0x4000); @@ -103,7 +102,7 @@ static const device_t zenith_scratchpad_device = { .init = zenith_scratchpad_init, .close = zenith_scratchpad_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -145,7 +144,7 @@ machine_xt_z184_init(const machine_t *model) lpt1_remove(); /* only one parallel port */ lpt2_remove(); - lpt1_init(0x278); + lpt1_setup(LPT2_ADDR); device_add(&ns8250_device); serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ @@ -199,7 +198,7 @@ machine_xt_z159_init(const machine_t *model) /* parallel port is on the memory board */ lpt1_remove(); /* only one parallel port */ lpt2_remove(); - lpt1_init(0x278); + lpt1_setup(LPT2_ADDR); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index bb0f0cd80..5b3523e00 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -15,9 +15,11 @@ * * 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 @@ -29,12 +31,14 @@ #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/timer.h> #include <86box/network.h> // Temporarily here till we move everything out into the right files @@ -55,6 +59,15 @@ 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 }, @@ -68,6 +81,7 @@ const machine_filter_t machine_types[] = { { "[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 }, @@ -243,7 +257,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmpc_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -282,7 +296,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmpc82_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -360,7 +374,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmxt_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -399,7 +413,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmxt86_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -484,6 +498,45 @@ const machine_t machines[] = { .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", @@ -906,7 +959,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &jukopc_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -1647,14 +1700,14 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &vendex_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, .snd_device = NULL, .net_device = NULL }, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) +#ifdef USE_LASERXT { .name = "[8088] VTech Laser Turbo XT", .internal_name = "ltxt", @@ -1694,7 +1747,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_LASERXT) */ +#endif /* USE_LASERXT */ /* Has a standard PS/2 KBC (so, use IBM PS/2 Type 1). */ { .name = "[8088] Xi8088", @@ -2283,6 +2336,45 @@ const machine_t machines[] = { .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", @@ -2519,7 +2611,7 @@ const machine_t machines[] = { .net_device = NULL }, -#if defined(DEV_BRANCH) && defined(USE_LASERXT) +#ifdef USE_LASERXT { .name = "[8086] VTech Laser XT3", .internal_name = "lxt3", @@ -2559,7 +2651,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_LASERXT) */ +#endif /* USE_LASERXT */ /* 286 AT machines */ /* Has IBM AT KBC firmware. */ @@ -2595,7 +2687,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmat_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -2715,7 +2807,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ibmxt286_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, @@ -3003,7 +3095,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#if defined(DEV_BRANCH) && defined(USE_OLIVETTI) +#ifdef USE_OLIVETTI /* Has Olivetti KBC firmware. */ { .name = "[ISA] Olivetti M290", @@ -3044,8 +3136,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_OLIVETTI) */ -#if defined(DEV_BRANCH) && defined(USE_OPEN_AT) +#endif /* USE_OLIVETTI */ +#ifdef USE_OPEN_AT /* Has IBM AT KBC firmware. */ { .name = "[ISA] OpenAT", @@ -3086,7 +3178,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_OPEN_AT) */ +#endif /* USE_OPEN_AT */ /* Has IBM AT KBC firmware. */ { .name = "[ISA] Phoenix IBM AT", @@ -3247,6 +3339,45 @@ const machine_t machines[] = { .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", @@ -3327,6 +3458,45 @@ const machine_t machines[] = { .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", @@ -3432,7 +3602,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 512, - .max = 16384, + .max = 5120, .step = 128 }, .nvrmask = 127, @@ -3472,7 +3642,7 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 512, - .max = 16384, + .max = 8192, .step = 128 }, .nvrmask = 127, @@ -4270,9 +4440,9 @@ const machine_t machines[] = { .max_voltage = 0, .min_multi = 0, .max_multi = 0, - + }, - .bus_flags = MACHINE_PS2, + .bus_flags = MACHINE_PS2, .flags = MACHINE_IDE | MACHINE_VIDEO , /* Machine has internal OTI 077 Video card*/ .ram = { .min = 2048, @@ -5564,10 +5734,10 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, - .min_bus = 25000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, .min_multi = 0, .max_multi = 0 }, @@ -5604,10 +5774,10 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_386DX | CPU_PKG_SOCKET1, .block = CPU_BLOCK_NONE, - .min_bus = 25000000, - .max_bus = 66666667, - .min_voltage = 5000, - .max_voltage = 5000, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, .min_multi = 0, .max_multi = 0 }, @@ -5877,10 +6047,10 @@ const machine_t machines[] = { /* Uses some variant of Phoenix MultiKey/42 as the Intel 8242 chip has a Phoenix copyright. */ { - .name = "[OPTi 895] Mylex MVI486", + .name = "[OPTi 495] Mylex MVI486", .internal_name = "mvi486", .type = MACHINE_TYPE_486, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .chipset = MACHINE_CHIPSET_OPTI_495, .init = machine_at_mvi486_init, .p1_handler = NULL, .gpio_handler = NULL, @@ -6556,7 +6726,7 @@ const machine_t machines[] = { .step = 1024 }, .nvrmask = 127, - .kbc_device = &keyboard_ps2_ami_device, + .kbc_device = &keyboard_at_ami_device, .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, @@ -6775,7 +6945,7 @@ const machine_t machines[] = { { .name = "[OPTi 895] Packard Bell PB450", .internal_name = "pb450", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_pb450_init, .p1_handler = NULL, @@ -6804,7 +6974,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &pb450_device, .fdc_device = NULL, .sio_device = NULL, .vid_device = &gd5428_vlb_onboard_device, @@ -6935,7 +7105,7 @@ const machine_t machines[] = { }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { - .name = "[SiS 471] ASUS VL/I-486SV2G (GX4)", + .name = "[SiS 471] ASUS VL/I-486SV2GX4", .internal_name = "vli486sv2g", .type = MACHINE_TYPE_486_S3, .chipset = MACHINE_CHIPSET_SIS_471, @@ -7300,7 +7470,7 @@ const machine_t machines[] = { { .name = "[ALi M1429G] MSI MS-4134", .internal_name = "ms4134", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_ms4134_init, .p1_handler = NULL, @@ -7340,7 +7510,7 @@ const machine_t machines[] = { { .name = "[ALi M1429G] TriGem 486GP", .internal_name = "tg486gp", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1429G, .init = machine_at_tg486gp_init, .p1_handler = NULL, @@ -7380,7 +7550,7 @@ const machine_t machines[] = { { .name = "[ALi M1489] AAEON SBC-490", .internal_name = "sbc490", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_sbc490_init, .p1_handler = NULL, @@ -7421,7 +7591,7 @@ const machine_t machines[] = { { .name = "[ALi M1489] ABIT AB-PB4", .internal_name = "abpb4", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_abpb4_init, .p1_handler = NULL, @@ -7465,7 +7635,7 @@ const machine_t machines[] = { { .name = "[ALi M1489] AMI WinBIOS 486 PCI", .internal_name = "win486pci", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_win486pci_init, .p1_handler = NULL, @@ -7509,7 +7679,7 @@ const machine_t machines[] = { { .name = "[ALi M1489] MSI MS-4145", .internal_name = "ms4145", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_ms4145_init, .p1_handler = NULL, @@ -7549,7 +7719,7 @@ const machine_t machines[] = { { .name = "[ALi M1489] ESA TF-486", .internal_name = "tf486", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_tf486_init, .p1_handler = NULL, @@ -7589,7 +7759,7 @@ const machine_t machines[] = { { .name = "[ALi M1489] Acrosser AR-B1476", .internal_name = "arb1476", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_ALI_M1489, .init = machine_at_arb1476_init, .p1_handler = NULL, @@ -7629,7 +7799,7 @@ const machine_t machines[] = { { .name = "[OPTi 802G] IBM Aptiva 510/710/Vision", .internal_name = "aptiva510", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_aptiva510_init, .p1_handler = NULL, @@ -7669,7 +7839,7 @@ const machine_t machines[] = { { .name = "[OPTi 802G] IBM PC 330 (type 6573)", .internal_name = "pc330_6573", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_OPTI_895_802G, .init = machine_at_pc330_6573_init, .p1_handler = NULL, @@ -7709,7 +7879,7 @@ const machine_t machines[] = { { .name = "[i420EX] ASUS PVI-486AP4", .internal_name = "486ap4", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_486ap4_init, .p1_handler = NULL, @@ -7749,7 +7919,7 @@ const machine_t machines[] = { { .name = "[i420EX] Intel Classic/PCI ED", .internal_name = "ninja", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_ninja_init, .p1_handler = NULL, @@ -7789,7 +7959,7 @@ const machine_t machines[] = { { .name = "[i420EX] Anigma BAT4IP3e", .internal_name = "bat4ip3e", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_bat4ip3e_init, .p1_handler = NULL, @@ -7829,7 +7999,7 @@ const machine_t machines[] = { { .name = "[i420EX] Advanced Integration Research 486PI", .internal_name = "486pi", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_486pi_init, .p1_handler = NULL, @@ -7869,7 +8039,7 @@ const machine_t machines[] = { { .name = "[i420EX] ICS SB486P", .internal_name = "sb486p", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420EX, .init = machine_at_sb486p_init, .p1_handler = NULL, @@ -7909,7 +8079,7 @@ const machine_t machines[] = { { .name = "[i420TX] ASUS PCI/I-486SP3", .internal_name = "486sp3", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_486sp3_init, .p1_handler = NULL, @@ -7949,7 +8119,7 @@ const machine_t machines[] = { { .name = "[i420TX] Intel Classic/PCI", .internal_name = "alfredo", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_alfredo_init, .p1_handler = NULL, @@ -7989,7 +8159,7 @@ const machine_t machines[] = { { .name = "[i420TX] AMI Super Voyager PCI", .internal_name = "amis76", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420TX, .init = machine_at_amis76_init, .p1_handler = NULL, @@ -8030,7 +8200,7 @@ const machine_t machines[] = { { .name = "[i420ZX] ASUS PCI/I-486SP3G", .internal_name = "486sp3g", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_INTEL_420ZX, .init = machine_at_486sp3g_init, .p1_handler = NULL, @@ -8070,7 +8240,7 @@ const machine_t machines[] = { { .name = "[IMS 8848] J-Bond PCI400C-B", .internal_name = "pci400cb", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_IMS_8848, .init = machine_at_pci400cb_init, .p1_handler = NULL, @@ -8110,7 +8280,7 @@ const machine_t machines[] = { { .name = "[SiS 496] ASUS PVI-486SP3C", .internal_name = "486sp3c", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_486sp3c_init, .p1_handler = NULL, @@ -8150,7 +8320,7 @@ const machine_t machines[] = { { .name = "[SiS 496] Lucky Star LS-486E", .internal_name = "ls486e", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_ls486e_init, .p1_handler = NULL, @@ -8167,8 +8337,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -8190,7 +8360,7 @@ const machine_t machines[] = { { .name = "[SiS 496] Micronics M4Li", .internal_name = "m4li", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_m4li_init, .p1_handler = NULL, @@ -8230,7 +8400,7 @@ const machine_t machines[] = { { .name = "[SiS 496] Rise Computer R418", .internal_name = "r418", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_r418_init, .p1_handler = NULL, @@ -8247,8 +8417,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, .max = 261120, @@ -8271,7 +8441,7 @@ const machine_t machines[] = { { .name = "[SiS 496] Soyo 4SAW2", .internal_name = "4saw2", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_4saw2_init, .p1_handler = NULL, @@ -8312,7 +8482,7 @@ const machine_t machines[] = { { .name = "[SiS 496] Zida Tomato 4DP", .internal_name = "4dps", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_4dps_init, .p1_handler = NULL, @@ -8352,7 +8522,7 @@ const machine_t machines[] = { { .name = "[SiS 496] MSI MS-4144", .internal_name = "ms4144", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_SIS_496, .init = machine_at_ms4144_init, .p1_handler = NULL, @@ -8392,7 +8562,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] A-Trend ATC-1415", .internal_name = "atc1415", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_atc1415_init, .p1_handler = NULL, @@ -8432,7 +8602,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] ECS Elite UM8810P-AIO", .internal_name = "ecs486", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_ecs486_init, .p1_handler = NULL, @@ -8449,8 +8619,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .bus_flags = MACHINE_PCI | MACHINE_BUS_PS2_LATCH, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -8472,7 +8642,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] Epson ActionPC 2600", .internal_name = "actionpc2600", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_actionpc2600_init, .p1_handler = NULL, @@ -8513,7 +8683,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] Epson ActionTower 8400", .internal_name = "actiontower8400", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_actiontower8400_init, .p1_handler = NULL, @@ -8554,7 +8724,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] PC Chips M919", .internal_name = "m919", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_m919_init, .p1_handler = NULL, @@ -8594,7 +8764,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] Samsung SPC7700P-LW", .internal_name = "spc7700plw", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_spc7700plw_init, .p1_handler = NULL, @@ -8634,7 +8804,7 @@ const machine_t machines[] = { { .name = "[UMC 8881] Shuttle HOT-433A", .internal_name = "hot433a", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, .init = machine_at_hot433a_init, .p1_handler = NULL, @@ -8670,11 +8840,52 @@ const machine_t machines[] = { .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_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, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_VIA_VT82C496G, .init = machine_at_g486vpa_init, .p1_handler = NULL, @@ -8714,7 +8925,7 @@ const machine_t machines[] = { { .name = "[VIA VT82C496G] FIC VIP-IO2", .internal_name = "486vipio2", - .type = MACHINE_TYPE_486_S3, + .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_VIA_VT82C496G, .init = machine_at_486vipio2_init, .p1_handler = NULL, @@ -9067,8 +9278,8 @@ const machine_t machines[] = { .min_multi = MACHINE_MULTIPLIER_FIXED, .max_multi = MACHINE_MULTIPLIER_FIXED }, - .bus_flags = MACHINE_BUS_PS2_LATCH | MACHINE_PCI, - .flags = MACHINE_APM, + .bus_flags = MACHINE_PCI, + .flags = MACHINE_PS2_KBC | MACHINE_APM, .ram = { .min = 2048, .max = 196608, @@ -9368,6 +9579,46 @@ const machine_t machines[] = { .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 @@ -9414,6 +9665,46 @@ const machine_t machines[] = { }, /* 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", @@ -9551,7 +9842,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3520, @@ -9591,7 +9882,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3520, @@ -9632,7 +9923,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -9660,6 +9951,46 @@ const machine_t machines[] = { .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", @@ -9836,7 +10167,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -10490,7 +10821,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -10573,7 +10904,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -10657,7 +10988,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -10738,7 +11069,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -10873,9 +11204,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, - .max = 196608, - .step = 8192 + .min = 4096, + .max = 524288, + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -10908,14 +11239,14 @@ const machine_t machines[] = { .min_voltage = 3450, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 2.5 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, + .min = 4096, .max = 524288, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -10953,9 +11284,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 524288, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -10974,18 +11305,18 @@ const machine_t machines[] = { /* 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 Tigereye", - .internal_name = "gw2kte", + .name = "[i430VX] Gateway 2000 Mailman", + .internal_name = "gw2kma", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430VX, - .init = machine_at_gw2kte_init, + .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_NONE, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), .min_bus = 50000000, .max_bus = 66666667, .min_voltage = 3380, @@ -10998,7 +11329,7 @@ const machine_t machines[] = { .ram = { .min = 8192, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -11222,7 +11553,7 @@ const machine_t machines[] = { /* 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 M3A", + .name = "[i430HX] Acer AcerPower Ultima", .internal_name = "acerm3a", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, @@ -11244,9 +11575,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal SCSI */ .ram = { - .min = 8192, - .max = 196608, - .step = 8192 + .min = 4096, + .max = 524288, + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -11275,18 +11606,18 @@ const machine_t machines[] = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, .min_bus = 50000000, - .max_bus = 83333333, + .max_bus = 75000000, .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 4.0 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 8192, - .max = 262144, - .step = 8192 + .min = 4096, + .max = 524288, + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11319,14 +11650,14 @@ const machine_t machines[] = { .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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 = 8192, + .min = 4096, .max = 524288, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11355,7 +11686,7 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 60000000, .max_bus = 66666667, .min_voltage = 2800, .max_voltage = 3520, @@ -11365,9 +11696,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { - .min = 8192, - .max = 131072, - .step = 8192 + .min = 4096, + .max = 524288, + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -11385,7 +11716,7 @@ const machine_t machines[] = { PC87306 Super I/O chip, command 0xA1 returns '5'. Command 0xA0 copyright string: (C)1994 AMI . */ { - .name = "[i430HX] Intel TC430HX", + .name = "[i430HX] Intel TC430HX (Tucson)", .internal_name = "tc430hx", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, @@ -11396,20 +11727,21 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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 + .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 = 131072, - .step = 8192 + .max = 524288, + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -11425,7 +11757,7 @@ const machine_t machines[] = { }, /* OEM version of Intel TC430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ { - .name = "[i430HX] Toshiba Infinia 7200", + .name = "[i430HX] Toshiba Infinia 7201", .internal_name = "infinia7200", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, @@ -11436,20 +11768,21 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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 + .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 = 131072, - .step = 8192 + .max = 524288, + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -11465,7 +11798,7 @@ const machine_t machines[] = { }, /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ { - .name = "[i430HX] Intel CU430HX", + .name = "[i430HX] Intel CU430HX (Cumberland)", .internal_name = "cu430hx", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430HX, @@ -11476,20 +11809,21 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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 + .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 = 196608, - .step = 8192 + .max = 524288, + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -11516,20 +11850,21 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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 + .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 = 196608, - .step = 8192 + .max = 524288, + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -11543,6 +11878,46 @@ const machine_t machines[] = { .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 . @@ -11559,7 +11934,8 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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, @@ -11571,8 +11947,8 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, - .max = 196608, - .step = 8192 + .max = 524288, + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -11611,9 +11987,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, - .max = 786432, - .step = 8192 + .min = 4096, + .max = 524288, + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -11653,9 +12029,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_SCSI | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11688,14 +12064,14 @@ const machine_t machines[] = { .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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 = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11729,14 +12105,14 @@ const machine_t machines[] = { .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11774,9 +12150,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11793,7 +12169,7 @@ const machine_t machines[] = { /* 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 2240", + .name = "[i430VX] Compaq Presario 224x", .internal_name = "presario2240", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -11805,19 +12181,19 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 66666667, .max_bus = 66666667, .min_voltage = 2800, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, .ram = { - .min = 8192, - .max = 131072, - .step = 8192 + .min = 16384, + .max = 49152, + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -11834,7 +12210,7 @@ const machine_t machines[] = { /* Has a SM(S)C FDC37C931APM Super I/O chip with on-chip KBC with Compaq KBC firmware. */ { - .name = "[i430VX] Compaq Presario 4500", + .name = "[i430VX] Compaq Presario 45xx", .internal_name = "presario4500", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -11846,19 +12222,19 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 66666667, .max_bus = 66666667, .min_voltage = 2800, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, .ram = { - .min = 8192, - .max = 131072, - .step = 8192 + .min = 16384, + .max = 49152, + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -11875,7 +12251,7 @@ const machine_t machines[] = { /* Has a SM(S)C FDC37C932FR Super I/O chip with on-chip KBC with AMI MegaKey (revision '5') KBC firmware. */ { - .name = "[i430VX] Dell Hannibal+", + .name = "[i430VX] Dell Dimension XPS Pxxxa/Mxxxa", .internal_name = "dellhannibalp", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -11886,20 +12262,21 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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.0 + .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 = 8192 + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -11937,9 +12314,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -11969,7 +12346,7 @@ const machine_t machines[] = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, .min_bus = 50000000, - .max_bus = 66666667, + .max_bus = 75000000, .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, @@ -11977,10 +12354,52 @@ const machine_t machines[] = { }, .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_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -12014,14 +12433,14 @@ const machine_t machines[] = { .min_voltage = 2200, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { - .min = 16384, + .min = 8192, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -12039,7 +12458,7 @@ const machine_t machines[] = { PC87306 Super I/O chip, command 0xA1 returns '5'. Command 0xA0 copyright string: (C)1994 AMI . */ { - .name = "[i430VX] Packard Bell PB680", + .name = "[i430VX] Packard Bell Multimedia C110", .internal_name = "pb680", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -12050,7 +12469,8 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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, @@ -12063,7 +12483,7 @@ const machine_t machines[] = { .ram = { .min = 8192, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -12080,7 +12500,7 @@ const machine_t machines[] = { /* 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 PB810", + .name = "[i430VX] Packard Bell Multimedia M415", .internal_name = "pb810", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -12097,14 +12517,14 @@ const machine_t machines[] = { .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 4.0 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 511, .kbc_device = NULL, @@ -12138,14 +12558,14 @@ const machine_t machines[] = { .min_voltage = 2600, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -12159,48 +12579,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Unknown PS/2 KBC. */ - { - .name = "[i430HX] Radisys EPC-2102", - .internal_name = "epc2102", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430HX, - .init = machine_at_epc2102_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 83333333, - .min_voltage = 2500, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { - .min = 8192, - .max = 262144, - .max = 786432, - .step = 8192 - }, - .nvrmask = 127, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* 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. */ { @@ -12226,9 +12604,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 131072, - .step = 8192 + .step = 4096 }, .nvrmask = 127, .kbc_device = NULL, @@ -12303,7 +12681,7 @@ const machine_t machines[] = { .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, @@ -12326,7 +12704,7 @@ const machine_t machines[] = { }, /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ { - .name = "[i430TX] Gateway Tomahawk", + .name = "[i430TX] Gateway E-1000", .internal_name = "tomahawk", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -12338,12 +12716,12 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 60000000, .max_bus = 66666667, .min_voltage = 2100, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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, @@ -12364,10 +12742,10 @@ const machine_t machines[] = { .snd_device = &cs4236b_device, .net_device = &pcnet_am79c973_onboard_device }, -#if defined(DEV_BRANCH) && defined(USE_AN430TX) +#ifdef USE_AN430TX /* This has the Phoenix MultiKey KBC firmware. */ { - .name = "[i430TX] Intel AN430TX", + .name = "[i430TX] Intel AN430TX (Anchorage)", .internal_name = "an430tx", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -12378,13 +12756,14 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, @@ -12405,10 +12784,10 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_AN430TX) */ +#endif /* USE_AN430TX */ /* This has the AMIKey KBC firmware, which is an updated 'F' type. */ { - .name = "[i430TX] Intel YM430TX", + .name = "[i430TX] Intel YM430TX (Yamamoto)", .internal_name = "ym430tx", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -12419,20 +12798,21 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .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.0 + .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, + .min = 4096, .max = 262144, - .step = 8192 + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -12446,7 +12826,7 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* PhoenixBIOS 4.0 Rel 6.0 for 430TX, most likely has AMI KBC of some sort. Also has onboard Yamaha YMF701 which can't be emulated yet. */ + /* 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. */ { @@ -12462,12 +12842,12 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK(CPU_WINCHIP, CPU_WINCHIP2), - .min_bus = 50000000, + .min_bus = 60000000, .max_bus = 66666667, .min_voltage = 2500, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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 */ @@ -12508,13 +12888,13 @@ const machine_t machines[] = { .min_voltage = 2700, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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 = 786432, + .max = 262144, .step = 8192 }, .nvrmask = 255, @@ -12549,14 +12929,14 @@ const machine_t machines[] = { .min_voltage = 2700, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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, + .min = 4096, .max = 262144, - .step = 8192 + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -12584,8 +12964,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 55000000, - .max_bus = 75000000, + .min_bus = 60000000, + .max_bus = 66666667, .min_voltage = 2800, .max_voltage = 3520, .min_multi = 1.5, @@ -12594,9 +12974,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { - .min = 8192, + .min = 4096, .max = 262144, - .step = 8192 + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -12625,18 +13005,18 @@ const machine_t machines[] = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, .min_bus = 50000000, - .max_bus = 66666667, + .max_bus = 75000000, .min_voltage = 2100, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .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, + .min = 4096, .max = 262144, - .step = 8192 + .step = 4096 }, .nvrmask = 255, .kbc_device = NULL, @@ -12652,7 +13032,7 @@ const machine_t machines[] = { }, /* [TEST] Has AMIKey 'H' KBC firmware. */ { - .name = "[i430TX] TriGem Richmond", + .name = "[i430TX] TriGem RD535 (Richmond)", .internal_name = "richmond", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -12664,12 +13044,12 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 50000000, + .min_bus = 60000000, .max_bus = 66666667, .min_voltage = 2100, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, @@ -12776,11 +13156,52 @@ const machine_t machines[] = { .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 CB52X-SI", + .name = "[SiS 5571] Daewoo CD520", .internal_name = "cb52xsi", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_SIS_5571, @@ -13627,7 +14048,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, - .max = 524288, + .max = 786432, .step = 8192 }, .nvrmask = 511, @@ -13707,7 +14128,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, - .max = 1048576, + .max = 524288, .step = 8192 }, .nvrmask = 127, @@ -13744,7 +14165,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -13759,7 +14180,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cs4236_onboard_device, .net_device = NULL }, /* Has the AMIKey-2 (updated 'H') KBC firmware. */ @@ -13829,7 +14250,7 @@ const machine_t machines[] = { .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 = 131072, + .max = 524288, .step = 8192 }, .nvrmask = 127, @@ -13840,8 +14261,8 @@ const machine_t machines[] = { .device = NULL, .fdc_device = NULL, .sio_device = NULL, - .vid_device = &s3_virge_375_onboard_pci_device, - .snd_device = &cs4236b_device, + .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 @@ -13868,7 +14289,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -13883,7 +14304,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cs4236_onboard_device, .net_device = NULL }, /* Has the AMIKey-2 (updated 'H') KBC firmware. */ @@ -14151,7 +14572,7 @@ const machine_t machines[] = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, .min_bus = 60000000, - .max_bus = 100000000, + .max_bus = 83333333, .min_voltage = 1500, .max_voltage = 3500, .min_multi = 2.0, @@ -14387,6 +14808,47 @@ const machine_t machines[] = { }, /* 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", @@ -14530,11 +14992,11 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 8.0 }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .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 = 1048576, + .max = 524288, .step = 8192 }, .nvrmask = 255, @@ -14615,7 +15077,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1371 */ .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, @@ -14730,7 +15192,7 @@ const machine_t machines[] = { .package = CPU_PKG_SLOT1, .block = CPU_BLOCK_NONE, .min_bus = 66666667, - .max_bus = 66666667, + .max_bus = 100000000, .min_voltage = 1800, .max_voltage = 3500, .min_multi = 1.5, @@ -14760,7 +15222,7 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] A-Trend ATC-6310BXII", + .name = "[SMSC VictoryBX-66] A-Trend ATC6310BXII", .internal_name = "atc6310bxii", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, @@ -14896,7 +15358,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_PENTIUMPRO), .min_bus = 66666667, .max_bus = 150000000, .min_voltage = 1300, @@ -15093,6 +15555,47 @@ const machine_t machines[] = { /* 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. */ { @@ -15161,7 +15664,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, + .max = 1572864, .step = 8192 }, .nvrmask = 255, @@ -15195,7 +15698,7 @@ const machine_t machines[] = { .package = CPU_PKG_SLOT2, .block = CPU_BLOCK_NONE, .min_bus = 100000000, - .max_bus = 133333333, + .max_bus = 100000000, .min_voltage = 1800, .max_voltage = 3500, .min_multi = 1.5, @@ -15479,7 +15982,7 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] A-Trend ATC-7020BXII", + .name = "[SMSC VictoryBX-66] A-Trend ATC7020BXII", .internal_name = "atc7020bxii", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, @@ -15740,7 +16243,7 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), + .block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_PENTIUM2, CPU_CYRIX3S), .min_bus = 0, .max_bus = 66666667, .min_voltage = 0, @@ -15812,8 +16315,8 @@ const machine_t machines[] = { /* Saved copies - jumpers get applied to these. We use also machine_gpio to store IBM PC/XT jumpers as they need more than one byte. */ -static uint8_t machine_p1_default; -static uint8_t machine_p1; +static uint32_t machine_p1_default; +static uint32_t machine_p1; static uint32_t machine_gpio_default; static uint32_t machine_gpio; @@ -16084,19 +16587,39 @@ machine_get_nvrmask(int m) int machine_has_flags(int m, int flags) { - return (machines[m].flags & 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) { - return (machines[m].bus_flags & 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)) + ret |= MACHINE_BUS_XT_KBD; + + 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_bus(m, MACHINE_CARTRIDGE) ? 1 : 0); + return (machine_has_flags(m, MACHINE_CARTRIDGE) ? 1 : 0); } int @@ -16152,3 +16675,26 @@ 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 16976fa83..3eb2762bc 100644 --- a/src/machine_status.c +++ b/src/machine_status.c @@ -45,11 +45,13 @@ machine_status_init(void) machine_status.mo[i].active = false; } + for (size_t i = 0; i < 2; i++) + machine_status.cartridge[i].empty = (strlen(cart_fns[i]) == 0); + machine_status.cassette.empty = (strlen(cassette_fname) == 0); - for (size_t i = 0; i < HDD_BUS_USB; i++) { + for (size_t i = 0; i < HDD_BUS_USB; i++) machine_status.hdd[i].active = false; - } for (size_t i = 0; i < NET_CARD_MAX; i++) { machine_status.net[i].active = false; diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index d3d5d1ce7..0e52beb4e 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -9,9 +9,21 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c mmu_2386.c - rom.c row.c smram.c spd.c sst_flash.c) +add_library(mem OBJECT + catalyst_flash.c + i2c_eeprom.c + intel_flash.c + mem.c + mmu_2386.c + rom.c + row.c + smram.c + spd.c + sst_flash.c +) diff --git a/src/mem/catalyst_flash.c b/src/mem/catalyst_flash.c index 7cd40e9d7..00e2422a3 100644 --- a/src/mem/catalyst_flash.c +++ b/src/mem/catalyst_flash.c @@ -192,10 +192,9 @@ catalyst_flash_init(UNUSED(const device_t *info)) FILE *fp; flash_t *dev; - dev = malloc(sizeof(flash_t)); - memset(dev, 0, sizeof(flash_t)); + dev = calloc(1, sizeof(flash_t)); - sprintf(flash_path, "%s.bin", machine_get_internal_name_ex(machine)); + sprintf(flash_path, "%s.bin", machine_get_nvr_name_ex(machine)); mem_mapping_disable(&bios_mapping); mem_mapping_disable(&bios_high_mapping); @@ -240,7 +239,7 @@ const device_t catalyst_flash_device = { .init = catalyst_flash_init, .close = catalyst_flash_close, .reset = catalyst_flash_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/mem/i2c_eeprom.c b/src/mem/i2c_eeprom.c index 8e4a6cc14..a8ae7ed04 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -128,8 +128,7 @@ log2i(uint32_t i) void * i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t writable) { - i2c_eeprom_t *dev = (i2c_eeprom_t *) malloc(sizeof(i2c_eeprom_t)); - memset(dev, 0, sizeof(i2c_eeprom_t)); + i2c_eeprom_t *dev = (i2c_eeprom_t *) calloc(1, sizeof(i2c_eeprom_t)); /* Round size up to the next power of 2. */ uint32_t pow_size = 1 << log2i(size); diff --git a/src/mem/intel_flash.c b/src/mem/intel_flash.c index 7949f302a..e193f3545 100644 --- a/src/mem/intel_flash.c +++ b/src/mem/intel_flash.c @@ -351,10 +351,9 @@ intel_flash_init(const device_t *info) flash_t *dev; uint8_t type = info->local & 0xff; - dev = malloc(sizeof(flash_t)); - memset(dev, 0, sizeof(flash_t)); + dev = calloc(1, sizeof(flash_t)); - sprintf(flash_path, "%s.bin", machine_get_internal_name_ex(machine)); + sprintf(flash_path, "%s.bin", machine_get_nvr_name_ex(machine)); dev->flags = info->local & 0xff; @@ -564,7 +563,7 @@ const device_t intel_flash_bxt_ami_device = { .init = intel_flash_init, .close = intel_flash_close, .reset = intel_flash_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -578,7 +577,7 @@ const device_t intel_flash_bxt_device = { .init = intel_flash_init, .close = intel_flash_close, .reset = intel_flash_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -592,7 +591,7 @@ const device_t intel_flash_bxb_device = { .init = intel_flash_init, .close = intel_flash_close, .reset = intel_flash_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/mem/mem.c b/src/mem/mem.c index ae6e4ae00..d1c6de49d 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -225,6 +225,19 @@ flushmmucache(void) #endif } +void +flushmmucache_pc(void) +{ + mmuflush++; + + pccache = (uint32_t) 0xffffffff; + pccache2 = (uint8_t *) 0xffffffff; + +#ifdef USE_DYNAREC + codegen_flush(); +#endif +} + void flushmmucache_nopc(void) { @@ -307,7 +320,7 @@ mmutranslatereal_normal(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -323,12 +336,15 @@ mmutranslatereal_normal(uint32_t addr, int rw) mmu_perm = temp & 4; rammap(addr2) |= (rw ? 0x60 : 0x20); - return (temp & ~0x3fffff) + (addr & 0x3fffff); + uint64_t page = temp & ~0x3fffff; + if (cpu_features & CPU_FEATURE_PSE36) + page |= (uint64_t) (temp & 0x1e000) << 19; + return page + (addr & 0x3fffff); } temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !cpl_override && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -392,7 +408,7 @@ mmutranslatereal_pae(uint32_t addr, int rw) if (temp & 0x80) { /*2MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) { + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -413,7 +429,7 @@ mmutranslatereal_pae(uint32_t addr, int rw) addr4 = (temp & ~0xfffULL) + ((addr >> 9) & 0xff8); temp = rammap64(addr4) & 0x000000ffffffffffULL; temp3 = temp & temp4; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !cpl_override && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || (cr0 & WP_FLAG)))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -475,16 +491,19 @@ mmutranslate_noabrt_normal(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) return 0xffffffffffffffffULL; - return (temp & ~0x3fffff) + (addr & 0x3fffff); + uint64_t page = temp & ~0x3fffff; + if (cpu_features & CPU_FEATURE_PSE36) + page |= (uint64_t) (temp & 0x1e000) << 19; + return page + (addr & 0x3fffff); } temp = rammap((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !cpl_override && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) return 0xffffffffffffffffULL; return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); @@ -519,7 +538,7 @@ mmutranslate_noabrt_pae(uint32_t addr, int rw) if (temp & 0x80) { /*2MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) return 0xffffffffffffffffULL; return ((temp & ~0x1fffffULL) + (addr & 0x1fffff)) & 0x000000ffffffffffULL; @@ -530,7 +549,7 @@ mmutranslate_noabrt_pae(uint32_t addr, int rw) temp3 = temp & temp4; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !cpl_override && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) return 0xffffffffffffffffULL; return ((temp & ~0xfffULL) + ((uint64_t) (addr & 0xfff))) & 0x000000ffffffffffULL; @@ -2338,41 +2357,47 @@ mem_mapping_recalc(uint64_t base, uint64_t size) /* In range? */ if (map->enable && (uint64_t) map->base < ((uint64_t) base + (uint64_t) size) && ((uint64_t) map->base + (uint64_t) map->size) > (uint64_t) base) { + uint64_t i_a = ((~map->base_ignore) & 0xffffffffULL) + 0x00000001ULL; + uint64_t i_s = 0x00000000ULL; + uint64_t i_e = map->base_ignore; + uint64_t i_c = 0x00000000ULL; uint64_t start = (map->base < base) ? map->base : base; uint64_t end = (((uint64_t) map->base + (uint64_t) map->size) < (base + size)) ? ((uint64_t) map->base + (uint64_t) map->size) : (base + size); if (start < map->base) start = map->base; - for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { - /* CPU */ - n = !!in_smm; - wp = _mem_wp[c >> MEM_GRANULARITY_BITS]; + for (i_c = i_s; i_c <= i_e; i_c += i_a) { + for (c = (start + i_c); c < (end + i_c); c += MEM_GRANULARITY_SIZE) { + /* CPU */ + n = !!in_smm; + wp = _mem_wp[c >> MEM_GRANULARITY_BITS]; - if (map->exec && mem_mapping_access_allowed(map->flags, - _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) - _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); - if (!wp && (map->write_b || map->write_w || map->write_l) && - mem_mapping_access_allowed(map->flags, - _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) - write_mapping[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && - mem_mapping_access_allowed(map->flags, - _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) - read_mapping[c >> MEM_GRANULARITY_BITS] = map; + if (map->exec && mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) + _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + write_mapping[c >> MEM_GRANULARITY_BITS] = map; + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + read_mapping[c >> MEM_GRANULARITY_BITS] = map; - /* Bus */ - n |= STATE_BUS; - wp = _mem_wp_bus[c >> MEM_GRANULARITY_BITS]; + /* Bus */ + n |= STATE_BUS; + wp = _mem_wp_bus[c >> MEM_GRANULARITY_BITS]; - if (!wp && (map->write_b || map->write_w || map->write_l) && - mem_mapping_access_allowed(map->flags, - _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) - write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; - if ((map->read_b || map->read_w || map->read_l) && - mem_mapping_access_allowed(map->flags, - _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) - read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; + } } } map = map->next; @@ -2584,6 +2609,20 @@ mem_mapping_set_addr(mem_mapping_t *map, uint32_t base, uint32_t size) mem_mapping_recalc(map->base, map->size); } +void +mem_mapping_set_base_ignore(mem_mapping_t *map, uint32_t base_ignore) +{ + /* Remove old mapping. */ + map->enable = 0; + mem_mapping_recalc(map->base, map->size); + + /* Set new mapping. */ + map->enable = 1; + map->base_ignore = base_ignore; + + mem_mapping_recalc(map->base, map->size); +} + void mem_mapping_set_exec(mem_mapping_t *map, uint8_t *exec) { @@ -2980,8 +3019,8 @@ umc_smram_recalc(uint32_t start, int set) umc_page_recalc(c, set); } -void -mem_remap_top_ex(int kb, uint32_t start) +static void +mem_remap_top_ex_common(int kb, uint32_t start, int mid) { uint32_t c; int offset; @@ -3084,37 +3123,61 @@ mem_remap_top_ex(int kb, uint32_t start) mem_mapping_set_addr(&ram_remapped_mapping2, (start * 1024) + 0x00020000, 0x00020000); mem_mapping_set_exec(&ram_remapped_mapping2, ram + 0x000d0000); - mem_mapping_set_addr(&ram_mid_mapping, 0x000c0000, 0x00010000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000c0000); - mem_mapping_set_addr(&ram_mid_mapping2, 0x000f0000, 0x00010000); - mem_mapping_set_exec(&ram_mid_mapping2, ram + 0x000f0000); + if (mid) { + mem_mapping_set_addr(&ram_mid_mapping, 0x000c0000, 0x00010000); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000c0000); + mem_mapping_set_addr(&ram_mid_mapping2, 0x000f0000, 0x00010000); + mem_mapping_set_exec(&ram_mid_mapping2, ram + 0x000f0000); + } } else { mem_mapping_set_addr(&ram_remapped_mapping, start * 1024, size * 1024); mem_mapping_set_exec(&ram_remapped_mapping, ram + start_addr); mem_mapping_disable(&ram_remapped_mapping2); - mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000); - mem_mapping_disable(&ram_mid_mapping2); + if (mid) { + mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000); + mem_mapping_disable(&ram_mid_mapping2); + } } } else { mem_mapping_disable(&ram_remapped_mapping); mem_mapping_disable(&ram_remapped_mapping2); - mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000); - mem_mapping_disable(&ram_mid_mapping2); + if (mid) { + mem_mapping_set_addr(&ram_mid_mapping, 0x000a0000, 0x00060000); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0x000a0000); + mem_mapping_disable(&ram_mid_mapping2); + } } flushmmucache(); } +void +mem_remap_top_ex(int kb, uint32_t start) +{ + mem_remap_top_ex_common(kb, start, 1); +} + +void +mem_remap_top_ex_nomid(int kb, uint32_t start) +{ + mem_remap_top_ex_common(kb, start, 0); +} + void mem_remap_top(int kb) { mem_remap_top_ex(kb, (mem_size >= 1024) ? mem_size : 1024); } +void +mem_remap_top_nomid(int kb) +{ + mem_remap_top_ex_nomid(kb, (mem_size >= 1024) ? mem_size : 1024); +} + void mem_reset_page_blocks(void) { diff --git a/src/mem/mmu_2386.c b/src/mem/mmu_2386.c index abc34ff96..7418a88d8 100644 --- a/src/mem/mmu_2386.c +++ b/src/mem/mmu_2386.c @@ -198,7 +198,7 @@ mmutranslatereal_2386(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -219,7 +219,7 @@ mmutranslatereal_2386(uint32_t addr, int rw) temp = mem_readl_map((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !cpl_override && !(temp3 & 2) && (((CPL == 3) && !cpl_override) || ((is486 || isibm486) && (cr0 & WP_FLAG))))) { cr2 = addr; temp &= 1; if (CPL == 3) @@ -258,7 +258,7 @@ mmutranslate_noabrt_2386(uint32_t addr, int rw) if ((temp & 0x80) && (cr4 & CR4_PSE)) { /*4MB page*/ - if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + if (((CPL == 3) && !(temp & 4) && !cpl_override) || (rw && !cpl_override && !(temp & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) return 0xffffffffffffffffULL; return (temp & ~0x3fffff) + (addr & 0x3fffff); @@ -267,7 +267,7 @@ mmutranslate_noabrt_2386(uint32_t addr, int rw) temp = mem_readl_map((temp & ~0xfff) + ((addr >> 10) & 0xffc)); temp3 = temp & temp2; - if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) + if (!(temp & 1) || ((CPL == 3) && !(temp3 & 4) && !cpl_override) || (rw && !cpl_override && !(temp3 & 2) && ((CPL == 3) || (cr0 & WP_FLAG)))) return 0xffffffffffffffffULL; return (uint64_t) ((temp & ~0xfff) + (addr & 0xfff)); @@ -278,6 +278,7 @@ readmembl_2386(uint32_t addr) { mem_mapping_t *map; uint64_t a; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); @@ -287,7 +288,7 @@ readmembl_2386(uint32_t addr) high_page = 0; - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_read_2386(addr); addr64 = (uint32_t) a; @@ -308,6 +309,7 @@ writemembl_2386(uint32_t addr, uint8_t val) { mem_mapping_t *map; uint64_t a; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; mem_debug_check_addr(addr, 2); GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); @@ -317,7 +319,7 @@ writemembl_2386(uint32_t addr, uint8_t val) high_page = 0; - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_write_2386(addr); addr64 = (uint32_t) a; @@ -336,12 +338,13 @@ uint8_t readmembl_no_mmut_2386(uint32_t addr, uint32_t a64) { mem_mapping_t *map; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 1); mem_logical_addr = addr; - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return 0xff; @@ -361,12 +364,13 @@ void writemembl_no_mmut_2386(uint32_t addr, uint32_t a64, uint8_t val) { mem_mapping_t *map; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 1); mem_logical_addr = addr; - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return; @@ -384,6 +388,7 @@ readmemwl_2386(uint32_t addr) { mem_mapping_t *map; uint64_t a; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; addr64a[0] = addr; addr64a[1] = addr + 1; @@ -399,7 +404,7 @@ readmemwl_2386(uint32_t addr) if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { for (uint8_t i = 0; i < 2; i++) { a = mmutranslate_read_2386(addr + i); addr64a[i] = (uint32_t) a; @@ -414,7 +419,7 @@ readmemwl_2386(uint32_t addr) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_read_2386(addr); addr64a[0] = (uint32_t) a; @@ -442,6 +447,7 @@ writememwl_2386(uint32_t addr, uint16_t val) { mem_mapping_t *map; uint64_t a; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; addr64a[0] = addr; addr64a[1] = addr + 1; @@ -457,7 +463,7 @@ writememwl_2386(uint32_t addr, uint16_t val) if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { for (uint8_t i = 0; i < 2; i++) { /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ @@ -479,7 +485,7 @@ writememwl_2386(uint32_t addr, uint16_t val) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_write_2386(addr); addr64a[0] = (uint32_t) a; @@ -508,6 +514,7 @@ uint16_t readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) { mem_mapping_t *map; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 2); @@ -517,7 +524,7 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return 0xffff; } @@ -527,7 +534,7 @@ readmemwl_no_mmut_2386(uint32_t addr, uint32_t *a64) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return 0xffff; @@ -552,6 +559,7 @@ void writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) { mem_mapping_t *map; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 2); @@ -561,7 +569,7 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) if (!cpu_cyrix_alignment || (addr & 7) == 7) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffe) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return; } @@ -572,7 +580,7 @@ writememwl_no_mmut_2386(uint32_t addr, uint32_t *a64, uint16_t val) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return; @@ -600,6 +608,7 @@ readmemll_2386(uint32_t addr) mem_mapping_t *map; int i; uint64_t a = 0x0000000000000000ULL; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); @@ -615,7 +624,7 @@ readmemll_2386(uint32_t addr) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { for (i = 0; i < 4; i++) { if (i == 0) { a = mmutranslate_read_2386(addr + i); @@ -644,7 +653,7 @@ readmemll_2386(uint32_t addr) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_read_2386(addr); addr64a[0] = (uint32_t) a; @@ -674,6 +683,7 @@ writememll_2386(uint32_t addr, uint32_t val) mem_mapping_t *map; int i; uint64_t a = 0x0000000000000000ULL; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; for (i = 0; i < 4; i++) { addr64a[i] = (uint64_t) (addr + i); @@ -689,7 +699,7 @@ writememll_2386(uint32_t addr, uint32_t val) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { for (i = 0; i < 4; i++) { /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ @@ -723,7 +733,7 @@ writememll_2386(uint32_t addr, uint32_t val) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_write_2386(addr); addr64a[0] = (uint32_t) a; @@ -758,6 +768,7 @@ uint32_t readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) { mem_mapping_t *map; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_READ, 4); @@ -767,7 +778,7 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return 0xffffffff; } @@ -777,7 +788,7 @@ readmemll_no_mmut_2386(uint32_t addr, uint32_t *a64) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return 0xffffffff; @@ -804,6 +815,7 @@ void writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) { mem_mapping_t *map; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; GDBSTUB_MEM_ACCESS(addr, GDBSTUB_MEM_WRITE, 4); @@ -813,7 +825,7 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) if ((addr & 3) && (!cpu_cyrix_alignment || (addr & 7) > 4)) cycles -= timing_misaligned; if ((addr & 0xfff) > 0xffc) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return; } @@ -824,7 +836,7 @@ writememll_no_mmut_2386(uint32_t addr, uint32_t *a64, uint32_t val) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { if (cpu_state.abrt || high_page) return; @@ -858,6 +870,7 @@ readmemql_2386(uint32_t addr) mem_mapping_t *map; int i; uint64_t a = 0x0000000000000000ULL; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); @@ -872,7 +885,7 @@ readmemql_2386(uint32_t addr) if (addr & 7) { cycles -= timing_misaligned; if ((addr & 0xfff) > 0xff8) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { for (i = 0; i < 8; i++) { if (i == 0) { a = mmutranslate_read_2386(addr + i); @@ -901,7 +914,7 @@ readmemql_2386(uint32_t addr) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { a = mmutranslate_read_2386(addr); addr64a[0] = (uint32_t) a; @@ -924,6 +937,7 @@ writememql_2386(uint32_t addr, uint64_t val) mem_mapping_t *map; int i; uint64_t a = 0x0000000000000000ULL; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; for (i = 0; i < 8; i++) { addr64a[i] = (uint64_t) (addr + i); @@ -938,7 +952,7 @@ writememql_2386(uint32_t addr, uint64_t val) if (addr & 7) { cycles -= timing_misaligned; if ((addr & 0xfff) > 0xff8) { - if (cr0 >> 31) { + if (temp_cr0 >> 31) { for (i = 0; i < 8; i++) { /* Do not translate a page that has a valid lookup, as that is by definition valid and the whole purpose of the lookup is to avoid repeat identical translations. */ @@ -972,7 +986,7 @@ writememql_2386(uint32_t addr, uint64_t val) } } - if (cr0 >> 31) { + if (temp_cr0 >> 31) { addr64a[0] = mmutranslate_write_2386(addr); if (addr64a[0] > 0xffffffffULL) return; @@ -1013,13 +1027,14 @@ do_mmutranslate_2386(uint32_t addr, uint32_t *a64, int num, int write) int i; uint32_t last_addr = addr + (num - 1); uint64_t a = 0x0000000000000000ULL; + uint32_t temp_cr0 = cpu_old_paging ? (cr0 ^ 0x80000000) : cr0; mem_debug_check_addr(addr, write ? 2 : read_type); for (i = 0; i < num; i++) a64[i] = (uint64_t) addr; - if (!(cr0 >> 31)) + if (!(temp_cr0 >> 31)) return; for (i = 0; i < num; i++) { diff --git a/src/mem/row.c b/src/mem/row.c index ccd0325a4..c3e10841f 100644 --- a/src/mem/row.c +++ b/src/mem/row.c @@ -334,15 +334,15 @@ row_init(const device_t *info) /* NOTE: NOT const, so that we can patch it at init. */ device_t row_device = { - .name = "DRAM Rows", + .name = "DRAM Rows", .internal_name = "dram_rows", - .flags = DEVICE_AT, - .local = 0x0000, - .init = row_init, - .close = row_close, - .reset = row_reset, - { .available = NULL }, + .flags = DEVICE_ISA16, + .local = 0x0000, + .init = row_init, + .close = row_close, + .reset = row_reset, + .available = NULL, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/mem/smram.c b/src/mem/smram.c index 0532e2dd5..afbc5475c 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -245,12 +245,11 @@ smram_add(void) return NULL; } - temp_smram = (smram_t *) malloc(sizeof(smram_t)); + temp_smram = (smram_t *) calloc(1, sizeof(smram_t)); if (temp_smram == NULL) { - fatal("smram_add(): temp_smram malloc failed\n"); + fatal("smram_add(): temp_smram calloc failed\n"); return NULL; } - memset(temp_smram, 0x00, sizeof(smram_t)); memset(&(temp_smram->mapping), 0x00, sizeof(mem_mapping_t)); /* Add struct to the beginning of the list if necessary.*/ diff --git a/src/mem/spd.c b/src/mem/spd.c index a0896a05a..01cd7b464 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -221,8 +221,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) if (!(slot_mask & (1 << slot))) continue; /* slot disabled */ - spd_modules[slot] = (spd_t *) malloc(sizeof(spd_t)); - memset(spd_modules[slot], 0, sizeof(spd_t)); + spd_modules[slot] = (spd_t *) calloc(1, sizeof(spd_t)); spd_modules[slot]->slot = slot; spd_modules[slot]->size = rows[row]; @@ -595,7 +594,7 @@ static const device_t spd_device = { .init = spd_init, .close = spd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index cd6ec7cd9..b41e0f2e2 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -505,10 +505,9 @@ static void * sst_init(const device_t *info) { FILE *fp; - sst_t *dev = malloc(sizeof(sst_t)); - memset(dev, 0, sizeof(sst_t)); + sst_t *dev = calloc(1, sizeof(sst_t)); - sprintf(flash_path, "%s.bin", machine_get_internal_name_ex(machine)); + sprintf(flash_path, "%s.bin", machine_get_nvr_name_ex(machine)); mem_mapping_disable(&bios_mapping); mem_mapping_disable(&bios_high_mapping); @@ -576,7 +575,7 @@ const device_t sst_flash_29ee010_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -590,7 +589,7 @@ const device_t sst_flash_29ee020_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -604,7 +603,7 @@ const device_t winbond_flash_w29c512_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -618,7 +617,7 @@ const device_t winbond_flash_w29c010_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -632,7 +631,7 @@ const device_t winbond_flash_w29c020_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -646,7 +645,7 @@ const device_t winbond_flash_w29c040_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -660,7 +659,7 @@ const device_t sst_flash_39sf512_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -674,7 +673,7 @@ const device_t sst_flash_39sf010_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -688,7 +687,7 @@ const device_t sst_flash_39sf020_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -702,7 +701,7 @@ const device_t sst_flash_39sf040_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -716,7 +715,7 @@ const device_t sst_flash_39lf512_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -730,7 +729,7 @@ const device_t sst_flash_39lf010_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -744,7 +743,7 @@ const device_t sst_flash_39lf020_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -758,7 +757,7 @@ const device_t sst_flash_39lf040_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -772,7 +771,7 @@ const device_t sst_flash_39lf080_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -786,7 +785,7 @@ const device_t sst_flash_39lf016_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -808,7 +807,7 @@ const device_t sst_flash_49lf002_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -822,7 +821,7 @@ const device_t sst_flash_49lf020_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -836,7 +835,7 @@ const device_t sst_flash_49lf020a_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -850,7 +849,7 @@ const device_t sst_flash_49lf003_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -864,7 +863,7 @@ const device_t sst_flash_49lf030_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -878,7 +877,7 @@ const device_t sst_flash_49lf004_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -892,7 +891,7 @@ const device_t sst_flash_49lf004c_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -906,7 +905,7 @@ const device_t sst_flash_49lf040_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -920,7 +919,7 @@ const device_t sst_flash_49lf008_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -934,7 +933,7 @@ const device_t sst_flash_49lf008c_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -948,7 +947,7 @@ const device_t sst_flash_49lf080_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -962,7 +961,7 @@ const device_t sst_flash_49lf016_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -977,7 +976,7 @@ const device_t sst_flash_49lf160_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -991,7 +990,7 @@ const device_t amd_flash_29f020a_device = { .init = sst_init, .close = sst_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 0783e4b4c..71f41f059 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -9,20 +9,42 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # set(net_sources) -list(APPEND net_sources network.c net_pcap.c net_slirp.c net_dp8390.c net_3c501.c - net_3c503.c net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c net_modem.c utils/getline.c) +list(APPEND net_sources + network.c + net_pcap.c + net_slirp.c + net_dp8390.c + net_3c501.c + net_3c503.c + net_ne2000.c + net_pcnet.c + net_wd8003.c + net_plip.c + net_event.c + net_null.c + net_eeprom_nmc93cxx.c + net_tulip.c + net_rtl8139.c + net_l80225.c + net_modem.c + utils/getline.c +) find_package(PkgConfig REQUIRED) pkg_check_modules(SLIRP REQUIRED IMPORTED_TARGET slirp) target_link_libraries(86Box PkgConfig::SLIRP) if(WIN32) - target_link_libraries(PkgConfig::SLIRP INTERFACE wsock32 ws2_32 iphlpapi iconv) + target_link_libraries(PkgConfig::SLIRP INTERFACE wsock32 ws2_32 iphlpapi) + if (NOT MSVC) + target_link_libraries(PkgConfig::SLIRP INTERFACE iconv) + endif() if(STATIC_BUILD) add_compile_definitions(LIBSLIRP_STATIC) endif() diff --git a/src/network/net_3c501.c b/src/network/net_3c501.c index 868ee036f..f5809afb1 100644 --- a/src/network/net_3c501.c +++ b/src/network/net_3c501.c @@ -56,7 +56,6 @@ #include <86box/thread.h> #include <86box/timer.h> #include <86box/network.h> -#include <86box/bswap.h> #include <86box/plat_unused.h> /* Maximum number of times we report a link down to the guest (failure to send frame) */ @@ -1080,8 +1079,7 @@ threec501_nic_init(UNUSED(const device_t *info)) uint32_t mac; threec501_t *dev; - dev = malloc(sizeof(threec501_t)); - memset(dev, 0x00, sizeof(threec501_t)); + dev = calloc(1, sizeof(threec501_t)); dev->maclocal[0] = 0x02; /* 02:60:8C (3Com OID) */ dev->maclocal[1] = 0x60; dev->maclocal[2] = 0x8C; @@ -1156,30 +1154,31 @@ threec501_nic_close(void *priv) static const device_config_t threec501_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x280", .value = 0x280 }, { .description = "0x300", .value = 0x300 }, { .description = "0x310", .value = 0x310 }, { .description = "0x320", .value = 0x320 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2/9", .value = 9 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, @@ -1188,28 +1187,34 @@ static const device_config_t threec501_config[] = { { .description = "IRQ 7", .value = 7 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "DMA 1", .value = 1 }, { .description = "DMA 2", .value = 2 }, { .description = "DMA 3", .value = 3 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -1222,7 +1227,7 @@ const device_t threec501_device = { .init = threec501_nic_init, .close = threec501_nic_close, .reset = elnkR3Reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = threec501_config diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index 11e823326..b35e0d453 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -60,7 +60,6 @@ #include <86box/timer.h> #include <86box/network.h> #include <86box/net_dp8390.h> -#include <86box/bswap.h> #include <86box/plat_unused.h> typedef struct threec503_t { @@ -573,8 +572,7 @@ threec503_nic_init(UNUSED(const device_t *info)) uint32_t mac; threec503_t *dev; - dev = malloc(sizeof(threec503_t)); - memset(dev, 0x00, sizeof(threec503_t)); + dev = calloc(1, sizeof(threec503_t)); dev->maclocal[0] = 0x02; /* 02:60:8C (3Com OID) */ dev->maclocal[1] = 0x60; dev->maclocal[2] = 0x8C; @@ -656,14 +654,14 @@ threec503_nic_close(void *priv) static const device_config_t threec503_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x250", .value = 0x250 }, { .description = "0x280", .value = 0x280 }, { .description = "0x2a0", .value = 0x2a0 }, @@ -674,80 +672,83 @@ static const device_config_t threec503_config[] = { { .description = "0x350", .value = 0x350 }, { .description = "", .value = 0 } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 5", .value = 5 }, { .description = "", .value = 0 } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_int = 3, + .file_filter = "", + .spinner = { 0 }, + .selection = { { .description = "DMA 1", .value = 1 }, { .description = "DMA 2", .value = 2 }, { .description = "DMA 3", .value = 3 }, { .description = "", .value = 0 } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "", .value = 0 } - }, + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xCC000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xCC000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "DC00", .value = 0xDC000 }, { .description = "D800", .value = 0xD8000 }, { .description = "C800", .value = 0xC8000 }, { .description = "CC00", .value = 0xCC000 }, - { .description = "", .value = 0 } + { .description = "", .value = 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format off }; const device_t threec503_device = { - .name = "3Com EtherLink II", + .name = "3Com EtherLink II", .internal_name = "3c503", - .flags = DEVICE_ISA, - .local = 0, - .init = threec503_nic_init, - .close = threec503_nic_close, - .reset = NULL, - { .available = NULL }, + .flags = DEVICE_ISA, + .local = 0, + .init = threec503_nic_init, + .close = threec503_nic_close, + .reset = NULL, + .available = NULL, .speed_changed = NULL, - .force_redraw = NULL, - .config = threec503_config + .force_redraw = NULL, + .config = threec503_config }; diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index b563b703a..623dec56c 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -396,7 +396,7 @@ dp8390_rx_common(void *priv, uint8_t *buf, int io_len) } else { endbytes = (dev->page_stop - dev->curr_page) * 256; memcpy(startptr + sizeof(pkthdr), buf, endbytes - sizeof(pkthdr)); - startptr = &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap]; + startptr = &dev->mem[((dev->page_start * 256) - dev->mem_start) & dev->mem_wrap]; memcpy(startptr, buf + endbytes - sizeof(pkthdr), io_len - endbytes + 8); } dev->curr_page = nextpage; @@ -918,8 +918,7 @@ dp8390_set_defaults(dp8390_t *dev, uint8_t flags) void dp8390_mem_alloc(dp8390_t *dev, uint32_t start, uint32_t size) { - dev->mem = (uint8_t *) malloc(size * sizeof(uint8_t)); - memset(dev->mem, 0, size * sizeof(uint8_t)); + dev->mem = (uint8_t *) calloc(size, sizeof(uint8_t)); dev->mem_start = start; dev->mem_end = start + size; dev->mem_size = size; @@ -1007,8 +1006,7 @@ dp8390_soft_reset(dp8390_t *dev) static void * dp8390_init(UNUSED(const device_t *info)) { - dp8390_t *dp8390 = (dp8390_t *) malloc(sizeof(dp8390_t)); - memset(dp8390, 0, sizeof(dp8390_t)); + dp8390_t *dp8390 = (dp8390_t *) calloc(1, sizeof(dp8390_t)); /* Set values assuming WORD and only the clear IRQ flag - - the NIC can then call dp8390_set_defaults() again to @@ -1047,7 +1045,7 @@ const device_t dp8390_device = { .init = dp8390_init, .close = dp8390_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/network/net_eeprom_nmc93cxx.c index 3ad6bd030..b4fdce1e6 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/network/net_eeprom_nmc93cxx.c @@ -277,7 +277,7 @@ const device_t nmc93cxx_device = { .init = nmc93cxx_eeprom_init, .close = nmc93cxx_eeprom_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/network/net_modem.c b/src/network/net_modem.c index e48467a86..a8eab4290 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -264,7 +264,7 @@ modem_read_phonebook_file(modem_t *modem, const char *path) if (strspn(entry.phone, "01234567890*=,;#+>") != strlen(entry.phone)) { /* Invalid characters. */ - pclog("Modem: Invalid character in phone number %s\n", entry.phone); + modem_log("Modem: Invalid character in phone number %s\n", entry.phone); continue; } @@ -434,7 +434,7 @@ host_to_modem_cb(void *priv) { modem_t *modem = (modem_t *) priv; - if (modem->in_warmup) + if (modem->in_warmup || (modem->serial == NULL)) goto no_write_to_machine; if ((modem->serial->type >= SERIAL_16550) && modem->serial->fifo_enabled) { @@ -617,14 +617,16 @@ modem_enter_idle_state(modem_t *modem) if (modem->listen_port) { modem->serversocket = plat_netsocket_create_server(NET_SOCKET_TCP, modem->listen_port); if (modem->serversocket == (SOCKET) -1) { - pclog("Failed to set up server on port %d\n", modem->listen_port); + modem_log("Failed to set up server on port %d\n", modem->listen_port); } } - serial_set_cts(modem->serial, 1); - serial_set_dsr(modem->serial, 1); - serial_set_dcd(modem->serial, (!modem->dcdmode ? 1 : 0)); - serial_set_ri(modem->serial, 0); + if (modem->serial != NULL) { + serial_set_cts(modem->serial, 1); + serial_set_dsr(modem->serial, 1); + serial_set_dcd(modem->serial, (!modem->dcdmode ? 1 : 0)); + serial_set_ri(modem->serial, 0); + } } void @@ -640,8 +642,11 @@ modem_enter_connected_state(modem_t *modem) plat_netsocket_close(modem->serversocket); modem->serversocket = -1; memset(&modem->telClient, 0, sizeof(modem->telClient)); - serial_set_dcd(modem->serial, 1); - serial_set_ri(modem->serial, 0); + + if (modem->serial != NULL) { + serial_set_dcd(modem->serial, 1); + serial_set_ri(modem->serial, 0); + } } void @@ -703,14 +708,14 @@ modem_dial(modem_t *modem, const char *str) modem->numberinprogress[0] = 0; modem->clientsocket = plat_netsocket_create(NET_SOCKET_TCP); if (modem->clientsocket == -1) { - pclog("Failed to create client socket\n"); + modem_log("Failed to create client socket\n"); modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); return; } if (-1 == plat_netsocket_connect(modem->clientsocket, buf, port)) { - pclog("Failed to connect to %s\n", buf); + modem_log("Failed to connect to %s\n", buf); modem_send_res(modem, ResNOCARRIER); modem_enter_idle_state(modem); return; @@ -1128,7 +1133,7 @@ modem_dtr_callback_timer(void *priv) } void -modem_dtr_callback(serial_t *serial, int status, void *priv) +modem_dtr_callback(UNUSED(serial_t *serial), int status, void *priv) { modem_t *dev = (modem_t *) priv; dev->dtrstate = !!status; @@ -1147,7 +1152,7 @@ fifo8_resize_2x(Fifo8 *fifo) if (!used) return; - uint8_t *temp_buf = calloc(fifo->capacity * 2, 1); + uint8_t *temp_buf = calloc(size, 1); if (!temp_buf) { fatal("net_modem: Out Of Memory!\n"); } @@ -1391,7 +1396,8 @@ modem_cmdpause_timer_callback(void *priv) } else { modem->ringing = true; modem_send_res(modem, ResRING); - serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); + if (modem->serial != NULL) + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); modem->ringtimer = 3000; modem->reg[MREG_RING_COUNT] = 0; } @@ -1405,7 +1411,8 @@ modem_cmdpause_timer_callback(void *priv) return; } modem_send_res(modem, ResRING); - serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); + if (modem->serial != NULL) + serial_set_ri(modem->serial, !serial_get_ri(modem->serial)); modem->ringtimer = 3000; } @@ -1440,7 +1447,8 @@ modem_cmdpause_timer_callback(void *priv) if (modem->connected) { uint8_t buffer[16]; int wouldblock = 0; - int res = plat_netsocket_receive(modem->clientsocket, buffer, sizeof(buffer), &wouldblock); + int recv = MIN(modem->rx_data.capacity - modem->rx_data.num, sizeof(buffer)); + int res = plat_netsocket_receive(modem->clientsocket, buffer, recv, &wouldblock); if (res > 0) { if (modem->telnet_mode) @@ -1475,7 +1483,7 @@ modem_cmdpause_timer_callback(void *priv) /* Initialize the device for use by the user. */ static void * -modem_init(const device_t *info) +modem_init(UNUSED(const device_t *info)) { modem_t *modem = (modem_t *) calloc(1, sizeof(modem_t)); const char *phonebook_file = NULL; @@ -1488,8 +1496,8 @@ modem_init(const device_t *info) modem->clientsocket = modem->serversocket = modem->waitingclientsocket = -1; - fifo8_create(&modem->data_pending, 0x20000); - fifo8_create(&modem->rx_data, 0x20000); + fifo8_create(&modem->data_pending, 0x40000); + fifo8_create(&modem->rx_data, 0x40000); timer_add(&modem->dtr_timer, modem_dtr_callback_timer, modem, 0); timer_add(&modem->host_to_serial_timer, host_to_modem_cb, modem, 0); @@ -1523,30 +1531,31 @@ modem_close(void *priv) // clang-format off static const device_config_t modem_config[] = { { - .name = "port", - .description = "Serial Port", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 } } }, { - .name = "baudrate", - .description = "Baud Rate", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 115200, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { + .name = "baudrate", + .description = "Baud Rate", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 115200, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "115200", .value = 115200 }, { .description = "57600", .value = 57600 }, { .description = "56000", .value = 56000 }, @@ -1561,32 +1570,44 @@ static const device_config_t modem_config[] = { { .description = "1200", .value = 1200 }, { .description = "600", .value = 600 }, { .description = "300", .value = 300 }, - } + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "listen_port", - .description = "TCP/IP listening port", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "listen_port", + .description = "TCP/IP listening port", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 32767 }, - .default_int = 0 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "phonebook_file", - .description = "Phonebook File", - .type = CONFIG_FNAME, - .default_string = "", - .file_filter = "Text files (*.txt)|*.txt" + .name = "phonebook_file", + .description = "Phonebook File", + .type = CONFIG_FNAME, + .default_string = NULL, + .file_filter = "Text files (*.txt)|*.txt", + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "telnet_mode", - .description = "Telnet emulation", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "telnet_mode", + .description = "Telnet emulation", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -1600,7 +1621,7 @@ const device_t modem_device = { .init = modem_init, .close = modem_close, .reset = NULL, - { .poll = NULL }, + .available = NULL, .speed_changed = modem_speed_changed, .force_redraw = NULL, .config = modem_config diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 0f3480492..71e5c2ca7 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -66,7 +66,6 @@ #include <86box/network.h> #include <86box/net_dp8390.h> #include <86box/net_ne2000.h> -#include <86box/bswap.h> #include <86box/isapnp.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -313,7 +312,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) static uint32_t page3_read(nic_t *dev, uint32_t off, UNUSED(unsigned int len)) { - if (dev->board >= NE2K_RTL8019AS) + if (dev->board >= NE2K_RTL8019AS_PNP) switch (off) { case 0x1: /* 9346CR */ return (dev->_9346cr); @@ -328,7 +327,7 @@ page3_read(nic_t *dev, uint32_t off, UNUSED(unsigned int len)) return (dev->config3 & 0x46); case 0x8: /* CSNSAV */ - return ((dev->board == NE2K_RTL8019AS) ? dev->pnp_csnsav : 0x00); + return ((dev->board == NE2K_RTL8019AS_PNP) ? dev->pnp_csnsav : 0x00); case 0xe: /* 8029ASID0 */ if (dev->board == NE2K_RTL8029AS) @@ -351,7 +350,7 @@ page3_read(nic_t *dev, uint32_t off, UNUSED(unsigned int len)) static void page3_write(nic_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len)) { - if (dev->board >= NE2K_RTL8019AS) { + if (dev->board >= NE2K_RTL8019AS_PNP) { nelog(3, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", dev->name, off, len, val); @@ -911,16 +910,16 @@ static void * nic_init(const device_t *info) { uint32_t mac; - char *rom; + uint32_t mac_oui; + char *rom = NULL; nic_t *dev; + int set_oui = 0; - dev = malloc(sizeof(nic_t)); - memset(dev, 0x00, sizeof(nic_t)); + dev = calloc(1, sizeof(nic_t)); dev->name = info->name; dev->board = info->local; - rom = NULL; - if (dev->board >= NE2K_RTL8019AS) { + if (dev->board >= NE2K_RTL8019AS_PNP) { dev->base_address = 0x340; dev->base_irq = 12; if (dev->board == NE2K_RTL8029AS) { @@ -957,8 +956,8 @@ nic_init(const device_t *info) dev->maclocal[4] = random_generate(); dev->maclocal[5] = random_generate(); mac = (((int) dev->maclocal[3]) << 16); - mac |= (((int) dev->maclocal[4]) << 8); - mac |= ((int) dev->maclocal[5]); + mac |= (((int) dev->maclocal[4]) << 8); + mac |= ((int) dev->maclocal[5]); device_set_config_mac("mac", mac); } else { dev->maclocal[3] = (mac >> 16) & 0xff; @@ -987,6 +986,7 @@ nic_init(const device_t *info) dev->maclocal[2] = 0xB0; dev->is_8bit = 1; rom = NULL; + set_oui = 1; dp8390_set_defaults(dev->dp8390, DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); dp8390_mem_alloc(dev->dp8390, 0x2000, 0x2000); break; @@ -1005,6 +1005,7 @@ nic_init(const device_t *info) dev->maclocal[1] = 0x86; dev->maclocal[2] = 0xB0; rom = ROM_PATH_NE2000; + set_oui = 1; dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; @@ -1015,6 +1016,7 @@ nic_init(const device_t *info) dev->maclocal[2] = 0xB0; dev->is_8bit = 1; rom = ROM_PATH_NE2000; + set_oui = 1; dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CHECK_CR | DP8390_FLAG_CLEAR_IRQ); dp8390_mem_alloc(dev->dp8390, 0x4000, 0x4000); break; @@ -1040,18 +1042,18 @@ nic_init(const device_t *info) dp8390_mem_alloc(dev->dp8390, 0x4000, 0x8000); break; - case NE2K_RTL8019AS: + case NE2K_RTL8019AS_PNP: case NE2K_RTL8029AS: dev->is_pci = (dev->board == NE2K_RTL8029AS) ? 1 : 0; dev->maclocal[0] = 0x00; /* 00:E0:4C (Realtek OID) */ dev->maclocal[1] = 0xE0; dev->maclocal[2] = 0x4C; - rom = (dev->board == NE2K_RTL8019AS) ? ROM_PATH_RTL8019 : ROM_PATH_RTL8029; + rom = (dev->board == NE2K_RTL8019AS_PNP) ? ROM_PATH_RTL8019 : ROM_PATH_RTL8029; if (dev->is_pci) dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC); else dp8390_set_defaults(dev->dp8390, DP8390_FLAG_EVEN_MAC | DP8390_FLAG_CLEAR_IRQ); - dp8390_set_id(dev->dp8390, 0x50, (dev->board == NE2K_RTL8019AS) ? 0x70 : 0x43); + dp8390_set_id(dev->dp8390, 0x50, (dev->board == NE2K_RTL8019AS_PNP) ? 0x70 : 0x43); dp8390_mem_alloc(dev->dp8390, 0x4000, 0x8000); break; @@ -1059,6 +1061,24 @@ 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); + + /* Set up our BIA. */ + if (mac_oui & 0xff000000) { + mac_oui = (((int) dev->maclocal[0]) << 16); + mac_oui |= (((int) dev->maclocal[1]) << 8); + mac_oui |= ((int) dev->maclocal[2]); + device_set_config_mac("mac", mac); + } else { + dev->maclocal[0] = (mac_oui >> 16) & 0xff; + dev->maclocal[1] = (mac_oui >> 8) & 0xff; + dev->maclocal[2] = (mac_oui & 0xff); + } + } + memcpy(dev->dp8390->physaddr, dev->maclocal, sizeof(dev->maclocal)); nelog(2, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", @@ -1070,13 +1090,13 @@ nic_init(const device_t *info) * Make this device known to the I/O system. * PnP and PCI devices start with address spaces inactive. */ - if ((dev->board < NE2K_RTL8019AS) && (dev->board != NE2K_ETHERNEXT_MC)) + if ((dev->board < NE2K_RTL8019AS_PNP) && (dev->board != NE2K_ETHERNEXT_MC)) nic_ioset(dev, dev->base_address); /* Set up our BIOS ROM space, if any. */ nic_rom_init(dev, rom); - if (dev->board >= NE2K_RTL8019AS) { + if (dev->board >= NE2K_RTL8019AS_PNP) { if (dev->is_pci) { /* * Configure the PCI space registers. @@ -1124,7 +1144,7 @@ nic_init(const device_t *info) pci_add_card(PCI_ADD_NORMAL, nic_pci_read, nic_pci_write, dev, &dev->pci_slot); } - /* Initialize the RTL8029 EEPROM. */ + /* Initialize the RTL80x9 EEPROM. */ memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); if (dev->board == NE2K_RTL8029AS) { @@ -1138,7 +1158,7 @@ nic_init(const device_t *info) const char *pnp_rom_file = NULL; int pnp_rom_len = 0x4a; switch (dev->board) { - case NE2K_RTL8019AS: + case NE2K_RTL8019AS_PNP: pnp_rom_file = "roms/network/rtl8019as/RTL8019A.BIN"; break; @@ -1162,7 +1182,7 @@ nic_init(const device_t *info) } switch (info->local) { - case NE2K_RTL8019AS: + case NE2K_RTL8019AS_PNP: case NE2K_DE220P: dev->pnp_card = isapnp_add_card(pnp_rom, pnp_rom_len, nic_pnp_config_changed, nic_pnp_csn_changed, @@ -1214,14 +1234,14 @@ de220p_available(void) // clang-format off static const device_config_t ne1000_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, @@ -1229,16 +1249,17 @@ static const device_config_t ne1000_config[] = { { .description = "0x360", .value = 0x360 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, @@ -1247,27 +1268,32 @@ static const device_config_t ne1000_config[] = { { .description = "IRQ 9", .value = 9 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t ne1000_compat_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "0x200", .value = 0x200 }, { .description = "0x220", .value = 0x220 }, @@ -1287,16 +1313,17 @@ static const device_config_t ne1000_compat_config[] = { { .description = "0x3e0", .value = 0x3e0 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, @@ -1306,27 +1333,43 @@ static const device_config_t ne1000_compat_config[] = { { .description = "IRQ 9", .value = 9 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "mac_oui", + .description = "MAC Address OUI", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t ne2000_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, @@ -1334,16 +1377,17 @@ static const device_config_t ne2000_config[] = { { .description = "0x360", .value = 0x360 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, @@ -1352,43 +1396,49 @@ static const device_config_t ne2000_config[] = { { .description = "IRQ 9", .value = 9 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "bios_addr", - .description = "BIOS address", + .description = "BIOS Address", .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0x00000 }, { .description = "D000", .value = 0xD0000 }, { .description = "D800", .value = 0xD8000 }, { .description = "C800", .value = 0xC8000 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t ne2000_compat_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file. */ { .description = "0x200", .value = 0x200 }, { .description = "0x220", .value = 0x220 }, @@ -1408,16 +1458,17 @@ static const device_config_t ne2000_compat_config[] = { { .description = "0x3e0", .value = 0x3e0 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 10, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 10, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: Windows 95 .INF file - not giving impossible IRQ's such as 6, 8, or 13. */ { .description = "IRQ 3", .value = 3 }, @@ -1432,43 +1483,60 @@ static const device_config_t ne2000_compat_config[] = { { .description = "IRQ 15", .value = 15 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "mac_oui", + .description = "MAC Address OUI", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 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 = 0x00000 }, { .description = "D000", .value = 0xD0000 }, { .description = "D800", .value = 0xD8000 }, { .description = "C800", .value = 0xC8000 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t ne2000_compat_8bit_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x320, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x320, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: board docs, https://github.com/skiselev/isa8_eth */ { .description = "0x200", .value = 0x200 }, { .description = "0x220", .value = 0x220 }, @@ -1488,16 +1556,17 @@ static const device_config_t ne2000_compat_8bit_config[] = { { .description = "0x3e0", .value = 0x3e0 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: board docs, https://github.com/skiselev/isa8_eth */ { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, @@ -1506,23 +1575,39 @@ static const device_config_t ne2000_compat_8bit_config[] = { { .description = "IRQ 9", .value = 9 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "mac_oui", + .description = "MAC Address OUI", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { /* Source: board docs, https://github.com/skiselev/isa8_eth */ { .description = "Disabled", .value = 0x00000 }, { .description = "C000", .value = 0xC0000 }, @@ -1535,6 +1620,7 @@ static const device_config_t ne2000_compat_8bit_config[] = { { .description = "DC00", .value = 0xDC000 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -1542,40 +1628,56 @@ static const device_config_t ne2000_compat_8bit_config[] = { static const device_config_t rtl8019as_config[] = { { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t rtl8029as_config[] = { { - .name = "bios", - .description = "Enable BIOS", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 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 = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t mca_mac_config[] = { { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -1589,7 +1691,7 @@ const device_t ne1000_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ne1000_config @@ -1603,7 +1705,7 @@ const device_t ne1000_compat_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ne1000_compat_config @@ -1612,12 +1714,12 @@ const device_t ne1000_compat_device = { const device_t ne2000_device = { .name = "Novell NE2000", .internal_name = "novell_ne2k", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = NE2K_NE2000, .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ne2000_config @@ -1626,12 +1728,12 @@ const device_t ne2000_device = { const device_t ne2000_compat_device = { .name = "NE2000 Compatible", .internal_name = "ne2k", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = NE2K_NE2000_COMPAT, .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ne2000_compat_config @@ -1645,7 +1747,7 @@ const device_t ne2000_compat_8bit_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ne2000_compat_8bit_config @@ -1659,21 +1761,21 @@ const device_t ethernext_mc_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mca_mac_config }; -const device_t rtl8019as_device = { +const device_t rtl8019as_pnp_device = { .name = "Realtek RTL8019AS", .internal_name = "ne2kpnp", - .flags = DEVICE_ISA | DEVICE_AT, - .local = NE2K_RTL8019AS, + .flags = DEVICE_ISA16, + .local = NE2K_RTL8019AS_PNP, .init = nic_init, .close = nic_close, .reset = NULL, - { .available = rtl8019as_available }, + .available = rtl8019as_available, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8019as_config @@ -1682,12 +1784,12 @@ const device_t rtl8019as_device = { const device_t de220p_device = { .name = "D-Link DE-220P", .internal_name = "de220p", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = NE2K_DE220P, .init = nic_init, .close = nic_close, .reset = NULL, - { .available = de220p_available }, + .available = de220p_available, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8019as_config @@ -1701,7 +1803,7 @@ const device_t rtl8029as_device = { .init = nic_init, .close = nic_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8029as_config diff --git a/src/network/net_null.c b/src/network/net_null.c index 6fb3f3440..6d5f68e46 100644 --- a/src/network/net_null.c +++ b/src/network/net_null.c @@ -218,8 +218,8 @@ net_null_close(void *priv) } const netdrv_t net_null_drv = { - &net_null_in_available, - &net_null_init, - &net_null_close, - NULL + .notify_in = &net_null_in_available, + .init = &net_null_init, + .close = &net_null_close, + .priv = NULL }; diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 852191c55..2af34d786 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -572,8 +572,8 @@ net_pcap_close(void *priv) } const netdrv_t net_pcap_drv = { - &net_pcap_in_available, - &net_pcap_init, - &net_pcap_close, - NULL + .notify_in = &net_pcap_in_available, + .init = &net_pcap_init, + .close = &net_pcap_close, + .priv = NULL }; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 1e28c5846..b13fd8438 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -46,9 +46,9 @@ #include <86box/thread.h> #include <86box/network.h> #include <86box/net_pcnet.h> -#include <86box/bswap.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +#include <86box/bswap.h> /* PCI info. */ #define PCI_VENDID 0x1022 /* AMD */ @@ -2481,36 +2481,58 @@ pcnet_readl(uint16_t addr, void *priv) static void pcnet_mmio_writeb(uint32_t addr, uint8_t val, void *priv) { + if (!(addr & 0x10)) { + pcnet_aprom_writeb((nic_t *) priv, addr, val); + return; + } pcnet_write((nic_t *) priv, addr, val, 1); } static void pcnet_mmio_writew(uint32_t addr, uint16_t val, void *priv) { + if (!(addr & 0x10)) { + pcnet_aprom_writeb((nic_t *) priv, addr, val); + pcnet_aprom_writeb((nic_t *) priv, addr + 1, val >> 8); + return; + } pcnet_write((nic_t *) priv, addr, val, 2); } static void pcnet_mmio_writel(uint32_t addr, uint32_t val, void *priv) { + if (!(addr & 0x10)) { + pcnet_aprom_writeb((nic_t *) priv, addr, val); + pcnet_aprom_writeb((nic_t *) priv, addr + 1, val >> 8); + pcnet_aprom_writeb((nic_t *) priv, addr + 2, val >> 16); + pcnet_aprom_writeb((nic_t *) priv, addr + 3, val >> 24); + return; + } pcnet_write((nic_t *) priv, addr, val, 4); } static uint8_t pcnet_mmio_readb(uint32_t addr, void *priv) { + if (!(addr & 0x10)) + return pcnet_aprom_readb((nic_t *) priv, addr); return (pcnet_read((nic_t *) priv, addr, 1)); } static uint16_t pcnet_mmio_readw(uint32_t addr, void *priv) { + if (!(addr & 0x10)) + return pcnet_aprom_readb((nic_t *) priv, addr) | (pcnet_aprom_readb((nic_t *) priv, addr + 1) << 8); return (pcnet_read((nic_t *) priv, addr, 2)); } static uint32_t pcnet_mmio_readl(uint32_t addr, void *priv) { + if (!(addr & 0x10)) + return pcnet_aprom_readb((nic_t *) priv, addr) | (pcnet_aprom_readb((nic_t *) priv, addr + 1) << 8) | (pcnet_aprom_readb((nic_t *) priv, addr + 2) << 16) | (pcnet_aprom_readb((nic_t *) priv, addr + 3) << 24); return (pcnet_read((nic_t *) priv, addr, 4)); } @@ -2607,7 +2629,7 @@ pcnet_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) /* Then let's set the PCI regs. */ pcnet_pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - pcnet_pci_bar[0].addr &= 0xff00; + pcnet_pci_bar[0].addr &= 0xffe0; dev->PCIBase = pcnet_pci_bar[0].addr; /* Log the new base. */ pcnet_log(4, "%s: New I/O base is %04X\n", dev->name, dev->PCIBase); @@ -2685,7 +2707,7 @@ pcnet_pci_read(UNUSED(int func), int addr, void *priv) case 0x0E: return 0; /*Header type */ case 0x10: - return 1; /*I/O space*/ + return pcnet_pci_bar[0].addr_regs[0] | 1; /*I/O space*/ case 0x11: return pcnet_pci_bar[0].addr_regs[1]; case 0x12: @@ -2894,14 +2916,13 @@ pcnet_init(const device_t *info) int c; uint16_t checksum; - dev = malloc(sizeof(nic_t)); - memset(dev, 0x00, sizeof(nic_t)); + dev = calloc(1, sizeof(nic_t)); dev->name = info->name; dev->board = info->local & 0xff; dev->is_pci = !!(info->flags & DEVICE_PCI); dev->is_vlb = !!(info->flags & DEVICE_VLB); - dev->is_isa = !!(info->flags & (DEVICE_ISA | DEVICE_AT)); + dev->is_isa = !!(info->flags & (DEVICE_ISA16)); if (dev->is_pci || dev->is_vlb) dev->transfer_size = 4; @@ -3067,62 +3088,68 @@ pcnet_close(void *priv) // clang-format off static const device_config_t pcnet_pci_config[] = { { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t pcnet_isa_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 4", .value = 4 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "IRQ 9", .value = 9 }, + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, { .description = "IRQ 12", .value = 12 }, { .description = "IRQ 15", .value = 15 }, - { .description = "" } + { .description = "" } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "DMA 0", .value = 0 }, { .description = "DMA 3", .value = 3 }, { .description = "DMA 5", .value = 5 }, @@ -3130,61 +3157,72 @@ static const device_config_t pcnet_isa_config[] = { { .description = "DMA 7", .value = 7 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t pcnet_vlb_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x300", .value = 0x300 }, { .description = "0x320", .value = 0x320 }, { .description = "0x340", .value = 0x340 }, { .description = "0x360", .value = 0x360 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, .selection = { - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 4", .value = 4 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "IRQ 9", .value = 9 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 9", .value = 9 }, { .description = "IRQ 10", .value = 10 }, { .description = "IRQ 11", .value = 11 }, { .description = "IRQ 12", .value = 12 }, { .description = "IRQ 15", .value = 15 }, - { .description = "" } + { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, .default_string = "", - .default_int = -1 + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -3193,12 +3231,12 @@ static const device_config_t pcnet_vlb_config[] = { const device_t pcnet_am79c960_device = { .name = "AMD PCnet-ISA", .internal_name = "pcnetisa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = DEV_AM79C960, .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_isa_config @@ -3207,12 +3245,12 @@ const device_t pcnet_am79c960_device = { const device_t pcnet_am79c960_eb_device = { .name = "Racal Interlan EtherBlaster", .internal_name = "pcnetracal", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = DEV_AM79C960_EB, .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_isa_config @@ -3226,7 +3264,7 @@ const device_t pcnet_am79c960_vlb_device = { .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_vlb_config @@ -3235,12 +3273,12 @@ const device_t pcnet_am79c960_vlb_device = { const device_t pcnet_am79c961_device = { .name = "AMD PCnet-ISA+", .internal_name = "pcnetisaplus", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = DEV_AM79C961, .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_pci_config @@ -3254,7 +3292,7 @@ const device_t pcnet_am79c970a_device = { .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_pci_config @@ -3268,7 +3306,7 @@ const device_t pcnet_am79c973_device = { .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_pci_config @@ -3282,7 +3320,7 @@ const device_t pcnet_am79c973_onboard_device = { .init = pcnet_init, .close = pcnet_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pcnet_pci_config diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 8b0bf460c..8c46213c6 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -26,12 +26,12 @@ #include #define HAVE_STDARG_H #include <86box/86box.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/timer.h> #include <86box/pit.h> #include <86box/device.h> #include <86box/thread.h> -#include <86box/timer.h> #include <86box/network.h> #include <86box/plat_unused.h> @@ -445,8 +445,7 @@ plip_rx(void *priv, uint8_t *buf, int io_len) static void * plip_lpt_init(void *lpt) { - plip_t *dev = (plip_t *) malloc(sizeof(plip_t)); - memset(dev, 0, sizeof(plip_t)); + plip_t *dev = (plip_t *) calloc(1, sizeof(plip_t)); plip_log(1, "PLIP: lpt_init()\n"); @@ -508,7 +507,7 @@ const device_t plip_device = { .init = plip_net_init, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index bc44b3fb1..5138b5168 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -28,6 +28,9 @@ #include #include #include +#ifdef _MVC_VER +#include +#endif #include #define HAVE_STDARG_H #include <86box/86box.h> @@ -41,10 +44,10 @@ #include <86box/thread.h> #include <86box/network.h> #include <86box/net_eeprom_nmc93cxx.h> -#include <86box/bswap.h> #include <86box/nvr.h> #include "cpu.h" #include <86box/plat_unused.h> +#include <86box/bswap.h> #define PCI_PERIOD 30 /* 30 ns period = 33.333333 Mhz frequency */ @@ -352,7 +355,8 @@ enum chip_flags { #define RTL8139_PCI_REVID_8139 0x10 #define RTL8139_PCI_REVID_8139CPLUS 0x20 -#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS +/* Return 0x10 - the RTL8139C+ datasheet and Windows 2000 driver both confirm this. */ +#define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139 #pragma pack(push, 1) typedef struct RTL8139TallyCounters { @@ -530,14 +534,14 @@ rtl8139_write_buffer(RTL8139State *s, const void *buf, int size) if (size > wrapped) { dma_bm_write(s->RxBuf + s->RxBufAddr, - buf, size - wrapped, 1); + (uint8_t *) buf, size - wrapped, 1); } /* reset buffer pointer */ s->RxBufAddr = 0; dma_bm_write(s->RxBuf + s->RxBufAddr, - buf + (size - wrapped), wrapped, 1); + (uint8_t *) buf + (size - wrapped), wrapped, 1); s->RxBufAddr = wrapped; @@ -1075,10 +1079,11 @@ rtl8139_reset(void *priv) s->cplus_enabled = 0; #if 0 - s->BasicModeCtrl = 0x3100; // 100Mbps, full duplex, autonegotiation s->BasicModeCtrl = 0x2100; // 100Mbps, full duplex -#endif + s->BasicModeCtrl = 0x3100; // 100Mbps, full duplex, autonegotiation s->BasicModeCtrl = 0x1000; // autonegotiation +#endif + s->BasicModeCtrl = 0x1100; // full duplex, autonegotiation rtl8139_reset_phy(s); @@ -1205,7 +1210,7 @@ rtl8139_CpCmd_read(RTL8139State *s) } static void -rtl8139_IntrMitigate_write(UNUSED(RTL8139State *s), uint32_t val) +rtl8139_IntrMitigate_write(UNUSED(RTL8139State *s), UNUSED(uint32_t val)) { rtl8139_log("C+ IntrMitigate register write(w) val=0x%04x\n", val); } @@ -3111,7 +3116,7 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) case 0x05: return s->pci_conf[addr & 0xFF] & 1; case 0x08: - return 0x20; + return RTL8139_PCI_REVID; case 0x09: return 0x0; case 0x0a: @@ -3146,7 +3151,7 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) } static void -rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) +rtl8139_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; @@ -3310,11 +3315,15 @@ nic_close(void *priv) // clang-format off static const device_config_t rtl8139c_config[] = { { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -3328,7 +3337,7 @@ const device_t rtl8139c_plus_device = { .init = nic_init, .close = nic_close, .reset = rtl8139_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = rtl8139c_config diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 92434973d..11f1a74b2 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -133,7 +133,7 @@ net_slirp_clock_get_ns(UNUSED(void *opaque)) static void * net_slirp_timer_new(SlirpTimerCb cb, void *cb_opaque, UNUSED(void *opaque)) { - pc_timer_t *timer = malloc(sizeof(pc_timer_t)); + pc_timer_t *timer = calloc(1, sizeof(pc_timer_t)); timer_add(timer, cb, cb_opaque, 0); return timer; } @@ -422,8 +422,7 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv #ifndef _WIN32 slirp->pfd_size = 16 * sizeof(struct pollfd); - slirp->pfd = malloc(slirp->pfd_size); - memset(slirp->pfd, 0, slirp->pfd_size); + slirp->pfd = calloc(1, slirp->pfd_size); #endif /* Set the IP addresses to use. */ @@ -544,7 +543,8 @@ net_slirp_close(void *priv) } const netdrv_t net_slirp_drv = { - &net_slirp_in_available, - &net_slirp_init, - &net_slirp_close + .notify_in = &net_slirp_in_available, + .init = &net_slirp_init, + .close = &net_slirp_close, + .priv = NULL }; diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 03eb21e88..7d988368c 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -32,9 +32,9 @@ #include <86box/thread.h> #include <86box/network.h> #include <86box/net_eeprom_nmc93cxx.h> -#include <86box/bswap.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +#include <86box/bswap.h> #define ROM_PATH_DEC21140 "roms/network/dec21140/BIOS13502.BIN" @@ -452,7 +452,9 @@ tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc) static bool tulip_filter_address(TULIPState *s, const uint8_t *addr) { +#ifdef BLOCK_BROADCAST static const char broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +#endif bool ret = false; for (uint8_t i = 0; i < 16 && ret == false; i++) { @@ -461,9 +463,15 @@ tulip_filter_address(TULIPState *s, const uint8_t *addr) } } +/* + Do not block broadcast packets - needed for connections to the guest + to succeed when using SLiRP. + */ +#ifdef BLOCK_BROADCAST if (!memcmp(addr, broadcast, ETH_ALEN)) { return true; } +#endif if (s->csr[6] & (CSR6_PR | CSR6_RA)) { /* Promiscuous mode enabled */ @@ -488,7 +496,7 @@ tulip_receive(void *priv, uint8_t *buf, int size) { struct tulip_descriptor desc; TULIPState *s = (TULIPState *) priv; - + int first = 1; if (size < 14 || size > sizeof(s->rx_frame) - 4 || s->rx_frame_len || tulip_rx_stopped(s)) @@ -506,7 +514,11 @@ tulip_receive(void *priv, uint8_t *buf, int size) if (!(desc.status & RDES0_OWN)) { s->csr[5] |= CSR5_RU; tulip_update_int(s); - return s->rx_frame_size - s->rx_frame_len; + if (first) + /* Stop at the very beginning, tell the host 0 bytes have been received. */ + return 0; + else + return (s->rx_frame_size - s->rx_frame_len) % s->rx_frame_size; } desc.status = 0; @@ -527,6 +539,7 @@ tulip_receive(void *priv, uint8_t *buf, int size) } tulip_desc_write(s, s->current_rx_desc, &desc); tulip_next_rx_descriptor(s, &desc); + first = 0; } while (s->rx_frame_len); return 1; @@ -1625,7 +1638,7 @@ nic_init(const device_t *info) s->pci_conf[0x04] = 7; /* Enable our BIOS space in PCI, if needed. */ - if (s->bios_addr > 0) { + if (s->has_bios) { rom_init(&s->bios_rom, ROM_PATH_DEC21140, s->bios_addr, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); tulip_pci_bar[2].addr = 0xffff0000; } else @@ -1651,29 +1664,41 @@ nic_close(void *priv) // clang-format off static const device_config_t dec_tulip_21143_config[] = { { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t dec_tulip_21140_config[] = { { - .name = "bios", - .description = "Enable BIOS", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "bios", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -1687,7 +1712,7 @@ const device_t dec_tulip_device = { .init = nic_init, .close = nic_close, .reset = tulip_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = dec_tulip_21143_config @@ -1701,7 +1726,7 @@ const device_t dec_tulip_21140_device = { .init = nic_init, .close = nic_close, .reset = tulip_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = dec_tulip_21140_config @@ -1715,7 +1740,7 @@ const device_t dec_tulip_21140_vpc_device = { .init = nic_init, .close = nic_close, .reset = tulip_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = dec_tulip_21140_config @@ -1729,7 +1754,7 @@ const device_t dec_tulip_21040_device = { .init = nic_init, .close = nic_close, .reset = tulip_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = dec_tulip_21143_config diff --git a/src/network/net_vde.c b/src/network/net_vde.c index d783c9c9d..4f8d5c21f 100644 --- a/src/network/net_vde.c +++ b/src/network/net_vde.c @@ -302,9 +302,9 @@ void *net_vde_init(const netcard_t *card, const uint8_t *mac_addr, void *priv, c // VDE Driver structure //- const netdrv_t net_vde_drv = { - &net_vde_in_available, - &net_vde_init, - &net_vde_close, - NULL + .notify_in = &net_vde_in_available, + .init = &net_vde_init, + .close = &net_vde_close, + .priv = NULL }; diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 04b922aaf..1ca8d8697 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -63,7 +63,6 @@ #include <86box/network.h> #include <86box/net_dp8390.h> #include <86box/net_wd8003.h> -#include <86box/bswap.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -651,8 +650,7 @@ wd_init(const device_t *info) uint32_t mac; wd_t *dev; - dev = malloc(sizeof(wd_t)); - memset(dev, 0x00, sizeof(wd_t)); + dev = calloc(1, sizeof(wd_t)); dev->name = info->name; dev->board = info->local; @@ -808,46 +806,48 @@ wd_close(void *priv) // clang-format off static const device_config_t wd8003_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x300, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x300, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x240", .value = 0x240 }, { .description = "0x280", .value = 0x280 }, { .description = "0x300", .value = 0x300 }, { .description = "0x380", .value = 0x380 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2", .value = 2 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "ram_addr", - .description = "RAM address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD0000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "ram_addr", + .description = "RAM Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C800", .value = 0xC8000 }, { .description = "CC00", .value = 0xCC000 }, { .description = "D000", .value = 0xD0000 }, @@ -856,27 +856,32 @@ static const device_config_t wd8003_config[] = { { .description = "DC00", .value = 0xDC000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd8003eb_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x280, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x280, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x200", .value = 0x200 }, { .description = "0x220", .value = 0x220 }, { .description = "0x240", .value = 0x240 }, @@ -889,32 +894,34 @@ static const device_config_t wd8003eb_config[] = { { .description = "0x380", .value = 0x380 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2/9", .value = 9 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, { .description = "IRQ 7", .value = 7 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "ram_addr", - .description = "RAM address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD0000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "ram_addr", + .description = "RAM Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C000", .value = 0xC0000 }, { .description = "C400", .value = 0xC4000 }, { .description = "C800", .value = 0xC8000 }, @@ -925,27 +932,33 @@ static const device_config_t wd8003eb_config[] = { { .description = "DC00", .value = 0xDC000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "ram_size", - .description = "RAM size", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 8192, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "8 kB", .value = 8192 }, - { .description = "32 kB", .value = 32768 }, + .name = "ram_size", + .description = "RAM size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 8192, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "8 KB", .value = 8192 }, + { .description = "32 KB", .value = 32768 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -954,14 +967,14 @@ static const device_config_t wd8003eb_config[] = { http://www.stack.nl/~marcolz/network/wd80x3.html#WD8013EBT */ static const device_config_t wd8013_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x280, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x280, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x200", .value = 0x200 }, { .description = "0x220", .value = 0x220 }, { .description = "0x240", .value = 0x240 }, @@ -974,16 +987,17 @@ static const device_config_t wd8013_config[] = { { .description = "0x380", .value = 0x380 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 3, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "IRQ 2/9", .value = 9 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 4", .value = 4 }, @@ -994,16 +1008,17 @@ static const device_config_t wd8013_config[] = { { .description = "IRQ 15", .value = 15 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "ram_addr", - .description = "RAM address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD0000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "ram_addr", + .description = "RAM Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C000", .value = 0xC0000 }, { .description = "C400", .value = 0xC4000 }, { .description = "C800", .value = 0xC8000 }, @@ -1014,63 +1029,78 @@ static const device_config_t wd8013_config[] = { { .description = "DC00", .value = 0xDC000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "ram_size", - .description = "RAM size", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 16384, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "16 kB", .value = 16384 }, - { .description = "64 kB", .value = 65536 }, + .name = "ram_size", + .description = "RAM size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 16384, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "16 KB", .value = 16384 }, + { .description = "64 KB", .value = 65536 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t wd8013epa_config[] = { { - .name = "ram_size", - .description = "Initial RAM size", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 16384, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "8 kB", .value = 8192 }, - { .description = "16 kB", .value = 16384 }, + .name = "ram_size", + .description = "Initial RAM size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 16384, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "8 KB", .value = 8192 }, + { .description = "16 KB", .value = 16384 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t mca_mac_config[] = { { - .name = "mac", - .description = "MAC Address", - .type = CONFIG_MAC, - .default_string = "", - .default_int = -1 + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -1084,7 +1114,7 @@ const device_t wd8003e_device = { .init = wd_init, .close = wd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = wd8003_config @@ -1098,7 +1128,7 @@ const device_t wd8003eb_device = { .init = wd_init, .close = wd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = wd8003eb_config @@ -1112,7 +1142,7 @@ const device_t wd8013ebt_device = { .init = wd_init, .close = wd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = wd8013_config @@ -1126,7 +1156,7 @@ const device_t wd8003eta_device = { .init = wd_init, .close = wd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mca_mac_config @@ -1140,7 +1170,7 @@ const device_t wd8003ea_device = { .init = wd_init, .close = wd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mca_mac_config @@ -1154,7 +1184,7 @@ const device_t wd8013epa_device = { .init = wd_init, .close = wd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = wd8013epa_config diff --git a/src/network/network.c b/src/network/network.c index 7c02609ae..66990e51d 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -54,7 +54,9 @@ #include #include #include +#ifndef _MSC_VER #include +#endif #include #define HAVE_STDARG_H #include <86box/86box.h> @@ -75,40 +77,46 @@ # include #endif -static const device_t *net_cards[] = { - &device_none, - &device_internal, - &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_device, - &wd8003e_device, - &wd8003eb_device, - &wd8013ebt_device, - &plip_device, - ðernext_mc_device, - &wd8003eta_device, - &wd8003ea_device, - &wd8013epa_device, - &pcnet_am79c973_device, - &pcnet_am79c970a_device, - &dec_tulip_device, - &rtl8029as_device, - &rtl8139c_plus_device, - &dec_tulip_21140_device, - &dec_tulip_21140_vpc_device, - &dec_tulip_21040_device, - &pcnet_am79c960_vlb_device, - &modem_device, - NULL +typedef struct { + const device_t *device; +} NETWORK_CARD; + +static const NETWORK_CARD net_cards[] = { + // clang-format off + { &device_none }, + { &device_internal }, + { &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 }, + { &plip_device }, + { ðernext_mc_device }, + { &wd8003eta_device }, + { &wd8003ea_device }, + { &wd8013epa_device }, + { &pcnet_am79c973_device }, + { &pcnet_am79c970a_device }, + { &dec_tulip_device }, + { &rtl8029as_device }, + { &rtl8139c_plus_device }, + { &dec_tulip_21140_device }, + { &dec_tulip_21140_vpc_device }, + { &dec_tulip_21040_device }, + { &pcnet_am79c960_vlb_device }, + { &modem_device }, + { NULL } + // clang-format on }; netcard_conf_t net_cards_conf[NET_CARD_MAX]; @@ -581,7 +589,7 @@ network_reset(void) net_card_current = i; if (net_cards_conf[i].device_num > NET_INTERNAL) - device_add_inst(net_cards[net_cards_conf[i].device_num], i + 1); + device_add_inst(net_cards[net_cards_conf[i].device_num].device, i + 1); } } @@ -712,8 +720,8 @@ network_available(void) int network_card_available(int card) { - if (net_cards[card]) - return (device_available(net_cards[card])); + if (net_cards[card].device) + return (device_available(net_cards[card].device)); return 1; } @@ -722,24 +730,24 @@ network_card_available(int card) const device_t * network_card_getdevice(int card) { - return (net_cards[card]); + return (net_cards[card].device); } /* UI */ int network_card_has_config(int card) { - if (!net_cards[card]) + if (!net_cards[card].device) return 0; - return (device_has_config(net_cards[card]) ? 1 : 0); + return (device_has_config(net_cards[card].device) ? 1 : 0); } /* UI */ const char * network_card_get_internal_name(int card) { - return device_get_internal_name(net_cards[card]); + return device_get_internal_name(net_cards[card].device); } /* UI */ @@ -748,8 +756,8 @@ network_card_get_from_internal_name(char *s) { int c = 0; - while (net_cards[c] != NULL) { - if (!strcmp(net_cards[c]->internal_name, s)) + while (net_cards[c].device != NULL) { + if (!strcmp(net_cards[c].device->internal_name, s)) return c; c++; } diff --git a/src/nvr.c b/src/nvr.c index d833618d0..7f43a76c1 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -161,9 +161,9 @@ nvr_init(nvr_t *nvr) int c; /* Set up the NVR file's name. */ - c = strlen(machine_get_internal_name()) + 5; + c = strlen(machine_get_nvr_name()) + 5; nvr->fn = (char *) malloc(c + 1); - sprintf(nvr->fn, "%s.nvr", machine_get_internal_name()); + sprintf(nvr->fn, "%s.nvr", machine_get_nvr_name()); /* Initialize the internal clock as needed. */ memset(&intclk, 0x00, sizeof(intclk)); @@ -326,14 +326,15 @@ nvr_time_sync(void) /* Get current time from internal clock. */ void -nvr_time_get(struct tm *tm) +nvr_time_get(void *priv) { - uint8_t dom; - uint8_t mon; - uint8_t sum; - uint8_t wd; - uint16_t cent; - uint16_t yr; + struct tm *tm = (struct tm *) priv; + uint8_t dom; + uint8_t mon; + uint8_t sum; + uint8_t wd; + uint16_t cent; + uint16_t yr; tm->tm_sec = intclk.tm_sec; tm->tm_min = intclk.tm_min; @@ -352,8 +353,10 @@ nvr_time_get(struct tm *tm) /* Set internal clock time. */ void -nvr_time_set(struct tm *tm) +nvr_time_set(void *priv) { + struct tm *tm = (struct tm *) priv; + intclk.tm_sec = tm->tm_sec; intclk.tm_min = tm->tm_min; intclk.tm_hour = tm->tm_hour; diff --git a/src/nvr_at.c b/src/nvr_at.c index 9465839a7..bde80b434 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -1219,12 +1219,12 @@ nvr_at_close(void *priv) const device_t at_nvr_old_device = { .name = "PC/AT NVRAM (No century)", .internal_name = "at_nvr_old", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1233,12 +1233,12 @@ const device_t at_nvr_old_device = { const device_t at_nvr_device = { .name = "PC/AT NVRAM", .internal_name = "at_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 1, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1247,12 +1247,12 @@ const device_t at_nvr_device = { const device_t at_mb_nvr_device = { .name = "PC/AT NVRAM", .internal_name = "at_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x40 | 0x20 | 1, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1261,12 +1261,12 @@ const device_t at_mb_nvr_device = { const device_t ps_nvr_device = { .name = "PS/1 or PS/2 NVRAM", .internal_name = "ps_nvr", - .flags = DEVICE_PS2, + .flags = DEVICE_ISA16, .local = 2, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1275,12 +1275,12 @@ const device_t ps_nvr_device = { const device_t amstrad_nvr_device = { .name = "Amstrad NVRAM", .internal_name = "amstrad_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 3, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1289,12 +1289,12 @@ const device_t amstrad_nvr_device = { const device_t ibmat_nvr_device = { .name = "IBM AT NVRAM", .internal_name = "ibmat_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 4, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1303,12 +1303,12 @@ const device_t ibmat_nvr_device = { const device_t piix4_nvr_device = { .name = "Intel PIIX4 PC/AT NVRAM", .internal_name = "piix4_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x10 | 1, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1317,12 +1317,12 @@ const device_t piix4_nvr_device = { const device_t ps_no_nmi_nvr_device = { .name = "PS/1 or PS/2 NVRAM (No NMI)", .internal_name = "ps1_nvr", - .flags = DEVICE_PS2, + .flags = DEVICE_ISA16, .local = 0x10 | 2, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1331,12 +1331,12 @@ const device_t ps_no_nmi_nvr_device = { const device_t amstrad_no_nmi_nvr_device = { .name = "Amstrad NVRAM (No NMI)", .internal_name = "amstrad_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x10 | 3, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1345,12 +1345,12 @@ const device_t amstrad_no_nmi_nvr_device = { const device_t ami_1992_nvr_device = { .name = "AMI Color 1992 PC/AT NVRAM", .internal_name = "ami_1992_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x10 | 4, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1359,12 +1359,12 @@ const device_t ami_1992_nvr_device = { const device_t ami_1994_nvr_device = { .name = "AMI WinBIOS 1994 PC/AT NVRAM", .internal_name = "ami_1994_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x10 | 5, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1373,12 +1373,12 @@ const device_t ami_1994_nvr_device = { const device_t ami_1995_nvr_device = { .name = "AMI WinBIOS 1995 PC/AT NVRAM", .internal_name = "ami_1995_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x10 | 6, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1387,12 +1387,12 @@ const device_t ami_1995_nvr_device = { const device_t via_nvr_device = { .name = "VIA PC/AT NVRAM", .internal_name = "via_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x10 | 7, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1401,12 +1401,12 @@ const device_t via_nvr_device = { const device_t p6rp4_nvr_device = { .name = "ASUS P/I-P6RP4 PC/AT NVRAM", .internal_name = "p6rp4_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 32, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1415,12 +1415,12 @@ const device_t p6rp4_nvr_device = { const device_t amstrad_megapc_nvr_device = { .name = "Amstrad MegaPC NVRAM", .internal_name = "amstrad_megapc_nvr", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 36, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL @@ -1434,7 +1434,7 @@ const device_t elt_nvr_device = { .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, - { .available = NULL }, + .available = NULL, .speed_changed = nvr_at_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/nvr_ps2.c b/src/nvr_ps2.c index 67eaccc38..febf6c165 100644 --- a/src/nvr_ps2.c +++ b/src/nvr_ps2.c @@ -114,8 +114,7 @@ ps2_nvr_init(const device_t *info) FILE *fp = NULL; int c; - nvr = (ps2_nvr_t *) malloc(sizeof(ps2_nvr_t)); - memset(nvr, 0x00, sizeof(ps2_nvr_t)); + nvr = (ps2_nvr_t *) calloc(1, sizeof(ps2_nvr_t)); if (info->local) nvr->size = 2048; @@ -123,9 +122,9 @@ ps2_nvr_init(const device_t *info) nvr->size = 8192; /* Set up the NVR file's name. */ - c = strlen(machine_get_internal_name()) + 9; + c = strlen(machine_get_nvr_name()) + 9; nvr->fn = (char *) malloc(c + 1); - sprintf(nvr->fn, "%s_sec.nvr", machine_get_internal_name()); + sprintf(nvr->fn, "%s_sec.nvr", machine_get_nvr_name()); io_sethandler(0x0074, 3, ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr); @@ -170,7 +169,7 @@ const device_t ps2_nvr_device = { .init = ps2_nvr_init, .close = ps2_nvr_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -184,7 +183,7 @@ const device_t ps2_nvr_55ls_device = { .init = ps2_nvr_init, .close = ps2_nvr_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/pci.c b/src/pci.c index b4f5eafe5..ab585c456 100644 --- a/src/pci.c +++ b/src/pci.c @@ -790,7 +790,7 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), if (next_pci_card < PCI_CARDS_NUM) { dev = &pci_card_descs[next_pci_card]; - dev->type = add_type | PCI_ADD_STRICT; + dev->type = add_type | PCI_ADD_STRICT; dev->read = read; dev->write = write; dev->priv = priv; @@ -885,7 +885,7 @@ pci_register_cards(void) type = pci_card_descs[i].type; slot = pci_card_descs[i].slot; #endif - normal = (pci_card_descs[i].type == PCI_CARD_NORMAL); + normal = ((pci_card_descs[i].type & ~PCI_ADD_STRICT) == PCI_CARD_NORMAL); /* If this is a normal card, increase the next normal card index. */ if (normal) diff --git a/src/pci_dummy.c b/src/pci_dummy.c index 704f85d8c..bceb58c22 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -278,7 +278,7 @@ pci_dummy_card_init(UNUSED(const device_t *info)) { pci_dummy_t *dev = (pci_dummy_t *) calloc(1, sizeof(pci_dummy_t)); - pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev, &dev->pci_slot); + pci_add_card(PCI_ADD_NORMAL, pci_dummy_pci_read, pci_dummy_pci_write, dev, &dev->pci_slot); return dev; } @@ -291,7 +291,7 @@ const device_t pci_dummy_device = { .init = pci_dummy_card_init, .close = pci_dummy_close, .reset = pci_dummy_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/pic.c b/src/pic.c index 82905261a..cf17e8205 100644 --- a/src/pic.c +++ b/src/pic.c @@ -17,6 +17,7 @@ * Copyright 2015-2020 Andrew Jenner. * Copyright 2016-2020 Miran Grca. */ +#include #include #include #include @@ -244,7 +245,7 @@ pic_update_pending_at(void) } static void -pic_callback(void *priv) +pic_callback(UNUSED(void *priv)) { update_pending(); } @@ -496,7 +497,7 @@ pic_read(uint16_t addr, void *priv) simply read whatever is currently on the data bus. */ } - pic_log("pic_read(%04X, %08X) = %02X\n", addr, priv, dev->data_bus); + pic_log("pic_read(%04X) = %02X\n", addr, dev->data_bus); return dev->data_bus; } @@ -628,7 +629,7 @@ pic_reset_hard(void) /* The situation is as follows: There is a giant mess when it comes to these latches on real hardware, to the point that there's even boards with board-level latched that get used in place of the latches on the chipset, therefore, I'm just doing this here for the sake of simplicity. */ - if (machine_has_bus(machine, MACHINE_BUS_PS2_LATCH)) { + if (machine_has_flags(machine, MACHINE_PS2_KBC)) { pic_kbd_latch(0x01); pic_mouse_latch(0x01); } else { diff --git a/src/pit.c b/src/pit.c index 8b9f23a79..a283d1205 100644 --- a/src/pit.c +++ b/src/pit.c @@ -960,7 +960,7 @@ const device_t i8253_device = { .init = pit_init, .close = pit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL @@ -974,7 +974,7 @@ const device_t i8253_ext_io_device = { .init = pit_init, .close = pit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -988,7 +988,7 @@ const device_t i8254_device = { .init = pit_init, .close = pit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL @@ -1002,7 +1002,7 @@ const device_t i8254_sec_device = { .init = pit_init, .close = pit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL @@ -1016,7 +1016,7 @@ const device_t i8254_ext_io_device = { .init = pit_init, .close = pit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1030,7 +1030,7 @@ const device_t i8254_ps2_device = { .init = pit_init, .close = pit_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pit_speed_changed, .force_redraw = NULL, .config = NULL @@ -1250,14 +1250,14 @@ pit_set_clock(uint32_t clock) } const pit_intf_t pit_classic_intf = { - &pit_read, - &pit_write, - &pit_ctr_get_count, - &pit_ctr_set_gate, - &pit_ctr_set_using_timer, - &pit_ctr_set_out_func, - &pit_ctr_set_load_func, - &ctr_clock, - &pit_set_pit_const, - NULL, + .read = &pit_read, + .write = &pit_write, + .get_count = &pit_ctr_get_count, + .set_gate = &pit_ctr_set_gate, + .set_using_timer = &pit_ctr_set_using_timer, + .set_out_func = &pit_ctr_set_out_func, + .set_load_func = &pit_ctr_set_load_func, + .ctr_clock = &ctr_clock, + .set_pit_const = &pit_set_pit_const, + .data = NULL, }; diff --git a/src/pit_fast.c b/src/pit_fast.c index 0d56a6616..b92b59f3c 100644 --- a/src/pit_fast.c +++ b/src/pit_fast.c @@ -751,7 +751,7 @@ const device_t i8253_fast_device = { .init = pitf_init, .close = pitf_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL @@ -765,7 +765,7 @@ const device_t i8254_fast_device = { .init = pitf_init, .close = pitf_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL @@ -779,7 +779,7 @@ const device_t i8254_sec_fast_device = { .init = pitf_init, .close = pitf_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL @@ -793,7 +793,7 @@ const device_t i8254_ext_io_fast_device = { .init = pitf_init, .close = pitf_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -807,21 +807,21 @@ const device_t i8254_ps2_fast_device = { .init = pitf_init, .close = pitf_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pitf_speed_changed, .force_redraw = NULL, .config = NULL }; const pit_intf_t pit_fast_intf = { - &pitf_read, - &pitf_write, - &pitf_ctr_get_count, - &pitf_ctr_set_gate, - &pitf_ctr_set_using_timer, - &pitf_ctr_set_out_func, - &pitf_ctr_set_load_func, - &pitf_ctr_clock, - &pitf_set_pit_const, - NULL, + .read = &pitf_read, + .write = &pitf_write, + .get_count = &pitf_ctr_get_count, + .set_gate = &pitf_ctr_set_gate, + .set_using_timer = &pitf_ctr_set_using_timer, + .set_out_func = &pitf_ctr_set_out_func, + .set_load_func = &pitf_ctr_set_load_func, + .ctr_clock = &pitf_ctr_clock, + .set_pit_const = &pitf_set_pit_const, + .data = NULL, }; diff --git a/src/port_6x.c b/src/port_6x.c index 971b92d28..b8183d651 100644 --- a/src/port_6x.c +++ b/src/port_6x.c @@ -212,7 +212,7 @@ const device_t port_6x_device = { .init = port_6x_init, .close = port_6x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -226,7 +226,7 @@ const device_t port_6x_xi8088_device = { .init = port_6x_init, .close = port_6x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -240,7 +240,7 @@ const device_t port_6x_ps2_device = { .init = port_6x_init, .close = port_6x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -254,7 +254,7 @@ const device_t port_6x_olivetti_device = { .init = port_6x_init, .close = port_6x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/port_92.c b/src/port_92.c index 18e60326c..d1a53a321 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -235,7 +235,7 @@ const device_t port_92_device = { .init = port_92_init, .close = port_92_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -249,7 +249,7 @@ const device_t port_92_key_device = { .init = port_92_init, .close = port_92_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -263,7 +263,7 @@ const device_t port_92_inv_device = { .init = port_92_init, .close = port_92_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -277,7 +277,7 @@ const device_t port_92_word_device = { .init = port_92_init, .close = port_92_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -291,7 +291,7 @@ const device_t port_92_pci_device = { .init = port_92_init, .close = port_92_close, .reset = port_92_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index 6ee52baba..071bf7113 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -9,11 +9,19 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(print OBJECT png.c prt_cpmap.c prt_escp.c prt_text.c prt_ps.c) +add_library(print OBJECT + png.c + prt_cpmap.c + prt_escp.c + prt_text.c + prt_ps.c +) if(PCL) target_compile_definitions(print PRIVATE USE_PCL) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index d91a52e0c..0198444a0 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1952,7 +1952,7 @@ read_status(void *priv) static void * escp_init(void *lpt) { - escp_t *dev; + escp_t *dev = NULL; /* Initialize FreeType. */ if (ft_lib == NULL) { @@ -1964,8 +1964,7 @@ escp_init(void *lpt) } /* Initialize a device instance. */ - dev = (escp_t *) malloc(sizeof(escp_t)); - memset(dev, 0x00, sizeof(escp_t)); + dev = (escp_t *) calloc(1, sizeof(escp_t)); dev->ctrl = 0x04; dev->lpt = lpt; @@ -2058,7 +2057,7 @@ escp_close(void *priv) } const lpt_device_t lpt_prt_escp_device = { - .name = "Generic ESC/P Dot-Matrix", + .name = "Generic ESC/P Dot-Matrix Printer", .internal_name = "dot_matrix", .init = escp_init, .close = escp_close, diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index dcd018881..1298018ee 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -26,8 +26,8 @@ #include #include #include <86box/86box.h> -#include <86box/lpt.h> #include <86box/timer.h> +#include <86box/lpt.h> #include <86box/pit.h> #include <86box/path.h> #include <86box/plat.h> @@ -366,13 +366,12 @@ ps_read_status(void *priv) static void * ps_init(void *lpt) { - ps_t *dev; + ps_t *dev = (ps_t *) calloc(1, sizeof(ps_t)); gsapi_revision_t rev; - dev = (ps_t *) malloc(sizeof(ps_t)); - memset(dev, 0x00, sizeof(ps_t)); dev->ctrl = 0x04; dev->lpt = lpt; + dev->pcl = false; /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); @@ -415,11 +414,9 @@ ps_init(void *lpt) static void * pcl_init(void *lpt) { - ps_t *dev; + ps_t *dev = (ps_t *) calloc(1, sizeof(ps_t)); gsapi_revision_t rev; - dev = (ps_t *) malloc(sizeof(ps_t)); - memset(dev, 0x00, sizeof(ps_t)); dev->ctrl = 0x04; dev->lpt = lpt; dev->pcl = true; diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index ddf9faf53..e04ef9680 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -421,11 +421,9 @@ read_status(void *priv) static void * prnt_init(void *lpt) { - prnt_t *dev; - /* Initialize a device instance. */ - dev = (prnt_t *) malloc(sizeof(prnt_t)); - memset(dev, 0x00, sizeof(prnt_t)); + prnt_t *dev = (prnt_t *) calloc(1, sizeof(prnt_t)); + dev->ctrl = 0x04; dev->lpt = lpt; diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index db0a6353f..c08a03016 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -8,6 +8,11 @@ # # CMake build script. # +# Authors: David Hrdlička, +# Jasmine Iwanek, +# +# Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -184,16 +189,22 @@ add_library(ui STATIC qt_mediahistorymanager.hpp ../qt_resources.qrc + ./qdarkstyle/dark/darkstyle.qrc ) if(RTMIDI) target_compile_definitions(ui PRIVATE USE_RTMIDI) endif() +if(WACOM) + target_compile_definitions(ui PRIVATE USE_WACOM) +endif() + if(WIN32) enable_language(RC) target_sources(86Box PUBLIC 86Box-qt.rc) target_sources(plat PRIVATE win_dynld.c) + target_link_libraries(86Box dwmapi) # CMake 3.22 messed this up for clang/clang++ # See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 @@ -223,10 +234,20 @@ if(WIN32 AND NOT MINGW) target_sources(plat PRIVATE win_opendir.c) endif() +if(WIN32 AND NOT CPPTHREADS) + target_sources(plat PRIVATE win_thread.c) +endif() + if(WIN32) - target_sources(plat PRIVATE win_serial_passthrough.c win_netsocket.c) + target_sources(plat PRIVATE + win_serial_passthrough.c + win_netsocket.c + ) else() - target_sources(plat PRIVATE ../unix/unix_serial_passthrough.c ../unix/unix_netsocket.c) + target_sources(plat PRIVATE + ../unix/unix_serial_passthrough.c + ../unix/unix_netsocket.c + ) endif() if(WIN32) @@ -260,18 +281,14 @@ if (WIN32) ) endif() -target_link_libraries( - plat - PRIVATE +target_link_libraries(plat PRIVATE Qt${QT_MAJOR}::Widgets Qt${QT_MAJOR}::Gui Qt${QT_MAJOR}::Network Threads::Threads ) -target_link_libraries( - ui - PRIVATE +target_link_libraries(ui PRIVATE Qt${QT_MAJOR}::Widgets Qt${QT_MAJOR}::Gui Qt${QT_MAJOR}::OpenGL @@ -404,7 +421,7 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) target_compile_definitions(ui PRIVATE XKBCOMMON_X11) target_link_libraries(ui PRIVATE X11::xcb PUBLIC PkgConfig::XKBCOMMON_X11) target_sources(ui PRIVATE xkbcommon_x11_keyboard.cpp) - set(QT5_PRIVATE_HEADERS ON) + set(QT_PRIVATE_HEADERS ON) endif() endif() endif() @@ -426,23 +443,68 @@ if (UNIX AND NOT APPLE AND NOT HAIKU) target_sources(ui PRIVATE xkbcommon_wl_keyboard.cpp) endif() target_compile_definitions(ui PRIVATE WAYLAND) - set(QT5_PRIVATE_HEADERS ON) + set(QT_PRIVATE_HEADERS ON) endif() endif() endif() # Add private headers for Qt5 if required. - if (NOT USE_QT6 AND DEFINED QT5_PRIVATE_HEADERS) + if (DEFINED QT_PRIVATE_HEADERS) find_package(Qt${QT_MAJOR}Gui) if (Qt${QT_MAJOR}Gui_FOUND) include_directories(${Qt${QT_MAJOR}Gui_PRIVATE_INCLUDE_DIRS}) endif() endif() endif() + +option(EMBED_QTBASE_TRANSLATIONS "Embed the base Qt translations into the executable" ON) + +if (EMBED_QTBASE_TRANSLATIONS) + # Get the Qt translations directory + get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_MAJOR}::qmake IMPORTED_LOCATION) + execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT_TRANSLATIONS_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + set(QM_FILES) file(GLOB po_files "${CMAKE_CURRENT_SOURCE_DIR}/languages/*.po") foreach(po_file ${po_files}) get_filename_component(PO_FILE_NAME ${po_file} NAME_WE) + + if (EMBED_QTBASE_TRANSLATIONS) + # Get the language and country + string(REGEX MATCH "^[a-z]+" PO_LANGUAGE ${PO_FILE_NAME}) + string(REGEX MATCH "[A-Z]+$" PO_COUNTRY ${PO_FILE_NAME}) + + # Find the base Qt translation for the language and country + set(qt_translation_file_dest "qt_${PO_LANGUAGE}_${PO_COUNTRY}.qm") + if (EXISTS "${QT_TRANSLATIONS_DIR}/qtbase_${PO_LANGUAGE}_${PO_COUNTRY}.qm") + set(qt_translation_file "qtbase_${PO_LANGUAGE}_${PO_COUNTRY}.qm") + # Fall back to just the language if country isn't found + elseif (EXISTS "${QT_TRANSLATIONS_DIR}/qtbase_${PO_LANGUAGE}.qm") + set(qt_translation_file "qtbase_${PO_LANGUAGE}.qm") + # If the translation is still not found, try the legacy Qt one + elseif (EXISTS "${QT_TRANSLATIONS_DIR}/qt_${PO_LANGUAGE}_${PO_COUNTRY}.qm") + set(qt_translation_file "qt_${PO_LANGUAGE}_${PO_COUNTRY}.qm") + # Fall back to just the language again + elseif (EXISTS "${QT_TRANSLATIONS_DIR}/qt_${PO_LANGUAGE}.qm") + set(qt_translation_file "qt_${PO_LANGUAGE}.qm") + else() + unset(qt_translation_file) + endif() + + # Copy the translation file to the build directory + if (qt_translation_file) + file(COPY "${QT_TRANSLATIONS_DIR}/${qt_translation_file}" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + if (NOT (qt_translation_file STREQUAL qt_translation_file_dest)) + # Rename the file for consistency + file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/${qt_translation_file}" "${CMAKE_CURRENT_BINARY_DIR}/${qt_translation_file_dest}") + endif() + # Add the file to the translations list + string(APPEND QT_TRANSLATIONS_LIST " ${qt_translation_file_dest}\n") + list(APPEND QM_FILES "${CMAKE_CURRENT_BINARY_DIR}/${qt_translation_file_dest}") + endif() + endif() + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/86box_${PO_FILE_NAME}.qm" COMMAND "$" -i ${po_file} -o ${CMAKE_CURRENT_BINARY_DIR}/86box_${PO_FILE_NAME}.qm WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" @@ -450,5 +512,6 @@ foreach(po_file ${po_files}) list(APPEND QM_FILES "${CMAKE_CURRENT_BINARY_DIR}/86box_${PO_FILE_NAME}.qm") list(APPEND QM_FILES "${po_file}") endforeach() -configure_file(qt_translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) + +configure_file(qt_translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/qt_translations.qrc) target_sources(ui PRIVATE ${QM_FILES} ${CMAKE_CURRENT_BINARY_DIR}/qt_translations.qrc) diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index 5c533b216..bddfabb5b 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -17,218 +17,226 @@ * Copyright 2023 Miran Grca. */ #include +#ifdef ENABLE_IOCTL_LOG #include +#endif #include #include #include #include #include #define HAVE_STDARG_H -#include <86box/86box.h> #include <86box/scsi_device.h> #include <86box/cdrom.h> +#include <86box/log.h> #include <86box/plat_unused.h> -#include <86box/plat_cdrom.h> +#include <86box/plat_cdrom_ioctl.h> /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static int toc_valid = 0; +typedef struct ioctl_t { + cdrom_t *dev; + void *log; + void *handle; + char path[256]; +} ioctl_t; -#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG -int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; +#ifdef ENABLE_IOCTL_LOG +int ioctl_do_log = ENABLE_IOCTL_LOG; void -dummy_cdrom_ioctl_log(const char *fmt, ...) +ioctl_log(void *priv, const char *fmt, ...) { - va_list ap; - - if (dummy_cdrom_ioctl_do_log) { + if (ioctl_do_log) { + va_list ap; va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define dummy_cdrom_ioctl_log(fmt, ...) +# define ioctl_log(priv, fmt, ...) #endif -static int -plat_cdrom_open(void) +/* Internal functions. */ +static void +ioctl_close_handle(UNUSED(const ioctl_t *ioctl)) { - return 0; } static int -plat_cdrom_load(void) +ioctl_open_handle(UNUSED(ioctl_t *ioctl)) { return 0; } static void -plat_cdrom_read_toc(void) +ioctl_read_toc(ioctl_t *ioctl) { - if (!toc_valid) - toc_valid = 1; } -int -plat_cdrom_is_track_audio(uint32_t sector) +/* Shared functions. */ +static int +ioctl_get_track_info(UNUSED(const void *local), UNUSED(const uint32_t track), + UNUSED(int end), UNUSED(track_info_t *ti)) { - plat_cdrom_read_toc(); + return 0; +} + +static void +ioctl_get_raw_track_info(UNUSED(const void *local), int *num, uint8_t *rti) +{ + *num = 1; + memset(rti, 0x00, 11); +} + +static int +ioctl_is_track_pre(const void *local, UNUSED(const uint32_t sector)) +{ + ioctl_t *ioctl = (ioctl_t *) local; + + ioctl_read_toc(ioctl); const int ret = 0; - dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + ioctl_log("ioctl_is_track_audio(%08X): %i\n", sector, ret); return ret; } -int -plat_cdrom_is_track_pre(uint32_t sector) +static int +ioctl_read_sector(const void *local, UNUSED(uint8_t *buffer), UNUSED(uint32_t const sector)) { - plat_cdrom_read_toc(); + ioctl_t *ioctl = (ioctl_t *) local; - const int ret = 0; + ioctl_open_handle(ioctl); - dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + ioctl_close_handle(ioctl); - return ret; -} - -uint32_t -plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) -{ - plat_cdrom_read_toc(); - - return 0x00000000; -} - -uint32_t -plat_cdrom_get_last_block(void) -{ - plat_cdrom_read_toc(); - - return 0x00000000; -} - -int -plat_cdrom_ext_medium_changed(void) -{ - int ret = 0; - - dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); - - return ret; -} - -void -plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) -{ - plat_cdrom_read_toc(); - - *st_track = 1; - *end = 1; - lead_out->min = 0; - lead_out->sec = 0; - lead_out->fr = 2; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", - *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); -} - -/* This replaces both Info and EndInfo, they are specified by a variable. */ -int -plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) -{ - plat_cdrom_read_toc(); - - if ((track < 1) || (track == 0xaa)) { - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); - return 0; - } - - start->min = 0; - start->sec = 0; - start->fr = 2; - - *track_num = 1; - *attr = 0x14; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", - track, start->min, start->sec, start->fr, *track_num, *attr); - - return 1; -} - -/* TODO: See if track start is adjusted by 150 or not. */ -int -plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) -{ - *track = 1; - *attr = 0x14; - *index = 1; - - rel_pos->min = 0; - rel_pos->sec = 0; - rel_pos->fr = 0; - abs_pos->min = 0; - abs_pos->sec = 0; - abs_pos->fr = 2; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); - - return 1; -} - -int -plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) -{ - dummy_cdrom_ioctl_log("BytesPerSector=2048\n"); - - return 2048; -} - -int -plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) -{ - plat_cdrom_open(); - - if (raw) { - dummy_cdrom_ioctl_log("Raw\n"); - /* Raw */ - } else { - dummy_cdrom_ioctl_log("Cooked\n"); - /* Cooked */ - } - plat_cdrom_close(); - dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); + ioctl_log("ReadSector sector=%d.\n", sector); return 0; } -void -plat_cdrom_eject(void) +static uint8_t +ioctl_get_track_type(UNUSED(const void *local), UNUSED(const uint32_t sector)) { - plat_cdrom_open(); - plat_cdrom_close(); + return 0x00; } -void -plat_cdrom_close(void) +static uint32_t +ioctl_get_last_block(const void *local) { + ioctl_t *ioctl = (ioctl_t *) local; + + ioctl_read_toc(ioctl); + + return 0x00000000; } -int -plat_cdrom_set_drive(const char *drv) +static int +ioctl_read_dvd_structure(UNUSED(const void *local), UNUSED(const uint8_t layer), UNUSED(const uint8_t format), + UNUSED(uint8_t *buffer), UNUSED(uint32_t *info)) { - plat_cdrom_close(); + return -0x00052100; +} - toc_valid = 0; +static int +ioctl_is_dvd(UNUSED(const void *local)) +{ + return 0; +} - plat_cdrom_load(); +static int +ioctl_has_audio(UNUSED(const void *local)) +{ + return 0; +} + +static int +ioctl_is_empty(const void *local) +{ return 1; } + +static int +ioctl_ext_medium_changed(UNUSED(void *local)) +{ +#if 0 + ioctl_t *ioctl = (ioctl_t *) local; +#endif + int ret = 0; + + ioctl_log("ioctl_ext_medium_changed(): %i\n", ret); + + return ret; +} + +static void +ioctl_close(void *local) +{ + ioctl_t *ioctl = (ioctl_t *) local; + + ioctl_close_handle(ioctl); + ioctl->handle = NULL; + + ioctl_log(ioctl->log, "Log closed\n"); + + log_close(ioctl->log); + ioctl->log = NULL; +} + +static void +ioctl_load(const void *local) +{ + const ioctl_t *ioctl = (const ioctl_t *) local; + + if (ioctl_open_handle((ioctl_t *) ioctl)) { + ioctl_close_handle((ioctl_t *) ioctl); + + ioctl_read_toc((ioctl_t *) ioctl); + } +} + +static const cdrom_ops_t ioctl_ops = { + ioctl_get_track_info, + ioctl_get_raw_track_info, + ioctl_is_track_pre, + ioctl_read_sector, + ioctl_get_track_type, + ioctl_get_last_block, + ioctl_read_dvd_structure, + ioctl_is_dvd, + ioctl_has_audio, + ioctl_is_empty, + ioctl_close, + ioctl_load +}; + +/* Public functions. */ +void * +ioctl_open(cdrom_t *dev, const char *drv) +{ + ioctl_t *ioctl = (ioctl_t *) calloc(1, sizeof(ioctl_t)); + + if (ioctl != NULL) { + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i IOCtl", dev->id + 1); + ioctl->log = log_open(n); + + memset(ioctl->path, 0x00, sizeof(ioctl->path)); + + sprintf(ioctl->path, "%s", drv); + ioctl_log(ioctl->log, "Path is %s\n", ioctl->path); + + ioctl->dev = dev; + + dev->ops = &ioctl_ops; + } + + return ioctl; +} diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot new file mode 100644 index 000000000..ac2db7d07 --- /dev/null +++ b/src/qt/languages/86box.pot @@ -0,0 +1,2137 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: \n" +"X-Source-Language: en_US\n" + +msgid "&Action" +msgstr "" + +msgid "&Keyboard requires capture" +msgstr "" + +msgid "&Right CTRL is left ALT" +msgstr "" + +msgid "&Hard Reset..." +msgstr "" + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "" + +msgid "Ctrl+Alt+&Esc" +msgstr "" + +msgid "&Pause" +msgstr "" + +msgid "E&xit..." +msgstr "" + +msgid "&View" +msgstr "" + +msgid "&Hide status bar" +msgstr "" + +msgid "Hide &toolbar" +msgstr "" + +msgid "&Resizeable window" +msgstr "" + +msgid "R&emember size && position" +msgstr "" + +msgid "Re&nderer" +msgstr "" + +msgid "&Qt (Software)" +msgstr "" + +msgid "Qt (&OpenGL)" +msgstr "" + +msgid "Open&GL (3.0 Core)" +msgstr "" + +msgid "&VNC" +msgstr "" + +msgid "Specify dimensions..." +msgstr "" + +msgid "F&orce 4:3 display ratio" +msgstr "" + +msgid "&Window scale factor" +msgstr "" + +msgid "&0.5x" +msgstr "" + +msgid "&1x" +msgstr "" + +msgid "1.&5x" +msgstr "" + +msgid "&2x" +msgstr "" + +msgid "&3x" +msgstr "" + +msgid "&4x" +msgstr "" + +msgid "&5x" +msgstr "" + +msgid "&6x" +msgstr "" + +msgid "&7x" +msgstr "" + +msgid "&8x" +msgstr "" + +msgid "Filter method" +msgstr "" + +msgid "&Nearest" +msgstr "" + +msgid "&Linear" +msgstr "" + +msgid "Hi&DPI scaling" +msgstr "" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "" + +msgid "Fullscreen &stretch mode" +msgstr "" + +msgid "&Full screen stretch" +msgstr "" + +msgid "&4:3" +msgstr "" + +msgid "&Square pixels (Keep ratio)" +msgstr "" + +msgid "&Integer scale" +msgstr "" + +msgid "4:&3 Integer scale" +msgstr "" + +msgid "E&GA/(S)VGA settings" +msgstr "" + +msgid "&Inverted VGA monitor" +msgstr "" + +msgid "VGA screen &type" +msgstr "" + +msgid "RGB &Color" +msgstr "" + +msgid "&RGB Grayscale" +msgstr "" + +msgid "&Amber monitor" +msgstr "" + +msgid "&Green monitor" +msgstr "" + +msgid "&White monitor" +msgstr "" + +msgid "Grayscale &conversion type" +msgstr "" + +msgid "BT&601 (NTSC/PAL)" +msgstr "" + +msgid "BT&709 (HDTV)" +msgstr "" + +msgid "&Average" +msgstr "" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "" + +msgid "Change contrast for &monochrome display" +msgstr "" + +msgid "&Media" +msgstr "" + +msgid "&Tools" +msgstr "" + +msgid "&Settings..." +msgstr "" + +msgid "&Update status bar icons" +msgstr "" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "" + +msgid "&Preferences..." +msgstr "" + +msgid "Enable &Discord integration" +msgstr "" + +msgid "Sound &gain..." +msgstr "" + +msgid "Begin trace\tCtrl+T" +msgstr "" + +msgid "End trace\tCtrl+T" +msgstr "" + +msgid "&Help" +msgstr "" + +msgid "&Documentation..." +msgstr "" + +msgid "&About 86Box..." +msgstr "" + +msgid "&New image..." +msgstr "" + +msgid "&Existing image..." +msgstr "" + +msgid "Existing image (&Write-protected)..." +msgstr "" + +msgid "&Record" +msgstr "" + +msgid "&Play" +msgstr "" + +msgid "&Rewind to the beginning" +msgstr "" + +msgid "&Fast forward to the end" +msgstr "" + +msgid "E&ject" +msgstr "" + +msgid "&Image..." +msgstr "" + +msgid "E&xport to 86F..." +msgstr "" + +msgid "&Mute" +msgstr "" + +msgid "E&mpty" +msgstr "" + +msgid "&Reload previous image" +msgstr "" + +msgid "&Folder..." +msgstr "" + +msgid "Target &framerate" +msgstr "" + +msgid "&Sync with video" +msgstr "" + +msgid "&25 fps" +msgstr "" + +msgid "&30 fps" +msgstr "" + +msgid "&50 fps" +msgstr "" + +msgid "&60 fps" +msgstr "" + +msgid "&75 fps" +msgstr "" + +msgid "&VSync" +msgstr "" + +msgid "&Select shader..." +msgstr "" + +msgid "&Remove shader" +msgstr "" + +msgid "Preferences" +msgstr "" + +msgid "Sound Gain" +msgstr "" + +msgid "New Image" +msgstr "" + +msgid "Settings" +msgstr "" + +msgid "Specify Main Window Dimensions" +msgstr "" + +msgid "OK" +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Save these settings as &global defaults" +msgstr "" + +msgid "&Default" +msgstr "" + +msgid "Language:" +msgstr "" + +msgid "Icon set:" +msgstr "" + +msgid "Gain" +msgstr "" + +msgid "File name:" +msgstr "" + +msgid "Disk size:" +msgstr "" + +msgid "RPM mode:" +msgstr "" + +msgid "Progress:" +msgstr "" + +msgid "Width:" +msgstr "" + +msgid "Height:" +msgstr "" + +msgid "Lock to this size" +msgstr "" + +msgid "Machine type:" +msgstr "" + +msgid "Machine:" +msgstr "" + +msgid "Configure" +msgstr "" + +msgid "CPU type:" +msgstr "" + +msgid "Speed:" +msgstr "" + +msgid "Frequency:" +msgstr "" + +msgid "FPU:" +msgstr "" + +msgid "Wait states:" +msgstr "" + +msgid "MB" +msgstr "" + +msgid "Memory:" +msgstr "" + +msgid "Time synchronization" +msgstr "" + +msgid "Disabled" +msgstr "" + +msgid "Enabled (local time)" +msgstr "" + +msgid "Enabled (UTC)" +msgstr "" + +msgid "Dynamic Recompiler" +msgstr "" + +msgid "Video:" +msgstr "" + +msgid "Video #2:" +msgstr "" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "" + +msgid "IBM 8514/A Graphics" +msgstr "" + +msgid "XGA Graphics" +msgstr "" + +msgid "Mouse:" +msgstr "" + +msgid "Joystick:" +msgstr "" + +msgid "Joystick 1..." +msgstr "" + +msgid "Joystick 2..." +msgstr "" + +msgid "Joystick 3..." +msgstr "" + +msgid "Joystick 4..." +msgstr "" + +msgid "Sound card #1:" +msgstr "" + +msgid "Sound card #2:" +msgstr "" + +msgid "Sound card #3:" +msgstr "" + +msgid "Sound card #4:" +msgstr "" + +msgid "MIDI Out Device:" +msgstr "" + +msgid "MIDI In Device:" +msgstr "" + +msgid "Standalone MPU-401" +msgstr "" + +msgid "Use FLOAT32 sound" +msgstr "" + +msgid "FM synth driver" +msgstr "" + +msgid "Nuked (more accurate)" +msgstr "" + +msgid "YMFM (faster)" +msgstr "" + +msgid "Network type:" +msgstr "" + +msgid "PCap device:" +msgstr "" + +msgid "Network adapter:" +msgstr "" + +msgid "COM1 Device:" +msgstr "" + +msgid "COM2 Device:" +msgstr "" + +msgid "COM3 Device:" +msgstr "" + +msgid "COM4 Device:" +msgstr "" + +msgid "LPT1 Device:" +msgstr "" + +msgid "LPT2 Device:" +msgstr "" + +msgid "LPT3 Device:" +msgstr "" + +msgid "LPT4 Device:" +msgstr "" + +msgid "Serial port 1" +msgstr "" + +msgid "Serial port 2" +msgstr "" + +msgid "Serial port 3" +msgstr "" + +msgid "Serial port 4" +msgstr "" + +msgid "Parallel port 1" +msgstr "" + +msgid "Parallel port 2" +msgstr "" + +msgid "Parallel port 3" +msgstr "" + +msgid "Parallel port 4" +msgstr "" + +msgid "HD Controller:" +msgstr "" + +msgid "FD Controller:" +msgstr "" + +msgid "Tertiary IDE Controller" +msgstr "" + +msgid "Quaternary IDE Controller" +msgstr "" + +msgid "SCSI" +msgstr "" + +msgid "Controller 1:" +msgstr "" + +msgid "Controller 2:" +msgstr "" + +msgid "Controller 3:" +msgstr "" + +msgid "Controller 4:" +msgstr "" + +msgid "Cassette" +msgstr "" + +msgid "Hard disks:" +msgstr "" + +msgid "&New..." +msgstr "" + +msgid "&Existing..." +msgstr "" + +msgid "&Remove" +msgstr "" + +msgid "Bus:" +msgstr "" + +msgid "Channel:" +msgstr "" + +msgid "ID:" +msgstr "" + +msgid "&Specify..." +msgstr "" + +msgid "Sectors:" +msgstr "" + +msgid "Heads:" +msgstr "" + +msgid "Cylinders:" +msgstr "" + +msgid "Size (MB):" +msgstr "" + +msgid "Type:" +msgstr "" + +msgid "Image Format:" +msgstr "" + +msgid "Block Size:" +msgstr "" + +msgid "Floppy drives:" +msgstr "" + +msgid "Turbo timings" +msgstr "" + +msgid "Check BPB" +msgstr "" + +msgid "CD-ROM drives:" +msgstr "" + +msgid "MO drives:" +msgstr "" + +msgid "ZIP drives:" +msgstr "" + +msgid "ZIP 250" +msgstr "" + +msgid "ISA RTC:" +msgstr "" + +msgid "ISA Memory Expansion" +msgstr "" + +msgid "Card 1:" +msgstr "" + +msgid "Card 2:" +msgstr "" + +msgid "Card 3:" +msgstr "" + +msgid "Card 4:" +msgstr "" + +msgid "ISABugger device" +msgstr "" + +msgid "POST card" +msgstr "" + +msgid "86Box" +msgstr "" + +msgid "Error" +msgstr "" + +msgid "Fatal error" +msgstr "" + +msgid " - PAUSED" +msgstr "" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "" + +msgid "Speed" +msgstr "" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "" + +msgid "ZIP images" +msgstr "" + +msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." +msgstr "" + +msgid "(empty)" +msgstr "" + +msgid "All files" +msgstr "" + +msgid "Turbo" +msgstr "" + +msgid "On" +msgstr "" + +msgid "Off" +msgstr "" + +msgid "All images" +msgstr "" + +msgid "Basic sector images" +msgstr "" + +msgid "Surface images" +msgstr "" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "" + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "" + +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "" + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "" + +msgid "Machine" +msgstr "" + +msgid "Display" +msgstr "" + +msgid "Input devices" +msgstr "" + +msgid "Sound" +msgstr "" + +msgid "Network" +msgstr "" + +msgid "Ports (COM & LPT)" +msgstr "" + +msgid "Storage controllers" +msgstr "" + +msgid "Hard disks" +msgstr "" + +msgid "Floppy & CD-ROM drives" +msgstr "" + +msgid "Other removable devices" +msgstr "" + +msgid "Other peripherals" +msgstr "" + +msgid "Click to capture mouse" +msgstr "" + +msgid "Press %1 to release mouse" +msgstr "" + +msgid "Press %1 or middle button to release mouse" +msgstr "" + +msgid "Bus" +msgstr "" + +msgid "File" +msgstr "" + +msgid "C" +msgstr "" + +msgid "H" +msgstr "" + +msgid "S" +msgstr "" + +msgid "KB" +msgstr "" + +msgid "Could not initialize the video renderer." +msgstr "" + +msgid "Default" +msgstr "" + +msgid "%i estat(s) d'espera" +msgstr "" + +msgid "Type" +msgstr "" + +msgid "No PCap devices found" +msgstr "" + +msgid "Invalid PCap device" +msgstr "" + +msgid "2-axis, 2-button joystick(s)" +msgstr "" + +msgid "2-axis, 4-button joystick" +msgstr "" + +msgid "2-axis, 6-button joystick" +msgstr "" + +msgid "2-axis, 8-button joystick" +msgstr "" + +msgid "3-axis, 2-button joystick" +msgstr "" + +msgid "3-axis, 4-button joystick" +msgstr "" + +msgid "4-axis, 4-button joystick" +msgstr "" + +msgid "CH Flightstick Pro" +msgstr "" + +msgid "Microsoft SideWinder Pad" +msgstr "" + +msgid "Thrustmaster Flight Control System" +msgstr "" + +msgid "None" +msgstr "" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "" + +msgid "Floppy %i (%s): %ls" +msgstr "" + +msgid "Advanced sector images" +msgstr "" + +msgid "Flux images" +msgstr "" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "" + +msgid "Are you sure you want to exit 86Box?" +msgstr "" + +msgid "Unable to initialize Ghostscript" +msgstr "" + +msgid "Unable to initialize GhostPCL" +msgstr "" + +msgid "MO %i (%ls): %ls" +msgstr "" + +msgid "MO images" +msgstr "" + +msgid "Welcome to 86Box!" +msgstr "" + +msgid "Internal device" +msgstr "" + +msgid "Exit" +msgstr "" + +msgid "No ROMs found" +msgstr "" + +msgid "Do you want to save the settings?" +msgstr "" + +msgid "This will hard reset the emulated machine." +msgstr "" + +msgid "Save" +msgstr "" + +msgid "About 86Box" +msgstr "" + +msgid "86Box v" +msgstr "" + +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 "" + +msgid "Hardware not available" +msgstr "" + +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "" + +msgid "Invalid configuration" +msgstr "" + +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 "" + +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 "" + +msgid "Don't exit" +msgstr "" + +msgid "Reset" +msgstr "" + +msgid "Don't reset" +msgstr "" + +msgid "CD-ROM images" +msgstr "" + +msgid "%1 Device Configuration" +msgstr "" + +msgid "Monitor in sleep mode" +msgstr "" + +msgid "OpenGL Shaders" +msgstr "" + +msgid "OpenGL options" +msgstr "" + +msgid "You are loading an unsupported configuration" +msgstr "" + +msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." +msgstr "" + +msgid "Continue" +msgstr "" + +msgid "Cassette: %s" +msgstr "" + +msgid "Cassette images" +msgstr "" + +msgid "Cartridge %i: %ls" +msgstr "" + +msgid "Cartridge images" +msgstr "" + +msgid "Error initializing renderer" +msgstr "" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "" + +msgid "Resume execution" +msgstr "" + +msgid "Pause execution" +msgstr "" + +msgid "Press Ctrl+Alt+Del" +msgstr "" + +msgid "Press Ctrl+Alt+Esc" +msgstr "" + +msgid "Hard reset" +msgstr "" + +msgid "ACPI shutdown" +msgstr "" + +msgid "Hard disk (%1)" +msgstr "" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "" + +msgid "Custom..." +msgstr "" + +msgid "Custom (large)..." +msgstr "" + +msgid "Add New Hard Disk" +msgstr "" + +msgid "Add Existing Hard Disk" +msgstr "" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "" + +msgid "Disk images cannot be larger than 127 GB." +msgstr "" + +msgid "Hard disk images" +msgstr "" + +msgid "Unable to read file" +msgstr "" + +msgid "Unable to write file" +msgstr "" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "" + +msgid "Disk image file already exists" +msgstr "" + +msgid "Please specify a valid file name." +msgstr "" + +msgid "Disk image created" +msgstr "" + +msgid "Make sure the file exists and is readable." +msgstr "" + +msgid "Make sure the file is being saved to a writable directory." +msgstr "" + +msgid "Disk image too large" +msgstr "" + +msgid "Remember to partition and format the newly-created drive." +msgstr "" + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "" + +msgid "Unsupported disk image" +msgstr "" + +msgid "Overwrite" +msgstr "" + +msgid "Don't overwrite" +msgstr "" + +msgid "Raw image" +msgstr "" + +msgid "HDI image" +msgstr "" + +msgid "HDX image" +msgstr "" + +msgid "Fixed-size VHD" +msgstr "" + +msgid "Dynamic-size VHD" +msgstr "" + +msgid "Differencing VHD" +msgstr "" + +msgid "(N/A)" +msgstr "" + +msgid "Raw image (.img)" +msgstr "" + +msgid "HDI image (.hdi)" +msgstr "" + +msgid "HDX image (.hdx)" +msgstr "" + +msgid "Fixed-size VHD (.vhd)" +msgstr "" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "" + +msgid "Differencing VHD (.vhd)" +msgstr "" + +msgid "Large blocks (2 MB)" +msgstr "" + +msgid "Small blocks (512 KB)" +msgstr "" + +msgid "VHD files" +msgstr "" + +msgid "Select the parent VHD" +msgstr "" + +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 "" + +msgid "Parent and child disk timestamps do not match" +msgstr "" + +msgid "Could not fix VHD timestamp." +msgstr "" + +msgid "MFM/RLL" +msgstr "" + +msgid "XTA" +msgstr "" + +msgid "ESDI" +msgstr "" + +msgid "IDE" +msgstr "" + +msgid "ATAPI" +msgstr "" + +msgid "CD-ROM %i (%s): %s" +msgstr "" + +msgid "160 KB" +msgstr "" + +msgid "180 KB" +msgstr "" + +msgid "320 KB" +msgstr "" + +msgid "360 KB" +msgstr "" + +msgid "640 KB" +msgstr "" + +msgid "720 KB" +msgstr "" + +msgid "1.2 MB" +msgstr "" + +msgid "1.25 MB" +msgstr "" + +msgid "1.44 MB" +msgstr "" + +msgid "DMF (cluster 1024)" +msgstr "" + +msgid "DMF (cluster 2048)" +msgstr "" + +msgid "2.88 MB" +msgstr "" + +msgid "ZIP 100" +msgstr "" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "" + +msgid "5.25\" 600 MB" +msgstr "" + +msgid "5.25\" 650 MB" +msgstr "" + +msgid "5.25\" 1 GB" +msgstr "" + +msgid "5.25\" 1.3 GB" +msgstr "" + +msgid "Perfect RPM" +msgstr "" + +msgid "1% below perfect RPM" +msgstr "" + +msgid "1.5% below perfect RPM" +msgstr "" + +msgid "2% below perfect RPM" +msgstr "" + +msgid "(System Default)" +msgstr "" + +msgid "Failed to initialize network driver" +msgstr "" + +msgid "The network configuration will be switched to the null driver" +msgstr "" + +msgid "Mouse sensitivity:" +msgstr "" + +msgid "Select media images from program working directory" +msgstr "" + +msgid "PIT mode:" +msgstr "" + +msgid "Auto" +msgstr "" + +msgid "Slow" +msgstr "" + +msgid "Fast" +msgstr "" + +msgid "&Auto-pause on focus loss" +msgstr "" + +msgid "WinBox is no longer supported" +msgstr "" + +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 "" + +msgid "Generate" +msgstr "" + +msgid "Joystick configuration" +msgstr "" + +msgid "Device" +msgstr "" + +msgid "%1 (X axis)" +msgstr "" + +msgid "%1 (Y axis)" +msgstr "" + +msgid "MCA devices" +msgstr "" + +msgid "List of MCA devices:" +msgstr "" + +msgid "Tablet tool" +msgstr "" + +msgid "Qt (OpenGL &ES)" +msgstr "" + +msgid "About Qt" +msgstr "" + +msgid "MCA devices..." +msgstr "" + +msgid "Show non-primary monitors" +msgstr "" + +msgid "Open screenshots folder..." +msgstr "" + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "" + +msgid "Cursor/Puck" +msgstr "" + +msgid "Pen" +msgstr "" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "" + +msgid "&Connected" +msgstr "" + +msgid "Clear image history" +msgstr "" + +msgid "Create..." +msgstr "" + +msgid "previous image" +msgstr "" + +msgid "Host CD/DVD Drive (%1)" +msgstr "" + +msgid "Unknown Bus" +msgstr "" + +msgid "Null Driver" +msgstr "" + +msgid "NIC %02i (%ls) %ls" +msgstr "" + +msgid "Error opening \"%1\": %2" +msgstr "" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "" + +msgid "Error linking shader program in file \"%1\"" +msgstr "" + +msgid "OpenGL 3.0 renderer options" +msgstr "" + +msgid "Render behavior" +msgstr "" + +msgid "Use target framerate:" +msgstr "" + +msgid " fps" +msgstr "" + +msgid "VSync" +msgstr "" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "" + +msgid "Synchronize with video" +msgstr "" + +msgid "Shaders" +msgstr "" + +msgid "Remove" +msgstr "" + +msgid "No shader selected" +msgstr "" + +msgid "Browse..." +msgstr "" + +msgid "Shader error" +msgstr "" + +msgid "Could not load shaders." +msgstr "" + +msgid "More information in details." +msgstr "" + +msgid "Couldn't create OpenGL context." +msgstr "" + +msgid "Couldn't switch to OpenGL context." +msgstr "" + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "" + +msgid "OpenGL initialization failed. Error %1." +msgstr "" + +msgid "Error initializing OpenGL" +msgstr "" + +msgid "Falling back to software rendering.\n" +msgstr "" + +msgid "Allocating memory for unpack buffer failed.\n" +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>" +msgstr "" + +msgid "This machine might have been moved or copied." +msgstr "" + +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 "" + +msgid "I Moved It" +msgstr "" + +msgid "I Copied It" +msgstr "" + +msgid "86Box Monitor #" +msgstr "" + +msgid "No MCA devices." +msgstr "" + +msgid "MiB" +msgstr "" + +msgid "Network Card #1" +msgstr "" + +msgid "Network Card #2" +msgstr "" + +msgid "Network Card #3" +msgstr "" + +msgid "Network Card #4" +msgstr "" + +msgid "Mode" +msgstr "" + +msgid "Interface" +msgstr "" + +msgid "Adapter" +msgstr "" + +msgid "VDE Socket" +msgstr "" + +msgid "86Box Unit Tester" +msgstr "" + +msgid "Novell NetWare 2.x Key Card" +msgstr "" + +msgid "Serial port passthrough 1" +msgstr "" + +msgid "Serial port passthrough 2" +msgstr "" + +msgid "Serial port passthrough 3" +msgstr "" + +msgid "Serial port passthrough 4" +msgstr "" + +msgid "Vision Systems LBA Enhancer" +msgstr "" + +msgid "Renderer options..." +msgstr "" + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "" + +msgid "Mouse Systems Serial Mouse" +msgstr "" + +msgid "Microsoft Serial Mouse" +msgstr "" + +msgid "Logitech Serial Mouse" +msgstr "" + +msgid "PS/2 Mouse" +msgstr "" + +msgid "3M MicroTouch (Serial)" +msgstr "" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "" + +msgid "Roland MT-32 Emulation" +msgstr "" + +msgid "Roland MT-32 (New) Emulation" +msgstr "" + +msgid "Roland CM-32L Emulation" +msgstr "" + +msgid "Roland CM-32LN Emulation" +msgstr "" + +msgid "OPL4-ML Daughterboard" +msgstr "" + +msgid "System MIDI" +msgstr "" + +msgid "MIDI Input Device" +msgstr "" + +msgid "BIOS Address" +msgstr "" + +msgid "Enable BIOS extension ROM Writes" +msgstr "" + +msgid "Address" +msgstr "" + +msgid "IRQ" +msgstr "" + +msgid "BIOS Revision" +msgstr "" + +msgid "Translate 26 -> 17" +msgstr "" + +msgid "Language" +msgstr "" + +msgid "Enable backlight" +msgstr "" + +msgid "Invert colors" +msgstr "" + +msgid "BIOS size" +msgstr "" + +msgid "Map C0000-C7FFF as UMB" +msgstr "" + +msgid "Map C8000-CFFFF as UMB" +msgstr "" + +msgid "Map D0000-D7FFF as UMB" +msgstr "" + +msgid "Map D8000-DFFFF as UMB" +msgstr "" + +msgid "Map E0000-E7FFF as UMB" +msgstr "" + +msgid "Map E8000-EFFFF as UMB" +msgstr "" + +msgid "JS9 Jumper (JIM)" +msgstr "" + +msgid "MIDI Output Device" +msgstr "" + +msgid "MIDI Real time" +msgstr "" + +msgid "MIDI Thru" +msgstr "" + +msgid "MIDI Clockout" +msgstr "" + +msgid "SoundFont" +msgstr "" + +msgid "Output Gain" +msgstr "" + +msgid "Chorus" +msgstr "" + +msgid "Chorus Voices" +msgstr "" + +msgid "Chorus Level" +msgstr "" + +msgid "Chorus Speed" +msgstr "" + +msgid "Chorus Depth" +msgstr "" + +msgid "Chorus Waveform" +msgstr "" + +msgid "Reverb" +msgstr "" + +msgid "Reverb Room Size" +msgstr "" + +msgid "Reverb Damping" +msgstr "" + +msgid "Reverb Width" +msgstr "" + +msgid "Reverb Level" +msgstr "" + +msgid "Interpolation Method" +msgstr "" + +msgid "Reverb Output Gain" +msgstr "" + +msgid "Reversed stereo" +msgstr "" + +msgid "Nice ramp" +msgstr "" + +msgid "Hz" +msgstr "" + +msgid "Buttons" +msgstr "" + +msgid "Serial Port" +msgstr "" + +msgid "RTS toggle" +msgstr "" + +msgid "Revision" +msgstr "" + +msgid "Controller" +msgstr "" + +msgid "Show Crosshair" +msgstr "" + +msgid "DMA" +msgstr "" + +msgid "MAC Address" +msgstr "" + +msgid "MAC Address OUI" +msgstr "" + +msgid "Enable BIOS" +msgstr "" + +msgid "Baud Rate" +msgstr "" + +msgid "TCP/IP listening port" +msgstr "" + +msgid "Phonebook File" +msgstr "" + +msgid "Telnet emulation" +msgstr "" + +msgid "RAM Address" +msgstr "" + +msgid "RAM size" +msgstr "" + +msgid "Initial RAM size" +msgstr "" + +msgid "Serial Number" +msgstr "" + +msgid "Host ID" +msgstr "" + +msgid "FDC Address" +msgstr "" + +msgid "MPU-401 Address" +msgstr "" + +msgid "MPU-401 IRQ" +msgstr "" + +msgid "Receive MIDI input" +msgstr "" + +msgid "Low DMA" +msgstr "" + +msgid "Enable Game port" +msgstr "" + +msgid "Surround module" +msgstr "" + +msgid "CODEC" +msgstr "" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "" + +msgid "SB Address" +msgstr "" + +msgid "WSS IRQ" +msgstr "" + +msgid "WSS DMA" +msgstr "" + +msgid "Enable OPL" +msgstr "" + +msgid "Receive MIDI input (MPU-401)" +msgstr "" + +msgid "SB low DMA" +msgstr "" + +msgid "6CH variant (6-channel)" +msgstr "" + +msgid "Enable CMS" +msgstr "" + +msgid "Mixer" +msgstr "" + +msgid "High DMA" +msgstr "" + +msgid "Control PC speaker" +msgstr "" + +msgid "Memory size" +msgstr "" + +msgid "EMU8000 Address" +msgstr "" + +msgid "IDE Controller" +msgstr "" + +msgid "Codec" +msgstr "" + +msgid "GUS type" +msgstr "" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "" + +msgid "Display type" +msgstr "" + +msgid "Composite type" +msgstr "" + +msgid "RGB type" +msgstr "" + +msgid "Line doubling type" +msgstr "" + +msgid "Snow emulation" +msgstr "" + +msgid "Monitor type" +msgstr "" + +msgid "Character set" +msgstr "" + +msgid "XGA type" +msgstr "" + +msgid "Instance" +msgstr "" + +msgid "MMIO Address" +msgstr "" + +msgid "RAMDAC type" +msgstr "" + +msgid "Blend" +msgstr "" + +msgid "Bilinear filtering" +msgstr "" + +msgid "Dithering" +msgstr "" + +msgid "Enable NMI for CGA emulation" +msgstr "" + +msgid "Voodoo type" +msgstr "" + +msgid "Framebuffer memory size" +msgstr "" + +msgid "Texture memory size" +msgstr "" + +msgid "Dither subtraction" +msgstr "" + +msgid "Screen Filter" +msgstr "" + +msgid "Render threads" +msgstr "" + +msgid "SLI" +msgstr "" + +msgid "Start Address" +msgstr "" + +msgid "Contiguous Size" +msgstr "" + +msgid "I/O Width" +msgstr "" + +msgid "Transfer Speed" +msgstr "" + +msgid "EMS mode" +msgstr "" + +msgid "Address for > 2 MB" +msgstr "" + +msgid "Frame Address" +msgstr "" + +msgid "USA" +msgstr "" + +msgid "Danish" +msgstr "" + +msgid "Always at selected speed" +msgstr "" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "" + +msgid "64 kB starting from F0000" +msgstr "" + +msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "" + +msgid "Sine" +msgstr "" + +msgid "Triangle" +msgstr "" + +msgid "Linear" +msgstr "" + +msgid "4th Order" +msgstr "" + +msgid "7th Order" +msgstr "" + +msgid "Non-timed (original)" +msgstr "" + +msgid "45 Hz (JMP2 not populated)" +msgstr "" + +msgid "Two" +msgstr "" + +msgid "Three" +msgstr "" + +msgid "Wheel" +msgstr "" + +msgid "Five + Wheel" +msgstr "" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "" + +msgid "Q1 - SMT3(R) Serial" +msgstr "" + +msgid "8 KB" +msgstr "" + +msgid "32 KB" +msgstr "" + +msgid "16 KB" +msgstr "" + +msgid "64 KB" +msgstr "" + +msgid "Disable BIOS" +msgstr "" + +msgid "512 KB" +msgstr "" + +msgid "2 MB" +msgstr "" + +msgid "8 MB" +msgstr "" + +msgid "28 MB" +msgstr "" + +msgid "1 MB" +msgstr "" + +msgid "4 MB" +msgstr "" + +msgid "12 MB" +msgstr "" + +msgid "16 MB" +msgstr "" + +msgid "20 MB" +msgstr "" + +msgid "24 MB" +msgstr "" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "" + +msgid "Classic" +msgstr "" + +msgid "256 KB" +msgstr "" + +msgid "Composite" +msgstr "" + +msgid "Old" +msgstr "" + +msgid "New" +msgstr "" + +msgid "Color (generic)" +msgstr "" + +msgid "Green Monochrome" +msgstr "" + +msgid "Amber Monochrome" +msgstr "" + +msgid "Gray Monochrome" +msgstr "" + +msgid "Color (no brown)" +msgstr "" + +msgid "Color (IBM 5153)" +msgstr "" + +msgid "Simple doubling" +msgstr "" + +msgid "sRGB interpolation" +msgstr "" + +msgid "Linear interpolation" +msgstr "" + +msgid "128 KB" +msgstr "" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "" + +msgid "Color 40x25 (5153/CGA)" +msgstr "" + +msgid "Color 80x25 (5153/CGA)" +msgstr "" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "" + +msgid "Green" +msgstr "" + +msgid "Amber" +msgstr "" + +msgid "Gray" +msgstr "" + +msgid "Color" +msgstr "" + +msgid "U.S. English" +msgstr "" + +msgid "Scandinavian" +msgstr "" + +msgid "Other languages" +msgstr "" + +msgid "Bochs latest" +msgstr "" + +msgid "Mono Non-Interlaced" +msgstr "" + +msgid "Color Interlaced" +msgstr "" + +msgid "Color Non-Interlaced" +msgstr "" + +msgid "3Dfx Voodoo Graphics" +msgstr "" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "" + +msgid "8-bit" +msgstr "" + +msgid "16-bit" +msgstr "" + +msgid "Standard (150ns)" +msgstr "" + +msgid "High-Speed (120ns)" +msgstr "" + +msgid "Enabled" +msgstr "" + +msgid "Standard" +msgstr "" + +msgid "High-Speed" +msgstr "" + +msgid "Stereo LPT DAC" +msgstr "" + +msgid "Generic Text Printer" +msgstr "" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "" + +msgid "Generic PostScript Printer" +msgstr "" + +msgid "Generic PCL5e Printer" +msgstr "" + +msgid "Parallel Line Internet Protocol" +msgstr "" + +msgid "Protection Dongle for Savage Quest" +msgstr "" + +msgid "Serial Passthrough Device" +msgstr "" + +msgid "Passthrough Mode" +msgstr "" + +msgid "Host Serial Device" +msgstr "" + +msgid "Name of pipe" +msgstr "" + +msgid "Data bits" +msgstr "" + +msgid "Stop bits" +msgstr "" + +msgid "Baud Rate of Passthrough" +msgstr "" + +msgid "Named Pipe (Server)" +msgstr "" + +msgid "Host Serial Passthrough" +msgstr "" + +msgid "Eject %s" +msgstr "" + +msgid "&Unmute" +msgstr "" + +msgid "Softfloat FPU" +msgstr "" + +msgid "High performance impact" +msgstr "" + +msgid "RAM Disk (max. speed)" +msgstr "" + +msgid "IBM 8514/A clone (ISA)" +msgstr "" + +msgid "Vendor" +msgstr "" + +msgid "30 Hz (JMP2 = 1)" +msgstr "" + +msgid "60 Hz (JMP2 = 2)" +msgstr "" + +msgid "Generic PC/XT Memory Expansion" +msgstr "" + +msgid "Generic PC/AT Memory Expansion" +msgstr "" diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index 94b35a235..e49ab3223 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -16,7 +16,7 @@ msgid "&Right CTRL is left ALT" msgstr "CTRL &dret és ALT esquerre" msgid "&Hard Reset..." -msgstr "&Reinicialització completa..." +msgstr "&Reinicialització completa ..." msgid "&Ctrl+Alt+Del\tCtrl+F12" msgstr "&Ctrl+Alt+Del\tCtrl+F12" @@ -28,7 +28,7 @@ msgid "&Pause" msgstr "&Pausa" msgid "E&xit..." -msgstr "&Sortir..." +msgstr "&Sortir ..." msgid "&View" msgstr "&Vista" @@ -43,7 +43,7 @@ msgid "&Resizeable window" msgstr "&Finestra redimensionable" msgid "R&emember size && position" -msgstr "&Recordar mida i posició" +msgstr "&Recordar grandària i posició" msgid "Re&nderer" msgstr "Re&nderitzador" @@ -61,7 +61,7 @@ msgid "&VNC" msgstr "&VNC" msgid "Specify dimensions..." -msgstr "E&specificar dimensions..." +msgstr "E&specificar dimensions ..." msgid "F&orce 4:3 display ratio" msgstr "F&orçar ràtio 4:3" @@ -181,7 +181,7 @@ msgid "&Tools" msgstr "&Eines" msgid "&Settings..." -msgstr "&Ajustaments..." +msgstr "&Ajustaments ..." msgid "&Update status bar icons" msgstr "&Actualitzar icones a la barra d'estat" @@ -190,13 +190,13 @@ msgid "Take s&creenshot\tCtrl+F11" msgstr "Prendre c&aptura\tCtrl+F11" msgid "&Preferences..." -msgstr "&Preferències..." +msgstr "&Preferències ..." msgid "Enable &Discord integration" -msgstr "Habilita la integració amb el &Discord" +msgstr "Activar la integració amb el &Discord" msgid "Sound &gain..." -msgstr "&Guany de so..." +msgstr "&Guany de so ..." msgid "Begin trace\tCtrl+T" msgstr "Començar traça\tCtrl+T" @@ -208,19 +208,19 @@ msgid "&Help" msgstr "&Ajuda" msgid "&Documentation..." -msgstr "&Documentació..." +msgstr "&Documentació ..." msgid "&About 86Box..." -msgstr "&Quant a 86Box..." +msgstr "&Quant a 86Box ..." msgid "&New image..." -msgstr "&Nova imatge..." +msgstr "&Nova imatge ..." msgid "&Existing image..." -msgstr "Imatge &Existent..." +msgstr "Imatge &Existent ..." msgid "Existing image (&Write-protected)..." -msgstr "Imatge Existent (&Només-lectura)..." +msgstr "Imatge Existent (&Només-lectura) ..." msgid "&Record" msgstr "&Gravar" @@ -238,10 +238,10 @@ msgid "E&ject" msgstr "E&xtreure" msgid "&Image..." -msgstr "&Imatge..." +msgstr "&Imatge ..." msgid "E&xport to 86F..." -msgstr "E&xportar a 86F..." +msgstr "E&xportar a 86F ..." msgid "&Mute" msgstr "&Silenciar" @@ -250,40 +250,40 @@ msgid "E&mpty" msgstr "E&xtreure disc" msgid "&Reload previous image" -msgstr "&Recarregar imatge prèvia" +msgstr "&Recarregar imatge anterior" msgid "&Folder..." -msgstr "&Carpeta..." +msgstr "&Carpeta ..." msgid "Target &framerate" -msgstr "&Taxa de refresc objectiu" +msgstr "objectiu de &taxa de refresc" msgid "&Sync with video" msgstr "&Sincronitzar amb vídeo" msgid "&25 fps" -msgstr "&25 fps" +msgstr "&25 fotogrames/s" msgid "&30 fps" -msgstr "&30 fps" +msgstr "&30 fotogrames/s" msgid "&50 fps" -msgstr "&50 fps" +msgstr "&50 fotogrames/s" msgid "&60 fps" -msgstr "&60 fps" +msgstr "&60 fotogrames/s" msgid "&75 fps" -msgstr "&75 fps" +msgstr "&75 fotogrames/s" msgid "&VSync" msgstr "&VSync" msgid "&Select shader..." -msgstr "&Seleccionar shader..." +msgstr "&Seleccionar shader ..." msgid "&Remove shader" -msgstr "&Eliminar shader" +msgstr "S&upressió de shader" msgid "Preferences" msgstr "Preferències" @@ -340,7 +340,7 @@ msgid "Height:" msgstr "Alçada:" msgid "Lock to this size" -msgstr "Bloquejar aquesta mida" +msgstr "Bloquejar aquesta grandària" msgid "Machine type:" msgstr "Tipus de màquina:" @@ -376,7 +376,7 @@ msgid "Time synchronization" msgstr "Sincronització horària" msgid "Disabled" -msgstr "Desactuvat" +msgstr "Deshabilitat" msgid "Enabled (local time)" msgstr "Activat (hora local)" @@ -390,8 +390,11 @@ msgstr "Recopilador Dinàmic" msgid "Video:" msgstr "Vídeo:" -msgid "Voodoo Graphics" -msgstr "Gràfics Voodoo" +msgid "Video #2:" +msgstr "Vídeo 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Gràfics Voodoo 1 o 2" msgid "IBM 8514/A Graphics" msgstr "Gràfics IBM 8514/A" @@ -406,16 +409,16 @@ msgid "Joystick:" msgstr "Joystick:" msgid "Joystick 1..." -msgstr "Joystick 1..." +msgstr "Joystick 1 ..." msgid "Joystick 2..." -msgstr "Joystick 2..." +msgstr "Joystick 2 ..." msgid "Joystick 3..." -msgstr "Joystick 3..." +msgstr "Joystick 3 ..." msgid "Joystick 4..." -msgstr "Joystick 4..." +msgstr "Joystick 4 ..." msgid "Sound card #1:" msgstr "Targeta de so 1:" @@ -541,13 +544,13 @@ msgid "Hard disks:" msgstr "Discs durs:" msgid "&New..." -msgstr "&Nou..." +msgstr "&Nou ..." msgid "&Existing..." -msgstr "&Existent..." +msgstr "&Existent ..." msgid "&Remove" -msgstr "E&liminar" +msgstr "S&upressió" msgid "Bus:" msgstr "Bus:" @@ -559,7 +562,7 @@ msgid "ID:" msgstr "ID:" msgid "&Specify..." -msgstr "E&specificar..." +msgstr "E&specificar ..." msgid "Sectors:" msgstr "Sectors:" @@ -571,7 +574,7 @@ msgid "Cylinders:" msgstr "Cilindres:" msgid "Size (MB):" -msgstr "Mida (MB):" +msgstr "Grandària (MB):" msgid "Type:" msgstr "Tipus:" @@ -580,7 +583,7 @@ msgid "Image Format:" msgstr "Format d'imatge:" msgid "Block Size:" -msgstr "Mida del bloc:" +msgstr "Grandària del bloc:" msgid "Floppy drives:" msgstr "Unitats de disquet:" @@ -684,6 +687,12 @@ msgstr "La màquina \"%hs\" no està disponible perquè falten ROM al directori msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "La targeta de vídeo \"%hs\" no està disponible perquè falten ROM al directori roms/video. Canvi a una targeta de vídeo disponible." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "La targeta de vídeo 2 \"%hs\" no està disponible perquè falten ROM al directori roms/video. Deshabilitant la segona targeta de vídeo." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "El dispositiu \"%hs\" no està disponible perquè falten ROM. Ignorant el dispositiu." + msgid "Machine" msgstr "Màquina" @@ -762,17 +771,26 @@ msgstr "No s'han trobat dispositius PCap" msgid "Invalid PCap device" msgstr "El dispositiu PCap no és vàlid" -msgid "Standard 2-button joystick(s)" -msgstr "Joystick(s) estàndard de 2 botons" +msgid "2-axis, 2-button joystick(s)" +msgstr "Joystick(s) de 2 eixes, 2 botons" -msgid "Standard 4-button joystick" -msgstr "Joystick(s) estàndard de 4 botons" +msgid "2-axis, 4-button joystick" +msgstr "Joystick de 2 eixes, 4 botons" -msgid "Standard 6-button joystick" -msgstr "Joystick(s) estàndard de 6 botons" +msgid "2-axis, 6-button joystick" +msgstr "Joystick de 2 eixes, 6 botons" -msgid "Standard 8-button joystick" -msgstr "Joystick(s) estàndard de 8 botons" +msgid "2-axis, 8-button joystick" +msgstr "Joystick de 2 eixes, 8 botons" + +msgid "3-axis, 2-button joystick" +msgstr "Joystick de 3 eixes, 2 botons" + +msgid "3-axis, 4-button joystick" +msgstr "Joystick de 3 eixes, 4 botons" + +msgid "4-axis, 4-button joystick" +msgstr "Joystick de 4 eixes, 4 botons" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Esteu segur que voleu sortir de 86Box?" msgid "Unable to initialize Ghostscript" msgstr "No es pot inicialitzar Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "No es pot inicialitzar GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Imatges MO" msgid "Welcome to 86Box!" msgstr "Benvingut a 86Box!" -msgid "Internal controller" -msgstr "Controlador intern" +msgid "Internal device" +msgstr "Dispositiu intern" msgid "Exit" msgstr "Sortir" @@ -841,7 +862,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 emulador d'ordinadors antics\n\nAutors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne i altres.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho i altres.\n\nAlliberat sota la GNU General Public License versió 2 o posterior. Veure LLICENSE per a més informació." +msgstr "Un emulador d'ordinadors antics\n\nAutors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne i altres.\n\nAmb contribucions bàsiques anteriors de Sarah Walker, Leilei, JohnElliott, greatpsycho i altres.\n\nAlliberat sota la GNU General Public License versió 2 o posterior. Veure LLICENSE per a més informació." msgid "Hardware not available" msgstr "Maquinari no disponible" @@ -853,7 +874,10 @@ msgid "Invalid configuration" msgstr "Configuració invàlida" 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 és necessària per a la conversió automàtica de fitxers PostScript a PDF.\n\nQualsevol document enviat a la impressora genèrica postScript es desarà com a fitxer PostScript (.ps)." +msgstr "%1 és necessària per a la conversió automàtica de fitxers PostScript a PDF.\n\nQualsevol document enviat a la impressora genèrica PostScript es desarà com a fitxer PostScript (.ps)." + +msgid "%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" @@ -874,7 +898,7 @@ msgid "CD-ROM images" msgstr "Imatges de CD-ROM" msgid "%1 Device Configuration" -msgstr "%1 Configuració de Dispositiu" +msgstr "Configuració de Dispositiu %1" msgid "Monitor in sleep mode" msgstr "Monitor en mode estalvi" @@ -937,10 +961,10 @@ msgid "MFM/RLL or ESDI CD-ROM drives never existed" msgstr "Les unitats de CD-ROM MFM/RLL o ESDI no van existir mai" msgid "Custom..." -msgstr "Personalitzat..." +msgstr "Personalitzat ..." msgid "Custom (large)..." -msgstr "Personalitzat (gran)..." +msgstr "Personalitzat (gran) ..." msgid "Add New Hard Disk" msgstr "Afegir disc dur nou" @@ -964,7 +988,7 @@ msgid "Unable to write file" msgstr "No has estat possible escriure el fitxer" msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "Les imatges HDI o HDX amb una mida de sector diferent de 512 no s'admeten." +msgstr "Les imatges HDI o HDX amb una grandària de sector diferent de 512 no s'admeten." msgid "Disk image file already exists" msgstr "El fitxer d'imatge de disc ja existeix" @@ -999,6 +1023,27 @@ msgstr "Sobreescriure" msgid "Don't overwrite" msgstr "No sobreescriure" +msgid "Raw image" +msgstr "Imatge crua" + +msgid "HDI image" +msgstr "Imatge HDI" + +msgid "HDX image" +msgstr "Imatge HDX" + +msgid "Fixed-size VHD" +msgstr "VHD de grandària fixa" + +msgid "Dynamic-size VHD" +msgstr "VHD de grandària dinàmica" + +msgid "Differencing VHD" +msgstr "VHD diferencial" + +msgid "(N/A)" +msgstr "(Cap)" + msgid "Raw image (.img)" msgstr "Imatge crua (.img)" @@ -1009,10 +1054,10 @@ msgid "HDX image (.hdx)" msgstr "Imatge HDX (.hdx)" msgid "Fixed-size VHD (.vhd)" -msgstr "VHD de mida fixa (.vhd)" +msgstr "VHD de grandària fixa (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "VHD de mida dinàmica (.vhd)" +msgstr "VHD de grandària dinàmica (.vhd)" msgid "Differencing VHD (.vhd)" msgstr "VHD diferencial (.vhd)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1168,7 +1213,919 @@ msgid "&Auto-pause on focus loss" msgstr "&Pausa automàtica en la pèrdua del focus" msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" +msgstr "Winbox ja no és compatible" 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 behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "El desenvolupament del gerent de Winbox es va aturar el 2022 per falta de mantenidors. A mesura que dirigim els nostres esforços cap a la millora de 86Box, hem pres la decisió de deixar de donar suport a Winbox com a gerent.\n\nNo es proporcionaran més actualitzacions a través de Winbox i és possible que es trobi amb un comportament incorrecte si continueu utilitzant -lo amb versions més recents de 86Box. Qualsevol informe d'errors relacionat amb el comportament de WinBox es tancarà com a no vàlid.\n\nVés a 86box.net per obtenir una llista d’altres gestors que puguis utilitzar." + +msgid "Generate" +msgstr "Generar" + +msgid "Joystick configuration" +msgstr "Configuració del joystick" + +msgid "Device" +msgstr "Dispositiu" + +msgid "%1 (X axis)" +msgstr "%1 (eix X)" + +msgid "%1 (Y axis)" +msgstr "%1 (eix Y)" + +msgid "MCA devices" +msgstr "Dispositius MCA" + +msgid "List of MCA devices:" +msgstr "Lista de dispositius MCA:" + +msgid "Tablet tool" +msgstr "Eina de tauleta" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Quant a Qt" + +msgid "MCA devices..." +msgstr "Dispositius MCA ..." + +msgid "Show non-primary monitors" +msgstr "Mostrar monitors no primaris" + +msgid "Open screenshots folder..." +msgstr "Obrir la carpeta de captures de pantalla ..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Apliqueu el mode d’estirament de pantalla completa en màxima" + +msgid "Cursor/Puck" +msgstr "Cursor/Puck" + +msgid "Pen" +msgstr "Ploma" + +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 "Create..." +msgstr "Crear ..." + +msgid "previous image" +msgstr "imatge anterior" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Unitat CD/DVD d'amfitrió (%1)" + +msgid "Unknown Bus" +msgstr "Bus desconegut" + +msgid "Null Driver" +msgstr "Controlador nul" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Error d'obertura \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Error en recopilar el vertex shader al fitxer \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Error en recopilar el fragment shader al fitxer \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Error en enllaçar el programa de shader al fitxer \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opcions del renderitzador OpenGL 3.0" + +msgid "Render behavior" +msgstr "Comportament del renderitzador" + +msgid "Use target framerate:" +msgstr "Utilitzeu el objectiu de la velocitat:" + +msgid " fps" +msgstr " fotogrames/s" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Feu que cada fotograma sigui immediatament, en sincronització amb la pantalla emulada.</p><p><span style=" font-style:italic;">Aquesta és l’opció recomanada si els shaders en ús no utilitzen FrameTime per a efectes animats.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sincronitzar amb vídeo" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Supressió" + +msgid "No shader selected" +msgstr "Cap shader seleccionat" + +msgid "Browse..." +msgstr "Navegació..." + +msgid "Shader error" +msgstr "Error del shader" + +msgid "Could not load shaders." +msgstr "No has estat possible carregar els shaders." + +msgid "More information in details." +msgstr "Més informació en els detalls." + +msgid "Couldn't create OpenGL context." +msgstr "No has estat possible crear un context d'OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "No has estat possible canviar al context d'OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Es requereix la versió 3.0 o superior d'OpenGL. La versió actual és %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "No has estat possible inicialitzar OpenGL. Error %1." + +msgid "Error initializing OpenGL" +msgstr "Error en inicialitzar OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Tornant al renderitzador software.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "No has estat possible assignar la memòria per a un buffer de desempaquetament.\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>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 "This machine might have been moved or copied." +msgstr "Aquesta màquina podria haver estat moguda o copiada." + +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 "Per tal d’assegurar una funcionalitat adequada de xarxa, 86box ha de saber si aquesta màquina es va moure o copiar.\n\nSeleccioneu \"Ho he copiat\" si no esteu segurs." + +msgid "I Moved It" +msgstr "Ho vaig moure" + +msgid "I Copied It" +msgstr "Ho he copiat" + +msgid "86Box Monitor #" +msgstr "Monitor de 86Box " + +msgid "No MCA devices." +msgstr "No s'han trobat dispositius MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Targeta de xarxa 1" + +msgid "Network Card #2" +msgstr "Targeta de xarxa 2" + +msgid "Network Card #3" +msgstr "Targeta de xarxa 3" + +msgid "Network Card #4" +msgstr "Targeta de xarxa 4" + +msgid "Mode" +msgstr "Mode" + +msgid "Interface" +msgstr "Interfície" + +msgid "Adapter" +msgstr "Adaptador" + +msgid "VDE Socket" +msgstr "Socket de VDE" + +msgid "86Box Unit Tester" +msgstr "Test de la unitat de 86 Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Targeta de clau de Novell Netware 2.x" + +msgid "Serial port passthrough 1" +msgstr "Pas del port sèrie 1" + +msgid "Serial port passthrough 2" +msgstr "Pas del port sèrie 2" + +msgid "Serial port passthrough 3" +msgstr "Pas del port sèrie 3" + +msgid "Serial port passthrough 4" +msgstr "Pas del port sèrie 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Opcions del renderitzador ..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Ratolí bus Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Ratolí bus Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Ratolí sèrie Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Ratolí sèrie Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Ratolí sèrie Logitech" + +msgid "PS/2 Mouse" +msgstr "Ratolí PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (sèrie)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Mòdem estàndard, complint els Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulació de Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulació de Roland MT-32 (nou)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulació de Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulació de Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Placa filla OPL4-ML" + +msgid "System MIDI" +msgstr "MIDI de sistema" + +msgid "MIDI Input Device" +msgstr "Dispositiu d'entrada MIDI" + +msgid "BIOS Address" +msgstr "Adreça de BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Activar les escrits a la ROM extensor de BIOS" + +msgid "Address" +msgstr "Adreça" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revisió de la BIOS" + +msgid "Translate 26 -> 17" +msgstr "Traduir 26 -> 17" + +msgid "Language" +msgstr "Idioma" + +msgid "Enable backlight" +msgstr "Activar la llum posterior" + +msgid "Invert colors" +msgstr "Colors invertits" + +msgid "BIOS size" +msgstr "Grandària de la BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapa C0000-C7FFF com UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapa C8000-CFFFF com UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapa D0000-D7FFF com UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapa D8000-DFFFF com UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapa E0000-E7FFF com UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapa E8000-EFFFF com UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Jumper JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Dispositiu de sortida MIDI" + +msgid "MIDI Real time" +msgstr "MIDI en temps real" + +msgid "MIDI Thru" +msgstr "Pas de l’entrada MIDI" + +msgid "MIDI Clockout" +msgstr "Rellotge MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Guany de sortida" + +msgid "Chorus" +msgstr "Cor" + +msgid "Chorus Voices" +msgstr "Veus de cor" + +msgid "Chorus Level" +msgstr "Nivell de cor" + +msgid "Chorus Speed" +msgstr "Velocitat del cor" + +msgid "Chorus Depth" +msgstr "Profunditat de cor" + +msgid "Chorus Waveform" +msgstr "Forma d'ona del cor" + +msgid "Reverb" +msgstr "Reverberació" + +msgid "Reverb Room Size" +msgstr "Grandària del loc de reveberació" + +msgid "Reverb Damping" +msgstr "Amortiment de reverberació" + +msgid "Reverb Width" +msgstr "Amplada de reverberació" + +msgid "Reverb Level" +msgstr "Nivell de reverberació" + +msgid "Interpolation Method" +msgstr "Mètode d'interpolació" + +msgid "Reverb Output Gain" +msgstr "Guany de sortida de reverberació" + +msgid "Reversed stereo" +msgstr "Estèreo invertit" + +msgid "Nice ramp" +msgstr "Rampa bonica" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Botons" + +msgid "Serial Port" +msgstr "Port sèrie" + +msgid "RTS toggle" +msgstr "Commutació RTS" + +msgid "Revision" +msgstr "Revisió" + +msgid "Controller" +msgstr "Controlador" + +msgid "Show Crosshair" +msgstr "Mostra el cursor de creuers" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Adreça MAC" + +msgid "MAC Address OUI" +msgstr "OUI de adreça MAC" + +msgid "Enable BIOS" +msgstr "Activar BIOS" + +msgid "Baud Rate" +msgstr "Taxa de baud" + +msgid "TCP/IP listening port" +msgstr "Port d'escolta TCP/IP" + +msgid "Phonebook File" +msgstr "Arxiu de la llibreta de telèfon" + +msgid "Telnet emulation" +msgstr "Emulació de telnet" + +msgid "RAM Address" +msgstr "Adreça de RAM" + +msgid "RAM size" +msgstr "Grandària de RAM" + +msgid "Initial RAM size" +msgstr "Grandària inicial de RAMu" + +msgid "Serial Number" +msgstr "Número de sèrie" + +msgid "Host ID" +msgstr "Identificador d'amfitrió" + +msgid "FDC Address" +msgstr "Adreça del FDC" + +msgid "MPU-401 Address" +msgstr "Adreça del MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Rebre l'entrada MIDI" + +msgid "Low DMA" +msgstr "DMA baix" + +msgid "Enable Game port" +msgstr "Activar port de joc" + +msgid "Surround module" +msgstr "Mòdul Surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Activar la interrupció del codec en la configuració del CODEC (necessari per alguns controladors)" + +msgid "SB Address" +msgstr "Adreça de SB" + +msgid "WSS IRQ" +msgstr "IRQ de WSS" + +msgid "WSS DMA" +msgstr "DMA de WSS" + +msgid "Enable OPL" +msgstr "Activar OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Rebre l'entrada MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "DMA baix del SB" + +msgid "6CH variant (6-channel)" +msgstr "Variant de 6Ch (6 canals)" + +msgid "Enable CMS" +msgstr "Activar CMS" + +msgid "Mixer" +msgstr "Mescadora" + +msgid "High DMA" +msgstr "DMA alt" + +msgid "Control PC speaker" +msgstr "Controlar l'altaveu del PC" + +msgid "Memory size" +msgstr "Grandària de memòria" + +msgid "EMU8000 Address" +msgstr "Adreça de EMU8000" + +msgid "IDE Controller" +msgstr "Controlador IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Tipus de GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Activar comanda 0x04 \"Sortir de 86Box\"" + +msgid "Display type" +msgstr "Tipus de pantalla" + +msgid "Composite type" +msgstr "Tipus de pantalla composta" + +msgid "RGB type" +msgstr "Tipus de pantalla RGB" + +msgid "Line doubling type" +msgstr "Tipus de doblatge de línia" + +msgid "Snow emulation" +msgstr "Emulació de neu" + +msgid "Monitor type" +msgstr "Tipus de moitor" + +msgid "Character set" +msgstr "Conjunt de caràcters" + +msgid "XGA type" +msgstr "Tipus de XGA" + +msgid "Instance" +msgstr "Instància" + +msgid "MMIO Address" +msgstr "Adreça de MMIO" + +msgid "RAMDAC type" +msgstr "Tipus de RAMDAC" + +msgid "Blend" +msgstr "Barrejar" + +msgid "Bilinear filtering" +msgstr "Filtratge bilineal" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Activar NMI per a emulació CGA" + +msgid "Voodoo type" +msgstr "Tipus de targeta Voodoo" + +msgid "Framebuffer memory size" +msgstr "Grandària de memòria framebuffer" + +msgid "Texture memory size" +msgstr "Grandària de memòria de textura" + +msgid "Dither subtraction" +msgstr "Sibtracció de dither" + +msgid "Screen Filter" +msgstr "Filtre de pantalla" + +msgid "Render threads" +msgstr "Fils de renderització" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Adreça inicial" + +msgid "Contiguous Size" +msgstr "Grandària contigua" + +msgid "I/O Width" +msgstr "Amplada de E/S" + +msgid "Transfer Speed" +msgstr "Velocitat de transferència" + +msgid "EMS mode" +msgstr "Mode EMS" + +msgid "Address for > 2 MB" +msgstr "Adreça per a > 2 MB" + +msgid "Frame Address" +msgstr "Adreça de marc" + +msgid "USA" +msgstr "Estats Units" + +msgid "Danish" +msgstr "Danès" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusoidal" + +msgid "Triangle" +msgstr "Triangular" + +msgid "Linear" +msgstr "Lineal" + +msgid "4th Order" +msgstr "Del 4t ordre" + +msgid "7th Order" +msgstr "Del 7è ordre" + +msgid "Non-timed (original)" +msgstr "No cronometrat (original)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 no poblat)" + +msgid "Two" +msgstr "Dos" + +msgid "Three" +msgstr "Tres" + +msgid "Wheel" +msgstr "Roda" + +msgid "Five + Wheel" +msgstr "Cinc + roda" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 sèrie / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) sèrie" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Desactivar la BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr " 8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (estèreo)" + +msgid "Classic" +msgstr "Clàssic" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Compost" + +msgid "Old" +msgstr "Vella" + +msgid "New" +msgstr "Nova" + +msgid "Color (generic)" +msgstr "Color (genèric)" + +msgid "Green Monochrome" +msgstr "Moncorom verd" + +msgid "Amber Monochrome" +msgstr "Monocrom ambre" + +msgid "Gray Monochrome" +msgstr "Monocrom gris" + +msgid "Color (no brown)" +msgstr "Color (sense marró)" + +msgid "Color (IBM 5153)" +msgstr "Color (IBM 5153)" + +msgid "Simple doubling" +msgstr "Doble simple" + +msgid "sRGB interpolation" +msgstr "Interpolació sRGB" + +msgid "Linear interpolation" +msgstr "Interpolació lineal" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monocrom (5151/MDA) (blanc)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monocrom (5151/MDA) (verd)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monocrom (5151/MDA) (ambre)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Color 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Color 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Color millorat - mode normal (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Color millorat - mode millorat (5154/ECD)" + +msgid "Green" +msgstr "Verd" + +msgid "Amber" +msgstr "Ambre" + +msgid "Gray" +msgstr "Gris" + +msgid "Color" +msgstr "Color" + +msgid "U.S. English" +msgstr "Anglès dels EUA" + +msgid "Scandinavian" +msgstr "Escandinau" + +msgid "Other languages" +msgstr "Altres idiomes" + +msgid "Bochs latest" +msgstr "Bochs més recent" + +msgid "Mono Non-Interlaced" +msgstr "Monocrom no interlat" + +msgid "Color Interlaced" +msgstr "Color interlat" + +msgid "Color Non-Interlaced" +msgstr "Color no interlat" + +msgid "3Dfx Voodoo Graphics" +msgstr "Gràfics 3dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 unitats TMU)" + +msgid "8-bit" +msgstr "8 bits" + +msgid "16-bit" +msgstr "16 bits" + +msgid "Standard (150ns)" +msgstr "Estàndard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Alta velocitat (120ns)" + +msgid "Enabled" +msgstr "Activada" + +msgid "Standard" +msgstr "Estàndard" + +msgid "High-Speed" +msgstr "Alta velocitat" + +msgid "Stereo LPT DAC" +msgstr "DAC LPT estèreo" + +msgid "Generic Text Printer" +msgstr "Impressora de text genèrica" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Impressora de matriu de punts ESC/P genèrica" + +msgid "Generic PostScript Printer" +msgstr "Impressora PostScript genèrica" + +msgid "Generic PCL5e Printer" +msgstr "Impressora PCL5e genèrica" + +msgid "Parallel Line Internet Protocol" +msgstr "Protocol d'Internet de línia paraŀlela" + +msgid "Protection Dongle for Savage Quest" +msgstr "Dispositiu de protecció per a Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Dispositiu de pas de sèrie" + +msgid "Passthrough Mode" +msgstr "Mode de pas" + +msgid "Host Serial Device" +msgstr "Dispositiu de sèrie amfitrió" + +msgid "Name of pipe" +msgstr "Nom de la canonada" + +msgid "Data bits" +msgstr "Bits de dades" + +msgid "Stop bits" +msgstr "Bits de aturada" + +msgid "Baud Rate of Passthrough" +msgstr "Taxa de baud de pas" + +msgid "Named Pipe (Server)" +msgstr "Pipe anomenat (servidor)" + +msgid "Host Serial Passthrough" +msgstr "Pas del port sèrie amfitrió" + +msgid "Eject %s" +msgstr "Extreure %s" + +msgid "&Unmute" +msgstr "&Saver" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Alt impact en el rendiment" + +msgid "RAM Disk (max. speed)" +msgstr "Disc RAM (velocitat màxima)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Clon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Frabricant" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Expansió de memòria genèrica PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Expansió de memòria genèrica PC/AT" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 84debf20b..cafadd63b 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -390,8 +390,11 @@ msgstr "Dynamický překladač" msgid "Video:" msgstr "Grafika:" -msgid "Voodoo Graphics" -msgstr "Použít grafický akcelerátor Voodoo" +msgid "Video #2:" +msgstr "Grafika 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Použít grafický akcelerátor Voodoo 1 nebo 2" msgid "IBM 8514/A Graphics" msgstr "Grafika IBM 8514/A" @@ -442,7 +445,7 @@ msgid "Use FLOAT32 sound" msgstr "Použít zvuk FLOAT32" msgid "FM synth driver" -msgstr "FM synth driver" +msgstr "Ovladač syntezátoru FM" msgid "Nuked (more accurate)" msgstr "Nuked (přesnější)" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Kritická chyba" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - POZASTAVENO" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Stiskněte Ctrl+Alt+PgDn pro návrat z režimu celé obrazovky." @@ -684,6 +687,12 @@ msgstr "Počítač \"%hs\" není dostupný, jelikož chybí obraz jeho paměti R msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Video adaptér \"%hs\" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce \"roms/video\". Konfigurace se přepne na jiný dostupný adaptér." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Video adaptér 2 \"%hs\" není dostupný, jelikož chybí obraz jeho paměti ROM ve složce \"roms/video\". Druhá grafická karta se zakáže." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Zařízení \"%hs\" není dostupné, jelikož chybí obraz jeho paměti ROM. Zařízení je ignorováno." + msgid "Machine" msgstr "Počítač" @@ -762,17 +771,26 @@ msgstr "Nebyla nalezena žádná PCap zařízení" msgid "Invalid PCap device" msgstr "Neplatné PCap zařízení" -msgid "Standard 2-button joystick(s)" -msgstr "Standardní 2tlačítkový joystick" +msgid "2-axis, 2-button joystick(s)" +msgstr "2osový, 2tlačítkový joystick" -msgid "Standard 4-button joystick" -msgstr "Standardní 4tlačítkový joystick" +msgid "2-axis, 4-button joystick" +msgstr "2osový, 4tlačítkový joystick" -msgid "Standard 6-button joystick" -msgstr "Standardní 6tlačítkový joystick" +msgid "2-axis, 6-button joystick" +msgstr "2osový, 6tlačítkový joystick" -msgid "Standard 8-button joystick" -msgstr "Standardní 8tlačítkový joystick" +msgid "2-axis, 8-button joystick" +msgstr "2osový, 8tlačítkový joystick" + +msgid "3-axis, 2-button joystick" +msgstr "3osový, 2tlačítkový joystick" + +msgid "3-axis, 4-button joystick" +msgstr "3osový, 4tlačítkový joystick" + +msgid "4-axis, 4-button joystick" +msgstr "4osový, 4tlačítkový joystick" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Opravdu chcete ukončit 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Nastala chyba při inicializaci knihovny Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Nastala chyba při inicializaci knihovny GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Obrazy MO" msgid "Welcome to 86Box!" msgstr "Vítejte v programu 86Box!" -msgid "Internal controller" -msgstr "Vestavěný řadič" +msgid "Internal device" +msgstr "Vestavěné zařízení" msgid "Exit" msgstr "Ukončit" @@ -841,7 +862,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 "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." +msgstr "Emulátor starých počítačů\n\nAutoři: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nS předchozími příspěvky od Sarah Walker, leilei, JohnElliott, greatpsycho a dalších.\n\nZveřejněno pod licencí GNU General Public License verze 2 nebo novější. Viz soubor LICENSE pro více informací." msgid "Hardware not available" msgstr "Hardware není dostupný" @@ -855,6 +876,9 @@ msgstr "Neplatná konfigurace" 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 potřeba pro automatický převod PostScript dokumentů do PDF.\n\nJakékoliv dokumenty vytisknuté přes obecnou PostScriptovou tiskárnu budou uloženy jako PostScript (.ps) soubory." +msgid "%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" @@ -874,7 +898,7 @@ msgid "CD-ROM images" msgstr "Obraz CD-ROM disku" msgid "%1 Device Configuration" -msgstr "Konfigurace zařízení %1" +msgstr "Nastavení zařízení %1" msgid "Monitor in sleep mode" msgstr "Monitor je v režimu spánku" @@ -999,6 +1023,27 @@ msgstr "Přepsat" msgid "Don't overwrite" msgstr "Nepřepisovat" +msgid "Raw image" +msgstr "Surový obraz" + +msgid "HDI image" +msgstr "HDI obraz" + +msgid "HDX image" +msgstr "HDX obraz" + +msgid "Fixed-size VHD" +msgstr "VHD s pevnou velikostí" + +msgid "Dynamic-size VHD" +msgstr "VHD s dynamickou velikostí" + +msgid "Differencing VHD" +msgstr "Rozdílový VHD" + +msgid "(N/A)" +msgstr "(Žadné)" + msgid "Raw image (.img)" msgstr "Surový obraz (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBox již není podporován" 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 "Vývoj správce WinBox byl zastaven v roce 2022 z důvodu nedostatku správců. Vzhledem k tomu, že naše úsilí směřujeme k tomu, abychom 86Box ještě vylepšili, rozhodli jsme se WinBox jako správce již nepodporovat.\n\nProstřednictvím WinBoxu nebudou poskytovány žádné další aktualizace a pokud jej budete nadále používat s novějšími verzemi 86Boxu, můžete se setkat s nesprávným chováním. Veškerá hlášení o chybách souvisejících s chováním WinBoxu budou uzavřena jako neplatná.\n\nSeznam dalších správců, které můžete používat, najdete na webu 86box.net." + +msgid "Generate" +msgstr "Vytvoř" + +msgid "Joystick configuration" +msgstr "Konfigurace joysticku" + +msgid "Device" +msgstr "Zařízení" + +msgid "%1 (X axis)" +msgstr "%1 (os X)" + +msgid "%1 (Y axis)" +msgstr "%1 (os Y)" + +msgid "MCA devices" +msgstr "Zařízení MCA" + +msgid "List of MCA devices:" +msgstr "Seznam zařízení MCA:" + +msgid "Tablet tool" +msgstr "Nástroj pro tablety" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "O programu Qt" + +msgid "MCA devices..." +msgstr "Zařízení MCA ..." + +msgid "Show non-primary monitors" +msgstr "Zobrazit neprimární monitory" + +msgid "Open screenshots folder..." +msgstr "Otevři složku screenshots..." + +msgid "Apply 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 "Pen" +msgstr "Pero" + +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 "Create..." +msgstr "Vytvoř..." + +msgid "previous image" +msgstr "předchozí obraz" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Jednotka CD/DVD hostitele (%1)" + +msgid "Unknown Bus" +msgstr "Neznámá sběrnice" + +msgid "Null Driver" +msgstr "Nulový ovladač" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Chyba při otevírání \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Chyba při kompilaci vertex shaderu v souboru \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Chyba při kompilaci fragment shaderu v souboru \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Chyba při linkování shader programu v souboru \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Možnosti vykreslovače OpenGL 3.0" + +msgid "Render behavior" +msgstr "Chování vykreslování" + +msgid "Use target framerate:" +msgstr "Použij cílovou snímkovou frekvenci:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Každý snímek se vykreslí okamžitě, synchronizovaně s emulovaným displejem.</p><p><span style=" font-style:italic;">Tuto možnost doporučujeme, pokud používané shadery nevyužívají frametime pro animované efekty.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Synchronizovat s obrazem" + +msgid "Shaders" +msgstr "Shadery" + +msgid "Remove" +msgstr "Odstraň" + +msgid "No shader selected" +msgstr "Není vybrán žádný shader" + +msgid "Browse..." +msgstr "Prohlížejte..." + +msgid "Shader error" +msgstr "Chyba shaderu" + +msgid "Could not load shaders." +msgstr "Nepodařilo se načíst shadery." + +msgid "More information in details." +msgstr "Více informací v podrobnostech." + +msgid "Couldn't create OpenGL context." +msgstr "Nepodařilo se vytvořit kontext OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Nepodařilo se přepnout na kontext OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Je vyžadována verze OpenGL 3.0 nebo vyšší. Aktuální verze je %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Inicializace OpenGL se nezdařila. Chyba %1." + +msgid "Error initializing OpenGL" +msgstr "Chyba při inicializaci OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Návrat k softwarovému vykreslování.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Alokace paměti pro rozbalovací vyrovnávací paměť se nezdařila.\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 "This machine might have been moved or copied." +msgstr "Tento počítač mohl být přemístěn nebo zkopírován." + +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 "Pro zajištění správné funkce sítě potřebuje 86Box vědět, zda byl tento počítač přesunut nebo zkopírován.\n\nJestliže si nejste jisti, zvolte \"Zkopíroval jsem ho\"." + +msgid "I Moved It" +msgstr "Přesunul jsem ho" + +msgid "I Copied It" +msgstr "Zkopíroval jsem ho" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Žádné zařízení MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Síťová karta 1" + +msgid "Network Card #2" +msgstr "Síťová karta 2" + +msgid "Network Card #3" +msgstr "Síťová karta 3" + +msgid "Network Card #4" +msgstr "Síťová karta 4" + +msgid "Mode" +msgstr "Režim" + +msgid "Interface" +msgstr "Rozhraní" + +msgid "Adapter" +msgstr "Adaptér" + +msgid "VDE Socket" +msgstr "Zásuvka VDE" + +msgid "86Box Unit Tester" +msgstr "86Box Unit Tester" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Klíčová karta Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Průchod sériového portu 1" + +msgid "Serial port passthrough 2" +msgstr "Průchod sériového portu 2" + +msgid "Serial port passthrough 3" +msgstr "Průchod sériového portu 3" + +msgid "Serial port passthrough 4" +msgstr "Průchod sériového portu 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Možnosti vykreslovače..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Sběrnicová myš Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Sběrnicová myš Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Sériová myš Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Sériová myš Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Sériová myš Logitech" + +msgid "PS/2 Mouse" +msgstr "Myš PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (sériová)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Modem kompatibilní se standardem Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulace Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulace Roland MT-32 (nový)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulace Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulace Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Dceřiná deska OPL4-ML" + +msgid "System MIDI" +msgstr "Systémové MIDI" + +msgid "MIDI Input Device" +msgstr "Vstupní zařízení MIDI" + +msgid "BIOS Address" +msgstr "Adresa BIOSu" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Povolení zápisu do rozšiřující paměti ROM systému BIOS" + +msgid "Address" +msgstr "Adresa" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revize BIOSu" + +msgid "Translate 26 -> 17" +msgstr "Přeložit 26 -> 17" + +msgid "Language" +msgstr "Jazyk" + +msgid "Enable backlight" +msgstr "Povolit podsvícení" + +msgid "Invert colors" +msgstr "Invertování barev" + +msgid "BIOS size" +msgstr "Velikost BIOSu" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapovat C0000-C7FFF jako UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapovat C8000-CFFFF jako UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapovat D0000-D7FFF jako UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapovat D8000-DFFFF jako UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapovat E0000-E7FFF jako UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapovat E8000-EFFFF jako UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 propojka (JIM)" + +msgid "MIDI Output Device" +msgstr "Výstupní zařízení MIDI" + +msgid "MIDI Real time" +msgstr "MIDI v reálném čase" + +msgid "MIDI Thru" +msgstr "Průchozí vstupu MIDI" + +msgid "MIDI Clockout" +msgstr "Odbíjení hodin MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Zesílení výstupu" + +msgid "Chorus" +msgstr "Sbor" + +msgid "Chorus Voices" +msgstr "Hlasy sboru" + +msgid "Chorus Level" +msgstr "Úroveň sboru" + +msgid "Chorus Speed" +msgstr "Rychlost sboru" + +msgid "Chorus Depth" +msgstr "Hloubka sboru" + +msgid "Chorus Waveform" +msgstr "Průběh sboru" + +msgid "Reverb" +msgstr "Dozvuk" + +msgid "Reverb Room Size" +msgstr "Velikost místnosti pro dozvuk" + +msgid "Reverb Damping" +msgstr "Tlumení dozvuku" + +msgid "Reverb Width" +msgstr "Šířka dozvuku" + +msgid "Reverb Level" +msgstr "Úroveň dozvuku" + +msgid "Interpolation Method" +msgstr "Metoda interpolace" + +msgid "Reverb Output Gain" +msgstr "Zesílení výstupu dozvuku" + +msgid "Reversed stereo" +msgstr "Obrácené stereo" + +msgid "Nice ramp" +msgstr "Pěkná rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Tlačítka" + +msgid "Serial Port" +msgstr "Sériový port" + +msgid "RTS toggle" +msgstr "Přepínač RTS" + +msgid "Revision" +msgstr "Revize" + +msgid "Controller" +msgstr "Řadič" + +msgid "Show Crosshair" +msgstr "Zobrazení křížového ukazatele" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Adresa MAC" + +msgid "MAC Address OUI" +msgstr "OUI adresy MAC" + +msgid "Enable BIOS" +msgstr "Povolit BIOS" + +msgid "Baud Rate" +msgstr "Přenosová rychlost" + +msgid "TCP/IP listening port" +msgstr "Naslouchací port TCP/IP" + +msgid "Phonebook File" +msgstr "Soubor telefonního seznamu" + +msgid "Telnet emulation" +msgstr "Emulace Telnetu" + +msgid "RAM Address" +msgstr "Adresa RAMu" + +msgid "RAM size" +msgstr "Velikost RAMu" + +msgid "Initial RAM size" +msgstr "Počáteční velikost RAMu" + +msgid "Serial Number" +msgstr "Sériové číslo" + +msgid "Host ID" +msgstr "ID hostitele" + +msgid "FDC Address" +msgstr "Adresa FDCu" + +msgid "MPU-401 Address" +msgstr "Adresa MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Příjem vstupu MIDI" + +msgid "Low DMA" +msgstr "Nízký DMA" + +msgid "Enable Game port" +msgstr "Povolit herní port" + +msgid "Surround module" +msgstr "Modul Surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Vyvolání přerušení CODEC při nastavení CODEC (potřebují některé ovladače)" + +msgid "SB Address" +msgstr "Adresa SB" + +msgid "WSS IRQ" +msgstr "IRQ WSS" + +msgid "WSS DMA" +msgstr "DMA WSS" + +msgid "Enable OPL" +msgstr "Povolit OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Příjem vstupu MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "Nízký DMA SB" + +msgid "6CH variant (6-channel)" +msgstr "Varianta 6CH (6 kanálů)" + +msgid "Enable CMS" +msgstr "Povolit CMS" + +msgid "Mixer" +msgstr "Směšovač" + +msgid "High DMA" +msgstr "Vysoký DMA" + +msgid "Control PC speaker" +msgstr "Ovládát reproduktoru PC" + +msgid "Memory size" +msgstr "Velikost pamĕti" + +msgid "EMU8000 Address" +msgstr "Adresa EMU8000" + +msgid "IDE Controller" +msgstr "Řadič IDE" + +msgid "Codec" +msgstr "Kodek" + +msgid "GUS type" +msgstr "Type GUSu" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Povolit příkaz 0x04 \"Ukončit 86Box\"" + +msgid "Display type" +msgstr "Typ obrazu" + +msgid "Composite type" +msgstr "Typ kompozitního obrazu" + +msgid "RGB type" +msgstr "Typ obrazu RGB" + +msgid "Line doubling type" +msgstr "Typ zdvojení řádku" + +msgid "Snow emulation" +msgstr "Emulace sněhu" + +msgid "Monitor type" +msgstr "Typ monitoru" + +msgid "Character set" +msgstr "Znaková sada" + +msgid "XGA type" +msgstr "Typ XGA" + +msgid "Instance" +msgstr "Instance" + +msgid "MMIO Address" +msgstr "Adresa MMIO" + +msgid "RAMDAC type" +msgstr "Typ RAMDACu" + +msgid "Blend" +msgstr "Směs" + +msgid "Bilinear filtering" +msgstr "Bilineární filtrování" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Povolit NMI pro emulace CGA" + +msgid "Voodoo type" +msgstr "Typ karty Voodoo" + +msgid "Framebuffer memory size" +msgstr "Velikost paměti framebufferu" + +msgid "Texture memory size" +msgstr "Velikost paměti textur" + +msgid "Dither subtraction" +msgstr "Odečítání ditheru" + +msgid "Screen Filter" +msgstr "Filtr obrazovky" + +msgid "Render threads" +msgstr "Vlákna vykreslování" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Počáteční adresa" + +msgid "Contiguous Size" +msgstr "Souvislá velikost" + +msgid "I/O Width" +msgstr "Šířka I/O" + +msgid "Transfer Speed" +msgstr "Rychlost přenosu" + +msgid "EMS mode" +msgstr "Režím EMS" + +msgid "Address for > 2 MB" +msgstr "Adresa pro > 2 MB" + +msgid "Frame Address" +msgstr "Rámcová adresa" + +msgid "USA" +msgstr "Spojené státy" + +msgid "Danish" +msgstr "Dánština" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusový" + +msgid "Triangle" +msgstr "Trojúhelníkový" + +msgid "Linear" +msgstr "Lineární" + +msgid "4th Order" +msgstr "4. řádu" + +msgid "7th Order" +msgstr "7. řádu" + +msgid "Non-timed (original)" +msgstr "Bez časování (originální)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 není vyplněn)" + +msgid "Two" +msgstr "Dvě" + +msgid "Three" +msgstr "Tři" + +msgid "Wheel" +msgstr "Kolečko" + +msgid "Five + Wheel" +msgstr "Pět + kolečko" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 sériová / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) sériová" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Zakázat BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr " 8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klasické" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Kompozitný" + +msgid "Old" +msgstr "Starý" + +msgid "New" +msgstr "Nový" + +msgid "Color (generic)" +msgstr "Barevný (obecný)" + +msgid "Green Monochrome" +msgstr "Zelený monochromatický" + +msgid "Amber Monochrome" +msgstr "Jantarový monochromatický" + +msgid "Gray Monochrome" +msgstr "Šedý monochromatický" + +msgid "Color (no brown)" +msgstr "Barevný (bez hnědé)" + +msgid "Color (IBM 5153)" +msgstr "Barevný (IBM 5153)" + +msgid "Simple doubling" +msgstr "Prosté zdvojení" + +msgid "sRGB interpolation" +msgstr "Interpolace sRGB" + +msgid "Linear interpolation" +msgstr "Lineární interpolace" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monochromatický (5151/MDA) (bílý)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monochromatický (5151/MDA) (zelený)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monochromatický (5151/MDA) (jantarový)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Barevný 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Barevný 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Rozšířený barevný - normální režim (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Rozšířený barevný - rozšířený režim (5154/ECD)" + +msgid "Green" +msgstr "Zelený" + +msgid "Amber" +msgstr "Jantarový" + +msgid "Gray" +msgstr "Šedý" + +msgid "Color" +msgstr "Barevný" + +msgid "U.S. English" +msgstr "Americká angličtina" + +msgid "Scandinavian" +msgstr "Skandinávské" + +msgid "Other languages" +msgstr "Ostatní jazyky" + +msgid "Bochs latest" +msgstr "Bochs nejnovější" + +msgid "Mono Non-Interlaced" +msgstr "Monochromatický bez prokládání" + +msgid "Color Interlaced" +msgstr "Barevný prokládaný" + +msgid "Color Non-Interlaced" +msgstr "Barevný bez prokládání" + +msgid "3Dfx Voodoo Graphics" +msgstr "Grafický akcelerátor 3dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 jednotky TMU)" + +msgid "8-bit" +msgstr "8-bitové" + +msgid "16-bit" +msgstr "16-bitové" + +msgid "Standard (150ns)" +msgstr "Standardní (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Vysokorychlostní (120ns)" + +msgid "Enabled" +msgstr "Zapnuta" + +msgid "Standard" +msgstr "Standardní" + +msgid "High-Speed" +msgstr "Vysokorychlostní" + +msgid "Stereo LPT DAC" +msgstr "Stereofonní převodník LPT" + +msgid "Generic Text Printer" +msgstr "Obecná textová tiskárna" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Obecná jehličková tiskárna ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Obecná tiskárna PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Obecná tiskárna PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Internetový protokol paralelní linky" + +msgid "Protection Dongle for Savage Quest" +msgstr "Ochranný klíč pro Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Zařízení průchodu sériového portu" + +msgid "Passthrough Mode" +msgstr "Režim průchodu" + +msgid "Host Serial Device" +msgstr "Hostitelské sériové zařízení" + +msgid "Name of pipe" +msgstr "Název potrubí" + +msgid "Data bits" +msgstr "Datové bity" + +msgid "Stop bits" +msgstr "Stop bity" + +msgid "Baud Rate of Passthrough" +msgstr "Přenosová rychlost průchodu" + +msgid "Named Pipe (Server)" +msgstr "Pojmenované potrubí (server)" + +msgid "Host Serial Passthrough" +msgstr "Průchod sériového portu hostitele" + +msgid "Eject %s" +msgstr "Vyjmout %s" + +msgid "&Unmute" +msgstr "&Roztišit" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Vysoký dopad na výkon" + +msgid "RAM Disk (max. speed)" +msgstr "Disk RAM (max. rychlost)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Klon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Výrobce" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Obecné rozšíření paměti PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Obecné rozšíření paměti PC/AT" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 70b856aa2..aa666cc48 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -16,7 +16,7 @@ msgid "&Right CTRL is left ALT" msgstr "&Die rechte Strg-Taste ist die Linke Alt-Taste" msgid "&Hard Reset..." -msgstr "&Hard-Reset..." +msgstr "&Kaltstart..." msgid "&Ctrl+Alt+Del\tCtrl+F12" msgstr "&Strg+Alt+Entf\tStrg+F12" @@ -100,10 +100,10 @@ msgid "&8x" msgstr "&8x" msgid "Filter method" -msgstr "Filteringmethode" +msgstr "Filterungsmethode" msgid "&Nearest" -msgstr "&Nächst" +msgstr "&Nächster Nachbar" msgid "&Linear" msgstr "&Linear" @@ -115,10 +115,10 @@ msgid "&Fullscreen\tCtrl+Alt+PgUp" msgstr "&Vollbild\tStrg+Alt+Bild auf" msgid "Fullscreen &stretch mode" -msgstr "&Stretching-Modus im Vollbildmodus" +msgstr "&Vollbild-Skalierungsmodus" msgid "&Full screen stretch" -msgstr "&Vollbild-Stretching" +msgstr "&Vollbild-Streckung" msgid "&4:3" msgstr "&4:3-Seitenverhältnis erzwingen" @@ -169,10 +169,10 @@ msgid "&Average" msgstr "&Durchschnittsmethode" msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" -msgstr "Overscan für CGA/PCjr/Tandy/E&GA/(S)VGA-Displays" +msgstr "Overscan für CGA/PCjr/Tandy/E&GA/(S)VGA-Monitore" msgid "Change contrast for &monochrome display" -msgstr "Kontrast für &monochrome Displays ändern" +msgstr "Kontrast für &monochrome Monitore ändern" msgid "&Media" msgstr "&Medien" @@ -193,7 +193,7 @@ msgid "&Preferences..." msgstr "&Einstellungen..." msgid "Enable &Discord integration" -msgstr "&Discord-Integration aktivieren" +msgstr "&Discord-Integration einschalten" msgid "Sound &gain..." msgstr "&Klangverstärkung..." @@ -214,13 +214,13 @@ msgid "&About 86Box..." msgstr "&Über 86Box..." msgid "&New image..." -msgstr "&Neues Image..." +msgstr "&Neues Abbild..." msgid "&Existing image..." -msgstr "&Bestehendes Image..." +msgstr "&Bestehendes Abbild..." msgid "Existing image (&Write-protected)..." -msgstr "Bestehendes Image (&schreibgeschützt)..." +msgstr "Bestehendes Abbild (&schreibgeschützt)..." msgid "&Record" msgstr "&Aufnehmen" @@ -238,7 +238,7 @@ msgid "E&ject" msgstr "A&uswerfen" msgid "&Image..." -msgstr "&Cartridgeimage..." +msgstr "&Cartridgeabbild..." msgid "E&xport to 86F..." msgstr "&In das 86F-Format e&xportieren..." @@ -250,7 +250,7 @@ msgid "E&mpty" msgstr "L&eer" msgid "&Reload previous image" -msgstr "&Voriges Image neu laden" +msgstr "&Voriges Abbild neu laden" msgid "&Folder..." msgstr "&Verzeichnis..." @@ -292,7 +292,7 @@ msgid "Sound Gain" msgstr "Klangverstärkung" msgid "New Image" -msgstr "Neues Image" +msgstr "Neues Abbild" msgid "Settings" msgstr "Optionen" @@ -325,7 +325,7 @@ msgid "File name:" msgstr "Dateiname:" msgid "Disk size:" -msgstr "Plattengröße:" +msgstr "Datenträgergröße:" msgid "RPM mode:" msgstr "Drehzahlmodus:" @@ -355,7 +355,7 @@ msgid "CPU type:" msgstr "CPU-Typ:" msgid "Speed:" -msgstr "Takt:" +msgstr "Geschwindigkeit:" msgid "Frequency:" msgstr "Frequenz:" @@ -376,13 +376,13 @@ msgid "Time synchronization" msgstr "Zeitsynchronisierung" msgid "Disabled" -msgstr "Deaktiviert" +msgstr "Ausgeschaltet" msgid "Enabled (local time)" -msgstr "Aktiviert (Lokale Uhrzeit)" +msgstr "Eingeschaltet (Lokale Uhrzeit)" msgid "Enabled (UTC)" -msgstr "Aktiviert (UTC)" +msgstr "Eingeschaltet (UTC)" msgid "Dynamic Recompiler" msgstr "Dynamischer Recompiler" @@ -390,8 +390,11 @@ msgstr "Dynamischer Recompiler" msgid "Video:" msgstr "Videokarte:" -msgid "Voodoo Graphics" -msgstr "Voodoo-Grafik" +msgid "Video #2:" +msgstr "Videokarte 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 oder 2 Grafik" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/A-Grafik" @@ -430,13 +433,13 @@ msgid "Sound card #4:" msgstr "Soundkarte 4:" msgid "MIDI Out Device:" -msgstr "MIDI Out-Gerät:" +msgstr "MIDI Ausgabegerät:" msgid "MIDI In Device:" -msgstr "MIDI In-Gerät:" +msgstr "MIDI Eingabegerät:" msgid "Standalone MPU-401" -msgstr "Standalone-MPU-401-Gerät" +msgstr "Eigenständiges-MPU-401-Gerät" msgid "Use FLOAT32 sound" msgstr "FLOAT32-Wiedergabe benutzen" @@ -577,7 +580,7 @@ msgid "Type:" msgstr "Typ:" msgid "Image Format:" -msgstr "Imageformat:" +msgstr "Abbildformat:" msgid "Block Size:" msgstr "Blockgröße:" @@ -637,10 +640,10 @@ msgid "Fatal error" msgstr "Fataler Fehler" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - PAUSIERT" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." -msgstr "Bitte Strg+Alt+Bild ab zur Rückkehr in den Fenstermodus drücken." +msgstr "Strg+Alt+Bild ab, zur Rückkehr in den Fenstermodus." msgid "Speed" msgstr "Geschwindigkeit" @@ -649,7 +652,7 @@ msgid "ZIP %03i %i (%s): %ls" msgstr "ZIP %03i %i (%s): %ls" msgid "ZIP images" -msgstr "ZIP-Images" +msgstr "ZIP-Abbilder" 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." @@ -664,19 +667,19 @@ msgid "Turbo" msgstr "Turbo" msgid "On" -msgstr "An" +msgstr "Ein" msgid "Off" msgstr "Aus" msgid "All images" -msgstr "Alle Images" +msgstr "Alle Abbilder" msgid "Basic sector images" -msgstr "Basissektorimages" +msgstr "Basissektorabbilder" msgid "Surface images" -msgstr "Oberflächenimages" +msgstr "Oberflächenabbilder" msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." msgstr "Das System \"%hs\" ist aufgrund von fehlenden ROMs im Verzeichnis roms/machines nicht verfügbar. Es wird auf ein verfügbares System gewechselt." @@ -684,6 +687,12 @@ msgstr "Das System \"%hs\" ist aufgrund von fehlenden ROMs im Verzeichnis roms/m msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Die Videokarte \"%hs\" ist aufgrund von fehlenden ROMs im Verzeichnis roms/video nicht verfügbar. Es wird auf eine verfügbare Videokarte gewechselt." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Das Gerät \"%hs\" ist aufgrund von fehlenden ROMs nicht verfügbar. Es wird ignoriert." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Die Videokarte 2 \"%hs\" ist aufgrund von fehlenden ROMs im Verzeichnis roms/video nicht verfügbar. Es wird deaktiviert." + msgid "Machine" msgstr "System" @@ -694,13 +703,13 @@ msgid "Input devices" msgstr "Eingabegeräte" msgid "Sound" -msgstr "Multimedia" +msgstr "Sound" msgid "Network" msgstr "Netzwerk" msgid "Ports (COM & LPT)" -msgstr "Anschlüsse (COM & LPT)" +msgstr "Anschlüsse (COM + LPT)" msgid "Storage controllers" msgstr "Speichercontroller" @@ -709,7 +718,7 @@ msgid "Hard disks" msgstr "Festplatten" msgid "Floppy & CD-ROM drives" -msgstr "Disketten- & CD-ROM-Laufwerke" +msgstr "Disketten- + CD-ROM-Laufwerke" msgid "Other removable devices" msgstr "Andere Wechsellaufwerke" @@ -718,13 +727,13 @@ msgid "Other peripherals" msgstr "Andere Peripheriegeräte" msgid "Click to capture mouse" -msgstr "Zum Einfangen des Mauszeigers bitte klicken" +msgstr "Klicken zum Einfangen des Mauszeigers" msgid "Press %1 to release mouse" -msgstr "Bitte %1 zur Mausfreigabe drücken" +msgstr "Drücke %1 zur Mausfreigabe" msgid "Press %1 or middle button to release mouse" -msgstr "Bitte %1 oder die mittlere Maustaste zur Mausfreigabe drücken" +msgstr "Drücke %1 oder die mittlere Maustaste zur Mausfreigabe" msgid "Ctrl+End" msgstr "Strg+Ende" @@ -765,17 +774,26 @@ msgstr "Keine PCap-Geräte gefunden" msgid "Invalid PCap device" msgstr "Ungültiges PCap-Gerät" -msgid "Standard 2-button joystick(s)" -msgstr "Standard 2-Tasten-Joystick(s)" +msgid "2-axis, 2-button joystick(s)" +msgstr "2-Achsen-, 2-Tasten-Joystick(s)" -msgid "Standard 4-button joystick" -msgstr "Standard 4-Tasten-Joystick" +msgid "2-axis, 4-button joystick" +msgstr "2-Achsen-, 4-Tasten-Joystick" -msgid "Standard 6-button joystick" -msgstr "Standard 6-Tasten-Joystick" +msgid "2-axis, 6-button joystick" +msgstr "2-Achsen-, 6-Tasten-Joystick" -msgid "Standard 8-button joystick" -msgstr "Standard 8-Tasten-Joystick" +msgid "2-axis, 8-button joystick" +msgstr "2-Achsen-, 8-Tasten-Joystick" + +msgid "3-axis, 2-button joystick" +msgstr "3-Achsen-, 2-Tasten-Joystick" + +msgid "3-axis, 4-button joystick" +msgstr "3-Achsen-, 4-Tasten-Joystick" + +msgid "4-axis, 4-button joystick" +msgstr "4-Achsen-, 4-Tasten-Joystick" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -796,13 +814,13 @@ msgid "Floppy %i (%s): %ls" msgstr "Diskette %i (%s): %ls" msgid "Advanced sector images" -msgstr "Fortgeschrittene Sektorimages" +msgstr "Fortgeschrittene Sektorabbilder" msgid "Flux images" -msgstr "Fluximages" +msgstr "Fluxabbilder" msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Sind Sie sich sicher, dass Sie einen Hard-Reset für das emulierte System durchführen wollen?" +msgstr "Sind Sie sich sicher, dass Sie einen Kaltstart für das emulierte System durchführen wollen?" msgid "Are you sure you want to exit 86Box?" msgstr "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" @@ -810,17 +828,20 @@ msgstr "Sind Sie sich sicher, dass Sie 86Box beenden wollen?" msgid "Unable to initialize Ghostscript" msgstr "Ghostscript konnte nicht initialisiert werden" +msgid "Unable to initialize GhostPCL" +msgstr "GhostPCL konnte nicht initialisiert werden" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" msgid "MO images" -msgstr "MO-Images" +msgstr "MO-Abbilder" msgid "Welcome to 86Box!" msgstr "Willkommen bei 86Box!" -msgid "Internal controller" -msgstr "Interner Controller" +msgid "Internal device" +msgstr "Interne Gerät" msgid "Exit" msgstr "Beenden" @@ -829,10 +850,10 @@ msgid "No ROMs found" msgstr "Keine ROMs gefunden" msgid "Do you want to save the settings?" -msgstr "Möchten Sie die Einstellungen speichern?" +msgstr "Sollen die Einstellungen gespeichert werden?" msgid "This will hard reset the emulated machine." -msgstr "Dies wird zu einem Hard-Reset des emulierten Systems führen." +msgstr "Dies wird zu einem Kaltstart des emulierten Systems führen." msgid "Save" msgstr "Speichern" @@ -844,19 +865,22 @@ msgid "86Box v" msgstr "86Box Version " msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." +msgstr "Ein Emulator für alte Computer\n\nAutoren: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nMit früheren Kernbeiträgen von Sarah Walker, leilei, JohnElliott, greatpsycho sowie andere.\n\nÜbersetzt von: dob205\n\nVeröffentlicht unter der GNU General Public License in der Version 2 oder neuer. Siehe LICENSE für mehr Informationen." msgid "Hardware not available" -msgstr "Hardware nicht verfügbar" +msgstr "Diese Hardware ist nicht verfügbar" msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." -msgstr "Bitte stellen Sie sicher, dass %1 installiert ist und sie eine %1-kompatible Netzwerkverbindung nutzen." +msgstr "Überprüfe, dass %1 installiert ist, und eine %1-kompatible Netzwerkverbindung genutzt wird." msgid "Invalid configuration" msgstr "Ungültige Konfiguration" 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 wird zur automatischen Konversion von PostScript-Dateien in das PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (.ps)-Dateien gesichert." +msgstr "%1 wird zur automatischen Konvertierung von PostScript-Dateien ins PDF-Format benötigt.\n\nSämtliche an den generischen PostScript-Drucker gesendete Dateien werden als PostScript (*.ps) Dateien gesichert." + +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" @@ -874,7 +898,7 @@ msgid "Don't reset" msgstr "Nicht zurücksetzen" msgid "CD-ROM images" -msgstr "CD-ROM-Images" +msgstr "CD-ROM-Abbilder" msgid "%1 Device Configuration" msgstr "%1-Gerätekonfiguration" @@ -889,10 +913,10 @@ msgid "OpenGL options" msgstr "OpenGL-Optionen" msgid "You are loading an unsupported configuration" -msgstr "Sie laden gerade eine nicht unterstützte Konfiguration" +msgstr "Zur Zeit wird eine nicht unterstützte Konfiguration geladen" 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 "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als \"invalid\" geschlossen werden." +msgstr "Das Filtern der CPU-Typen basierend auf dem ausgewählten System ist für dieses System deaktiviert.\n\nDies ermöglicht es, dass man eine sonst nicht mit dem ausgewählten System inkompatible CPU auswählen kann. Allerdings kann dies zu Inkompatiblilitäten mit dem BIOS des Systems oder anderen Programmen kommen.\n\nDas Aktivieren dieser Einstellung wird nicht unterstützt und sämtliche Bugreports können als \"ungültig\" geschlossen werden." msgid "Continue" msgstr "Fortfahren" @@ -901,19 +925,19 @@ msgid "Cassette: %s" msgstr "Kassette: %s" msgid "Cassette images" -msgstr "Kassettenimages" +msgstr "Kassettenabbilder" msgid "Cartridge %i: %ls" msgstr "Cartridge %i: %ls" msgid "Cartridge images" -msgstr "Cartridgeimages" +msgstr "Cartridgeabbilder" msgid "Error initializing renderer" -msgstr "Fehler bei der Rendererinitialisierung" +msgstr "Fehler bei der Initialisierung des Renderer" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Bitte benutzen Sie einen anderen Renderer." +msgstr "Der OpenGL (3.0-Kern)-Renderer konnte nicht initialisiert werden. Benutze einen anderen Renderer." msgid "Resume execution" msgstr "Fortsetzen" @@ -928,16 +952,16 @@ msgid "Press Ctrl+Alt+Esc" msgstr "Strg+Alt+Esc drücken" msgid "Hard reset" -msgstr "Hard-Reset" +msgstr "Kaltstart" msgid "ACPI shutdown" -msgstr "ACPI-basiertes Herunterfahren" +msgstr "ACPI basiertes Herunterfahren" msgid "Hard disk (%1)" msgstr "Festplatte (%1)" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "MFM/RLL- oder ESDI CD-ROM-Laufwerke hat es niemals gegeben" +msgstr "MFM/RLL- oder ESDI CD-ROM-Laufwerke existieren nicht" msgid "Custom..." msgstr "Angepasst..." @@ -952,13 +976,13 @@ msgid "Add Existing Hard Disk" msgstr "Bestehende Festplatte hinzufügen" msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI-Diskimages können nicht größer als 4 GB groß sein." +msgstr "HDI-Abbilder können nicht größer als 4 GB groß sein." msgid "Disk images cannot be larger than 127 GB." -msgstr "Festplattenimages können nicht größer als 127 GB groß sein." +msgstr "Festplattenabbilder können nicht größer als 127 GB groß sein." msgid "Hard disk images" -msgstr "Festplattenimages" +msgstr "Festplattenabbilder" msgid "Unable to read file" msgstr "Die Datei konnte nicht gelesen werden" @@ -967,34 +991,34 @@ msgid "Unable to write file" msgstr "Die Datei konnte nicht beschrieben werden" msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "HDI- oder HDX-Images mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." +msgstr "HDI- oder HDX-Abbilder mit einer Sektorgröße größer als 512 kB werden nicht unterstützt." msgid "Disk image file already exists" -msgstr "Die Festplattenimagedatei existiert bereits" +msgstr "Das Festplattenabbild existiert bereits" msgid "Please specify a valid file name." -msgstr "Bitte geben Sie einen gültigen Dateinamen ein." +msgstr "Gültiger Dateinamen eingeben." msgid "Disk image created" -msgstr "Disk-Image wurde erstellt" +msgstr "Disk-Abbild wurde erstellt" msgid "Make sure the file exists and is readable." -msgstr "Bitte stellen Sie sicher, dass die Datei existiert und lesbar ist." +msgstr "Stell sicher, dass die Datei existiert und lesbar ist." msgid "Make sure the file is being saved to a writable directory." -msgstr "Bitte stellen Sie sicher, dass die Datei in ein Verzeichnis mit Schreibberechtigungen gespeichert wird." +msgstr "Stell sicher, dass die Datei in ein Verzeichnis mit Schreibberechtigungen gespeichert wird." msgid "Disk image too large" -msgstr "Festplattenimage ist zu groß" +msgstr "Das Festplattenabbild ist zu groß" msgid "Remember to partition and format the newly-created drive." -msgstr "Bitte denken Sie an das Partitionieren und Formatieren des neu erstellten Laufwerks." +msgstr "Stellen Sie sicher, dass das neu erstellte Laufwerk partitioniert und formatiert wird." msgid "The selected file will be overwritten. Are you sure you want to use it?" -msgstr "Die ausgewählte Datei wird überschrieben. Möchten Sie diese Datei nutzen?" +msgstr "Die ausgewählte Datei wird überschrieben. Soll diese Datei genutzen werden?" msgid "Unsupported disk image" -msgstr "Nicht unterstütztes Festplattenimage" +msgstr "Nicht unterstütztes Festplattenabbild" msgid "Overwrite" msgstr "Überschreiben" @@ -1002,14 +1026,35 @@ msgstr "Überschreiben" msgid "Don't overwrite" msgstr "Nicht überschreiben" +msgid "Raw image" +msgstr "Rohdatenabbilder" + +msgid "HDI image" +msgstr "HDI-Abbild" + +msgid "HDX image" +msgstr "HDX-Abbild" + +msgid "Fixed-size VHD" +msgstr "VHD mit fester Größe" + +msgid "Dynamic-size VHD" +msgstr "VHD mit dynamischer Größe" + +msgid "Differencing VHD" +msgstr "Differenzierende VHD" + +msgid "(N/A)" +msgstr "(Kein)" + msgid "Raw image (.img)" -msgstr "Rohdatenimages (.img)" +msgstr "Rohdatenabbild (.img)" msgid "HDI image (.hdi)" -msgstr "HDI-Images (.hdi)" +msgstr "HDI-Abbild (.hdi)" msgid "HDX image (.hdx)" -msgstr "HDX-Images (.hdx)" +msgstr "HDX-Abbild (.hdx)" msgid "Fixed-size VHD (.vhd)" msgstr "VHD mit fester Größe (.vhd)" @@ -1033,7 +1078,7 @@ msgid "Select the parent VHD" msgstr "Eltern-VHD-Datei bitte auswählen" 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 "Dies bedeutet, dass das Elternimage nach der Erstellung des differenzierenden Images erzeugt wurde.\n\nDies kann auch passieren, falls die Image-Dateien verschoben oder kopiert wurden. Ebenso kann auch dies durch einen Bug im Programm, welches das Image erstellt hat, passieren.\n\nMöchten Sie die Zeitstempel korrigieren?" +msgstr "Dies bedeutet, dass das Elternabbild nach der Erstellung des differenzierenden Abbild erzeugt wurde.\n\nDies kann auch passieren, falls die Abbild-Dateien verschoben oder kopiert wurden. Ebenso kann auch dies durch einen Bug im Programm, welches das Abbild erstellt hat, passieren.\n\nSoll der Zeitstempel korrigiert werden?" msgid "Parent and child disk timestamps do not match" msgstr "Die Zeitstempel der Eltern- und der Kindesplatte stimmen nicht überein" @@ -1059,32 +1104,32 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" -msgstr "1,2 MB" +msgstr "1.2 MB" msgid "1.25 MB" -msgstr "1,25 MB" +msgstr "1.25 MB" msgid "1.44 MB" -msgstr "1,44 MB" +msgstr "1.44 MB" msgid "DMF (cluster 1024)" msgstr "DMF (1024 Cluster)" @@ -1093,40 +1138,40 @@ msgid "DMF (cluster 2048)" msgstr "DMF (2048 Cluster)" msgid "2.88 MB" -msgstr "2,88 MB" +msgstr "2.88 MB" msgid "ZIP 100" -msgstr "ZIP 100" +msgstr "ZIP-DRIVE 100" msgid "3.5\" 128 MB (ISO 10090)" -msgstr "3,5-Zoll 128 MB (ISO 10090)" +msgstr "3.5-Zoll 128 MB (ISO 10090)" msgid "3.5\" 230 MB (ISO 13963)" -msgstr "3,5-Zoll 230 MB (ISO 13963)" +msgstr "3.5-Zoll 230 MB (ISO 13963)" msgid "3.5\" 540 MB (ISO 15498)" -msgstr "3,5-Zoll 540 MB (ISO 15498)" +msgstr "3.5-Zoll 540 MB (ISO 15498)" msgid "3.5\" 640 MB (ISO 15498)" -msgstr "3,5-Zoll 640 MB (ISO 15498)" +msgstr "3.5-Zoll 640 MB (ISO 15498)" msgid "3.5\" 1.3 GB (GigaMO)" -msgstr "3,5-Zoll 1,3 GB (GigaMO)" +msgstr "3.5-Zoll 1,3 GB (GigaMO)" msgid "3.5\" 2.3 GB (GigaMO 2)" -msgstr "3,5-Zoll 2,3 GB (GigaMO 2)" +msgstr "3.5-Zoll 2,3 GB (GigaMO 2)" msgid "5.25\" 600 MB" -msgstr "5,25-Zoll 600 MB" +msgstr "5.25-Zoll 600 MB" msgid "5.25\" 650 MB" -msgstr "5,25-Zoll 650 MB" +msgstr "5.25-Zoll 650 MB" msgid "5.25\" 1 GB" msgstr "5,25-Zoll 1 GB" msgid "5.25\" 1.3 GB" -msgstr "5,25-Zoll 1,3 GB" +msgstr "5.25-Zoll 1,3 GB" msgid "Perfect RPM" msgstr "Perfekte Drehzahl" @@ -1135,7 +1180,7 @@ msgid "1% below perfect RPM" msgstr "1% unterhalb der perfekten Drehzahl" msgid "1.5% below perfect RPM" -msgstr "1,5% unterhalb der perfekten Drehzahl" +msgstr "1.5% unterhalb der perfekten Drehzahl" msgid "2% below perfect RPM" msgstr "2% unterhalb der perfekten Drehzahl" @@ -1171,7 +1216,919 @@ msgid "&Auto-pause on focus loss" msgstr "&Auto-Pause bei Fokusverlust" msgid "WinBox is no longer supported" -msgstr "WinBox wird nicht mehr unterstützt" +msgstr "Der WinBox Manager wird nicht mehr unterstützt" 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 "Die Entwicklung des WinBox-Managers wurde im Jahr 2022 eingestellt, da es an Betreuern mangelte. Da wir unsere Bemühungen darauf richten, 86Box noch besser zu machen, haben wir uns entschlossen, WinBox nicht mehr als Manager zu unterstützen.\n\nEs werden keine weiteren Updates für WinBox zur Verfügung gestellt, und es kann zu fehlerhaftem Verhalten kommen, wenn Sie WinBox weiterhin mit neueren Versionen von 86Box verwenden. Alle Fehlerberichte, die sich auf das Verhalten von WinBox beziehen, werden als ungültig geschlossen.\n\nAuf 86box.net finden Sie eine Liste anderer Manager, die Sie verwenden können." +msgstr "Die Entwicklung des WinBox-Managers wurde im Jahr 2022 eingestellt, da es an Betreuern mangelte. Da wir unsere Bemühungen darauf richten, 86Box noch besser zu machen, haben wir uns entschlossen, WinBox nicht mehr als Manager zu unterstützen.\n\nEs werden keine weiteren Updates für WinBox zur Verfügung gestellt, und es kann zu fehlerhaftem Verhalten kommen, wenn WinBox weiterhin mit neueren Versionen von 86Box verwendet wird. Alle Fehlerberichte, die sich auf das Verhalten von WinBox beziehen, werden als ungültig geschlossen.\n\nAuf 86box.net ist eine Liste anderer Manager zu finden, die verwendet werden können." + +msgid "Generate" +msgstr "Erzeugen" + +msgid "Joystick configuration" +msgstr "Joystick-Konfiguration" + +msgid "Device" +msgstr "Gerät" + +msgid "%1 (X axis)" +msgstr "%1 (X-Achse)" + +msgid "%1 (Y axis)" +msgstr "%1 (Y-Achse)" + +msgid "MCA devices" +msgstr "MCA-Geräte" + +msgid "List of MCA devices:" +msgstr "Liste die MCA-Geräte:" + +msgid "Tablet tool" +msgstr "Tablet-Werkzeug" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Über Qt" + +msgid "MCA devices..." +msgstr "MCA-Geräte..." + +msgid "Show non-primary monitors" +msgstr "Nicht-primäre Monitore anzeigen" + +msgid "Open screenshots folder..." +msgstr "Ordner „screenshots“ öffnen..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Vollbild-Streckmodus aktivieren, wenn das Fenster maximiert ist" + +msgid "Cursor/Puck" +msgstr "Mauszeiger/Puck" + +msgid "Pen" +msgstr "Stift" + +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 "Create..." +msgstr "Erstellen..." + +msgid "previous image" +msgstr "Vorheriges Abbild" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Host-CD/DVD-Laufwerk (%1)" + +msgid "Unknown Bus" +msgstr "Unbekannter Bus" + +msgid "Null Driver" +msgstr "Nulltreiber" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Fehler beim Öffnen \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Fehler beim Kompilieren des Vertex-Shaders in der Datei \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Fehler beim Kompilieren des Fragment-Shaders in der Datei \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Fehler beim Linken des Shader-Programms in der Datei \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 Renderer-Optionen" + +msgid "Render behavior" +msgstr "Rendering-Verhalten" + +msgid "Use target framerate:" +msgstr "Zielbildwiederholrate verwenden:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Jedes Bild sofort rendern, synchron mit der emulierten Monitor.</p><p><span style=" font-style:italic;">Dies ist die empfohlene Option, wenn die verwendeten Shader die Bildzeit für animierte Effekte nicht nutzen.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Mit Videoausgabe synchronisieren" + +msgid "Shaders" +msgstr "Shader" + +msgid "Remove" +msgstr "Entfernen" + +msgid "No shader selected" +msgstr "Kein Shader ausgewählt" + +msgid "Browse..." +msgstr "Durchsuchen..." + +msgid "Shader error" +msgstr "Shader-Fehler" + +msgid "Could not load shaders." +msgstr "Shader konnten nicht geladen werden." + +msgid "More information in details." +msgstr "Weitere Informationen im Einzelnen." + +msgid "Couldn't create OpenGL context." +msgstr "OpenGL-Kontext konnte nicht erstellt werden." + +msgid "Couldn't switch to OpenGL context." +msgstr "Konnte nicht in den OpenGL-Kontext wechseln." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "OpenGL-Version 3.0 oder höher ist erforderlich. Die aktuelle Version ist %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL-Initialisierung fehlgeschlagen. Fehler %1." + +msgid "Error initializing OpenGL" +msgstr "Fehler beim Initialisieren von OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Rückgriff auf Software-Rendering.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Nicht genug Speicher zum Entpacken.\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>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 "This machine might have been moved or copied." +msgstr "Dieses System wurde möglicherweise verschoben oder kopiert." + +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 "Um eine ordnungsgemäße Netzwerkfunktionalität zu gewährleisten, muss 86Box wissen, ob dieses System verschoben oder kopiert wurde. \n\nWählen Sie \"Ich habe es kopiert\", wenn Sie sich nicht sicher sind." + +msgid "I Moved It" +msgstr "Ich habe es verschoben" + +msgid "I Copied It" +msgstr "Ich habe es kopiert" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Keine MCA-Geräte." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Netzwerkkarte 1" + +msgid "Network Card #2" +msgstr "Netzwerkkarte 2" + +msgid "Network Card #3" +msgstr "Netzwerkkarte 3" + +msgid "Network Card #4" +msgstr "Netzwerkkarte 4" + +msgid "Mode" +msgstr "Modus" + +msgid "Interface" +msgstr "Schnittstelle" + +msgid "Adapter" +msgstr "Adapter" + +msgid "VDE Socket" +msgstr "VDE Port" + +msgid "86Box Unit Tester" +msgstr "86Box-Gerätetester" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x Schlüsselkarte" + +msgid "Serial port passthrough 1" +msgstr "Durchreichung der Serielle Schnittstelle 1" + +msgid "Serial port passthrough 2" +msgstr "Durchreichung der Serielle Schnittstelle 2" + +msgid "Serial port passthrough 3" +msgstr "Durchreichung der Serielle Schnittstelle 3" + +msgid "Serial port passthrough 4" +msgstr "Durchreichung der Serielle Schnittstelle 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Renderer-Optionen..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft Bus-Maus" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft Bus-Maus (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems Serielle Maus" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft Serielle Maus" + +msgid "Logitech Serial Mouse" +msgstr "Logitech Serielle Maus" + +msgid "PS/2 Mouse" +msgstr "PS/2-Maus" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (Seriell)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Standard Hayes-kompatibles Modem" + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32-Emulation" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32 (Neu)-Emulation" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32L-Emulation" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LN-Emulation" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML-Tochterplatine" + +msgid "System MIDI" +msgstr "System MIDI" + +msgid "MIDI Input Device" +msgstr "MIDI-Eingabegerät" + +msgid "BIOS Address" +msgstr "BIOS-Adresse" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Schreiben in BIOS Erweiterungs ROMs zulassen" + +msgid "Address" +msgstr "Adresse" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS-Revision" + +msgid "Translate 26 -> 17" +msgstr "Übersetzen 26 -> 17" + +msgid "Language" +msgstr "Sprache" + +msgid "Enable backlight" +msgstr "Hintergrundbeleuchtung einschalten" + +msgid "Invert colors" +msgstr "Farben invertieren" + +msgid "BIOS size" +msgstr "BIOS-Größe" + +msgid "Map C0000-C7FFF as UMB" +msgstr "C0000-C7FFF als UMB zuordnen" + +msgid "Map C8000-CFFFF as UMB" +msgstr "C8000-CFFFF als UMB zuordnen" + +msgid "Map D0000-D7FFF as UMB" +msgstr "D0000-D7FFF als UMB zuordnen" + +msgid "Map D8000-DFFFF as UMB" +msgstr "D8000-DFFFF als UMB zuordnen" + +msgid "Map E0000-E7FFF as UMB" +msgstr "E0000-E7FFF als UMB zuordnen" + +msgid "Map E8000-EFFFF as UMB" +msgstr "E8000-EFFFF als UMB zuordnen" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 Steckbrücke (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI-Ausgabegerät" + +msgid "MIDI Real time" +msgstr "MIDI in Echtzeit" + +msgid "MIDI Thru" +msgstr "MIDI-Durchgang" + +msgid "MIDI Clockout" +msgstr "MIDI-Taktausgabe" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Ausgangsverstärkung" + +msgid "Chorus" +msgstr "Chor" + +msgid "Chorus Voices" +msgstr "Chorstimmen" + +msgid "Chorus Level" +msgstr "Chorpegel" + +msgid "Chorus Speed" +msgstr "Chorgeschwindigkeit" + +msgid "Chorus Depth" +msgstr "Chortiefe" + +msgid "Chorus Waveform" +msgstr "Chor-Wellenform" + +msgid "Reverb" +msgstr "Nachhall" + +msgid "Reverb Room Size" +msgstr "Größe des Nachhallraums" + +msgid "Reverb Damping" +msgstr "Nachhalldämpfung" + +msgid "Reverb Width" +msgstr "Nachhall-Breite" + +msgid "Reverb Level" +msgstr "Nachhall-Pegel" + +msgid "Interpolation Method" +msgstr "Interpolationsmethode" + +msgid "Reverb Output Gain" +msgstr "Nachhall-Ausgangsverstärkung" + +msgid "Reversed stereo" +msgstr "Umgekehrtes Stereo" + +msgid "Nice ramp" +msgstr "Schöne Rampe" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Tasten" + +msgid "Serial Port" +msgstr "Serielle Schnittstelle" + +msgid "RTS toggle" +msgstr "RTS-Umschaltung" + +msgid "Revision" +msgstr "Revision" + +msgid "Controller" +msgstr "Controller" + +msgid "Show Crosshair" +msgstr "Fadenkreuz anzeigen" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC-Adresse" + +msgid "MAC Address OUI" +msgstr "OUI der MAC-Adresse" + +msgid "Enable BIOS" +msgstr "BIOS einschalten" + +msgid "Baud Rate" +msgstr "Baudrate" + +msgid "TCP/IP listening port" +msgstr "TCP/IP-Warteport" + +msgid "Phonebook File" +msgstr "Telefonbuch-Datei" + +msgid "Telnet emulation" +msgstr "Telnet-Emulation" + +msgid "RAM Address" +msgstr "RAM-Adresse" + +msgid "RAM size" +msgstr "RAM-Größe" + +msgid "Initial RAM size" +msgstr "Ursprüngliche RAM-Größe" + +msgid "Serial Number" +msgstr "Seriennummer" + +msgid "Host ID" +msgstr "Host-ID" + +msgid "FDC Address" +msgstr "FDC-Adresse" + +msgid "MPU-401 Address" +msgstr "MPU-401-Adresse" + +msgid "MPU-401 IRQ" +msgstr "MPU-401-RQ" + +msgid "Receive MIDI input" +msgstr "MIDI-Eingang empfangen" + +msgid "Low DMA" +msgstr "Niedrige DMA" + +msgid "Enable Game port" +msgstr "Game-Port einschalten" + +msgid "Surround module" +msgstr "Surround-Modul" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "CODEC-Interrupt bei CODEC-Einrichtung auslösen (wird von einigen Treibern benötigt)" + +msgid "SB Address" +msgstr "SB-Adresse" + +msgid "WSS IRQ" +msgstr "WSS-IRQ" + +msgid "WSS DMA" +msgstr "WSS-DMA" + +msgid "Enable OPL" +msgstr "OPL einschalten" + +msgid "Receive MIDI input (MPU-401)" +msgstr "MIDI-Eingang empfangen (MPU-401)" + +msgid "SB low DMA" +msgstr "Niedrige SB-DMA" + +msgid "6CH variant (6-channel)" +msgstr "6CH-Variante (6-Kanal)" + +msgid "Enable CMS" +msgstr "CMS einschalten" + +msgid "Mixer" +msgstr "Mixer" + +msgid "High DMA" +msgstr "Hohe DMA" + +msgid "Control PC speaker" +msgstr "PC-Lautsprecher steuern" + +msgid "Memory size" +msgstr "Speichergröße" + +msgid "EMU8000 Address" +msgstr "EMU8000-Adresse" + +msgid "IDE Controller" +msgstr "IDE-Controller" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "GUS-Typ" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Befehl 0x04 \"86Box beenden\" einschalten" + +msgid "Display type" +msgstr "Anzeigetyp" + +msgid "Composite type" +msgstr "Composite-Anzeigetyp" + +msgid "RGB type" +msgstr "RGB-Anzeigetyp" + +msgid "Line doubling type" +msgstr "Typ der Zeilenverdopplung" + +msgid "Snow emulation" +msgstr "Schnee-Emulation" + +msgid "Monitor type" +msgstr "Monitor-Typ" + +msgid "Character set" +msgstr "Zeichensatz" + +msgid "XGA type" +msgstr "XGA-Typ" + +msgid "Instance" +msgstr "Instanz" + +msgid "MMIO Address" +msgstr "MMIO-Adresse" + +msgid "RAMDAC type" +msgstr "RAMDAC-Typ" + +msgid "Blend" +msgstr "Mischung" + +msgid "Bilinear filtering" +msgstr "Bilineare Filterung" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "NMI für CGA-Emulation einschalten" + +msgid "Voodoo type" +msgstr "Voodoo-typ" + +msgid "Framebuffer memory size" +msgstr "Größe des Framebufferspeichers" + +msgid "Texture memory size" +msgstr "Größe des Texturspeichers" + +msgid "Dither subtraction" +msgstr "Dither-Subtraktion" + +msgid "Screen Filter" +msgstr "Bildschirm-Filter" + +msgid "Render threads" +msgstr "Render-Threads" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Startadresse" + +msgid "Contiguous Size" +msgstr "Zusammenhängende Größe" + +msgid "I/O Width" +msgstr "E/A-Breite" + +msgid "Transfer Speed" +msgstr "Übertragungsgeschwindigkeit" + +msgid "EMS mode" +msgstr "EMS-Modus" + +msgid "Address for > 2 MB" +msgstr "Adresse für > 2 MB" + +msgid "Frame Address" +msgstr "Rahmenadresse" + +msgid "USA" +msgstr "USA" + +msgid "Danish" +msgstr "Dänisch" + +msgid "Always at selected speed" +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 "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "128 kB ab E0000 (MSB der Adresse invertiert, letzte 64KB zuerst)" + +msgid "Sine" +msgstr "Sinus" + +msgid "Triangle" +msgstr "Dreieck" + +msgid "Linear" +msgstr "Lineare" + +msgid "4th Order" +msgstr "4. Ordnung" + +msgid "7th Order" +msgstr "7. Ordnung" + +msgid "Non-timed (original)" +msgstr "Nicht zeitgesteuert (Original)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 nicht bestückt)" + +msgid "Two" +msgstr "Zwei" + +msgid "Three" +msgstr "Drei" + +msgid "Wheel" +msgstr "Rad" + +msgid "Five + Wheel" +msgstr "Fünf + Rad" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 Seriell / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) Seriell" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "BIOS ausschalten" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr " 8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (Stereo)" + +msgid "Classic" +msgstr "Klassisch" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Composite" + +msgid "Old" +msgstr "Alt" + +msgid "New" +msgstr "Neu" + +msgid "Color (generic)" +msgstr "Farbe (generisch)" + +msgid "Green Monochrome" +msgstr "Grünes Monochrom" + +msgid "Amber Monochrome" +msgstr "Bernsteinfarbenes Monochrom" + +msgid "Gray Monochrome" +msgstr "Graues Monochrom" + +msgid "Color (no brown)" +msgstr "Farbe (kein Braun)" + +msgid "Color (IBM 5153)" +msgstr "Farbe (IBM 5153)" + +msgid "Simple doubling" +msgstr "Einfache Verdoppelung" + +msgid "sRGB interpolation" +msgstr "sRGB-Interpolation" + +msgid "Linear interpolation" +msgstr "Lineare Interpolation" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monochrom (5151/MDA) (weiß)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monochrom (5151/MDA) (grün)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monochrom (5151/MDA) (bernsteinfarben)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Farbe 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Farbe 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Erweiterte Farbe - Normaler Modus (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Erweiterte Farbe - Erweiterter Modus (5154/ECD)" + +msgid "Green" +msgstr "Grün" + +msgid "Amber" +msgstr "Bernsteinfarben" + +msgid "Gray" +msgstr "Graues" + +msgid "Color" +msgstr "Farbe" + +msgid "U.S. English" +msgstr "Amerikanisches Englisch" + +msgid "Scandinavian" +msgstr "Skandinavisch" + +msgid "Other languages" +msgstr "Andere Sprachen" + +msgid "Bochs latest" +msgstr "Bochs neueste" + +msgid "Mono Non-Interlaced" +msgstr "Monochrom (Kein Zeilensprungverfahren)" + +msgid "Color Interlaced" +msgstr "Farbe (Mit Zeilensprungverfahren)" + +msgid "Color Non-Interlaced" +msgstr "Farbe (Kein Zeilensprungverfahren)" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx Voodoo Grafik" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMUs)" + +msgid "8-bit" +msgstr "8-Bit" + +msgid "16-bit" +msgstr "16-Bit" + +msgid "Standard (150ns)" +msgstr "Standard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Höchstgeschwindigkeit (120ns)" + +msgid "Enabled" +msgstr "Eingeschaltet" + +msgid "Standard" +msgstr "Standard" + +msgid "High-Speed" +msgstr "Höchstgeschwindigkeit" + +msgid "Stereo LPT DAC" +msgstr "Stereo-LPT-DAC" + +msgid "Generic Text Printer" +msgstr "Generischer Textdrucker" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Allgemeiner ESC/P-Nadel-Drucker" + +msgid "Generic PostScript Printer" +msgstr "Generischer PostScript-Drucker" + +msgid "Generic PCL5e Printer" +msgstr "Generischer PCL5e-Drucker" + +msgid "Parallel Line Internet Protocol" +msgstr "Parallel Line Internet Protokoll" + +msgid "Protection Dongle for Savage Quest" +msgstr "Kopierschutz-Dongle für Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Gerät der Durchreichung der Serielle Schnittstelle" + +msgid "Passthrough Mode" +msgstr "Modus der Durchreichung" + +msgid "Host Serial Device" +msgstr "Host Serielles Gerät" + +msgid "Name of pipe" +msgstr "Name der Pipe" + +msgid "Data bits" +msgstr "Datenbits" + +msgid "Stop bits" +msgstr "Stoppbits" + +msgid "Baud Rate of Passthrough" +msgstr "Baudrate der Durchreichung" + +msgid "Named Pipe (Server)" +msgstr "Benanntes Pipe (Server)" + +msgid "Host Serial Passthrough" +msgstr "Durchreichung der seriellen Schnittstelle des Hosts" + +msgid "Eject %s" +msgstr "Auswerfen %s" + +msgid "&Unmute" +msgstr "&Ton einschalten" + +msgid "Softfloat FPU" +msgstr "Softfloat-FPU" + +msgid "High performance impact" +msgstr "Hohe Auswirkung auf die Leistung" + +msgid "RAM Disk (max. speed)" +msgstr "RAM-Diskette (maximale Geschwindigkeit)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A-Klon (ISA)" + +msgid "Vendor" +msgstr "Hersteller" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Generische PC/XT-Speichererweiterung" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Generische PC/AT-Speichererweiterung" diff --git a/src/qt/languages/en-GB.po b/src/qt/languages/en-GB.po index fa6d1e2c3..bd3a5ba99 100644 --- a/src/qt/languages/en-GB.po +++ b/src/qt/languages/en-GB.po @@ -26,3 +26,48 @@ msgstr "OpenGL (3.0 Core) renderer could not be initialised. Use another rendere 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 "Render behavior" +msgstr "Render behaviour" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilise frametime for animated effects.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Synchronise with video" + +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 "Color (generic)" +msgstr "Colour (generic)" + +msgid "Gray Monochrome" +msgstr "Grey Monochrome" + +msgid "Color (no brown)" +msgstr "Colour (no brown)" + +msgid "Color (IBM 5153)" +msgstr "Colour (IBM 5153)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Colour 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Colour 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Enhanced Colour - Normal Mode (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Enhanced Colour - Enhanced Mode (5154/ECD)" + +msgid "Gray" +msgstr "Grey" + +msgid "Color" +msgstr "Colour" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 21fedd7df..5cac8968f 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -256,7 +256,7 @@ msgid "&Folder..." msgstr "&Carpeta..." msgid "Target &framerate" -msgstr "&Tasa de refresco objetivo" +msgstr "Objetivo de &tasa de refresco" msgid "&Sync with video" msgstr "&Sincronizar con vídeo" @@ -390,14 +390,17 @@ msgstr "Recompilador Dinámico" msgid "Video:" msgstr "Vídeo:" -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" +msgid "Video #2:" +msgstr "Vídeo 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Gráficos Voodoo 1 o 2" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" +msgstr "Gráficos IBM 8514/A" msgid "XGA Graphics" -msgstr "XGA Graphics" +msgstr "Gráficos XGA" msgid "Mouse:" msgstr "Ratón:" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Error fatal" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - EN PAUSA" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Pulsa Ctrl+Alt+PgDn para volver a modo ventana." @@ -684,6 +687,12 @@ msgstr "La máquina \"%hs\" no está disponible debido a ROMs faltantes en el di msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "La tarjeta de vídeo \"%hs\" no está disponible debido a ROMs faltantes en el directorio roms/machines. Cambiando a una tarjeta de vídeo disponible." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "La tarjeta de vídeo 2 \"%hs\" no está disponible debido a ROMs faltantes en el directorio roms/machines. Deshabilitanto la segunda tarjeta de vídeo." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "El dispositivo \"%hs\" no está disponible debido a ROMs faltantes. Ignorando el dispositivo." + msgid "Machine" msgstr "Máquina" @@ -762,17 +771,26 @@ msgstr "No se encontraron dispositivos PCap" msgid "Invalid PCap device" msgstr "Dispositivo PCap inválido" -msgid "Standard 2-button joystick(s)" -msgstr "Mando(s) de 2 botones estándar" +msgid "2-axis, 2-button joystick(s)" +msgstr "Mando(s) de 2 ejes, 2 botones" -msgid "Standard 4-button joystick" -msgstr "Mando de 4 botones estándar" +msgid "2-axis, 4-button joystick" +msgstr "Mando de 2 ejes, 4 botones" -msgid "Standard 6-button joystick" -msgstr "Mando de 6 botones estándar" +msgid "2-axis, 6-button joystick" +msgstr "Mando de 2 ejes, 6 botones" -msgid "Standard 8-button joystick" -msgstr "Mando de 8 botones estándar" +msgid "2-axis, 8-button joystick" +msgstr "Mando de 2 ejes, 8 botones" + +msgid "3-axis, 2-button joystick" +msgstr "Mando de 3 ejes, 2 botones" + +msgid "3-axis, 4-button joystick" +msgstr "Mando de 3 ejes, 4 botones" + +msgid "4-axis, 4-button joystick" +msgstr "Mando de 4 ejes, 4 botones" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "¿Está seguro de que quiere cerrar a 86Box?" msgid "Unable to initialize Ghostscript" msgstr "No fué posible inicializar Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "No fué posible inicializar GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Imágenes de MO" msgid "Welcome to 86Box!" msgstr "¡Bienvenido a 86Box!" -msgid "Internal controller" -msgstr "Controladora interna" +msgid "Internal device" +msgstr "Dispositivo interno" msgid "Exit" msgstr "Salir" @@ -841,7 +862,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 emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." +msgstr "Un emulador de ordenadores antigüos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCon contribuciones anteriores de Sarah Walker, leilei, JohnElliott, greatpsycho y otros.\n\nLiberado bajo la GNU General Public License versión 2 o posterior. Ver LICENSE para más información." msgid "Hardware not available" msgstr "Equipo no disponible" @@ -855,6 +876,9 @@ msgstr "Configuración inválida" 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 es necesaria para la conversión automática de archivos PostScript a PDF.\n\nCualquier documento enviado a la impresora genérica postScript se guardará como archivo PostScript (.ps)." +msgid "%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" @@ -999,6 +1023,27 @@ msgstr "Sobreescribir" msgid "Don't overwrite" msgstr "No sobreescribir" +msgid "Raw image" +msgstr "Imagen plana" + +msgid "HDI image" +msgstr "Imagen HDI" + +msgid "HDX image" +msgstr "Imagen HDX" + +msgid "Fixed-size VHD" +msgstr "VHD de tamaño fijo" + +msgid "Dynamic-size VHD" +msgstr "VHD de tamaño dinámico" + +msgid "Differencing VHD" +msgstr "VHD diferencial" + +msgid "(N/A)" +msgstr "(Ninguno)" + msgid "Raw image (.img)" msgstr "Imagen plana (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,914 @@ 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ř" + +msgid "Joystick configuration" +msgstr "Configuración del mando" + +msgid "Device" +msgstr "Dispositivo" + +msgid "%1 (X axis)" +msgstr "%1 (eje X)" + +msgid "%1 (Y axis)" +msgstr "%1 (eje Y)" + +msgid "MCA devices" +msgstr "Dispositivos MCA" + +msgid "List of MCA devices:" +msgstr "Lista de dispositivos MCA:" + +msgid "Tablet tool" +msgstr "Herramienta de tableta" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Acerca de Qt" + +msgid "MCA devices..." +msgstr "Dispositivos MCA ..." + +msgid "Show non-primary monitors" +msgstr "Mostrar monitores no primarios" + +msgid "Open screenshots folder..." +msgstr "Abrir la carpeta screenshots..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Usar escalado pantalla completa en modalidad maximizada" + +msgid "Cursor/Puck" +msgstr "Cursor/Puck" + +msgid "Pen" +msgstr "Bolígrafo" + +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 "Create..." +msgstr "Crear..." + +msgid "previous image" +msgstr "imagen previa" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Unidad de CD/DVD anfitriona (%1)" + +msgid "Unknown Bus" +msgstr "Bus desconocido" + +msgid "Null Driver" +msgstr "Controlador nulo" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Error al abrir \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Error al compilar el vertex shader en el archivo \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Error al compilar el fragmentshader en el archivo \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Error al enlazar el programa shader en el archivo \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opciones del renderizador OpenGL 3.0" + +msgid "Render behavior" +msgstr "Comportamiento del renderizador" + +msgid "Use target framerate:" +msgstr "Usar objetivo de tasa de refresco:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Renderiza cada fotograma inmediatamente, en sincronía con la pantalla emulada.</p><p><span style=" font-style:italic;">Esta es la opción recomendada si los shaders en uso no utilizan frametime para efectos animados.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sincronizar con los gráficos" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Eliminar" + +msgid "No shader selected" +msgstr "Ningun shader seleccionado" + +msgid "Browse..." +msgstr "Buscar..." + +msgid "Shader error" +msgstr "Error del shader" + +msgid "Could not load shaders." +msgstr "No ha sido posible carregar los shaders." + +msgid "More information in details." +msgstr "Más informaciones en los detalles." + +msgid "Couldn't create OpenGL context." +msgstr "No ha sido posible crear el contexto OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "No ha sido posible cambiar al contexto OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Es requerida la versión 3.0 o más alta de OpenGL. La versión actual es %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "La inicialización de OpenGL no tuvo éxito. Error %1." + +msgid "Error initializing OpenGL" +msgstr "Error al inicializar OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Recurrir al renderizado por software.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "La allocación de memoria para el búfer de desempaquetado no tuvo éxito.\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>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 "This machine might have been moved or copied." +msgstr "Esta máquina puede haber sido movida o copiado." + +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 "Para acertarse de que la funcionalidad de red funcione correctamente, 86Box tiene que saber si esta máquina ha sido movida o copiada.\n\nSi no está seguro, escoge \"La he copiado\"." + +msgid "I Moved It" +msgstr "La he movido" + +msgid "I Copied It" +msgstr "La he copiado" + +msgid "86Box Monitor #" +msgstr "Monitor de 86Box " + +msgid "No MCA devices." +msgstr "No hay dispositovos MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Tarjeta de red 1" + +msgid "Network Card #2" +msgstr "Tarjeta de red 2" + +msgid "Network Card #3" +msgstr "Tarjeta de red 3" + +msgid "Network Card #4" +msgstr "Tarjeta de red 4" + +msgid "Mode" +msgstr "Modalidad" + +msgid "Interface" +msgstr "Interfaz" + +msgid "Adapter" +msgstr "Adaptador" + +msgid "VDE Socket" +msgstr "Toma VDE" + +msgid "86Box Unit Tester" +msgstr "Comprobador de unidad 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Tarjeta de llave Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Paso de puerto serie 1" + +msgid "Serial port passthrough 2" +msgstr "Paso de puerto serie 2" + +msgid "Serial port passthrough 3" +msgstr "Paso de puerto serie 3" + +msgid "Serial port passthrough 4" +msgstr "Paso de puerto serie 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Opciones del renderizador..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Ratón de bus Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Ratón de bus Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Ratón serie Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Ratón serie Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Ratón serie Logitech" + +msgid "PS/2 Mouse" +msgstr "Ratón PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (serie)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Módem estándar compatible con Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulación Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulación Roland MT-32 (nuevo)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulación Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulación Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Placa hija OPL4-ML" + +msgid "System MIDI" +msgstr "MIDI del sistema" + +msgid "MIDI Input Device" +msgstr "Dispositivo de entrada MIDI" + +msgid "BIOS Address" +msgstr "Dirección de BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Habilitar escrituras para el ROM de extensión de BIOS" + +msgid "Address" +msgstr "Dirección" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revisión de BIOS" + +msgid "Translate 26 -> 17" +msgstr "Traducir 26 -> 17" + +msgid "Language" +msgstr "Idioma" + +msgid "Enable backlight" +msgstr "Habilitar retroiluminación" + +msgid "Invert colors" +msgstr "Invertir colores" + +msgid "BIOS size" +msgstr "Tamaño de BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapear a C0000-C7FFF como UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapear a C8000-CFFFF como UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapear a D0000-D7FFF como UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapear a D8000-DFFFF como UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapear a E0000-E7FFF como UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapear a E8000-EFFFF como UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Puente JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Dispositivo de salida MIDI" + +msgid "MIDI Real time" +msgstr "MIDI en tiempo real" + +msgid "MIDI Thru" +msgstr "Atravesar la entrada MIDI" + +msgid "MIDI Clockout" +msgstr "Salida de reloj MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Ganancia de salida" + +msgid "Chorus" +msgstr "Coro" + +msgid "Chorus Voices" +msgstr "Voces del coro" + +msgid "Chorus Level" +msgstr "Nível del coro" + +msgid "Chorus Speed" +msgstr "Velocidad del coro" + +msgid "Chorus Depth" +msgstr "Profundidad del coro" + +msgid "Chorus Waveform" +msgstr "Forma de onda del coro" + +msgid "Reverb" +msgstr "Reverberación" + +msgid "Reverb Room Size" +msgstr "Tamaño del lugar de reverberación" + +msgid "Reverb Damping" +msgstr "Amortiguación de reverberación" + +msgid "Reverb Width" +msgstr "Anchura de reverberación" + +msgid "Reverb Level" +msgstr "Nível de reverberación" + +msgid "Interpolation Method" +msgstr "Método de interpolación" + +msgid "Reverb Output Gain" +msgstr "Ganancia de salida de reverberación" + +msgid "Reversed stereo" +msgstr "Estéreo invertido" + +msgid "Nice ramp" +msgstr "Rama bonita" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Botones" + +msgid "Serial Port" +msgstr "Puerto serie" + +msgid "RTS toggle" +msgstr "Conmutación RTS" + +msgid "Revision" +msgstr "Revisión" + +msgid "Controller" +msgstr "Controlador" + +msgid "Show Crosshair" +msgstr "Mostrar retícula" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Dirección MAC" + +msgid "MAC Address OUI" +msgstr "OUI de dirección MAC" + +msgid "Enable BIOS" +msgstr "Habilitar BIOS" + +msgid "Baud Rate" +msgstr "Tasa de baudios" + +msgid "TCP/IP listening port" +msgstr "Puerto de escucha TCP/IP" + +msgid "Phonebook File" +msgstr "Archivo de agenda telefónica" + +msgid "Telnet emulation" +msgstr "Emulación Telnet" + +msgid "RAM Address" +msgstr "Dirección de RAM" + +msgid "RAM size" +msgstr "Tamaño de RAM" + +msgid "Initial RAM size" +msgstr "Tamaño inicial de RAM" + +msgid "Serial Number" +msgstr "Número de serie" + +msgid "Host ID" +msgstr "ID de anfitrión" + +msgid "FDC Address" +msgstr "Dirección del FDC" + +msgid "MPU-401 Address" +msgstr "Dirección del MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IQ del MPU-401" + +msgid "Receive MIDI input" +msgstr "Recebir entrada MIDI" + +msgid "Low DMA" +msgstr "DMA bajo" + +msgid "Enable Game port" +msgstr "Habilitar puerto de juegos" + +msgid "Surround module" +msgstr "Módulo Surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Activar la interrupción CODEC en la configuración CODEC (necesario para algunos controladores)" + +msgid "SB Address" +msgstr "Dirección del SB" + +msgid "WSS IRQ" +msgstr "IRQ de WSS" + +msgid "WSS DMA" +msgstr "DMA de WSS" + +msgid "Enable OPL" +msgstr "Habilitar OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Recebir entrada MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "DMA bajo del SB" + +msgid "6CH variant (6-channel)" +msgstr "Variante 6CH (6 canales)" + +msgid "Enable CMS" +msgstr "Habilitar CMS" + +msgid "Mixer" +msgstr "Mezclador" + +msgid "High DMA" +msgstr "DMA alto" + +msgid "Control PC speaker" +msgstr "Controlar el altavoz del PC" + +msgid "Memory size" +msgstr "Tamaño de memoria" + +msgid "EMU8000 Address" +msgstr "Dirección de EMU8000" + +msgid "IDE Controller" +msgstr "Controlador IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Tipo de GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Habilitar comando 0x04 \"Salir de 86Box\"" + +msgid "Display type" +msgstr "Tipo de pantalla" + +msgid "Composite type" +msgstr "Tipo de pantalla compuesta" + +msgid "RGB type" +msgstr "Tipo de pantalla RGB" + +msgid "Line doubling type" +msgstr "Tipo de duplicación de línea" + +msgid "Snow emulation" +msgstr "Emulación de nieve" + +msgid "Monitor type" +msgstr "Tipo de monitor" + +msgid "Character set" +msgstr "Conjunto de caracteres" + +msgid "XGA type" +msgstr "Tipo de XGA" + +msgid "Instance" +msgstr "Instancia" + +msgid "MMIO Address" +msgstr "Dirección de MMIO" + +msgid "RAMDAC type" +msgstr "Tipo de RAMDAC" + +msgid "Blend" +msgstr "Mezclar" + +msgid "Bilinear filtering" +msgstr "Filtrado bilineal" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Habilitar NMI para emulación CGA" + +msgid "Voodoo type" +msgstr "Tipo de Voodoo" + +msgid "Framebuffer memory size" +msgstr "Tamaño de memoria del framebuffer" + +msgid "Texture memory size" +msgstr "Tamaño de memoria de textura" + +msgid "Dither subtraction" +msgstr "Sustracción de dither" + +msgid "Screen Filter" +msgstr "Filtro de pantalla" + +msgid "Render threads" +msgstr "Hilos de renderización" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Dirección inicial" + +msgid "Contiguous Size" +msgstr "Tamaño contiguo" + +msgid "I/O Width" +msgstr "Anchura de E/S" + +msgid "Transfer Speed" +msgstr "Velocidad de transferencia" + +msgid "EMS mode" +msgstr "Modo EMS" + +msgid "Address for > 2 MB" +msgstr "Dirección para > 2 MB" + +msgid "Frame Address" +msgstr "Dirección del marco" + +msgid "USA" +msgstr "EE.UU." + +msgid "Danish" +msgstr "Danés" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusoidal" + +msgid "Triangle" +msgstr "Triangular" + +msgid "Linear" +msgstr "Lineal" + +msgid "4th Order" +msgstr "De 4º orden" + +msgid "7th Order" +msgstr "De 7º orden" + +msgid "Non-timed (original)" +msgstr "No cronometrado (original)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 no poblado)" + +msgid "Two" +msgstr "Dos" + +msgid "Three" +msgstr "Tres" + +msgid "Wheel" +msgstr "Rueda" + +msgid "Five + Wheel" +msgstr "Cinco + rueda" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 serie / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) serie" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Deshabilitar BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr " 8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (estéreo)" + +msgid "Classic" +msgstr "Clásico" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Compuesto" + +msgid "Old" +msgstr "Viejo" + +msgid "New" +msgstr "Nuevo" + +msgid "Color (generic)" +msgstr "Color (genérico)" + +msgid "Green Monochrome" +msgstr "Monocromo verde" + +msgid "Amber Monochrome" +msgstr "Monocromo ámbar" + +msgid "Gray Monochrome" +msgstr "Monocromo gris" + +msgid "Color (no brown)" +msgstr "Color (sin marrón)" + +msgid "Color (IBM 5153)" +msgstr "Color (IBM 5153)" + +msgid "Simple doubling" +msgstr "Duplicación simple" + +msgid "sRGB interpolation" +msgstr "Interpolación sRGB" + +msgid "Linear interpolation" +msgstr "Interpolación lineare" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monocromo (5151/MDA) (blanco)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monocromo (5151/MDA) (verde)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monocromo (5151/MDA) (ámbar)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Color 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Color 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Color mejorado - modo normal (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Color mejorado - modo mejorado (5154/ECD)" + +msgid "Green" +msgstr "Verde" + +msgid "Amber" +msgstr "Ámbar" + +msgid "Gray" +msgstr "Gris" + +msgid "Color" +msgstr "Color" + +msgid "U.S. English" +msgstr "Inglés de EE.UU." + +msgid "Scandinavian" +msgstr "Escandinavo" + +msgid "Other languages" +msgstr "Otros idiomas" + +msgid "Bochs latest" +msgstr "Bochs más nuevo" + +msgid "Mono Non-Interlaced" +msgstr "Monocromo no entrelazado" + +msgid "Color Interlaced" +msgstr "Color entrelazado" + +msgid "Color Non-Interlaced" +msgstr "Color no entrelazado" + +msgid "3Dfx Voodoo Graphics" +msgstr "Gráficos 3dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 unidades TMU)" + +msgid "8-bit" +msgstr "8 bitss" + +msgid "16-bit" +msgstr "16 bits" + +msgid "Standard (150ns)" +msgstr "Estándar (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Alta velocidad (120ns)" + +msgid "Enabled" +msgstr "Habilitado" + +msgid "Standard" +msgstr "Estándar" + +msgid "High-Speed" +msgstr "Alta velocidad" + +msgid "Stereo LPT DAC" +msgstr "DAC LPT estéreo" + +msgid "Generic Text Printer" +msgstr "Impresora genérica de texto" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Impresora matricial ESC/P genérica" + +msgid "Generic PostScript Printer" +msgstr "Impresora genérica PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Impresora genérica PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Protocolo de Internet de línea paralela" + +msgid "Protection Dongle for Savage Quest" +msgstr "Dongle de protección para Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Dispositivo de paso de puerto serie" + +msgid "Passthrough Mode" +msgstr "Modo de paso" + +msgid "Host Serial Device" +msgstr "Dispositivo serie anfitrión" + +msgid "Name of pipe" +msgstr "Nombre de tubería" + +msgid "Data bits" +msgstr "Bits de datos" + +msgid "Stop bits" +msgstr "Bits de parada" + +msgid "Baud Rate of Passthrough" +msgstr "Tasa de baudios de paso" + +msgid "Named Pipe (Server)" +msgstr "Tubería con nombre (servidor)" + +msgid "Host Serial Passthrough" +msgstr "Paso del puerto serie del host" + +msgid "Eject %s" +msgstr "Extraer %s" + +msgid "&Unmute" +msgstr "&Reactivar sonido" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Alto impact en el rendimiento" + +msgid "RAM Disk (max. speed)" +msgstr "Disco RAM (velocidad máxima)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Clon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Fabricante" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Expansión de Memoria Generica PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Expansión de Memoria Generica PC/AT" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 829e9870f..21dcfd1bc 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -390,8 +390,11 @@ msgstr "Dynaaminen uudelleenkääntäjä" msgid "Video:" msgstr "Näytönohjain:" -msgid "Voodoo Graphics" -msgstr "Voodoo-grafiikkasuoritin" +msgid "Video #2:" +msgstr "Näytönohjain 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 tai 2-grafiikkasuoritin" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/A-grafiikkasuoritin" @@ -679,10 +682,16 @@ msgid "Surface images" msgstr "Pintalevykuvat" msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." -msgstr "Konetta \"%hs\" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen koneeseen." +msgstr "Konetta \"%hs\" ei voi käyttää, koska roms/machines-hakemistosta puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen koneeseen." 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ää puuttuvien ROM-tiedostojen vuoksi. Vaihdetaan käyttökelpoiseen näytönohjaimeen." +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." +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." +msgstr "Laite \"%hs\" ei voi käyttää puuttuvien ROM-tiedostojen vuoksi. Laitteen huomiotta jättäminen." msgid "Machine" msgstr "Tietokone" @@ -742,7 +751,7 @@ msgid "S" msgstr "S" msgid "KB" -msgstr "kt" +msgstr "Kt" msgid "Could not initialize the video renderer." msgstr "Videorenderöijän alustus epäonnistui" @@ -762,17 +771,26 @@ msgstr "PCap-laitteita ei löytynyt" msgid "Invalid PCap device" msgstr "Virheellinen PCap-laite" -msgid "Standard 2-button joystick(s)" -msgstr "Standardi 2-painikkeinen peliohjain/-ohjaimet" +msgid "2-axis, 2-button joystick(s)" +msgstr "2-akselinen 2-painikkeinen peliohjain/-ohjaimet" -msgid "Standard 4-button joystick" -msgstr "Standardi 4-painikkeinen peliohjain" +msgid "2-axis, 4-button joystick" +msgstr "2-akselinen 4-painikkeinen peliohjain" -msgid "Standard 6-button joystick" -msgstr "Standardi 6-painikkeinen peliohjain" +msgid "2-axis, 6-button joystick" +msgstr "2-akselinen 6-painikkeinen peliohjain" -msgid "Standard 8-button joystick" -msgstr "Standardi 8-painikkeinen peliohjain" +msgid "2-axis, 8-button joystick" +msgstr "2-akselinen 8-painikkeinen peliohjain" + +msgid "3-axis, 2-button joystick" +msgstr "3-akselinen 2-painikkeinen peliohjain" + +msgid "3-axis, 4-button joystick" +msgstr "3-akselinen 4-painikkeinen peliohjain" + +msgid "4-axis, 4-button joystick" +msgstr "4-akselinen 4-painikkeinen peliohjain" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Haluatko varmasti sulkea 86Boxin?" msgid "Unable to initialize Ghostscript" msgstr "Ghostscriptin alustus epäonnistui" +msgid "Unable to initialize GhostPCL" +msgstr "GhostPCLin alustus epäonnistui" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "MO-levykuvat" msgid "Welcome to 86Box!" msgstr "Tervetuloa 86Boxiin!" -msgid "Internal controller" -msgstr "Sisäinen ohjain" +msgid "Internal device" +msgstr "Sisäinen laite" msgid "Exit" msgstr "Poistu" @@ -841,7 +862,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 "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho ja muut.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." +msgstr "Vanhojen tietokoneiden emulaattori\n\nTekijät: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nSarah Walkerin, leilein, JohnElliottin, greatpsychon ja muiden aiemmat keskeiset panokset.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." msgid "Hardware not available" msgstr "Laitteisto ei ole saatavilla" @@ -855,6 +876,9 @@ msgstr "Virheelliset määritykset" 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 vaaditaan PostScript-tiedostojen automaattiseen muuntamiseen PDF-tiedostoiksi.\n\nKaikki geneeriselle PostScript-tulostimelle lähetetyt asiakirjat tallennetaan PostScript (.ps) -tiedostoina." +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" @@ -910,7 +934,7 @@ msgid "Error initializing renderer" msgstr "Virhe renderöijän alustuksessa" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) -renderöijän alustus epäonnistui. Käytä toista renderöijää." +msgstr "OpenGL (3.0 Core)-renderöijän alustus epäonnistui. Käytä toista renderöijää." msgid "Resume execution" msgstr "Jatka suoritusta" @@ -999,6 +1023,27 @@ msgstr "Korvaa" msgid "Don't overwrite" msgstr "Älä korvaa" +msgid "Raw image" +msgstr "Raaka levykuva" + +msgid "HDI image" +msgstr "HDI-levykuva" + +msgid "HDX image" +msgstr "HDX-levykuva" + +msgid "Fixed-size VHD" +msgstr "Kiinteä VHD" + +msgid "Dynamic-size VHD" +msgstr "Dynaaminen VHD" + +msgid "Differencing VHD" +msgstr "Differentiaalinen VHD" + +msgid "(N/A)" +msgstr "(Ei mikään)" + msgid "Raw image (.img)" msgstr "Raaka levykuva (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kt" +msgid "160 KB" +msgstr "160 Kt" -msgid "180 kB" -msgstr "180 kt" +msgid "180 KB" +msgstr "180 Kt" -msgid "320 kB" -msgstr "320 kt" +msgid "320 KB" +msgstr "320 Kt" -msgid "360 kB" -msgstr "360 kt" +msgid "360 KB" +msgstr "360 Kt" -msgid "640 kB" -msgstr "640 kt" +msgid "640 KB" +msgstr "640 Kt" -msgid "720 kB" -msgstr "720 kt" +msgid "720 KB" +msgstr "720 Kt" msgid "1.2 MB" msgstr "1.2 Mt" @@ -1172,3 +1217,915 @@ msgstr "WinBoxia ei enää tueta" 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-managerin kehitys lopetettiin vuonna 2022, koska ylläpitäjiä ei ollut riittävästi. Koska suuntaamme ponnistuksemme 86Boxin parantamiseen entisestään, olemme päättäneet olla enää tukematta WinBoxia managerina.\n\nWinBoxin kautta ei enää toimiteta päivityksiä, ja saatat kohdata virheellistä käyttäytymistä, jos jatkat sen käyttöä 86Boxin uudemmissa versioissa. Kaikki WinBoxin käyttäytymiseen liittyvät vikailmoitukset suljetaan virheellisinä.\n\nSiirry osoitteeseen 86box.net saadaksesi luettelon muista käyttämistäsi hallintaohjelmista." + +msgid "Generate" +msgstr "Luo" + +msgid "Joystick configuration" +msgstr "Peliohjainin kokoonpano" + +msgid "Device" +msgstr "Laite" + +msgid "%1 (X axis)" +msgstr "%1 (X-akseli)" + +msgid "%1 (Y axis)" +msgstr "%1 (Y-akseli)" + +msgid "MCA devices" +msgstr "MCA-laitteet" + +msgid "List of MCA devices:" +msgstr "Luettelo MCA-laitteista:" + +msgid "Tablet tool" +msgstr "Tablettityökalu" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Tietoja Qt:sta" + +msgid "MCA devices..." +msgstr "MCA-laitteet..." + +msgid "Show non-primary monitors" +msgstr "Näytä muut kuin ensisijaiset monitorit" + +msgid "Open screenshots folder..." +msgstr "Avaa kuvakaappaukset-kansio..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Sovelletaan koko näytön venytystilaa maksimoidessa" + +msgid "Cursor/Puck" +msgstr "Kursori/Kiekko" + +msgid "Pen" +msgstr "Kynä" + +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 "Create..." +msgstr "Luo..." + +msgid "previous image" +msgstr "edellinen levykuva" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Isäntä CD/DVD-asema (%1)" + +msgid "Unknown Bus" +msgstr "Tuntematon väylä" + +msgid "Null Driver" +msgstr "Nolla-ajuri" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Virhe \"%1\" avaamisessa: %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Virhe vertex-shaderin kääntämisessä tiedostossa \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Virhe fragmenttivarjostimen kääntämisessä tiedostossa \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Virhe varjostinohjelman linkittämisessä tiedostoon \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0-alustusasetukset" + +msgid "Render behavior" +msgstr "Renderöintikäyttäytyminen" + +msgid "Use target framerate:" +msgstr "Käytä kuvataajuustavoitetta:" + +msgid " fps" +msgstr " ruutua/s" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Renderöi jokainen ruutu välittömästi synkronoidusti emuloidun näytön kanssa.</p><p><span style=" font-style:italic;">Tämä on suositeltava vaihtoehto, jos käytössä olevat varjostimet eivät käytä frametimeä animaatioefekteihin.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Synkronisoi videoon" + +msgid "Shaders" +msgstr "Varjostinohjelmat" + +msgid "Remove" +msgstr "Poista" + +msgid "No shader selected" +msgstr "Ei valittu varjostinohjelmatta" + +msgid "Browse..." +msgstr "Selaa..." + +msgid "Shader error" +msgstr "Varjostinohjelmatvirhe" + +msgid "Could not load shaders." +msgstr "Varjostinohjelmateita ei voitu ladata." + +msgid "More information in details." +msgstr "Lisätietoja yksityiskohtaisesti." + +msgid "Couldn't create OpenGL context." +msgstr "OpenGL-kontekstia ei voitu luoda." + +msgid "Couldn't switch to OpenGL context." +msgstr "Ei voitu siirtyä OpenGL-kontekstiin." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Tarvitaan OpenGL-versio 3.0 tai uudempi. Nykyinen versio on %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL:n alustaminen epäonnistui. Virhe %1." + +msgid "Error initializing OpenGL" +msgstr "Virhe OpenGL:n alustamisessa" + +msgid "Falling back to software rendering.\n" +msgstr "Paluu ohjelmistoalustusöintiin.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Pakkauspuskurin muistin varaaminen epäonnistui.\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>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 "This machine might have been moved or copied." +msgstr "Kone on saatettu siirtää tai kopioida." + +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 "Varmistaakseen asianmukaisen verkkotoiminnon 86Boxin on tiedettävä, onko tämä kone siirretty vai kopioitu.\n\nValitse \"Kopioin sen\", jos et ole varma." + +msgid "I Moved It" +msgstr "Siirsin sen" + +msgid "I Copied It" +msgstr "Kopioin sen" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Ei MCA-laitteita." + +msgid "MiB" +msgstr "Mit" + +msgid "Network Card #1" +msgstr "Verkkokortti 1" + +msgid "Network Card #2" +msgstr "Verkkokortti 2" + +msgid "Network Card #3" +msgstr "Verkkokortti 3" + +msgid "Network Card #4" +msgstr "Verkkokortti 4" + +msgid "Mode" +msgstr "Tila" + +msgid "Interface" +msgstr "Liitäntä" + +msgid "Adapter" +msgstr "Sovitin" + +msgid "VDE Socket" +msgstr "VDE-pistorasia" + +msgid "86Box Unit Tester" +msgstr "86Box Unit Tester" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x -avainkortti" + +msgid "Serial port passthrough 1" +msgstr "Sarjaportin läpivienti 1" + +msgid "Serial port passthrough 2" +msgstr "Sarjaportin läpivienti 2" + +msgid "Serial port passthrough 3" +msgstr "Sarjaportin läpivienti 3" + +msgid "Serial port passthrough 4" +msgstr "Sarjaportin läpivienti 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Alustusasetukset..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft-väylähiiri" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft-väylähiiri (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems-sarjahiiri" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft-sarjahiiri" + +msgid "Logitech Serial Mouse" +msgstr "Logitech-sarjahiiri" + +msgid "PS/2 Mouse" +msgstr "PS/2 hiiri" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (sarja)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Tavallinen Hayes-yhteensopiva modeemi" + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32-emulointi" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32 (uusi)-emulointi" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32L-emulointi" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LN-emulointi" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML-tytärlevy" + +msgid "System MIDI" +msgstr "Järjestelmän MIDI" + +msgid "MIDI Input Device" +msgstr "MIDI-syöttölaite" + +msgid "BIOS Address" +msgstr "BIOS-osoite" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Käytä BIOS-laajennuksen ROM-kirjoitusten" + +msgid "Address" +msgstr "Osoite" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS-tarkistus" + +msgid "Translate 26 -> 17" +msgstr "Käännä 26 -> 17" + +msgid "Language" +msgstr "Kieli" + +msgid "Enable backlight" +msgstr "Käytä taustavalota" + +msgid "Invert colors" +msgstr "Käännä värit" + +msgid "BIOS size" +msgstr "BIOS-koko" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Kartta C0000-C7FFF UMB:nä" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Kartta C8000-CFFFF UMB:nä" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Kartta D0000-D7FFF UMB:nä" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Kartta D8000-DFFFF UMB:nä" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Kartta E0000-E7FFF UMB:nä" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Kartta E8000-EFFFF UMB:nä" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 Jumpperi (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI-lähtölaite" + +msgid "MIDI Real time" +msgstr "MIDI reaaliajassa" + +msgid "MIDI Thru" +msgstr "MIDI-tulon läpivienti" + +msgid "MIDI Clockout" +msgstr "MIDI-kellon ulostulo" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Lähtötaso" + +msgid "Chorus" +msgstr "Kuoro" + +msgid "Chorus Voices" +msgstr "Kuoron äänet" + +msgid "Chorus Level" +msgstr "Kuorotaso" + +msgid "Chorus Speed" +msgstr "Kuronopeus" + +msgid "Chorus Depth" +msgstr "Kuorosyvyys" + +msgid "Chorus Waveform" +msgstr "Kuoroaaltomuoto" + +msgid "Reverb" +msgstr "Jälkikaiunta" + +msgid "Reverb Room Size" +msgstr "Jälkikaiuntahuoneen koko" + +msgid "Reverb Damping" +msgstr "Jälkikaiunta vaimennus" + +msgid "Reverb Width" +msgstr "Jälkikaiunnan leveys" + +msgid "Reverb Level" +msgstr "Jälkikaiunnan taso" + +msgid "Interpolation Method" +msgstr "Interpolointimenetelmä" + +msgid "Reverb Output Gain" +msgstr "Jälkikaiunta lähtötaso" + +msgid "Reversed stereo" +msgstr "Käänteinen stereo" + +msgid "Nice ramp" +msgstr "Hieno ramppi" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Painikkeet" + +msgid "Serial Port" +msgstr "Sarjaportti" + +msgid "RTS toggle" +msgstr "RTS-vaihtokytkin" + +msgid "Revision" +msgstr "Tarkistus" + +msgid "Controller" +msgstr "Ohjain" + +msgid "Show Crosshair" +msgstr "Näytä ristikko" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC-osoite" + +msgid "MAC Address OUI" +msgstr "MAC-osoitteen OUI" + +msgid "Enable BIOS" +msgstr "Käytä BIOS:ta" + +msgid "Baud Rate" +msgstr "Baudinopeus" + +msgid "TCP/IP listening port" +msgstr "TCP/IP-kuunteluportti" + +msgid "Phonebook File" +msgstr "Puhelinluettelotiedosto" + +msgid "Telnet emulation" +msgstr "Telnet-emulointi" + +msgid "RAM Address" +msgstr "RAM-osoite" + +msgid "RAM size" +msgstr "RAM-koko" + +msgid "Initial RAM size" +msgstr "Alkuperäinen RAM-koko" + +msgid "Serial Number" +msgstr "Sarjanumero" + +msgid "Host ID" +msgstr "Isännän ID" + +msgid "FDC Address" +msgstr "FDC-osoite" + +msgid "MPU-401 Address" +msgstr "MPU-401-osoite" + +msgid "MPU-401 IRQ" +msgstr "MPU-401-IRQ" + +msgid "Receive MIDI input" +msgstr "Vastaanota MIDI-tulo" + +msgid "Low DMA" +msgstr "Matala DMA" + +msgid "Enable Game port" +msgstr "Käytä peliporttita" + +msgid "Surround module" +msgstr "Surround-moduuli" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "CODEC-keskeytyksen nostaminen CODEC-asennuksen yhteydessä (jotkut ohjaimet tarvitsevat sitä)" + +msgid "SB Address" +msgstr "SB-osoite" + +msgid "WSS IRQ" +msgstr "WSS-IRQ" + +msgid "WSS DMA" +msgstr "WSS-DMA" + +msgid "Enable OPL" +msgstr "Käytä OPL:ta" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Vastaanota MIDI-tulo (MPU-401)" + +msgid "SB low DMA" +msgstr "Matala SB-DMA" + +msgid "6CH variant (6-channel)" +msgstr "6CH-muunnos (6-kanavainen)" + +msgid "Enable CMS" +msgstr "Käytä CMS:ta" + +msgid "Mixer" +msgstr "Mikseri" + +msgid "High DMA" +msgstr "Korkea DMA" + +msgid "Control PC speaker" +msgstr "Ohjaus PC-kaiutin" + +msgid "Memory size" +msgstr "Muistin koko" + +msgid "EMU8000 Address" +msgstr "EMU8000-osoite" + +msgid "IDE Controller" +msgstr "IDE-ohjain" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "GUS-tyyppi" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Käytä komentota 0x04 \"Poistuminen 86Box\"" + +msgid "Display type" +msgstr "Näytön tyyppi" + +msgid "Composite type" +msgstr "Komposiittityyppi" + +msgid "RGB type" +msgstr "RGB-tyyppi" + +msgid "Line doubling type" +msgstr "Linjan kaksinkertaistamistyyppi" + +msgid "Snow emulation" +msgstr "Lumi-emulointi" + +msgid "Monitor type" +msgstr "Monitorityyppi" + +msgid "Character set" +msgstr "Merkistö" + +msgid "XGA type" +msgstr "XGA-tyyppi" + +msgid "Instance" +msgstr "Instanssi" + +msgid "MMIO Address" +msgstr "MMIO-osoite" + +msgid "RAMDAC type" +msgstr "RAMDAC-tyyppi" + +msgid "Blend" +msgstr "Sekoitus" + +msgid "Bilinear filtering" +msgstr "Bilineaarinen suodatus" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Käytä NMI:ta CGA-emulointia varten" + +msgid "Voodoo type" +msgstr "Voodoo-tyyppi" + +msgid "Framebuffer memory size" +msgstr "Kehyspuskurin muistin koko" + +msgid "Texture memory size" +msgstr "Tekstuurimuistin koko" + +msgid "Dither subtraction" +msgstr "Ditherin vähennys" + +msgid "Screen Filter" +msgstr "Seulasuodatin" + +msgid "Render threads" +msgstr "Renderöintisäikeet" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Aloitusosoite" + +msgid "Contiguous Size" +msgstr "Vierekkäinen koko" + +msgid "I/O Width" +msgstr "I/O-leveys" + +msgid "Transfer Speed" +msgstr "Siirtonopeus" + +msgid "EMS mode" +msgstr "EMS-tila" + +msgid "Address for > 2 MB" +msgstr "Osoite > 2 Mt" + +msgid "Frame Address" +msgstr "Kehyksen osoite" + +msgid "USA" +msgstr "USA" + +msgid "Danish" +msgstr "Tanskalainen" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sini" + +msgid "Triangle" +msgstr "Kolmio" + +msgid "Linear" +msgstr "Lineaarinen" + +msgid "4th Order" +msgstr "4. kertaluvun" + +msgid "7th Order" +msgstr "7. kertaluvun" + +msgid "Non-timed (original)" +msgstr "Ajastamaton (alkuperäinen)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 ei käytössä)" + +msgid "Two" +msgstr "Kaksi" + +msgid "Three" +msgstr "Kolme" + +msgid "Wheel" +msgstr "Pyörä" + +msgid "Five + Wheel" +msgstr "Viisi + pyörä" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 sarja / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) sarja" + +msgid "8 KB" +msgstr "8 Kt" + +msgid "32 KB" +msgstr "32 Kt" + +msgid "16 KB" +msgstr "16 Kt" + +msgid "64 KB" +msgstr "64 Kt" + +msgid "Disable BIOS" +msgstr "BIOS pois käytöstä" + +msgid "512 KB" +msgstr "512 Kt" + +msgid "2 MB" +msgstr "2 Mt" + +msgid "8 MB" +msgstr " 8 Mt" + +msgid "28 MB" +msgstr "28 Mt" + +msgid "1 MB" +msgstr "1 Mt" + +msgid "4 MB" +msgstr "4 Mt" + +msgid "12 MB" +msgstr "12 Mt" + +msgid "16 MB" +msgstr "16 Mt" + +msgid "20 MB" +msgstr "20 Mt" + +msgid "24 MB" +msgstr "24 Mt" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klassinen" + +msgid "256 KB" +msgstr "256 Kt" + +msgid "Composite" +msgstr "Komposiitti" + +msgid "Old" +msgstr "Vanha" + +msgid "New" +msgstr "Uusi" + +msgid "Color (generic)" +msgstr "Väri (yleinen)" + +msgid "Green Monochrome" +msgstr "Vihreä yksivärinen" + +msgid "Amber Monochrome" +msgstr "Keltainen yksivärinen" + +msgid "Gray Monochrome" +msgstr "Harmaa yksivärinen" + +msgid "Color (no brown)" +msgstr "Väri (ei ruskea)" + +msgid "Color (IBM 5153)" +msgstr "Väri (IBM 5153)" + +msgid "Simple doubling" +msgstr "Yksinkertainen kaksinkertaistaminen" + +msgid "sRGB interpolation" +msgstr "sRGB-interpolointi" + +msgid "Linear interpolation" +msgstr "Lineaarinen interpolointi" + +msgid "128 KB" +msgstr "128 Kt" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Yksivärinen (5151/MDA) (valkoinen)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Yksivärinen (5151/MDA) (vihreä)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Yksivärinen (5151/MDA) (keltainen)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Väri 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Väri 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Parannettu väri - Normaali tila (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Parannettu väri - Parannettu tila (5154/ECD)" + +msgid "Green" +msgstr "Vihreä" + +msgid "Amber" +msgstr "Keltainen" + +msgid "Gray" +msgstr "Harmaa" + +msgid "Color" +msgstr "Väri" + +msgid "U.S. English" +msgstr "Yhdysvaltain englanti" + +msgid "Scandinavian" +msgstr "Skandinaavinen" + +msgid "Other languages" +msgstr "Muut kielet" + +msgid "Bochs latest" +msgstr "Bochs uusin" + +msgid "Mono Non-Interlaced" +msgstr "Yksivärinen ei-välitetyt" + +msgid "Color Interlaced" +msgstr "Väri välitetyt" + +msgid "Color Non-Interlaced" +msgstr "Väri ei-välitetyt" + +msgid "3Dfx Voodoo Graphics" +msgstr "3dfx Voodoo-grafiikkasuoritin" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU:ta)" + +msgid "8-bit" +msgstr "8-bittinen" + +msgid "16-bit" +msgstr "16-bittinen" + +msgid "Standard (150ns)" +msgstr "Vakio (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Nopea (120ns)" + +msgid "Enabled" +msgstr "Käytössä" + +msgid "Standard" +msgstr "Vakio" + +msgid "High-Speed" +msgstr "Nopea" + +msgid "Stereo LPT DAC" +msgstr "Stereo-LPT-DAC" + +msgid "Generic Text Printer" +msgstr "Yleinen tekstitulostin" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Yleinen ESC/P pistematriisitulostin" + +msgid "Generic PostScript Printer" +msgstr "Yleinen PostScript-tulostin" + +msgid "Generic PCL5e Printer" +msgstr "Yleinen PCL5e-tulostin" + +msgid "Parallel Line Internet Protocol" +msgstr "Rinnakkaislinjan Internet-protokolla" + +msgid "Protection Dongle for Savage Quest" +msgstr "Savage Questin suojausdongle" + +msgid "Serial Passthrough Device" +msgstr "Sarjaportin läpivientilaite" + +msgid "Passthrough Mode" +msgstr "Läpivientitila" + +msgid "Host Serial Device" +msgstr "Isäntäkoneen sarjalaiten" + +msgid "Name of pipe" +msgstr "Putken nimi" + +msgid "Data bits" +msgstr "Databitit" + +msgid "Stop bits" +msgstr "Pysäytysbitit" + +msgid "Baud Rate of Passthrough" +msgstr "Läpiviennin baudinopeus" + +msgid "Named Pipe (Server)" +msgstr "Nimetty putki (palvelin)" + +msgid "Host Serial Passthrough" +msgstr "Isännän sarjaportin läpivienti" + +msgid "Eject %s" +msgstr "Poista kasettipesästä %s" + +msgid "&Unmute" +msgstr "&Poista mykistys" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Suuri vaikutus suorituskykyyn" + +msgid "RAM Disk (max. speed)" +msgstr "RAM-levy (maksiminopeus)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A-klooni (ISA)" + +msgid "Vendor" +msgstr "Valmistaja" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Yleinen PC/XT-muistilaajennus" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Yleinen PC/AT-muistilaajennus" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index db16abe07..ff8a5168f 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -124,7 +124,7 @@ msgid "&4:3" msgstr "&4:3" msgid "&Square pixels (Keep ratio)" -msgstr "pixels &Carrés(Keep ratio)" +msgstr "Pixels &carrés (Keep ratio)" msgid "&Integer scale" msgstr "Echelle &Entière" @@ -172,7 +172,7 @@ msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgid "Change contrast for &monochrome display" -msgstr "Modifier contraste affichage &monochrome" +msgstr "Modifier contraste affichage &monochrome" msgid "&Media" msgstr "&Media" @@ -390,8 +390,11 @@ msgstr "Recompilateur dynamique" msgid "Video:" msgstr "Vidéo:" -msgid "Voodoo Graphics" -msgstr "Graphique Voodoo" +msgid "Video #2:" +msgstr "Vidéo 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Graphique Voodoo 1 ou 2" msgid "IBM 8514/A Graphics" msgstr "Graphique IBM 8514/A" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Erreur fatale" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - EN PAUSE" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Appuyez sur Ctrl+Alt+PgDn pour revenir au mode fenêtré." @@ -684,6 +687,12 @@ msgstr "La machine \"%hs\" n'est pas disponible en raison de l'absence de ROMs d msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "La carte vidéo \"%hs\" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Basculer vers une carte vidéo disponible." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "La carte vidéo 2 \"%hs\" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Désactiver la deuxième carte vidéo." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Le dispositif \"%hs\" n'est pas disponible en raison de l'absence de ROMs. Ignorer le dispositif." + msgid "Machine" msgstr "Machine" @@ -741,9 +750,6 @@ msgstr "T" msgid "S" msgstr "S" -msgid "MiB" -msgstr "Mio" - msgid "KB" msgstr "Ko" @@ -765,17 +771,26 @@ msgstr "Aucun dispositif PCap trouvé" msgid "Invalid PCap device" msgstr "Dispositif PCap non valide" -msgid "Standard 2-button joystick(s)" -msgstr "Manette(s) standard avec 2 boutons" +msgid "2-axis, 2-button joystick(s)" +msgstr "Manette(s) avec 2 axes, 2 boutons" -msgid "Standard 4-button joystick" -msgstr "Manette standard avec 4 boutons" +msgid "2-axis, 4-button joystick" +msgstr "Manette avec 2 axes, 4 boutons" -msgid "Standard 6-button joystick" -msgstr "Manette standard avec 6 boutons" +msgid "2-axis, 6-button joystick" +msgstr "Manette avec 2 axes, 6 boutons" -msgid "Standard 8-button joystick" -msgstr "Manette standard avec 6 boutons" +msgid "2-axis, 8-button joystick" +msgstr "Manette avec 2 axes, 8 boutons" + +msgid "3-axis, 2-button joystick" +msgstr "Manette avec 3 axes, 2 boutons" + +msgid "3-axis, 4-button joystick" +msgstr "Manette avec 3 axes, 4 boutons" + +msgid "4-axis, 4-button joystick" +msgstr "Manette avec 4 axes, 4 boutons" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -810,6 +825,9 @@ msgstr "Etes-vous sûr de vouloir quitter 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Impossible d'initialiser Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Impossible d'initialiser GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "Magnéto-optique %i (%ls): %ls" @@ -819,8 +837,8 @@ msgstr "Images magnéto-optiques" msgid "Welcome to 86Box!" msgstr "Bienvenue dans 86Box !" -msgid "Internal controller" -msgstr "Côntrolleur interne" +msgid "Internal device" +msgstr "Dispositif interne" msgid "Exit" msgstr "Sortir" @@ -844,7 +862,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\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nLibéré sous la licence GNU General Public License version 2 ou ultérieure. Pour plus d'informations, voir le fichier LICENSE." +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." msgid "Hardware not available" msgstr "Matériel non disponible" @@ -858,6 +876,9 @@ msgstr "Configuration non valide" 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écessair pour la conversion automatique des fichiers PostScript dans PDF.\n\nTous les documents envoyés à l'imprimante générique PostScript seront sauvés comme des fichiers PostScript (.ps)." +msgid "%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écessair pour la conversion automatique des fichiers PCL dans PDF.\n\nTous les documents envoyés à l'imprimante générique PCL seront sauvés comme des fichiers Printer Command Language (.pcl)." + msgid "Entering fullscreen mode" msgstr "Entrer en mode plein écran" @@ -1002,6 +1023,27 @@ msgstr "Écraser" msgid "Don't overwrite" msgstr "Ne pas écraser" +msgid "Raw image" +msgstr "Image brute" + +msgid "HDI image" +msgstr "Image HDI" + +msgid "HDX image" +msgstr "Image HDX" + +msgid "Fixed-size VHD" +msgstr "VHD à taille fixe" + +msgid "Dynamic-size VHD" +msgstr "VHD à taille dynamique" + +msgid "Differencing VHD" +msgstr "VHD à différenciation" + +msgid "(N/A)" +msgstr "(N.D.)" + msgid "Raw image (.img)" msgstr "Image brute (.img)" @@ -1059,22 +1101,22 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" +msgid "160 KB" msgstr "160 Ko" -msgid "180 kB" +msgid "180 KB" msgstr "180 Ko" -msgid "320 kB" +msgid "320 KB" msgstr "320 Ko" -msgid "360 kB" +msgid "360 KB" msgstr "360 Ko" -msgid "640 kB" +msgid "640 KB" msgstr "640 Ko" -msgid "720 kB" +msgid "720 KB" msgstr "720 Ko" msgid "1.2 MB" @@ -1175,3 +1217,915 @@ 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." + +msgid "Generate" +msgstr "Générer" + +msgid "Joystick configuration" +msgstr "Configuration de manette" + +msgid "Device" +msgstr "Dispositif" + +msgid "%1 (X axis)" +msgstr "%1 (axe X)" + +msgid "%1 (Y axis)" +msgstr "%1 (axe Y)" + +msgid "MCA devices" +msgstr "Dispositifs MCA" + +msgid "List of MCA devices:" +msgstr "Liste des dispositifs MCA :" + +msgid "Tablet tool" +msgstr "Nástroj pro tablety" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "O programu Qt" + +msgid "MCA devices..." +msgstr "Dispositifs MCA..." + +msgid "Show non-primary monitors" +msgstr "Afficher les moniteurs non primaires" + +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 "Cursor/Puck" +msgstr "Curseur/Palette" + +msgid "Pen" +msgstr "Stylo" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Lecteur CD/DVD hôte (%1:)" + +msgid "&Connected" +msgstr "&Connecté" + +msgid "Clear image history" +msgstr "Effacer l'historique de l'image" + +msgid "Create..." +msgstr "Créer..." + +msgid "previous image" +msgstr "image précedente" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Lecteur CD/DVD hôte (%1)" + +msgid "Unknown Bus" +msgstr "Bus inconnu" + +msgid "Null Driver" +msgstr "Pilote nul" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Erreur d'ouverture de \"%1\" : %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Erreur de compilation du vertex shader dans le fichier \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Erreur de compilation du fragment shader dans le fichier \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Erreur de liaison du programme shader dans le fichier \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Options de rendu OpenGL 3.0" + +msgid "Render behavior" +msgstr "Comportement de rendu" + +msgid "Use target framerate:" +msgstr "Utiliser le taux de rafraîchissement cible:" + +msgid " fps" +msgstr " mages par seconde" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Rendre chaque image immédiatement, en synchronisation avec l'affichage émulé.</p><p><span style=" font-style:italic;">C'est l'option recommandée si les shaders utilisés n'utilisent pas le frametime pour les effets animés.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Synchronisation avec la vidéo" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Retirer" + +msgid "No shader selected" +msgstr "Pas de shader sélectionné" + +msgid "Browse..." +msgstr "Parcourir..." + +msgid "Shader error" +msgstr "Erreur de shader" + +msgid "Could not load shaders." +msgstr "Impossible de charger les shaders." + +msgid "More information in details." +msgstr "Plus d'informations dans les détails." + +msgid "Couldn't create OpenGL context." +msgstr "Impossible de créer un contexte OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Impossible de passer au contexte OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "La version 3.0 ou supérieure d'OpenGL est requise. La version actuelle est %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "L'initialisation d'OpenGL a échoué. Erreur %1." + +msgid "Error initializing OpenGL" +msgstr "Erreur d'initialisation d'OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Se rabattre sur le rendu logiciel.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "L'allocation de mémoire pour le tampon de décompression a échoué.\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>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 "This machine might have been moved or copied." +msgstr "Cette machine peut avoir été déplacée ou copiée." + +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 "Afin d'assurer le bon fonctionnement du réseau, 86Box doit savoir si cette machine a été déplacée ou copiée.\n\nSélectionnez « Je l'ai copié » si vous n'êtes pas sûr." + +msgid "I Moved It" +msgstr "Je l'ai déplacé" + +msgid "I Copied It" +msgstr "Je l'ai copié" + +msgid "86Box Monitor #" +msgstr "Moniteur 86Box " + +msgid "No MCA devices." +msgstr "Pas de dispositifs MCA." + +msgid "MiB" +msgstr "Mio" + +msgid "Network Card #1" +msgstr "Carte réseau 1" + +msgid "Network Card #2" +msgstr "Carte réseau 2" + +msgid "Network Card #3" +msgstr "Carte réseau 3" + +msgid "Network Card #4" +msgstr "Carte réseau 4" + +msgid "Mode" +msgstr "Mode" + +msgid "Interface" +msgstr "Interface" + +msgid "Adapter" +msgstr "Adaptateur" + +msgid "VDE Socket" +msgstr "Prise VDE" + +msgid "86Box Unit Tester" +msgstr "Testeur d'unité de 86Box" + +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" + +msgid "Serial port passthrough 2" +msgstr "Passage du port série 2" + +msgid "Serial port passthrough 3" +msgstr "Passage du port série 3" + +msgid "Serial port passthrough 4" +msgstr "Passage du port série 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Options de rendu..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Souris bus Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Souris bus Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Souris série Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Souris série Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Souris série Logitech" + +msgid "PS/2 Mouse" +msgstr "Souris PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (série)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Modem standard conforme à la norme Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Émulation Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Émulation Roland MT-32 (nouveau)" + +msgid "Roland CM-32L Emulation" +msgstr "Émulation Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Émulation Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Carte fille OPL4-ML" + +msgid "System MIDI" +msgstr "MIDI de système" + +msgid "MIDI Input Device" +msgstr "Dispositif d'entrée MIDI" + +msgid "BIOS Address" +msgstr "Adresse BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Activer les écritures au ROM d'extension du BIOS" + +msgid "Address" +msgstr "Adresse" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Révision BIOS" + +msgid "Translate 26 -> 17" +msgstr "Traduire 26 -> 17" + +msgid "Language" +msgstr "Language" + +msgid "Enable backlight" +msgstr "Activer le rétro-éclairage" + +msgid "Invert colors" +msgstr "Inversion des couleurs" + +msgid "BIOS size" +msgstr "Taille du BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapper C0000-C7FFF en tant qu'UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapper C8000-CFFFF en tant qu'UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapper D0000-D7FFF en tant qu'UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapper D8000-DFFFF en tant qu'UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapper E0000-E7FFF en tant qu'UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapper E8000-EFFFF en tant qu'UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Cavalier JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Dispositif de sortie MIDI" + +msgid "MIDI Real time" +msgstr "MIDI en temps réel" + +msgid "MIDI Thru" +msgstr "Passage de la entrée MIDI" + +msgid "MIDI Clockout" +msgstr "Horloge MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Gain sortie" + +msgid "Chorus" +msgstr "Chœur" + +msgid "Chorus Voices" +msgstr "Voix de chœur" + +msgid "Chorus Level" +msgstr "Niveau de chœur" + +msgid "Chorus Speed" +msgstr "Vitesse du chœur" + +msgid "Chorus Depth" +msgstr "Profondeur du chœur" + +msgid "Chorus Waveform" +msgstr "Forme d'onde du chœur" + +msgid "Reverb" +msgstr "Réverbération" + +msgid "Reverb Room Size" +msgstr "Taille de la salle de réverbération" + +msgid "Reverb Damping" +msgstr "Amortissement de réverbération" + +msgid "Reverb Width" +msgstr "Largeur de réverbération" + +msgid "Reverb Level" +msgstr "Niveau de réverbération" + +msgid "Interpolation Method" +msgstr "Méthode d'interpolation" + +msgid "Reverb Output Gain" +msgstr "Gain de sortie de réverbération" + +msgid "Reversed stereo" +msgstr "Stéréo inversée" + +msgid "Nice ramp" +msgstr "Belle rampe" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Boutons" + +msgid "Serial Port" +msgstr "Port série" + +msgid "RTS toggle" +msgstr "Basculement RTS" + +msgid "Revision" +msgstr "Révision" + +msgid "Controller" +msgstr "Contrôleur" + +msgid "Show Crosshair" +msgstr "Afficher le réticule" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Adresse MAC" + +msgid "MAC Address OUI" +msgstr "OUI de adresse MAC" + +msgid "Enable BIOS" +msgstr "Activer BIOS" + +msgid "Baud Rate" +msgstr "Taux de bauds" + +msgid "TCP/IP listening port" +msgstr "Port d'écoute TCP/IP" + +msgid "Phonebook File" +msgstr "Fichier de répertoire" + +msgid "Telnet emulation" +msgstr "Émulation de Telnet" + +msgid "RAM Address" +msgstr "Adresse RAM" + +msgid "RAM size" +msgstr "Taille du RAM" + +msgid "Initial RAM size" +msgstr "Taille initiale du RAM" + +msgid "Serial Number" +msgstr "Numéro de série" + +msgid "Host ID" +msgstr "ID de l'hôte" + +msgid "FDC Address" +msgstr "Adresse FDC" + +msgid "MPU-401 Address" +msgstr "Adresse MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Réception de l'entrée MIDI" + +msgid "Low DMA" +msgstr "DMA bas" + +msgid "Enable Game port" +msgstr "Activer le port de jeu" + +msgid "Surround module" +msgstr "Module d'ambiance" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Lever l'interruption CODEC lors de la configuration du CODEC (nécessaire pour certains pilotes)" + +msgid "SB Address" +msgstr "Adresse SB" + +msgid "WSS IRQ" +msgstr "IRQ WSS" + +msgid "WSS DMA" +msgstr "DMA WSS" + +msgid "Enable OPL" +msgstr "Activer OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Réception de l'entrée MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "DMA bas SB" + +msgid "6CH variant (6-channel)" +msgstr "Variante 6CH (6 canaux)" + +msgid "Enable CMS" +msgstr "Activer CMS" + +msgid "Mixer" +msgstr "Mixeur" + +msgid "High DMA" +msgstr "DMA haut" + +msgid "Control PC speaker" +msgstr "Contrôler l'haut-parleur du PC" + +msgid "Memory size" +msgstr "Taille de mémoire" + +msgid "EMU8000 Address" +msgstr "Adresse EMU8000" + +msgid "IDE Controller" +msgstr "Contrôleur IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Type de GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Activer la commande 0x04 « Sortir de 86Box »" + +msgid "Display type" +msgstr "Type d'écran" + +msgid "Composite type" +msgstr "Type de composite" + +msgid "RGB type" +msgstr "Type de RVB" + +msgid "Line doubling type" +msgstr "Type de doublage de ligne" + +msgid "Snow emulation" +msgstr "Émulation de neige" + +msgid "Monitor type" +msgstr "Type de moniteur" + +msgid "Character set" +msgstr "Jeu de caractères" + +msgid "XGA type" +msgstr "Type de XGA" + +msgid "Instance" +msgstr "Instance" + +msgid "MMIO Address" +msgstr "Adresse MMIO" + +msgid "RAMDAC type" +msgstr "Type de RAMDAC" + +msgid "Blend" +msgstr "Mélanger" + +msgid "Bilinear filtering" +msgstr "Filtrage bilinéaire" + +msgid "Dithering" +msgstr "Tramage" + +msgid "Enable NMI for CGA emulation" +msgstr "Activer NMI pour l'émulation CGA" + +msgid "Voodoo type" +msgstr "Type de Voodoo" + +msgid "Framebuffer memory size" +msgstr "Taille de la mémoire du tampon d'images" + +msgid "Texture memory size" +msgstr "Taille de la mémoire des textures" + +msgid "Dither subtraction" +msgstr "Soustraction de tramage" + +msgid "Screen Filter" +msgstr "Filtre d'écran" + +msgid "Render threads" +msgstr "Fils de rendu" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Adresse de départ" + +msgid "Contiguous Size" +msgstr "Taille contiguë" + +msgid "I/O Width" +msgstr "Largeur E/S" + +msgid "Transfer Speed" +msgstr "Vitesse de transfert" + +msgid "EMS mode" +msgstr "Mode EMS" + +msgid "Address for > 2 MB" +msgstr "Adresse pour > 2 MB" + +msgid "Frame Address" +msgstr "Adresse du frame" + +msgid "USA" +msgstr "États-Unis" + +msgid "Danish" +msgstr "Danois" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusoïdale" + +msgid "Triangle" +msgstr "Triangulaire" + +msgid "Linear" +msgstr "Linéaire" + +msgid "4th Order" +msgstr "Du 4e ordre" + +msgid "7th Order" +msgstr "Du 7e ordre" + +msgid "Non-timed (original)" +msgstr "Non temporisé (original)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 non alimenté)" + +msgid "Two" +msgstr "Deux" + +msgid "Three" +msgstr "Trois" + +msgid "Wheel" +msgstr "Molette" + +msgid "Five + Wheel" +msgstr "Cinq + molette" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 série / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) série" + +msgid "8 KB" +msgstr "8 Ko" + +msgid "32 KB" +msgstr "32 Ko" + +msgid "16 KB" +msgstr "16 Ko" + +msgid "64 KB" +msgstr "64 Ko" + +msgid "Disable BIOS" +msgstr "Désactiver BIOS" + +msgid "512 KB" +msgstr "512 Ko" + +msgid "2 MB" +msgstr "2 Mo" + +msgid "8 MB" +msgstr " 8 Mo" + +msgid "28 MB" +msgstr "28 Mo" + +msgid "1 MB" +msgstr "1 Mo" + +msgid "4 MB" +msgstr "4 Mo" + +msgid "12 MB" +msgstr "12 Mo" + +msgid "16 MB" +msgstr "16 Mo" + +msgid "20 MB" +msgstr "20 Mo" + +msgid "24 MB" +msgstr "24 Mo" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stéréo)" + +msgid "Classic" +msgstr "Classique" + +msgid "256 KB" +msgstr "256 Ko" + +msgid "Composite" +msgstr "Composite" + +msgid "Old" +msgstr "Ancien" + +msgid "New" +msgstr "Nouveau" + +msgid "Color (generic)" +msgstr "Couleur (générique)" + +msgid "Green Monochrome" +msgstr "Monochrome vert" + +msgid "Amber Monochrome" +msgstr "Monochrome ambre" + +msgid "Gray Monochrome" +msgstr "Monochrome gris" + +msgid "Color (no brown)" +msgstr "Couleur (sans brun)" + +msgid "Color (IBM 5153)" +msgstr "Couleur (IBM 5153)" + +msgid "Simple doubling" +msgstr "Doublage simple" + +msgid "sRGB interpolation" +msgstr "Interpolation sRVB" + +msgid "Linear interpolation" +msgstr "Interpolation linéairee" + +msgid "128 KB" +msgstr "128 Ko" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monochrome (5151/MDA) (blanc)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monochrome (5151/MDA) (vert)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monochrome (5151/MDA) (ambre)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Couler 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Couleur 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Couleur améliorée - Mode normal (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Couleur améliorée - Mode amélioré (5154/ECD)" + +msgid "Green" +msgstr "Vert" + +msgid "Amber" +msgstr "Ambre" + +msgid "Gray" +msgstr "Gris" + +msgid "Color" +msgstr "Couleur" + +msgid "U.S. English" +msgstr "Anglais des États-Unis" + +msgid "Scandinavian" +msgstr "Scandinave" + +msgid "Other languages" +msgstr "Autres langues" + +msgid "Bochs latest" +msgstr "Bochs dernière" + +msgid "Mono Non-Interlaced" +msgstr "Monochrome non entrelacé" + +msgid "Color Interlaced" +msgstr "Couler entrelacé" + +msgid "Color Non-Interlaced" +msgstr "Couleur non entrelacé" + +msgid "3Dfx Voodoo Graphics" +msgstr "Graphique 3dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 unités TMU)" + +msgid "8-bit" +msgstr "8 bits" + +msgid "16-bit" +msgstr "16 bits" + +msgid "Standard (150ns)" +msgstr "Standard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Haute vitesse (120ns)" + +msgid "Enabled" +msgstr "Activé" + +msgid "Standard" +msgstr "Standard" + +msgid "High-Speed" +msgstr "Haute vitesse" + +msgid "Stereo LPT DAC" +msgstr "Convertisseur numérique stéréo LPT" + +msgid "Generic Text Printer" +msgstr "Imprimante de texte générique" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Imprimant générique ESC/P à matrice à points" + +msgid "Generic PostScript Printer" +msgstr "Imprimante PostScript générique" + +msgid "Generic PCL5e Printer" +msgstr "Imprimante PCL5e générique" + +msgid "Parallel Line Internet Protocol" +msgstr "Protocole Internet à ligne parallèle" + +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" + +msgid "Passthrough Mode" +msgstr "Mode de passage" + +msgid "Host Serial Device" +msgstr "Dispositif sériel de l'hôte" + +msgid "Name of pipe" +msgstr "Nom du tuyau" + +msgid "Data bits" +msgstr "Bits de données" + +msgid "Stop bits" +msgstr "Bits d'arrêt" + +msgid "Baud Rate of Passthrough" +msgstr "Taux de bauds du passage" + +msgid "Named Pipe (Server)" +msgstr "Tuyau nommé (serveur)" + +msgid "Host Serial Passthrough" +msgstr "Passage du port série de l'hôte" + +msgid "Eject %s" +msgstr "Éjecter %s" + +msgid "&Unmute" +msgstr "&Réactiver son" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Impact important sur la performance" + +msgid "RAM Disk (max. speed)" +msgstr "Disque RAM (vitesse maximale)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Clon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Fabricant" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Expansion de la mémoire générique PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Expansion de la mémoire générique PC/AT" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index eb69971b8..9d242f8e0 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -196,7 +196,7 @@ msgid "Enable &Discord integration" msgstr "Omogući integraciju sa programom &Discord" msgid "Sound &gain..." -msgstr "&Pojačanje zvuka..." +msgstr "&Pojačavanje zvuka..." msgid "Begin trace\tCtrl+T" msgstr "Z&apočni praćenje\tCtrl+T" @@ -390,8 +390,11 @@ msgstr "Dinamički rekompilator" msgid "Video:" msgstr "Video:" -msgid "Voodoo Graphics" -msgstr "Voodoo grafika" +msgid "Video #2:" +msgstr "Video 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 ili 2 grafika" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/A grafika" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Fatalna greška" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - ZASTAO" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Pritisnite Ctrl+Alt+PgDn za povratak u prozorski način rada." @@ -684,6 +687,12 @@ msgstr "Sistem \"%hs\" nije dostupan jer ne postoje potrebni ROM-ovi u mapu roms msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Video kartica \"%hs\" nije dostupna jer ne postoje potrebni ROM-ovi u mapu roms/video. Prebacivanje na dostupnu video karticu." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Video kartica 2 \"%hs\" nije dostupna jer ne postoje potrebni ROM-ovi u mapu roms/video. Isključivanje druge video karice." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Uređaj \"%hs\" nije dostupan jer ne postoje potrebni ROM-ovi. Ignoriranje uređaja." + msgid "Machine" msgstr "Sistem" @@ -762,17 +771,26 @@ msgstr "Nema PCap uređaja" msgid "Invalid PCap device" msgstr "Nevažeći PCap uređaj" -msgid "Standard 2-button joystick(s)" -msgstr "Standardna palica za igru s 2 tipke" +msgid "2-axis, 2-button joystick(s)" +msgstr "Palica za igru s 2 osi, 2 tipke" -msgid "Standard 4-button joystick" -msgstr "Standardna palica za igru s 4 tipke" +msgid "2-axis, 4-button joystick" +msgstr "Palica za igru s 2 osi, 4 tipke" -msgid "Standard 6-button joystick" -msgstr "Standardna palica za igru s 6 tipke" +msgid "2-axis, 6-button joystick" +msgstr "Palica za igru s 2 osi, 6 tipke" -msgid "Standard 8-button joystick" -msgstr "Standardna palica za igru s 8 tipke" +msgid "2-axis, 8-button joystick" +msgstr "Palica za igru s 2 osi, 8 tipke" + +msgid "3-axis, 2-button joystick(s)" +msgstr "Palica za igru s 3 osi, 2 tipke" + +msgid "3-axis, 4-button joystick" +msgstr "Palica za igru s 3 osi, 4 tipke" + +msgid "4-axis, 4-button joystick" +msgstr "Palica za igru s 4 osi, 4 tipke" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Jeste li sigurni da želite zatvoriti 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Nije moguće inicijalizirati GhostScript" +msgid "Unable to initialize GhostPCL" +msgstr "Nije moguće inicijalizirati GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "MO slike" msgid "Welcome to 86Box!" msgstr "Dobrodošli u 86Box!" -msgid "Internal controller" -msgstr "Uunutarnji kontroler" +msgid "Internal device" +msgstr "Uunutarnji uređaj" msgid "Exit" msgstr "Izlazi" @@ -841,7 +862,7 @@ msgid "86Box v" msgstr "86Box verzija " msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." -msgstr "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i drugi.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." +msgstr "Emulator starih računala\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nS prethodnim osnovnim doprinosima Sarah Walker, Leilei, JohnElliott, greatpsycho i drugih.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za više informacija pogledajte datoteku LICENCE." msgid "Hardware not available" msgstr "Hardver nije dostupan" @@ -855,6 +876,9 @@ msgstr "Nevažeća 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 potrebno za automatsku konverziju PostScript datoteke u PDF datoteke.\n\nSvi dokumenti poslani na generički PostScript pisač bit će spremljeni kao PostScript (.ps) datoteke." +msgid "%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" @@ -999,6 +1023,27 @@ msgstr "Prepiši" msgid "Don't overwrite" msgstr "Ne prepiši" +msgid "Raw image" +msgstr "Slika neobrađenih podataka" + +msgid "HDI image" +msgstr "HDI slika" + +msgid "HDX image" +msgstr "HDX slika" + +msgid "Fixed-size VHD" +msgstr "VHD fiksne veličine" + +msgid "Dynamic-size VHD" +msgstr "VHD dinamičke veličine" + +msgid "Differencing VHD" +msgstr "Različiti VHD" + +msgid "(N/A)" +msgstr "(Bez)" + msgid "Raw image (.img)" msgstr "Slika neobrađenih podataka (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1,2 MB" @@ -1168,7 +1213,919 @@ msgid "&Auto-pause on focus loss" msgstr "&Automatska pauza pri gubitku fokusa" msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" +msgstr "WinBox seviše ne podržava" 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 behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "Razvoj menadžera WinBox zaustavio se 2022. zbog nedostatka održavača. Dok usmjeravamo svoje napore, da 86Box bude još bolji, odlučili smo se, da više ne podržavmo Winbox kao menadžer.\n\nDaljnja ažuriranja neće bit više osigurana putem WinBox-a i možete naići na pogrešno ponašanje ako ga nastavite koristiti s novijim verzijama 86Box-a. Sva izvješća o pogreškama u vezi s ponašanjem WinBox-a bit će zatvorena kao nevaljana.\n\nZa popis drugih menadžera koje možete koristiti, idite na 86box.net." + +msgid "Generate" +msgstr "Generiraj" + +msgid "Joystick configuration" +msgstr "Konfiguracija palice za igru" + +msgid "Device" +msgstr "Uređaj" + +msgid "%1 (X axis)" +msgstr "%1 (os X)" + +msgid "%1 (Y axis)" +msgstr "%1 (os Y)" + +msgid "MCA devices" +msgstr "Uređaji MCA" + +msgid "List of MCA devices:" +msgstr "Spisak uređaja MCA:" + +msgid "Tablet tool" +msgstr "Alat za tablet" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "O programu Qt" + +msgid "MCA devices..." +msgstr "Uređaji MCA ..." + +msgid "Show non-primary monitors" +msgstr "Prikaži neprimarne monitore" + +msgid "Open screenshots folder..." +msgstr "Otvori mapu snimaka zaslona..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Primijeni način cijelozaslonskog rastezanja u maksimiziranom načinu" + +msgid "Cursor/Puck" +msgstr "Kursor/Pak" + +msgid "Pen" +msgstr "Olovka" + +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 "Create..." +msgstr "Stvori..." + +msgid "previous image" +msgstr "prethodna slika" + +msgid "Host CD/DVD Drive (%1)" +msgstr "CD/DVD pogon nositelja (%1)" + +msgid "Unknown Bus" +msgstr "Nepoznata sabirnica" + +msgid "Null Driver" +msgstr "Nulti upravljački program" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Nije moguće otvoriti \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Nije moguće sastaviti vertex shader u datoteci \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Nije moguće sastaviti framgent shader u datoteci \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Nije moguće povezati program shader u datoteci \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opcije renderera OpenGL 3.0" + +msgid "Render behavior" +msgstr "Ponašanje rendera" + +msgid "Use target framerate:" +msgstr "Koristi ciljni broj okvira u sekundi:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Odmah napravi svaki okvir, sinkronizirano s emuliranim zaslonom.</p><p><span style=" font-style:italic;">Ovo je preporučena opcija, ako korišćeni shader ne koristi vreme okvira za animirane efekte.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sinkroniziraj s videom" + +msgid "Shaders" +msgstr "Shaderi" + +msgid "Remove" +msgstr "Ukloni" + +msgid "No shader selected" +msgstr "Bez odabranog shadera" + +msgid "Browse..." +msgstr "Pregledajte..." + +msgid "Shader error" +msgstr "Greška shadera" + +msgid "Could not load shaders." +msgstr "Nije moguće učitati shadere." + +msgid "More information in details." +msgstr "Više informacija u detaljima." + +msgid "Couldn't create OpenGL context." +msgstr "Nije moguće stvoriti kontekst OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Nije se moguće prebaciti na kontekst OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Potrebna je OpenGL verzija 3.0 ili više. Trenutna verzija je %1. %2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Nije moguće inicijalizirati OpenGL. Greška %1." + +msgid "Error initializing OpenGL" +msgstr "Nije moguće inicijalizirati OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Vraća se na softverski renderer.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Nije moguće idodijeliti memoriju za međuspremnik za raspakiranje.\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>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 "This machine might have been moved or copied." +msgstr "Ovaj je sistem mogao biti premješten ili kopiran." + +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 "Kako bi se osigurala pravilna funkcionalnost mreže, 86Box mora znati, je li ovaj sistem bio premješten ili kopiran.\n\nAko niste sigurni, odaberite \"Kopirao sam ga\"." + +msgid "I Moved It" +msgstr "Premjestio sam ga" + +msgid "I Copied It" +msgstr "Kopirao sam ga" + +msgid "86Box Monitor #" +msgstr "Monitor 86Box-a " + +msgid "No MCA devices." +msgstr "Nema uređaja MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Mrežna kartica 1" + +msgid "Network Card #2" +msgstr "Mrežna kartica 2" + +msgid "Network Card #3" +msgstr "Mrežna kartica 3" + +msgid "Network Card #4" +msgstr "Mrežna kartica 4" + +msgid "Mode" +msgstr "Način" + +msgid "Interface" +msgstr "Sučelje" + +msgid "Adapter" +msgstr "Adapter" + +msgid "VDE Socket" +msgstr "VDE utičnica" + +msgid "86Box Unit Tester" +msgstr "Jedinični ispitivač 86Box-a" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Kjučna kartica za Novell Netware 2.x" + +msgid "Serial port passthrough 1" +msgstr "Prolaz serijskih vrata 1" + +msgid "Serial port passthrough 2" +msgstr "Prolaz serijskih vrata 2" + +msgid "Serial port passthrough 3" +msgstr "Prolaz serijskih vrata 3" + +msgid "Serial port passthrough 4" +msgstr "Prolaz serijskih vrata 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Opcije rendera..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Sabirnički miš Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Sabirnički miš Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Serijski miš Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Serijski miš Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Serijski miš Logitech" + +msgid "PS/2 Mouse" +msgstr "Miš PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (serijski)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Standardni modem, usklađen s standardom Hayesom" + +msgid "Roland MT-32 Emulation" +msgstr "Emulacija Rolanda MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulacija Rolanda MT-32 (novog)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulacija Rolanda CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulacija Rolanda CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Kartica kćerka OPL4-ML" + +msgid "System MIDI" +msgstr "Sistemski MIDI" + +msgid "MIDI Input Device" +msgstr "Ulazni uređaj MIDI" + +msgid "BIOS Address" +msgstr "Adresa BIOS-a" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Omogući pisanje u ROM proširenja BIOS-a" + +msgid "Address" +msgstr "Adresa" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revizija BIOS-a" + +msgid "Translate 26 -> 17" +msgstr "Prevedi 26 -> 17" + +msgid "Language" +msgstr "Jezik" + +msgid "Enable backlight" +msgstr "Omogući pozadinsko osvjetljenje" + +msgid "Invert colors" +msgstr "Invertiraj boje" + +msgid "BIOS size" +msgstr "Veličina BIOS-a" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapiraj C0000-C7FFF kao UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapiraj C8000-CFFFF kao UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapiraj D0000-D7FFF kao UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapiraj D8000-DFFFF kao UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapiraj E0000-E7FFF kao UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapiraj E8000-EFFFF kao UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Džemper JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Izlazni uređaj MIDI" + +msgid "MIDI Real time" +msgstr "MIDI u realnom vremenu" + +msgid "MIDI Thru" +msgstr "Prolaz ulaza MIDI" + +msgid "MIDI Clockout" +msgstr "Taktovit MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Pojačavanje izlaza" + +msgid "Chorus" +msgstr "Zbor" + +msgid "Chorus Voices" +msgstr "Glasovi zbora" + +msgid "Chorus Level" +msgstr "Nivo zbora" + +msgid "Chorus Speed" +msgstr "Brzina zbora" + +msgid "Chorus Depth" +msgstr "Dubina zbora" + +msgid "Chorus Waveform" +msgstr "Valni oblik zbora" + +msgid "Reverb" +msgstr "Odjek" + +msgid "Reverb Room Size" +msgstr "Veličina sobe odjeka" + +msgid "Reverb Damping" +msgstr "Prigušivanje odjeka" + +msgid "Reverb Width" +msgstr "Širina odjeka" + +msgid "Reverb Level" +msgstr "Nivo odjeka" + +msgid "Interpolation Method" +msgstr "Metoda interpolacije" + +msgid "Reverb Output Gain" +msgstr "Pojačavanje izlaza odjeka" + +msgid "Reversed stereo" +msgstr "Obrnuti stereo" + +msgid "Nice ramp" +msgstr "Lijepa rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Gumbi" + +msgid "Serial Port" +msgstr "Serijska vrata" + +msgid "RTS toggle" +msgstr "Prebacivanje RTS" + +msgid "Revision" +msgstr "Revizija" + +msgid "Controller" +msgstr "Kontroler" + +msgid "Show Crosshair" +msgstr "Pokaži nišanski kursor" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Adresa MAC" + +msgid "MAC Address OUI" +msgstr "OUI adrese MAC" + +msgid "Enable BIOS" +msgstr "Omogući BIOS" + +msgid "Baud Rate" +msgstr "Baudova brzina" + +msgid "TCP/IP listening port" +msgstr "Port za slušanje TCP/IP" + +msgid "Phonebook File" +msgstr "Datoteka telefonskog imenika" + +msgid "Telnet emulation" +msgstr "Emulacija Telneta" + +msgid "RAM Address" +msgstr "Adresa RAM-a" + +msgid "RAM size" +msgstr "Veličina RAM-a" + +msgid "Initial RAM size" +msgstr "Početna veličina RAM-a" + +msgid "Serial Number" +msgstr "Serijski broj" + +msgid "Host ID" +msgstr "ID nositelja" + +msgid "FDC Address" +msgstr "Adresa FDC-a" + +msgid "MPU-401 Address" +msgstr "Adresa MPU-401-a" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401-a" + +msgid "Receive MIDI input" +msgstr "Primaj ulaz MIDI" + +msgid "Low DMA" +msgstr "Niski DMA" + +msgid "Enable Game port" +msgstr "Omogoći vrata za igru" + +msgid "Surround module" +msgstr "Modul Surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Podigni prekid CODEC na postavljanju CODEC-a (potrebno nekim upravljačkim programima)" + +msgid "SB Address" +msgstr "Adresa SB-a" + +msgid "WSS IRQ" +msgstr "IRQ WSS-a" + +msgid "WSS DMA" +msgstr "DMA WSS-a" + +msgid "Enable OPL" +msgstr "Omogući OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Primaj ulaz MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "Niski DMA SB-a" + +msgid "6CH variant (6-channel)" +msgstr "Varianta 6CH (6 kanala)" + +msgid "Enable CMS" +msgstr "Omogući CMS" + +msgid "Mixer" +msgstr "Mikser" + +msgid "High DMA" +msgstr "Visoki DMA" + +msgid "Control PC speaker" +msgstr "Kontroliraj zvučnik računala" + +msgid "Memory size" +msgstr "Veličina memorije" + +msgid "EMU8000 Address" +msgstr "Adresa EMU8000-a" + +msgid "IDE Controller" +msgstr "Kontroler IDE" + +msgid "Codec" +msgstr "Kodek" + +msgid "GUS type" +msgstr "Vrsta GUS-a" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Omogući naredbu 0x04 \"Izlazi iz 86Box-a\"" + +msgid "Display type" +msgstr "Vrsta zaslona" + +msgid "Composite type" +msgstr "Vrsta kompozitnog zaslona" + +msgid "RGB type" +msgstr "Vrsta zaslona RGB" + +msgid "Line doubling type" +msgstr "Vrsta udvostručenja linija" + +msgid "Snow emulation" +msgstr "Emulacija snijega" + +msgid "Monitor type" +msgstr "Vrsta monitora" + +msgid "Character set" +msgstr "Set znakova" + +msgid "XGA type" +msgstr "Vrsta kartice XGA" + +msgid "Instance" +msgstr "Primjer" + +msgid "MMIO Address" +msgstr "Adresa MMIO-a" + +msgid "RAMDAC type" +msgstr "Vrsta RAMDAC-a" + +msgid "Blend" +msgstr "Miješaj" + +msgid "Bilinear filtering" +msgstr "Bilinearno filtriranje" + +msgid "Dithering" +msgstr "Podrhtavanje" + +msgid "Enable NMI for CGA emulation" +msgstr "Omogući NMI za emulaciju CGA" + +msgid "Voodoo type" +msgstr "Vrsta kartice Voodoo" + +msgid "Framebuffer memory size" +msgstr "Veličina memorije za framebuffer" + +msgid "Texture memory size" +msgstr "Veličina memorije za teksturu" + +msgid "Dither subtraction" +msgstr "Oduzivanje podrhtaja" + +msgid "Screen Filter" +msgstr "Filtar zaslona" + +msgid "Render threads" +msgstr "Niti za render" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Početna adresa" + +msgid "Contiguous Size" +msgstr "Susjedna veličina" + +msgid "I/O Width" +msgstr "Širina I/O" + +msgid "Transfer Speed" +msgstr "Brzina prijenosa" + +msgid "EMS mode" +msgstr "Načina EMS" + +msgid "Address for > 2 MB" +msgstr "Adresa za > 2 MB" + +msgid "Frame Address" +msgstr "Adresa za frame" + +msgid "USA" +msgstr "SAD" + +msgid "Danish" +msgstr "Danski" + +msgid "Always at selected speed" +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 "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "128 kB od E0000 (MSB adrese invertiran, poslednjih 64KB prvo)" + +msgid "Sine" +msgstr "Sinusni" + +msgid "Triangle" +msgstr "Trokutni" + +msgid "Linear" +msgstr "Linearna" + +msgid "4th Order" +msgstr "4. reda" + +msgid "7th Order" +msgstr "7. reda" + +msgid "Non-timed (original)" +msgstr "Bez tajmera (originalni)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 prazan)" + +msgid "Two" +msgstr "Dva" + +msgid "Three" +msgstr "Tri" + +msgid "Wheel" +msgstr "Kotač" + +msgid "Five + Wheel" +msgstr "Pet + kotač" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 serijski / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) serijski" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Onemogući BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr " 8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klasičan" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Kompozitni" + +msgid "Old" +msgstr "Stara" + +msgid "New" +msgstr "Nova" + +msgid "Color (generic)" +msgstr "Bojni (generični)" + +msgid "Green Monochrome" +msgstr "Crno-bijeli zeleni" + +msgid "Amber Monochrome" +msgstr "Crno-bijeli jantarni" + +msgid "Gray Monochrome" +msgstr "Crno-biljeli sivi" + +msgid "Color (no brown)" +msgstr "Bojni (bez smeđe)" + +msgid "Color (IBM 5153)" +msgstr "Bojni (IBM 5153)" + +msgid "Simple doubling" +msgstr "Jednostavno udvostručenje" + +msgid "sRGB interpolation" +msgstr "Interpolacija sRGB" + +msgid "Linear interpolation" +msgstr "Linearna interpolacija" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Crno-biljeli (5151/MDA) (bijeli)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Crno-biljeli (5151/MDA) (zeleni)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Crno-biljeli (5151/MDA) (jantarni)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Bojni 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Bojni 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Bojni pojačani - normalni način (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Bojni pojačani - pojačani način (5154/ECD)" + +msgid "Green" +msgstr "Zelena" + +msgid "Amber" +msgstr "Jantarna" + +msgid "Gray" +msgstr "Siva" + +msgid "Color" +msgstr "Bojna" + +msgid "U.S. English" +msgstr "Američki engleski" + +msgid "Scandinavian" +msgstr "Skandinavski" + +msgid "Other languages" +msgstr "Ostali jezici" + +msgid "Bochs latest" +msgstr "Bochs poslednji" + +msgid "Mono Non-Interlaced" +msgstr "Crno-biljeli bez preplitanja" + +msgid "Color Interlaced" +msgstr "Bojni s preplitanjem" + +msgid "Color Non-Interlaced" +msgstr "Bojni bez preplitanja" + +msgid "3Dfx Voodoo Graphics" +msgstr "3dfx Voodoo grafika" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 jednote TMU)" + +msgid "8-bit" +msgstr "8-bitna" + +msgid "16-bit" +msgstr "16-bitna" + +msgid "Standard (150ns)" +msgstr "Standardna (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Visoka brzina (120ns)" + +msgid "Enabled" +msgstr "Omogoći" + +msgid "Standard" +msgstr "Standardna" + +msgid "High-Speed" +msgstr "Visoka brzina" + +msgid "Stereo LPT DAC" +msgstr "Stereo DAC za LPT" + +msgid "Generic Text Printer" +msgstr "Generični tekstovni pisač" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Generični pisač matrični ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Generični pisač PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Generični pisač PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Internet protokol za paralelnu liniju" + +msgid "Protection Dongle for Savage Quest" +msgstr "Zaštitni uređaj za Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Uređaj prolaza serijskih vrata" + +msgid "Passthrough Mode" +msgstr "Način prolaza" + +msgid "Host Serial Device" +msgstr "Serijska vrata nositelja" + +msgid "Name of pipe" +msgstr "Ime voda" + +msgid "Data bits" +msgstr "Bitovi podataka" + +msgid "Stop bits" +msgstr "Stop bitovi" + +msgid "Baud Rate of Passthrough" +msgstr "Baudova brzina prolaza" + +msgid "Named Pipe (Server)" +msgstr "Imenovani vod (server)" + +msgid "Host Serial Passthrough" +msgstr "Prolaz serijskih vrata nositelja" + +msgid "Eject %s" +msgstr "Izbaci %s" + +msgid "&Unmute" +msgstr "&Uključi zvuk" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Visoki učinak na brzinu izvršavanja" + +msgid "RAM Disk (max. speed)" +msgstr "Disk RAM (najviša brzina)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Klon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Proizvođać" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Generičko proširenje memorije PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Generičko proširenje memorije PC/AT" diff --git a/src/qt/languages/hu-HU.po b/src/qt/languages/hu-HU.po index ac088e148..2b5adacf4 100644 --- a/src/qt/languages/hu-HU.po +++ b/src/qt/languages/hu-HU.po @@ -259,7 +259,7 @@ msgid "Target &framerate" msgstr "Cél &képkockasebesség" msgid "&Sync with video" -msgstr "&Szinkronizálás a videóval " +msgstr "&Szinkronizálás a videóval" msgid "&25 fps" msgstr "&25 fps" @@ -390,8 +390,11 @@ msgstr "Dinamikus újrafordítás" msgid "Video:" msgstr "Videokártya:" -msgid "Voodoo Graphics" -msgstr "Voodoo-gyorsítókártya" +msgid "Video #2:" +msgstr "Videokártya 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 vagy 2-gyorsítókártya" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/A-gyorsítókártya" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Végzetes hiba" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - SZÜNETELT" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Használja a Ctrl+Alt+PgDn gombokat az ablakhoz való visszatéréshez." @@ -684,6 +687,12 @@ msgstr "A számítógép \"%hs\" nem elérhető a \"roms/machines\" mappából h msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "A videokártya \"%hs\" nem elérhető a \"roms/video\" mappából hiányzó ROM-képek miatt. Ehelyett egy másik kártya kerül futtatásra." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "A videokártya 2 \"%hs\" nem elérhető a \"roms/video\" mappából hiányzó ROM-képek miatt. A második videokártya kerül letiltásra." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Az eszköz \"%hs\" nem elérhető a hiányzó ROM-képek miatt. Az eszköz figyelmen kívül marad." + msgid "Machine" msgstr "Számítógép" @@ -762,17 +771,26 @@ msgstr "Nem találhatóak PCap eszközök" msgid "Invalid PCap device" msgstr "Érvénytelen PCap eszköz" -msgid "Standard 2-button joystick(s)" -msgstr "Szabványos 2-gombos játékvezérlő(k)" +msgid "2-axis, 2-button joystick(s)" +msgstr "2-tengelyes, 2-gombos játékvezérlő(k)" -msgid "Standard 4-button joystick" -msgstr "Szabványos 4-gombos játékvezérlő" +msgid "2-axis, 4-button joystick" +msgstr "2-tengelyes, 4-gombos játékvezérlő" -msgid "Standard 6-button joystick" -msgstr "Szabványos 6-gombos játékvezérlő" +msgid "2-axis, 6-button joystick" +msgstr "2-tengelyes, 6-gombos játékvezérlő" -msgid "Standard 8-button joystick" -msgstr "Szabványos 8-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, 4-button joystick" +msgstr "3-tengelyes, 4-gombos játékvezérlő" + +msgid "4-axis, 4-button joystick" +msgstr "4-tengelyes, 4-gombos játékvezérlő" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Biztos benne, hogy ki szeretne lépni a 86Box-ból?" msgid "Unable to initialize Ghostscript" msgstr "Nem sikerült inicializálni a Ghostscript-et" +msgid "Unable to initialize GhostPCL" +msgstr "Nem sikerült inicializálni a GhostPCL-et" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "MO-képfájlok" msgid "Welcome to 86Box!" msgstr "Üdvözli önt az 86Box!" -msgid "Internal controller" -msgstr "Integrált vezérlő" +msgid "Internal device" +msgstr "Integrált eszköz" msgid "Exit" msgstr "Kilépés" @@ -841,7 +862,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 "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." +msgstr "Régi számítógépek emulátora\n\nFejlesztők: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nSarah Walker, leilei, JohnElliott, greatpsycho és mások korábbi alapvető hozzájárulásával.\n\nFordította: Laci bá'\n\nMegjelent a GNU General Public License v2 vagy újabb alatt. További információért lásd a LICENSE fájlt." msgid "Hardware not available" msgstr "Hardver nem elérhető" @@ -855,6 +876,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." +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" @@ -999,6 +1023,27 @@ msgstr "Felülírás" msgid "Don't overwrite" msgstr "Ne írja felül" +msgid "Raw image" +msgstr "Nyers lemezkép" + +msgid "HDI image" +msgstr "HDI-lemezkép" + +msgid "HDX image" +msgstr "HDX-lemezkép" + +msgid "Fixed-size VHD" +msgstr "Rögzített méretű VHD" + +msgid "Dynamic-size VHD" +msgstr "Dinamikusan bővülő VHD" + +msgid "Differencing VHD" +msgstr "Különbség-VHD" + +msgid "(N/A)" +msgstr "(Nincs)" + msgid "Raw image (.img)" msgstr "Nyers lemezkép (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "A WinBox már nem támogatott" 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 "A WinBox menedzser fejlesztése 2022-ben leállt karbantartók hiányában. Mivel erőfeszítéseinket a 86Box még jobbá tételére irányítjuk, úgy döntöttünk, hogy a WinBox-ot mint menedzsert nem támogatjuk tovább.\n\nA WinBoxon keresztül nem lesznek további frissítések, és hibás viselkedéssel találkozhat, ha továbbra is a 86Box újabb verzióival használja. A WinBox viselkedésével kapcsolatos hibajelentéseket érvénytelennek nyilvánítjuk.\n\nA 86box.net oldalon talál egy listát más kezelőkről, amelyeket használhat." + +msgid "Generate" +msgstr "Generálja" + +msgid "Joystick configuration" +msgstr "Joystick konfiguráció" + +msgid "Device" +msgstr "Eszköz" + +msgid "%1 (X axis)" +msgstr "%1 (X tengely)" + +msgid "%1 (Y axis)" +msgstr "%1 (Y tengely)" + +msgid "MCA devices" +msgstr "MCA eszközök" + +msgid "List of MCA devices:" +msgstr "Az MCA-eszközök listája:" + +msgid "Tablet tool" +msgstr "Tablet eszköz" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "A Qt-ről" + +msgid "MCA devices..." +msgstr "MCA eszközök..." + +msgid "Show non-primary monitors" +msgstr "Nem elsődleges monitorok megjelenítése" + +msgid "Open screenshots folder..." +msgstr "Nyissa meg a képernyőképek mappát..." + +msgid "Apply 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 "Pen" +msgstr "Toll" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Gazdag CD/DVD-meghajtó (%1:)" + +msgid "&Connected" +msgstr "&Connected" + +msgid "Clear image history" +msgstr "Törölje a kép előzményeit" + +msgid "Create..." +msgstr "Hozzon létre..." + +msgid "previous image" +msgstr "előző képfájl" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Gazdag CD/DVD-meghajtó (%1)" + +msgid "Unknown Bus" +msgstr "Ismeretlen busz" + +msgid "Null Driver" +msgstr "Null Driver" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Hiba a \"%1\" megnyitásakor: %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Hiba a vertex shader fordításában a \"%1\" fájlban" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Hiba a fragment shader fordításában a \"%1\" fájlban" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Hiba a shader program összekapcsolásában a \"%1\" fájlban" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 renderelési beállítások" + +msgid "Render behavior" +msgstr "Renderelési viselkedés" + +msgid "Use target framerate:" +msgstr "Cél képkockasebesség használata:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Az egyes képkockák azonnali, az emulált kijelzővel szinkronizált megjelenítése.</p><p><span style=" font-style:italic;"">Ez az ajánlott opció, ha a használt shaderek nem használják a frametime-ot az animált effektusokhoz.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Szinkronizálás a videóval" + +msgid "Shaders" +msgstr "Shaderek" + +msgid "Remove" +msgstr "Távolítsa el a" + +msgid "No shader selected" +msgstr "Nincs shader kiválasztva" + +msgid "Browse..." +msgstr "Böngésszen..." + +msgid "Shader error" +msgstr "Shader hiba" + +msgid "Could not load shaders." +msgstr "Nem sikerült betölteni a shadereket." + +msgid "More information in details." +msgstr "További információ a részletekről." + +msgid "Couldn't create OpenGL context." +msgstr "Nem sikerült OpenGL-kontextust létrehozni." + +msgid "Couldn't switch to OpenGL context." +msgstr "Nem tudott OpenGL-kontextusra váltani." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Az OpenGL 3.0 vagy magasabb verziója szükséges. Az aktuális verzió %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Az OpenGL inicializálása sikertelen. Hiba %1." + +msgid "Error initializing OpenGL" +msgstr "Hiba az OpenGL inicializálásában" + +msgid "Falling back to software rendering.\n" +msgstr "Visszatérés a szoftveres rendereléshez.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "A memória kiosztása a kicsomagolási pufferhez sikertelen.\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>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 "This machine might have been moved or copied." +msgstr "Lehet, hogy ezt a gépet áthelyezték vagy lemásolták." + +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 megfelelő hálózati működés biztosítása érdekében a 86Box-nak tudnia kell, hogy a gépet áthelyezték vagy másolták-e.\n\nVálassza a \"Lemásoltam\" lehetőséget, ha nem biztos benne." + +msgid "I Moved It" +msgstr "Elmozdítottam" + +msgid "I Copied It" +msgstr "Lemásoltam" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Nincsenek MCA eszközök." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Hálózati kártya 1" + +msgid "Network Card #2" +msgstr "Hálózati kártya 2" + +msgid "Network Card #3" +msgstr "Hálózati kártya 3" + +msgid "Network Card #4" +msgstr "Hálózati kártya 4" + +msgid "Mode" +msgstr "Mód" + +msgid "Interface" +msgstr "Interfész" + +msgid "Adapter" +msgstr "Adapter" + +msgid "VDE Socket" +msgstr "VDE aljzat" + +msgid "86Box Unit Tester" +msgstr "86Box Unit Tester" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x kulcskártya" + +msgid "Serial port passthrough 1" +msgstr "Soros port áthaladás 1" + +msgid "Serial port passthrough 2" +msgstr "Soros port áthaladás 2" + +msgid "Serial port passthrough 3" +msgstr "Soros port áthaladás 3" + +msgid "Serial port passthrough 4" +msgstr "Soros port áthaladás 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Renderer opciók..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft busz egér" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft buszos egér (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Egérrendszerek Soros egér" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft soros egér" + +msgid "Logitech Serial Mouse" +msgstr "Logitech soros egér" + +msgid "PS/2 Mouse" +msgstr "PS/2 egér" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (soros)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Szabványos Hayes-kompatibilis modem" + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32 emuláció" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32 (Új) Emuláció" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32L emuláció" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LN emuláció" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML alaplap" + +msgid "System MIDI" +msgstr "Rendszer MIDI" + +msgid "MIDI Input Device" +msgstr "MIDI bemeneti eszköz" + +msgid "BIOS Address" +msgstr "BIOS cím" + +msgid "Enable BIOS extension ROM Writes" +msgstr "BIOS bővítés ROM írások engedélyezése" + +msgid "Address" +msgstr "Cím:" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS felülvizsgálata" + +msgid "Translate 26 -> 17" +msgstr "Fordítsd le 26 -> 17" + +msgid "Language" +msgstr "Nyelv" + +msgid "Enable backlight" +msgstr "Háttérvilágítás engedélyezése" + +msgid "Invert colors" +msgstr "Invertált színek" + +msgid "BIOS size" +msgstr "BIOS mérete" + +msgid "Map C0000-C7FFF as UMB" +msgstr "C0000-C7FFF mint UMB leképezése" + +msgid "Map C8000-CFFFF as UMB" +msgstr "C8000-CFFFF mint UMB leképezése" + +msgid "Map D0000-D7FFF as UMB" +msgstr "D0000-D7FFF mint UMB leképezése" + +msgid "Map D8000-DFFFF as UMB" +msgstr "D8000-DFFFF mint UMB leképezése" + +msgid "Map E0000-E7FFF as UMB" +msgstr "E0000-E7FFF mint UMB leképezése" + +msgid "Map E8000-EFFFF as UMB" +msgstr "E8000-EFFFF mint UMB leképezése" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 Jumper (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI kimeneti eszköz" + +msgid "MIDI Real time" +msgstr "MIDI valós időben" + +msgid "MIDI Thru" +msgstr "A MIDI bemenet átmenete" + +msgid "MIDI Clockout" +msgstr "A MIDI óra kimenete" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Kimeneti erősítés" + +msgid "Chorus" +msgstr "Kórus" + +msgid "Chorus Voices" +msgstr "Kórus hangok" + +msgid "Chorus Level" +msgstr "Kórus szint" + +msgid "Chorus Speed" +msgstr "Kórus sebesség" + +msgid "Chorus Depth" +msgstr "Kórus mélység" + +msgid "Chorus Waveform" +msgstr "Kórus hullámforma" + +msgid "Reverb" +msgstr "Visszhang" + +msgid "Reverb Room Size" +msgstr "Visszhangterem mérete" + +msgid "Reverb Damping" +msgstr "Visszhang csillapítás" + +msgid "Reverb Width" +msgstr "Visszhang szélessége" + +msgid "Reverb Level" +msgstr "Visszhang szint" + +msgid "Interpolation Method" +msgstr "Interpolációs módszer" + +msgid "Reverb Output Gain" +msgstr "Visszhang kimenetének erősítése" + +msgid "Reversed stereo" +msgstr "Fordított sztereó" + +msgid "Nice ramp" +msgstr "Szép rámpa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Gombok" + +msgid "Serial Port" +msgstr "Soros port" + +msgid "RTS toggle" +msgstr "RTS kapcsoló" + +msgid "Revision" +msgstr "Felülvizsgálat" + +msgid "Controller" +msgstr "Vezérlő" + +msgid "Show Crosshair" +msgstr "Keresztmetszet megjelenítése" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC cím" + +msgid "MAC Address OUI" +msgstr "MAC cím OUI" + +msgid "Enable BIOS" +msgstr "BIOS engedélyezése" + +msgid "Baud Rate" +msgstr "Baud-ráta" + +msgid "TCP/IP listening port" +msgstr "TCP/IP figyelő port" + +msgid "Phonebook File" +msgstr "Telefonkönyv fájl" + +msgid "Telnet emulation" +msgstr "Telnet emuláció" + +msgid "RAM Address" +msgstr "RAM cím" + +msgid "RAM size" +msgstr "RAM mérete" + +msgid "Initial RAM size" +msgstr "RAM kezdeti mérete" + +msgid "Serial Number" +msgstr "Sorszám" + +msgid "Host ID" +msgstr "Host azonosító" + +msgid "FDC Address" +msgstr "FDC cím" + +msgid "MPU-401 Address" +msgstr "MPU-401 cím" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "MIDI bemenet fogadása" + +msgid "Low DMA" +msgstr "Alacsony DMA" + +msgid "Enable Game port" +msgstr "Játékport engedélyezése" + +msgid "Surround module" +msgstr "Surround modul" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "CODEC megszakítás felemelése CODEC beállításakor (néhány illesztőprogramnak szükséges)" + +msgid "SB Address" +msgstr "SB cím" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "OPL engedélyezése" + +msgid "Receive MIDI input (MPU-401)" +msgstr "MIDI bemenet fogadása (MPU-401)" + +msgid "SB low DMA" +msgstr "SB alacsony DMA" + +msgid "6CH variant (6-channel)" +msgstr "6CH változat (6 csatornás)" + +msgid "Enable CMS" +msgstr "CMS engedélyezése" + +msgid "Mixer" +msgstr "Keverő" + +msgid "High DMA" +msgstr "Magas DMA" + +msgid "Control PC speaker" +msgstr "Control PC hangszóró" + +msgid "Memory size" +msgstr "Memória mérete" + +msgid "EMU8000 Address" +msgstr "EMU8000 cím" + +msgid "IDE Controller" +msgstr "IDE vezérlő" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "GUS típus" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "A 0x04 parancs engedélyezése \"Lépni a 86Box-ból\"" + +msgid "Display type" +msgstr "Megjelenítés típusa" + +msgid "Composite type" +msgstr "Összetett típus" + +msgid "RGB type" +msgstr "RGB típus" + +msgid "Line doubling type" +msgstr "Vonal megduplázásának típusa" + +msgid "Snow emulation" +msgstr "Hó emulációja" + +msgid "Monitor type" +msgstr "Monitor típusa" + +msgid "Character set" +msgstr "Karakterkészlet" + +msgid "XGA type" +msgstr "XGA típus" + +msgid "Instance" +msgstr "Példa" + +msgid "MMIO Address" +msgstr "MMIO cím" + +msgid "RAMDAC type" +msgstr "RAMDAC típus" + +msgid "Blend" +msgstr "Blend" + +msgid "Bilinear filtering" +msgstr "Bilineáris szűrés" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "NMI engedélyezése a CGA emulációhoz" + +msgid "Voodoo type" +msgstr "Voodoo típus" + +msgid "Framebuffer memory size" +msgstr "A keretpuffer memória mérete" + +msgid "Texture memory size" +msgstr "Textúra memória mérete" + +msgid "Dither subtraction" +msgstr "Dither kivonás" + +msgid "Screen Filter" +msgstr "Szűrő szűrő" + +msgid "Render threads" +msgstr "Renderelési szálak" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Kezdeti cím" + +msgid "Contiguous Size" +msgstr "Összefüggő méret" + +msgid "I/O Width" +msgstr "I/O szélesség" + +msgid "Transfer Speed" +msgstr "Átviteli sebesség" + +msgid "EMS mode" +msgstr "EMS üzemmód" + +msgid "Address for > 2 MB" +msgstr "Cím > 2 MB" + +msgid "Frame Address" +msgstr "Keret címe" + +msgid "USA" +msgstr "USA" + +msgid "Danish" +msgstr "Dán" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Szinuszos" + +msgid "Triangle" +msgstr "Háromszög" + +msgid "Linear" +msgstr "Lineáris" + +msgid "4th Order" +msgstr "4. rendű" + +msgid "7th Order" +msgstr "7. rendű" + +msgid "Non-timed (original)" +msgstr "Időzítő nélkül (eredeti)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (nincs jumper a JMP2-nél)" + +msgid "Two" +msgstr "Két" + +msgid "Three" +msgstr "Három" + +msgid "Wheel" +msgstr "Kerék" + +msgid "Five + Wheel" +msgstr "Öt + kerék" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 soros / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) soros" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "BIOS letiltása" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (sztereó)" + +msgid "Classic" +msgstr "Klasszikus" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Összetett" + +msgid "Old" +msgstr "Régi" + +msgid "New" +msgstr "Új" + +msgid "Color (generic)" +msgstr "Szín (általános)" + +msgid "Green Monochrome" +msgstr "Zöld monokróm" + +msgid "Amber Monochrome" +msgstr "Sárga monokróm" + +msgid "Gray Monochrome" +msgstr "Szürke monokróm" + +msgid "Color (no brown)" +msgstr "Szín (nem barna)" + +msgid "Color (IBM 5153)" +msgstr "Színes (IBM 5153)" + +msgid "Simple doubling" +msgstr "Egyszerű duplázás" + +msgid "sRGB interpolation" +msgstr "sRGB interpoláció" + +msgid "Linear interpolation" +msgstr "Lineáris interpoláció" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monokróm (5151/MDA) (fehér)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monokróm (5151/MDA) (zöld)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monokróm (5151/MDA) (sárga)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Színes 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Színes 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Fokozott szín - normál üzemmód (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Továbbfejlesztett szín - továbbfejlesztett üzemmód (5154/ECD)" + +msgid "Green" +msgstr "Zöld" + +msgid "Amber" +msgstr "Sárga" + +msgid "Gray" +msgstr "Szürke" + +msgid "Color" +msgstr "Színes" + +msgid "U.S. English" +msgstr "Amerikai angol" + +msgid "Scandinavian" +msgstr "Skandináv" + +msgid "Other languages" +msgstr "Egyéb nyelvek" + +msgid "Bochs latest" +msgstr "Bochs legújabb" + +msgid "Mono Non-Interlaced" +msgstr "Monokróm nem átlapolt" + +msgid "Color Interlaced" +msgstr "Színes átlapolt" + +msgid "Color Non-Interlaced" +msgstr "Színes nem átlapolt" + +msgid "3Dfx Voodoo Graphics" +msgstr "3dfx Voodoo-gyorsítókártya" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8 bites" + +msgid "16-bit" +msgstr "16 bites" + +msgid "Standard (150ns)" +msgstr "Standard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Nagy sebességű (120ns)" + +msgid "Enabled" +msgstr "Engedélyezve" + +msgid "Standard" +msgstr "Standard" + +msgid "High-Speed" +msgstr "Nagy sebességű" + +msgid "Stereo LPT DAC" +msgstr "Sztereó LPT DAC" + +msgid "Generic Text Printer" +msgstr "Általános szövegnyomtató" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Általános ESC/P pontmátrixnyomtató" + +msgid "Generic PostScript Printer" +msgstr "Általános PostScript nyomtató" + +msgid "Generic PCL5e Printer" +msgstr "Általános PCL5e nyomtató" + +msgid "Parallel Line Internet Protocol" +msgstr "Párhuzamos vonalas internetprotokoll" + +msgid "Protection Dongle for Savage Quest" +msgstr "Védelmi dongle a Savage Questhez" + +msgid "Serial Passthrough Device" +msgstr "Soros port áthaladó eszköz" + +msgid "Passthrough Mode" +msgstr "Áthaladó mód" + +msgid "Host Serial Device" +msgstr "Host soros eszköz" + +msgid "Name of pipe" +msgstr "A cső neve" + +msgid "Data bits" +msgstr "Adat bitek" + +msgid "Stop bits" +msgstr "Stop bitek" + +msgid "Baud Rate of Passthrough" +msgstr "Az átmenő átviteli sebesség Baud-rátája" + +msgid "Named Pipe (Server)" +msgstr "Megnevezett cső (kiszolgáló)" + +msgid "Host Serial Passthrough" +msgstr "Az állomás soros portjának áthaladása" + +msgid "Eject %s" +msgstr "%s kiadás" + +msgid "&Unmute" +msgstr "&Hang újra bekapcsolása" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Nagy hatással van a teljesítményre" + +msgid "RAM Disk (max. speed)" +msgstr "RAM lemez (max. sebesség)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A klón (ISA)" + +msgid "Vendor" +msgstr "Gyártó" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Általános PC/XT memóriabővítők" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Általános PC/AT memóriabővítők" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 0ce1efabb..c9af80127 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -37,7 +37,7 @@ msgid "&Hide status bar" msgstr "&Nascondi barra di stato" msgid "Hide &toolbar" -msgstr "Hide &toolbar" +msgstr "Nascondi &barra degli strumenti" msgid "&Resizeable window" msgstr "&Finestra ridimensionabile" @@ -256,7 +256,7 @@ msgid "&Folder..." msgstr "&Cartella..." msgid "Target &framerate" -msgstr "Imposta obiettivo &fotogrammi" +msgstr "Obiettivo &fotogrammi" msgid "&Sync with video" msgstr "&Sincronizza col video" @@ -390,8 +390,11 @@ msgstr "Ricompilatore dinamico" msgid "Video:" msgstr "Video:" -msgid "Voodoo Graphics" -msgstr "Grafica Voodoo" +msgid "Video #2:" +msgstr "Video 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Grafica Voodoo 1 o 2" msgid "IBM 8514/A Graphics" msgstr "Grafica IBM 8514/A" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Errore fatale" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - IN PAUSA" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Usa Ctrl+Alt+PgDn per tornare alla modalità finestra." @@ -684,6 +687,12 @@ msgstr "La macchina \"%hs\" non è disponibile a causa di immagini ROM mancanti msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "La scheda video \"%hs\" non è disponibile a causa di immagini ROM mancanti nella directory roms/video. Cambiando ad una scheda video disponibile." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "La scheda video 2 \"%hs\" non è disponibile a causa di immagini ROM mancanti nella directory roms/video. Disabilitando la seconda scheda video." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Il dispositivo \"%hs\" non è disponibile a causa di immagini ROM mancanti. Ignorando il dispositivo." + msgid "Machine" msgstr "Piastra madre" @@ -762,17 +771,26 @@ msgstr "Nessun dispositivo PCap trovato" msgid "Invalid PCap device" msgstr "Dispositivo PCap invalido" -msgid "Standard 2-button joystick(s)" -msgstr "Joystick comune da 2 pulsanti" +msgid "2-axis, 2-button joystick(s)" +msgstr "Joystick da 2 assi, 2 pulsanti" -msgid "Standard 4-button joystick" -msgstr "Joystick comune da 4 pulsanti" +msgid "2-axis, 4-button joystick" +msgstr "Joystick da 2 assi, 4 pulsanti" -msgid "Standard 6-button joystick" -msgstr "Joystick comune da 6 pulsanti" +msgid "2-axis, 6-button joystick" +msgstr "Joystick da 2 assi, 6 pulsanti" -msgid "Standard 8-button joystick" -msgstr "Joystick comune da 8 pulsanti" +msgid "2-axis, 8-button joystick" +msgstr "Joystick da 2 assi, 8 pulsanti" + +msgid "3-axis, 2-button joystick" +msgstr "Joystick da 3 assi, 2 pulsanti" + +msgid "3-axis, 4-button joystick" +msgstr "Joystick da 3 assi, 4 pulsanti" + +msgid "4-axis, 4-button joystick" +msgstr "Joystick da 4 assi, 4 pulsanti" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Sei sicuro di voler uscire da 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Impossibile inizializzare Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Impossibile inizializzare GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Immagini MO" msgid "Welcome to 86Box!" msgstr "Benvenuti in 86Box!" -msgid "Internal controller" -msgstr "Controller interno" +msgid "Internal device" +msgstr "Dispositivo integrato" msgid "Exit" msgstr "Esci" @@ -841,7 +862,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 emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." +msgstr "Un emulatore di computer vecchi\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nCon i precedenti contributi al nucleo di Sarah Walker, leilei, JohnElliott, greatpsycho e altri.\n\nTradotto da: explorerdotexe\n\nRilasciato sotto la Licenza Pubblica GNU versione 2 o dopo. Vedi LICENSE per maggior informazioni." msgid "Hardware not available" msgstr "Hardware non disponibile" @@ -853,7 +874,10 @@ msgid "Invalid configuration" 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)" +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" @@ -999,6 +1023,27 @@ msgstr "Sovrascrivi" msgid "Don't overwrite" msgstr "Non sovrascrivere" +msgid "Raw image" +msgstr "Immagine raw" + +msgid "HDI image" +msgstr "Immagine HDI" + +msgid "HDX image" +msgstr "Immagine HDX" + +msgid "Fixed-size VHD" +msgstr "VHD di dimensioni fisse" + +msgid "Dynamic-size VHD" +msgstr "VHD di dimensioni dinamiche" + +msgid "Differencing VHD" +msgstr "VHD differenziato" + +msgid "(N/A)" +msgstr "(N/D)" + msgid "Raw image (.img)" msgstr "Immagine raw (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBox non è più supportato" 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 "Lo sviluppo del gestore WinBox si è interrotto nel 2022 per mancanza di manutentori. Poiché i nostri sforzi sono rivolti a rendere 86Box ancora migliore, abbiamo deciso di non supportare più WinBox come gestore.\n\nNon saranno forniti ulteriori aggiornamenti tramite WinBox e si potrebbe riscontrare un comportamento non corretto se si continua a utilizzarlo con versioni più recenti di 86Box. Tutte le segnalazioni di bug relative al comportamento di WinBox saranno chiuse in quanto non valide.\n\nPer un elenco di altri gestori utilizzabili, visitare 86box.net." + +msgid "Generate" +msgstr "Generare" + +msgid "Joystick configuration" +msgstr "Configurazione del joystick" + +msgid "Device" +msgstr "Dispositivo" + +msgid "%1 (X axis)" +msgstr "%1 (asse X)" + +msgid "%1 (Y axis)" +msgstr "%1 (asse Y)" + +msgid "MCA devices" +msgstr "Dispositivi MCA" + +msgid "List of MCA devices:" +msgstr "Elenco dei dispositivi MCA:" + +msgid "Tablet tool" +msgstr "Strumento tablet" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Informazioni su Qt" + +msgid "MCA devices..." +msgstr "Dispositivi MCA..." + +msgid "Show non-primary monitors" +msgstr "Mostra i monitor non primari" + +msgid "Open screenshots folder..." +msgstr "Aprire la cartella screenshot..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Applica la modalità adattamento schermo intero in modalità massimizzata" + +msgid "Cursor/Puck" +msgstr "Cursore/Puck" + +msgid "Pen" +msgstr "Penna" + +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 "Create..." +msgstr "Creare..." + +msgid "previous image" +msgstr "immagine precedente" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Unità CD/DVD host (%1)" + +msgid "Unknown Bus" +msgstr "Autobus sconosciuto" + +msgid "Null Driver" +msgstr "Driver nullo" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Errore nell'apertura di \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Errore nella compilazione di vertex shader nel file \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Errore nella compilazione dello shader dei frammenti nel file \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Errore nel collegamento del programma shader nel file \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opzioni del renderer OpenGL 3.0" + +msgid "Render behavior" +msgstr "Comportamento di rendering" + +msgid "Use target framerate:" +msgstr "Utilizza l'obiettivo &fotogrammi:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Renderizza ogni fotogramma immediatamente, in sincronia con la visualizzazione emulata.</p><p><span style=" font-style:italic;">Questa è l'opzione consigliata se gli shader in uso non utilizzano il frametime per gli effetti animati.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sincronizza col video" + +msgid "Shaders" +msgstr "Shader" + +msgid "Remove" +msgstr "Rimuovere" + +msgid "No shader selected" +msgstr "Nessuno shader selezionato" + +msgid "Browse..." +msgstr "Sfoglia..." + +msgid "Shader error" +msgstr "Errore dello shader" + +msgid "Could not load shaders." +msgstr "Impossibile caricare gli shader." + +msgid "More information in details." +msgstr "Maggiori informazioni in dettaglio." + +msgid "Couldn't create OpenGL context." +msgstr "Impossibile creare un contesto OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Impossibile passare al contesto OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "È richiesta la versione OpenGL 3.0 o superiore. La versione attuale è %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Inizializzazione OpenGL non riuscita. Errore %1." + +msgid "Error initializing OpenGL" +msgstr "Errore nell'inizializzazione di OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Ricaduta sul rendering software." + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "L'allocazione della memoria per il buffer di disimballaggio non è riuscita." + +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 "This machine might have been moved or copied." +msgstr "Questa macchina potrebbe essere stata spostata o copiata." + +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 "Per garantire la corretta funzionalità di rete, 86Box deve sapere se la macchina è stata spostata o copiata.\"nSelezionare \"L'ho copiata\" se non si è sicuri." + +msgid "I Moved It" +msgstr "L'ho spostato" + +msgid "I Copied It" +msgstr "L'ho copiato" + +msgid "86Box Monitor #" +msgstr "Monitor 86Box #" + +msgid "No MCA devices." +msgstr "Nessun dispositivo MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Scheda di rete n. 1" + +msgid "Network Card #2" +msgstr "Scheda di rete n. 2" + +msgid "Network Card #3" +msgstr "Scheda di rete n. 3" + +msgid "Network Card #4" +msgstr "Scheda di rete n. 4" + +msgid "Mode" +msgstr "Modalità" + +msgid "Interface" +msgstr "Interfaccia" + +msgid "Adapter" +msgstr "Adattatore" + +msgid "VDE Socket" +msgstr "Presa VDE" + +msgid "86Box Unit Tester" +msgstr "Tester di unità 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Scheda chiave Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Passaggio della porta seriale 1" + +msgid "Serial port passthrough 2" +msgstr "Passaggio della porta seriale 2" + +msgid "Serial port passthrough 3" +msgstr "Passaggio della porta seriale 3" + +msgid "Serial port passthrough 4" +msgstr "Passaggio della porta seriale 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Opzioni del renderer..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Mouse bus Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Mouse bus Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse seriale Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Mouse seriale Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Mouse seriale Logitech" + +msgid "PS/2 Mouse" +msgstr "Mouse PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (seriale)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Modem standard conforme a Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulazione Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulazione Roland MT-32 (nuovo)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulazione Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulazione Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Scheda figlia OPL4-ML" + +msgid "System MIDI" +msgstr "MIDI di sistema" + +msgid "MIDI Input Device" +msgstr "Dispositivo di ingresso MIDI" + +msgid "BIOS Address" +msgstr "Indirizzo BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Abilita scrittura al ROM dell'estensione del BIOS" + +msgid "Address" +msgstr "Indirizzo" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revisione del BIOS" + +msgid "Translate 26 -> 17" +msgstr "Tradurre 26 -> 17" + +msgid "Language" +msgstr "Lingua" + +msgid "Enable backlight" +msgstr "Abilita la retroilluminazione" + +msgid "Invert colors" +msgstr "Invertire i colori" + +msgid "BIOS size" +msgstr "Dimensione del BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mappa C0000-C7FFF come UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mappa C8000-CFFFF come UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mappa D0000-D7FFF come UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mappa D8000-DFFFF come UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mappa E0000-E7FFF come UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mappa E8000-EFFFF come UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 ponticello (JIM)" + +msgid "MIDI Output Device" +msgstr "Dispositivo di uscita MIDI" + +msgid "MIDI Real time" +msgstr "MIDI in empo reale" + +msgid "MIDI Thru" +msgstr "Passaggio dell'ingresso MIDI" + +msgid "MIDI Clockout" +msgstr "Uscita del clock MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Guadagno di uscita" + +msgid "Chorus" +msgstr "Coro" + +msgid "Chorus Voices" +msgstr "Voci del coro" + +msgid "Chorus Level" +msgstr "Livello del coro" + +msgid "Chorus Speed" +msgstr "Velocità del coro" + +msgid "Chorus Depth" +msgstr "Profondità del coro" + +msgid "Chorus Waveform" +msgstr "Forma d'onda del coro" + +msgid "Reverb" +msgstr "Riverbero" + +msgid "Reverb Room Size" +msgstr "Dimensioni della sala di riverbero" + +msgid "Reverb Damping" +msgstr "Smorzamento del riverbero" + +msgid "Reverb Width" +msgstr "Larghezza del riverbero" + +msgid "Reverb Level" +msgstr "Livello di riverbero" + +msgid "Interpolation Method" +msgstr "Metodo di interpolazione" + +msgid "Reverb Output Gain" +msgstr "Guadagno dell'uscita del riverbero" + +msgid "Reversed stereo" +msgstr "Stereo invertito" + +msgid "Nice ramp" +msgstr "Bella rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Pulsanti" + +msgid "Serial Port" +msgstr "Porta seriale" + +msgid "RTS toggle" +msgstr "Commutazione RTS" + +msgid "Revision" +msgstr "Revisione" + +msgid "Controller" +msgstr "Controllore" + +msgid "Show Crosshair" +msgstr "Mostra mirino" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Indirizzo MAC" + +msgid "MAC Address OUI" +msgstr "Indirizzo MAC OUI" + +msgid "Enable BIOS" +msgstr "Abilita il BIOS" + +msgid "Baud Rate" +msgstr "Velocità di trasmissione" + +msgid "TCP/IP listening port" +msgstr "Porta di ascolto TCP/IP" + +msgid "Phonebook File" +msgstr "File rubrica" + +msgid "Telnet emulation" +msgstr "Emulazione Telnet" + +msgid "RAM Address" +msgstr "Indirizzo RAM" + +msgid "RAM size" +msgstr "Dimensione della RAM" + +msgid "Initial RAM size" +msgstr "Dimensione iniziale della RAM" + +msgid "Serial Number" +msgstr "Numero di serie" + +msgid "Host ID" +msgstr "ID host" + +msgid "FDC Address" +msgstr "Indirizzo FDC" + +msgid "MPU-401 Address" +msgstr "Indirizzo MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Ricezione dell'ingresso MIDI" + +msgid "Low DMA" +msgstr "DMA basso" + +msgid "Enable Game port" +msgstr "Abilita la porta giochi" + +msgid "Surround module" +msgstr "Modulo surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Solleva l'interrupt del CODEC all'impostazione del CODEC (necessario per alcuni driver)" + +msgid "SB Address" +msgstr "Indirizzo SB" + +msgid "WSS IRQ" +msgstr "IRQ WSS" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "Abilita l'OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Ricezione dell'ingresso MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "SB basso DMA" + +msgid "6CH variant (6-channel)" +msgstr "Variante 6CH (6 canali)" + +msgid "Enable CMS" +msgstr "Abilita il CMS" + +msgid "Mixer" +msgstr "Miscelatore" + +msgid "High DMA" +msgstr "DMA alto" + +msgid "Control PC speaker" +msgstr "Altoparlante del PC di controllo" + +msgid "Memory size" +msgstr "Dimensione della memoria" + +msgid "EMU8000 Address" +msgstr "Indirizzo EMU8000" + +msgid "IDE Controller" +msgstr "Controllore IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Tipo GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Abilita il comando 0x04 \"Esci da 86Box\"" + +msgid "Display type" +msgstr "Tipo di display" + +msgid "Composite type" +msgstr "Tipo composito" + +msgid "RGB type" +msgstr "Tipo RGB" + +msgid "Line doubling type" +msgstr "Tipo di raddoppio della linea" + +msgid "Snow emulation" +msgstr "Emulazione della neve" + +msgid "Monitor type" +msgstr "Tipo di monitor" + +msgid "Character set" +msgstr "Set di caratteri" + +msgid "XGA type" +msgstr "Tipo XGA" + +msgid "Instance" +msgstr "Istanza" + +msgid "MMIO Address" +msgstr "Indirizzo MMIO" + +msgid "RAMDAC type" +msgstr "Tipo di RAMDAC" + +msgid "Blend" +msgstr "Miscela" + +msgid "Bilinear filtering" +msgstr "Filtraggio bilineare" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Abilita l'NMI per l'emulazione CGA" + +msgid "Voodoo type" +msgstr "Tipo Voodoo" + +msgid "Framebuffer memory size" +msgstr "Dimensione della memoria del framebuffer" + +msgid "Texture memory size" +msgstr "Dimensione della memoria della texture" + +msgid "Dither subtraction" +msgstr "Sottrazione della retinatura" + +msgid "Screen Filter" +msgstr "Filtro a schermo" + +msgid "Render threads" +msgstr "Fili di rendering" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Indirizzo di partenza" + +msgid "Contiguous Size" +msgstr "Dimensione contigua" + +msgid "I/O Width" +msgstr "Larghezza I/O" + +msgid "Transfer Speed" +msgstr "Velocità di trasferimento" + +msgid "EMS mode" +msgstr "Modalità EMS" + +msgid "Address for > 2 MB" +msgstr "Indirizzo per > 2 MB" + +msgid "Frame Address" +msgstr "Indirizzo del frame" + +msgid "USA" +msgstr "Stati Uniti" + +msgid "Danish" +msgstr "Danese" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusoidale" + +msgid "Triangle" +msgstr "Triangolare" + +msgid "Linear" +msgstr "Lineare" + +msgid "4th Order" +msgstr "Del 4° ordine" + +msgid "7th Order" +msgstr "Del 7° ordine" + +msgid "Non-timed (original)" +msgstr "Senza timer (originale)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (nessun ponticello su JMP2)" + +msgid "Two" +msgstr "Due" + +msgid "Three" +msgstr "Tre" + +msgid "Wheel" +msgstr "Ruota" + +msgid "Five + Wheel" +msgstr "Cinque + ruota" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 seriale / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) seriale" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Disattivare il BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Classico" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Composito" + +msgid "Old" +msgstr "Vecchio" + +msgid "New" +msgstr "Nuovo" + +msgid "Color (generic)" +msgstr "Colore (generico)" + +msgid "Green Monochrome" +msgstr "Verde Monocromatico" + +msgid "Amber Monochrome" +msgstr "Ambra monocromatica" + +msgid "Gray Monochrome" +msgstr "Grigio monocromatico" + +msgid "Color (no brown)" +msgstr "Colore (no marrone)" + +msgid "Color (IBM 5153)" +msgstr "Colore (IBM 5153)" + +msgid "Simple doubling" +msgstr "Raddoppio semplice" + +msgid "sRGB interpolation" +msgstr "Interpolazione sRGB" + +msgid "Linear interpolation" +msgstr "Interpolazione lineare" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monocromatico (5151/MDA) (bianco)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monocromatico (5151/MDA) (verde)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monocromatico (5151/MDA) (ambra)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Colore 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Colore 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Colore avanzato - Modalità normale (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Colore migliorato - Modalità migliorata (5154/ECD)" + +msgid "Green" +msgstr "Verde" + +msgid "Amber" +msgstr "Ambra" + +msgid "Gray" +msgstr "Grigio" + +msgid "Color" +msgstr "Colore" + +msgid "U.S. English" +msgstr "Inglese statunitense" + +msgid "Scandinavian" +msgstr "Scandinavo" + +msgid "Other languages" +msgstr "Altre lingue" + +msgid "Bochs latest" +msgstr "Bochs ultima versione" + +msgid "Mono Non-Interlaced" +msgstr "Mono non interlacciato" + +msgid "Color Interlaced" +msgstr "Colore interlacciato" + +msgid "Color Non-Interlaced" +msgstr "Colore non interlacciato" + +msgid "3Dfx Voodoo Graphics" +msgstr "Grafica 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8-bit" + +msgid "16-bit" +msgstr "16 bit" + +msgid "Standard (150ns)" +msgstr "Standard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Alta velocità (120ns)" + +msgid "Enabled" +msgstr "Abilitato" + +msgid "Standard" +msgstr "Standard" + +msgid "High-Speed" +msgstr "Alta velocità" + +msgid "Stereo LPT DAC" +msgstr "DAC LPT stereo" + +msgid "Generic Text Printer" +msgstr "Stampante di testo generica" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Stampante a matrice di punti ESC/P generica" + +msgid "Generic PostScript Printer" +msgstr "Stampante PostScript generica" + +msgid "Generic PCL5e Printer" +msgstr "Stampante PCL5e generica" + +msgid "Parallel Line Internet Protocol" +msgstr "Linea parallela Protocollo Internet" + +msgid "Protection Dongle for Savage Quest" +msgstr "Dongle di protezione per Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Dispositivo del passaggio della porta seriale" + +msgid "Passthrough Mode" +msgstr "Modalità del passaggio" + +msgid "Host Serial Device" +msgstr "Dispositivo seriale host" + +msgid "Name of pipe" +msgstr "Nome del tubo" + +msgid "Data bits" +msgstr "Bit di dati" + +msgid "Stop bits" +msgstr "Bit di stop" + +msgid "Baud Rate of Passthrough" +msgstr "Velocità di trasmissione in baud del passaggio" + +msgid "Named Pipe (Server)" +msgstr "Tubo denominato (Server)" + +msgid "Host Serial Passthrough" +msgstr "Passaggio della porta seriale host" + +msgid "Eject %s" +msgstr "Espelli %s" + +msgid "&Unmute" +msgstr "&Riattiva l'audio" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Impatto elevato sulla prestazione" + +msgid "RAM Disk (max. speed)" +msgstr "Disco RAM (velocità massima)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Clone IBM 8514/A(ISA)" + +msgid "Vendor" +msgstr "Fabricante" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Espansione di memoria generica PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Espansione di memoria generica PC/AT" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index c20848be6..9a3289b51 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -390,8 +390,11 @@ msgstr "動的再コンパイル" msgid "Video:" msgstr "ビデオカード:" -msgid "Voodoo Graphics" -msgstr "Voodooグラフィック" +msgid "Video #2:" +msgstr "ビデオカード2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo1または2グラフィック" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/Aグラフィック" @@ -684,6 +687,12 @@ msgstr "roms/machines ディレクトリにROMがないため、マシン「%hs msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "roms/video ディレクトリにROMがないため、ビデオ カード「%hs」は使用できません。使用可能なビデオカードに切り替えます。" +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "roms/video ディレクトリにROMがないため、ビデオ カード2「%hs」は使用できません。2枚目のビデオカードを無効にします。" + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "ROMがないため、デバイス「%hs」は使用できません。装置を無視する。" + msgid "Machine" msgstr "マシン" @@ -762,17 +771,26 @@ msgstr "PCapデバイスがありません" msgid "Invalid PCap device" msgstr "不正なPCapデバイス" -msgid "Standard 2-button joystick(s)" -msgstr "標準ジョイスティック(2ボタン)" +msgid "2-axis, 2-button joystick(s)" +msgstr "ジョイスティック(2軸、2ボタン)" -msgid "Standard 4-button joystick" -msgstr "標準ジョイスティック(4ボタン)" +msgid "2-axis, 4-button joystick" +msgstr "ジョイスティック(2軸、4ボタン)" -msgid "Standard 6-button joystick" -msgstr "標準ジョイスティック(6ボタン)" +msgid "2-axis, 6-button joystick" +msgstr "ジョイスティック(2軸、6ボタン)" -msgid "Standard 8-button joystick" -msgstr "標準ジョイスティック(8ボタン)" +msgid "2-axis, 8-button joystick" +msgstr "ジョイスティック(2軸、8ボタン)" + +msgid "3-axis, 2-button joystick" +msgstr "ジョイスティック(3軸、2ボタン)" + +msgid "3-axis, 4-button joystick" +msgstr "ジョイスティック(3軸、4ボタン)" + +msgid "4-axis, 4-button joystick" +msgstr "ジョイスティック(4軸、4ボタン)" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "86Boxを終了しますか?" msgid "Unable to initialize Ghostscript" msgstr "Ghostscriptが初期化できません" +msgid "Unable to initialize GhostPCL" +msgstr "GhostPCLが初期化できません" + msgid "MO %i (%ls): %ls" msgstr "光磁気 %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "光磁気イメージ" msgid "Welcome to 86Box!" msgstr "86Boxへようこそ!" -msgid "Internal controller" -msgstr "内蔵コントローラー" +msgid "Internal device" +msgstr "内蔵デバイス" msgid "Exit" msgstr "終了" @@ -841,7 +862,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 "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" +msgstr "古いパソコンのエミュレーター\n\n著者: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nSarah Walker, leilei, JohnElliott, greatpsycho, その他の方々による以前からの多大な貢献。\n\nGNU General Public License version 2以降でリリースされています。詳しくは LICENSE をご覧ください。" msgid "Hardware not available" msgstr "ハードウェアが利用できません" @@ -855,6 +876,9 @@ msgstr "不正な設定です" 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 "PostScriptファイルをPDFに自動変換するには%1が必要です。\n\n汎用PostScriptプリンターに送信された文書は、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 Language (.pcl) files." +msgstr "PCLファイルをPDFに自動変換するには%1が必要です。\n\n汎用PCLプリンターに送信された文書は、Printer Command Language (.pcl) ファイルとして保存されます。" + msgid "Entering fullscreen mode" msgstr "全画面モードを入力" @@ -999,6 +1023,27 @@ msgstr "上書き" msgid "Don't overwrite" msgstr "上書きしない" +msgid "Raw image" +msgstr "Rawイメージ" + +msgid "HDI image" +msgstr "HDIイメージ" + +msgid "HDX image" +msgstr "HDXイメージ" + +msgid "Fixed-size VHD" +msgstr "VHD (容量固定)" + +msgid "Dynamic-size VHD" +msgstr "VHD (容量可変)" + +msgid "Differencing VHD" +msgstr "VHD (差分)" + +msgid "(N/A)" +msgstr "(該当なし)" + msgid "Raw image (.img)" msgstr "Rawイメージ (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBoxはサポート終了" 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マネージャーの開発は、メンテナ不足のため2022年に停止しました。86Boxをより良いものにするため、WinBoxをマネージャーとしてサポートしないことを決定しました。\n\nWinBoxを使ったアップデートは今後提供されませんし、86Boxの新しいバージョンでWinBoxを使い続けると、正しくない動作に遭遇するかもしれません。WinBoxの動作に関連するバグレポートは無効としてクローズされます。\n\n86box.netに他のマネージャのリストがあります。" + +msgid "Generate" +msgstr "生成する" + +msgid "Joystick configuration" +msgstr "ジョイスティックの構成" + +msgid "Device" +msgstr "デバイス" + +msgid "%1 (X axis)" +msgstr "1(X軸)" + +msgid "%1 (Y axis)" +msgstr "1(Y軸)" + +msgid "MCA devices" +msgstr "MCAデバイス" + +msgid "List of MCA devices:" +msgstr "MCAデバイスのリスト:" + +msgid "Tablet tool" +msgstr "タブレットツール" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Qtについて" + +msgid "MCA devices..." +msgstr "MCAデバイス..." + +msgid "Show non-primary monitors" +msgstr "プライマリーモニター以外のモニターを表示する" + +msgid "Open screenshots folder..." +msgstr "スクリーンショットフォルダを開く" + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "最大化時にフルスクリーンストレッチモードを適用" + +msgid "Cursor/Puck" +msgstr "カーソル/パック" + +msgid "Pen" +msgstr "ペン" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "ホスト CD/DVD ドライブ (%1:)" + +msgid "&Connected" +msgstr "コネクテッド" + +msgid "Clear image history" +msgstr "クリア画像履歴" + +msgid "Create..." +msgstr "作成..." + +msgid "previous image" +msgstr "前の画像" + +msgid "Host CD/DVD Drive (%1)" +msgstr "ホスト CD/DVD ドライブ (%1)" + +msgid "Unknown Bus" +msgstr "不明バス" + +msgid "Null Driver" +msgstr "ヌル・ドライバー" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "エラー・オープニング\"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "ファイル\"%1\"の頂点シェーダのコンパイルエラー。" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "ファイル\"%1\"のフラグメント・シェーダのコンパイル・エラー。" + +msgid "Error linking shader program in file \"%1\"" +msgstr "ファイル\"%1\"のシェーダープログラムのリンクエラー。" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0レンダラー設定" + +msgid "Render behavior" +msgstr "レンダリング動作" + +msgid "Use target framerate:" +msgstr "目標フレームレートを使用する:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSシンク" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>エミュレートされたディスプレイと同期して、各フレームを即座にレンダリングします。</p><p><span style=" font-style:italic;">これは、使用中のシェーダがアニメーション効果のためにフレームタイムを利用しない場合に推奨されるオプションです。</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "ビデオと同期" + +msgid "Shaders" +msgstr "シェーダー" + +msgid "Remove" +msgstr "削除" + +msgid "No shader selected" +msgstr "シェーダーが選択されていない" + +msgid "Browse..." +msgstr "ブラウズ..." + +msgid "Shader error" +msgstr "シェーダーエラー" + +msgid "Could not load shaders." +msgstr "シェーダーをロードできませんでした。" + +msgid "More information in details." +msgstr "詳細はこちら。" + +msgid "Couldn't create OpenGL context." +msgstr "OpenGLコンテキストを作成できませんでした。" + +msgid "Couldn't switch to OpenGL context." +msgstr "OpenGLコンテキストに切り替えられなかった。" + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "OpenGLのバージョン3.0以上が必要です。現在のバージョンは %1.%2 です。" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL の初期化に失敗しました。エラー %1。" + +msgid "Error initializing OpenGL" +msgstr "OpenGLの初期化エラー" + +msgid "Falling back to software rendering.\n" +msgstr "ソフトウェアレンダリングに逆戻り。" + +msgid "Allocating memory for unpack buffer failed.\n" +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>" +msgstr "<html><head/><body><p>メディアイメージ(CD-ROM、フロッピーなど)を選択するとき、オープンダイアログは86Box設定ファイルと同じディレクトリで開始します。この設定は、おそらく macOS でのみ違いがあります。</p></body></html>" + +msgid "This machine might have been moved or copied." +msgstr "このマシンは移動されたかコピーされた可能性がある。" + +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 "ネットワーク機能を正しく動作させるために、86Boxはこのマシンが移動されたかコピーされたかを知る必要があります。「コピーした」を選択してください。" + +msgid "I Moved It" +msgstr "動かした" + +msgid "I Copied It" +msgstr "コピーした" + +msgid "86Box Monitor #" +msgstr "86Box モニター" + +msgid "No MCA devices." +msgstr "MCAデバイスはない。" + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "ネットワークカード 1" + +msgid "Network Card #2" +msgstr "ネットワークカード 2" + +msgid "Network Card #3" +msgstr "ネットワークカード 3" + +msgid "Network Card #4" +msgstr "ネットワークカード 4" + +msgid "Mode" +msgstr "モード" + +msgid "Interface" +msgstr "インターフェース" + +msgid "Adapter" +msgstr "アダプター" + +msgid "VDE Socket" +msgstr "VDEソケット" + +msgid "86Box Unit Tester" +msgstr "86Boxユニットテスター" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.xキーカード" + +msgid "Serial port passthrough 1" +msgstr "シリアル・ポート・パススルー 1" + +msgid "Serial port passthrough 2" +msgstr "シリアル・ポート・パススルー 2" + +msgid "Serial port passthrough 3" +msgstr "シリアル・ポート・パススルー 3" + +msgid "Serial port passthrough 4" +msgstr "シリアル・ポート・パススルー 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "ビジョン・システムズ LBAエンハンサー" + +msgid "Renderer options..." +msgstr "レンダラー設定..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft バスマウス" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft バスマウス(InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems シリアルマウス" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft シリアルマウス" + +msgid "Logitech Serial Mouse" +msgstr "Logitech シリアルマウス" + +msgid "PS/2 Mouse" +msgstr "PS/2マウス" + +msgid "3M MicroTouch (Serial)" +msgstr "3Mマイクロタッチ(シリアル)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] 標準ヘイズ準拠モデム" + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32エミュレーション" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32(新しい)エミュレーション" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32Lエミュレーション" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LNエミュレーション" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-MLドーターボード" + +msgid "System MIDI" +msgstr "システムMIDI" + +msgid "MIDI Input Device" +msgstr "MIDI入力デバイス" + +msgid "BIOS Address" +msgstr "BIOSアドレス" + +msgid "Enable BIOS extension ROM Writes" +msgstr "BIOS拡張ROM書き込みを有効にする" + +msgid "Address" +msgstr "アドレス" + +msgid "IRQ" +msgstr "割り込み要求" + +msgid "BIOS Revision" +msgstr "BIOSリビジョン" + +msgid "Translate 26 -> 17" +msgstr "26→17を翻訳" + +msgid "Language" +msgstr "言語" + +msgid "Enable backlight" +msgstr "バックライトを有効にする" + +msgid "Invert colors" +msgstr "色の反転" + +msgid "BIOS size" +msgstr "BIOSサイズ" + +msgid "Map C0000-C7FFF as UMB" +msgstr "C0000-C7FFFをUMBとしてマップ" + +msgid "Map C8000-CFFFF as UMB" +msgstr "C8000-CFFFFをUMBとしてマップ" + +msgid "Map D0000-D7FFF as UMB" +msgstr "D0000-D7FFFをUMBとしてマップ" + +msgid "Map D8000-DFFFF as UMB" +msgstr "D8000-DFFFFをUMBとしてマップ" + +msgid "Map E0000-E7FFF as UMB" +msgstr "E0000~E7FFFをUMBとしてマップ" + +msgid "Map E8000-EFFFF as UMB" +msgstr "E8000-EFFFFをUMBとしてマップ" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9ジャンパ(JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI出力デバイス" + +msgid "MIDI Real time" +msgstr "リアルタイムMIDI" + +msgid "MIDI Thru" +msgstr "MIDI入力のパススルー" + +msgid "MIDI Clockout" +msgstr "MIDIクロックの出力" + +msgid "SoundFont" +msgstr "サウンドフォント" + +msgid "Output Gain" +msgstr "出力ゲイン" + +msgid "Chorus" +msgstr "コーラス" + +msgid "Chorus Voices" +msgstr "コーラスの声" + +msgid "Chorus Level" +msgstr "コーラス・レベル" + +msgid "Chorus Speed" +msgstr "コーラス・スピード" + +msgid "Chorus Depth" +msgstr "コーラスの深さ" + +msgid "Chorus Waveform" +msgstr "コーラス波形" + +msgid "Reverb" +msgstr "リバーブ" + +msgid "Reverb Room Size" +msgstr "リバーブ・ルームの大きさ" + +msgid "Reverb Damping" +msgstr "リバーブ・ダンピング" + +msgid "Reverb Width" +msgstr "リバーブ幅" + +msgid "Reverb Level" +msgstr "リバーブ・レベル" + +msgid "Interpolation Method" +msgstr "補間法" + +msgid "Reverb Output Gain" +msgstr "リバーブ出力のゲイン" + +msgid "Reversed stereo" +msgstr "逆ステレオ" + +msgid "Nice ramp" +msgstr "ナイス・スロープ" + +msgid "Hz" +msgstr "ヘルツ" + +msgid "Buttons" +msgstr "ボタン" + +msgid "Serial Port" +msgstr "シリアルポート" + +msgid "RTS toggle" +msgstr "RTSトグル" + +msgid "Revision" +msgstr "改訂" + +msgid "Controller" +msgstr "コントローラー" + +msgid "Show Crosshair" +msgstr "十字線を表示" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MACアドレス" + +msgid "MAC Address OUI" +msgstr "MACアドレスのOUI" + +msgid "Enable BIOS" +msgstr "BIOSを有効にする" + +msgid "Baud Rate" +msgstr "ボーレート" + +msgid "TCP/IP listening port" +msgstr "TCP/IPリスニングポート" + +msgid "Phonebook File" +msgstr "電話帳ファイル" + +msgid "Telnet emulation" +msgstr "Telnetエミュレーション" + +msgid "RAM Address" +msgstr "RAMアドレス" + +msgid "RAM size" +msgstr "RAMサイズ" + +msgid "Initial RAM size" +msgstr "初期RAMサイズ" + +msgid "Serial Number" +msgstr "シリアル番号" + +msgid "Host ID" +msgstr "ホストID" + +msgid "FDC Address" +msgstr "FDCアドレス" + +msgid "MPU-401 Address" +msgstr "MPU-401 アドレス" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "MIDI入力を受信する" + +msgid "Low DMA" +msgstr "低DMA" + +msgid "Enable Game port" +msgstr "ゲームポートを有効にする" + +msgid "Surround module" +msgstr "サラウンド・モジュール" + +msgid "CODEC" +msgstr "コーデック" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "CODECセットアップ時にCODEC割り込みを発生させる(一部のドライバで必要)" + +msgid "SB Address" +msgstr "SBアドレス" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "OPLを有効にする" + +msgid "Receive MIDI input (MPU-401)" +msgstr "MIDI入力を受信する(MPU-401)" + +msgid "SB low DMA" +msgstr "SBローDMA" + +msgid "6CH variant (6-channel)" +msgstr "6CHバリアント(6チャンネル)" + +msgid "Enable CMS" +msgstr "CMSを有効にする" + +msgid "Mixer" +msgstr "ミキサー" + +msgid "High DMA" +msgstr "ハイDMA" + +msgid "Control PC speaker" +msgstr "コントロールPCスピーカー" + +msgid "Memory size" +msgstr "メモリーサイズ" + +msgid "EMU8000 Address" +msgstr "EMU8000 アドレス" + +msgid "IDE Controller" +msgstr "IDEコントローラ" + +msgid "Codec" +msgstr "コーデック" + +msgid "GUS type" +msgstr "GUSタイプ" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "コマンド 0x04 \"86Boxを終了する\"を有効にする" + +msgid "Display type" +msgstr "表示タイプ" + +msgid "Composite type" +msgstr "コンポジット・タイプ" + +msgid "RGB type" +msgstr "RGBタイプ" + +msgid "Line doubling type" +msgstr "ライン倍増タイプ" + +msgid "Snow emulation" +msgstr "スノー・エミュレーション" + +msgid "Monitor type" +msgstr "モニタータイプ" + +msgid "Character set" +msgstr "文字セット" + +msgid "XGA type" +msgstr "XGAタイプ" + +msgid "Instance" +msgstr "インスタンス" + +msgid "MMIO Address" +msgstr "MMIOアドレス" + +msgid "RAMDAC type" +msgstr "RAMDACタイプ" + +msgid "Blend" +msgstr "ブレンド" + +msgid "Bilinear filtering" +msgstr "バイリニア・フィルタリング" + +msgid "Dithering" +msgstr "ディザリング" + +msgid "Enable NMI for CGA emulation" +msgstr "CGAエミュレーションのNMIを有効にする" + +msgid "Voodoo type" +msgstr "Voodooタイプ" + +msgid "Framebuffer memory size" +msgstr "フレームバッファのメモリサイズ" + +msgid "Texture memory size" +msgstr "テクスチャメモリサイズ" + +msgid "Dither subtraction" +msgstr "ディザ減算" + +msgid "Screen Filter" +msgstr "スクリーンフィルター" + +msgid "Render threads" +msgstr "レンダリングスレッド" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "開始アドレス" + +msgid "Contiguous Size" +msgstr "連続サイズ" + +msgid "I/O Width" +msgstr "I/O幅" + +msgid "Transfer Speed" +msgstr "転送速度" + +msgid "EMS mode" +msgstr "EMSモード" + +msgid "Address for > 2 MB" +msgstr "2MB以上のアドレス" + +msgid "Frame Address" +msgstr "フレームアドレス" + +msgid "USA" +msgstr "アメリカ" + +msgid "Danish" +msgstr "デンマーク語" + +msgid "Always at selected speed" +msgstr "常に選択された速度" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "BIOS設定+ホットキー(POST中はオフ)" + +msgid "64 kB starting from F0000" +msgstr "F0000から始まる64キロバイト" + +msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "E0000から始まる128キロバイト(アドレスMSBが反転、最後の64キロバイトが最初)" + +msgid "Sine" +msgstr "正弦" + +msgid "Triangle" +msgstr "三角" + +msgid "Linear" +msgstr "線形" + +msgid "4th Order" +msgstr "4次" + +msgid "7th Order" +msgstr "7次" + +msgid "Non-timed (original)" +msgstr "タイマーなし(オリジナル)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz(JMP2にジャンパーなし)" + +msgid "Two" +msgstr "二つ" + +msgid "Three" +msgstr "三つ" + +msgid "Wheel" +msgstr "ホイール" + +msgid "Five + Wheel" +msgstr "五つ+ホイール" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 シリアル / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R)シリアル" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "BIOSを無効にする" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "シグマテル STAC9721T(ステレオ)" + +msgid "Classic" +msgstr "クラシック" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "コンポジット" + +msgid "Old" +msgstr "古い" + +msgid "New" +msgstr "新しい" + +msgid "Color (generic)" +msgstr "カラー(ジェネリック)" + +msgid "Green Monochrome" +msgstr "みどりのモノクローム" + +msgid "Amber Monochrome" +msgstr "鼈甲色のモノクローム" + +msgid "Gray Monochrome" +msgstr "ねずみ色のモノクローム" + +msgid "Color (no brown)" +msgstr "カラー(ブラウンなし)" + +msgid "Color (IBM 5153)" +msgstr "カラー(IBM 5153)" + +msgid "Simple doubling" +msgstr "単純な倍加" + +msgid "sRGB interpolation" +msgstr "sRGB補間" + +msgid "Linear interpolation" +msgstr "線形補間" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "モノクローム(5151/MDA)(白い)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "モノクローム(5151/MDA)(みどり)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "モノクローム(5151/MDA)(鼈甲色)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "カラー40x25(5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "カラー80x25(5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "エンハンスト・カラー - ノーマルモード(5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "エンハンスト・カラー - エンハンスト・モード(5154/ECD)" + +msgid "Green" +msgstr "みどり" + +msgid "Amber" +msgstr "鼈甲色" + +msgid "Gray" +msgstr "ねずみ色" + +msgid "Color" +msgstr "カラー" + +msgid "U.S. English" +msgstr "アメリカ英語" + +msgid "Scandinavian" +msgstr "スカンジナビア" + +msgid "Other languages" +msgstr "その他の言語" + +msgid "Bochs latest" +msgstr "Bochs latest" + +msgid "Mono Non-Interlaced" +msgstr "モノラル・ノンインターレース" + +msgid "Color Interlaced" +msgstr "カラー・インターレース" + +msgid "Color Non-Interlaced" +msgstr "カラー・ノンインターレース" + +msgid "3Dfx Voodoo Graphics" +msgstr "3dfx Voodooグラフィック" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst(2 TMU単位)" + +msgid "8-bit" +msgstr "8ビット" + +msgid "16-bit" +msgstr "16ビット" + +msgid "Standard (150ns)" +msgstr "標準(150ns)" + +msgid "High-Speed (120ns)" +msgstr "高速(120ns)" + +msgid "Enabled" +msgstr "有効" + +msgid "Standard" +msgstr "スタンダード" + +msgid "High-Speed" +msgstr "高速" + +msgid "Stereo LPT DAC" +msgstr "ステレオLPT DAC" + +msgid "Generic Text Printer" +msgstr "汎用テキスト・プリンタ" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "汎用ESC/Pドットマトリクスプリンタ" + +msgid "Generic PostScript Printer" +msgstr "汎用ポストスクリプトプリンタ" + +msgid "Generic PCL5e Printer" +msgstr "汎用PCL5eプリンタ" + +msgid "Parallel Line Internet Protocol" +msgstr "パラレルライン・インターネット・プロトコル" + +msgid "Protection Dongle for Savage Quest" +msgstr "サベージ・クエスト用プロテクション・ドングル" + +msgid "Serial Passthrough Device" +msgstr "シリアル・ポート・パススルー・デバイス" + +msgid "Passthrough Mode" +msgstr "パススルーモード" + +msgid "Host Serial Device" +msgstr "ホスト・シリアル・デバイス" + +msgid "Name of pipe" +msgstr "パイプ名" + +msgid "Data bits" +msgstr "データビット" + +msgid "Stop bits" +msgstr "ストップビット" + +msgid "Baud Rate of Passthrough" +msgstr "パススルーのボーレート" + +msgid "Named Pipe (Server)" +msgstr "名前付きパイプ(サーバー)" + +msgid "Host Serial Passthrough" +msgstr "ホストシリアルポートのパススルー" + +msgid "Eject %s" +msgstr "%sを取り出す" + +msgid "&Unmute" +msgstr "ミュート解除(&U)" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "パフォーマンスへの影響が大きい" + +msgid "RAM Disk (max. speed)" +msgstr "RAMディスク(最高速度)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A クローン(ISA)" + +msgid "Vendor" +msgstr "業者" + +msgid "Generic PC/XT Memory Expansion" +msgstr "汎用PC/XTメモリ拡張カード" + +msgid "Generic PC/AT Memory Expansion" +msgstr "汎用PC/ATメモリ拡張カード" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index afecf78f6..c6928ad43 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -390,8 +390,11 @@ msgstr "동적 재컴파일" msgid "Video:" msgstr "비디오 카드:" -msgid "Voodoo Graphics" -msgstr "Voodoo 그래픽" +msgid "Video 2:" +msgstr "비디오 카드 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 또는 2 그래픽" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/A 그래픽" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "치명적인 오류" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - 일시 중지됨" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Ctrl+Alt+PgDn 키를 누르면 창 모드로 전환합니다." @@ -684,6 +687,12 @@ msgstr "roms/machines 디렉토리에 필요한 롬파일이 없어 기종 \"%hs msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "roms/video 디렉토리에 필요한 롬파일이 없어 비디오 카드 \"%hs\"을(를) 사용할 수 없습니다. 사용 가능한 기종으로 변경합니다." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "roms/video 디렉토리에 필요한 롬파일이 없어 비디오 카드 2 \"%hs\"을(를) 사용할 수 없습니다. 두 번째 비디오 카드를 비활성화합니다." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "필요한 롬파일이 없어 장치 \"%hs\"을(를) 사용할 수 없습니다. 장치를 무시합니다." + msgid "Machine" msgstr "기종" @@ -762,17 +771,26 @@ msgstr "PCap 장치가 없습니다" msgid "Invalid PCap device" msgstr "PCap 장치가 올바르지 않습니다" -msgid "Standard 2-button joystick(s)" -msgstr "표준 2버튼 조이스틱" +msgid "2-axis, 2-button joystick(s)" +msgstr "2축, 2버튼 조이스틱" -msgid "Standard 4-button joystick" -msgstr "표준 4버튼 조이스틱" +msgid "2-axis, 4-button joystick" +msgstr "2축, 4버튼 조이스틱" -msgid "Standard 6-button joystick" -msgstr "표준 6버튼 조이스틱" +msgid "2-axis, 6-button joystick" +msgstr "2축, 6버튼 조이스틱" -msgid "Standard 8-button joystick" -msgstr "표준 8버튼 조이스틱" +msgid "2-axis, 8-button joystick" +msgstr "2축, 8버튼 조이스틱" + +msgid "3-axis, 2-button joystick" +msgstr "3축, 2버튼 조이스틱" + +msgid "3-axis, 4-button joystick" +msgstr "3축, 4버튼 조이스틱" + +msgid "4-axis, 4-button joystick" +msgstr "4축, 4버튼 조이스틱" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "86Box를 끝내시겠습니까?" msgid "Unable to initialize Ghostscript" msgstr "Ghostscript를 초기화할 수 없습니다" +msgid "Unable to initialize GhostPCL" +msgstr "GhostPCL를 초기화할 수 없습니다" + msgid "MO %i (%ls): %ls" msgstr "광자기 %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "광자기 이미지" msgid "Welcome to 86Box!" msgstr "86Box에 어서오세요!" -msgid "Internal controller" -msgstr "내부 컨트롤러" +msgid "Internal device" +msgstr "내부 장치" msgid "Exit" msgstr "끝내기" @@ -841,7 +862,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 "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." +msgstr "고전 컴퓨터 에뮬레이터\n\n저자: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\n이전 핵심 기여자로는 Sarah Walker, leilei, JohnElliott, greatpsycho 등이 있습니다.\n\nGNU General Public 라이선스 (버전 2 이상)에 의해 배포되었습니다. 자세한 내용은 LICENSE 파일을 읽어 주세요." msgid "Hardware not available" msgstr "하드웨어를 이용할 수 없습니다" @@ -855,6 +876,9 @@ msgstr "올바르지 않은 설정입니다" 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 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PostScript 프린터로 보내신 임의의 문서는 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 Language (.pcl) files." +msgstr "%1은(는) PCL 파일을 PDF로 자동변환하는 데에 필요합니다.\n\n표준 PCL 프린터로 보내신 임의의 문서는 Printer Command Language (.pcl) 파일로 저장됩니다." + msgid "Entering fullscreen mode" msgstr "전체 화면으로 전환" @@ -999,6 +1023,27 @@ msgstr "덮어쓰기" msgid "Don't overwrite" msgstr "덮어쓰지 않음" +msgid "Raw image" +msgstr "Raw 이미지" + +msgid "HDI image" +msgstr "HDI 이미지" + +msgid "HDX image" +msgstr "HDX 이미지" + +msgid "Fixed-size VHD" +msgstr "고정 사이즈 VHD" + +msgid "Dynamic-size VHD" +msgstr "동적 사이즈 VHD" + +msgid "Differencing VHD" +msgstr "디퍼런싱 VHD" + +msgid "(N/A)" +msgstr "(해당 없음)" + msgid "Raw image (.img)" msgstr "Raw 이미지 (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBox는 더 이상 지원되지 않습니다" 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 매니저의 개발은 유지 관리자의 부족으로 인해 2022년에 중단되었습니다. 86Box를 더욱 개선하기 위한 노력의 일환으로 WinBox 매니저를 더 이상 지원하지 않기로 결정했습니다.\n\nWinBox를 통해 더 이상의 업데이트는 제공되지 않으며, 최신 버전의 86Box를 계속 사용할 경우 잘못된 동작이 발생할 수 있습니다. WinBox 동작과 관련된 모든 버그 보고는 유효하지 않은 것으로 종료됩니다.\n\n사용할 수 있는 다른 관리자 목록을 보려면 86box.net으로 이동하세요." + +msgid "Generate" +msgstr "생성" + +msgid "Joystick configuration" +msgstr "조이스틱 구성" + +msgid "Device" +msgstr "장치" + +msgid "%1 (X axis)" +msgstr "1(X 축)" + +msgid "%1 (Y axis)" +msgstr "1(Y 축)" + +msgid "MCA devices" +msgstr "MCA 장치" + +msgid "List of MCA devices:" +msgstr "MCA 장치 목록:" + +msgid "Tablet tool" +msgstr "태블릿 도구" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt(OpenGL &ES)" + +msgid "About Qt" +msgstr "Qt 소개" + +msgid "MCA devices..." +msgstr "MCA 장치..." + +msgid "Show non-primary monitors" +msgstr "기본 모니터가 아닌 모니터 표시" + +msgid "Open screenshots folder..." +msgstr "스크린샷 폴더 열기..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "최대화 시 전체 화면 비율 적용" + +msgid "Cursor/Puck" +msgstr "커서/퍽" + +msgid "Pen" +msgstr "펜" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "호스트 CD/DVD 드라이브(%1:)" + +msgid "&Connected" +msgstr "&커넥티드" + +msgid "Clear image history" +msgstr "이미지 기록 지우기" + +msgid "Create..." +msgstr "만들기..." + +msgid "previous image" +msgstr "이전 이미지" + +msgid "Host CD/DVD Drive (%1)" +msgstr "호스트 CD/DVD 드라이브 (%1)" + +msgid "Unknown Bus" +msgstr "알 수 없는 버스" + +msgid "Null Driver" +msgstr "Null 드라이버" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "열기 오류 \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "파일 \"%1\"에서 버텍스 셰이더를 컴파일하는 동안 오류가 발생했습니다." + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "파일에서 조각 셰이더 컴파일 중 오류 발생 \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "파일에서 셰이더 프로그램 연결 중 오류 \"%1\"\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 렌더러 옵션" + +msgid "Render behavior" +msgstr "렌더링 동작" + +msgid "Use target framerate:" +msgstr "목표 프레임 레이트를 사용합니다:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>;에뮬레이트된 디스플레이와 동기화하여 각 프레임을 즉시 렌더링합니다.</p><p><span style=" font-style:italic;">사용 중인 셰이더가 애니메이션 효과에 프레임 시간을 활용하지 않는 경우 권장되는 옵션입니다.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "비디오와 동기" + +msgid "Shaders" +msgstr "셰이더" + +msgid "Remove" +msgstr "제거" + +msgid "No shader selected" +msgstr "셰이더를 선택하지 않음" + +msgid "Browse..." +msgstr "찾아보기..." + +msgid "Shader error" +msgstr "셰이더 오류" + +msgid "Could not load shaders." +msgstr "셰이더를 로드할 수 없습니다." + +msgid "More information in details." +msgstr "자세한 내용은 자세히 알아보세요." + +msgid "Couldn't create OpenGL context." +msgstr "OpenGL 컨텍스트를 만들 수 없습니다." + +msgid "Couldn't switch to OpenGL context." +msgstr "OpenGL 컨텍스트로 전환할 수 없습니다." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "OpenGL 버전 3.0 이상이 필요합니다. 현재 버전은 %1.%2입니다." + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL 초기화에 실패했습니다. 오류 %1입니다." + +msgid "Error initializing OpenGL" +msgstr "OpenGL 초기화 중 오류 발생" + +msgid "Falling back to software rendering.\n" +msgstr "소프트웨어 렌더링으로 돌아가기.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +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 "This machine might have been moved or copied." +msgstr "이 컴퓨터가 이동되었거나 복사되었을 수 있습니다." + +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 "적절한 네트워킹 기능을 보장하기 위해 86Box는 이 머신이 이동 또는 복사되었는지 여부를 알아야 합니다.\n\n확실하지 않은 경우 \"복사했습니다\"를 선택합니다." + +msgid "I Moved It" +msgstr "옮겼어요" + +msgid "I Copied It" +msgstr "복사했습니다" + +msgid "86Box Monitor #" +msgstr "86Box 모니터 " + +msgid "No MCA devices." +msgstr "MCA 장치가 없습니다." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "네트워크 카드 1" + +msgid "Network Card #2" +msgstr "네트워크 카드 2" + +msgid "Network Card #3" +msgstr "네트워크 카드 3" + +msgid "Network Card #4" +msgstr "네트워크 카드 4" + +msgid "Mode" +msgstr "모드" + +msgid "Interface" +msgstr "인터페이스" + +msgid "Adapter" +msgstr "어댑터" + +msgid "VDE Socket" +msgstr "VDE 소켓" + +msgid "86Box Unit Tester" +msgstr "86Box 유닛 테스터" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x 키 카드" + +msgid "Serial port passthrough 1" +msgstr "직렬 포트 패스스루 1" + +msgid "Serial port passthrough 2" +msgstr "직렬 포트 패스스루 2" + +msgid "Serial port passthrough 3" +msgstr "직렬 포트 패스스루 3" + +msgid "Serial port passthrough 4" +msgstr "직렬 포트 패스스루 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "비전 시스템 LBA 인핸서" + +msgid "Renderer options..." +msgstr "렌더러 옵션..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "로지텍/마이크로소프트 버스 마우스" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "마이크로소프트 버스 마우스(인포트)" + +msgid "Mouse Systems Serial Mouse" +msgstr "마우스 시스템 시리얼 마우스" + +msgid "Microsoft Serial Mouse" +msgstr "마이크로소프트 직렬 마우스" + +msgid "Logitech Serial Mouse" +msgstr "로지텍 직렬 마우스" + +msgid "PS/2 Mouse" +msgstr "PS/2 마우스" + +msgid "3M MicroTouch (Serial)" +msgstr "3M 마이크로터치(직렬)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] 표준 헤이즈 호환 모뎀" + +msgid "Roland MT-32 Emulation" +msgstr "롤랜드 MT-32 에뮬레이션" + +msgid "Roland MT-32 (New) Emulation" +msgstr "롤랜드 MT-32(신규) 에뮬레이션" + +msgid "Roland CM-32L Emulation" +msgstr "롤랜드 CM-32L 에뮬레이션" + +msgid "Roland CM-32LN Emulation" +msgstr "롤랜드 CM-32LN 에뮬레이션" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML 도터보드" + +msgid "System MIDI" +msgstr "시스템 미디" + +msgid "MIDI Input Device" +msgstr "미디 입력 장치" + +msgid "BIOS Address" +msgstr "BIOS 주소" + +msgid "Enable BIOS extension ROM Writes" +msgstr "BIOS 확장 ROM 쓰기 활성화" + +msgid "Address" +msgstr "주소" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS 개정" + +msgid "Translate 26 -> 17" +msgstr "번역 26 -> 17" + +msgid "Language" +msgstr "언어" + +msgid "Enable backlight" +msgstr "백라이트 사용" + +msgid "Invert colors" +msgstr "색상 반전" + +msgid "BIOS size" +msgstr "BIOS 크기" + +msgid "Map C0000-C7FFF as UMB" +msgstr "C0000-C7FFF를 UMB로 매핑하기" + +msgid "Map C8000-CFFFF as UMB" +msgstr "C8000-CFFFF를 UMB로 매핑하기" + +msgid "Map D0000-D7FFF as UMB" +msgstr "D0000-D7FFF를 UMB로 매핑하기" + +msgid "Map D8000-DFFFF as UMB" +msgstr "D8000-DFFFF를 UMB로 매핑하기" + +msgid "Map E0000-E7FFF as UMB" +msgstr "E0000-E7FFF를 UMB로 매핑하기" + +msgid "Map E8000-EFFFF as UMB" +msgstr "E8000-EFFFF를 UMB로 매핑하기" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 점퍼(JIM)" + +msgid "MIDI Output Device" +msgstr "미디 출력 장치" + +msgid "MIDI Real time" +msgstr "실시간 MIDI" + +msgid "MIDI Thru" +msgstr "미디 입력 패스스루" + +msgid "MIDI Clockout" +msgstr "미디 클럭 출력" + +msgid "SoundFont" +msgstr "사운드 글꼴" + +msgid "Output Gain" +msgstr "출력 게인" + +msgid "Chorus" +msgstr "코러스" + +msgid "Chorus Voices" +msgstr "코러스 보이스" + +msgid "Chorus Level" +msgstr "코러스 레벨" + +msgid "Chorus Speed" +msgstr "코러스 속도" + +msgid "Chorus Depth" +msgstr "코러스 깊이" + +msgid "Chorus Waveform" +msgstr "코러스 파형" + +msgid "Reverb" +msgstr "리버브" + +msgid "Reverb Room Size" +msgstr "리버브 룸의 크기" + +msgid "Reverb Damping" +msgstr "리버브 댐핑" + +msgid "Reverb Width" +msgstr "리버브 폭" + +msgid "Reverb Level" +msgstr "리버브 레벨" + +msgid "Interpolation Method" +msgstr "보간 방법" + +msgid "Reverb Output Gain" +msgstr "리버브 출력의 게인" + +msgid "Reversed stereo" +msgstr "리버시블 스테레오" + +msgid "Nice ramp" +msgstr "멋진 경사로" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "버튼" + +msgid "Serial Port" +msgstr "직렬 포트" + +msgid "RTS toggle" +msgstr "RTS 토글" + +msgid "Revision" +msgstr "개정" + +msgid "Controller" +msgstr "컨트롤러" + +msgid "Show Crosshair" +msgstr "십자선 표시" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC 주소" + +msgid "MAC Address OUI" +msgstr "MAC 주소 OUI" + +msgid "Enable BIOS" +msgstr "BIOS 활성화" + +msgid "Baud Rate" +msgstr "전송 속도" + +msgid "TCP/IP listening port" +msgstr "TCP/IP 수신 포트" + +msgid "Phonebook File" +msgstr "전화번호부 파일" + +msgid "Telnet emulation" +msgstr "텔넷 에뮬레이션" + +msgid "RAM Address" +msgstr "RAM 주소" + +msgid "RAM size" +msgstr "RAM 크기" + +msgid "Initial RAM size" +msgstr "초기 RAM 크기" + +msgid "Serial Number" +msgstr "일련 번호" + +msgid "Host ID" +msgstr "호스트 ID" + +msgid "FDC Address" +msgstr "FDC 주소" + +msgid "MPU-401 Address" +msgstr "MPU-401 주소" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "미디 입력 받기" + +msgid "Low DMA" +msgstr "낮은 DMA" + +msgid "Enable Game port" +msgstr "게임 포트 사용" + +msgid "Surround module" +msgstr "서라운드 모듈" + +msgid "CODEC" +msgstr "코덱" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "코덱 설정 시 코덱 인터럽트 올리기(일부 드라이버에 필요)" + +msgid "SB Address" +msgstr "SB 주소" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "OPL 사용" + +msgid "Receive MIDI input (MPU-401)" +msgstr "미디 입력 수신(MPU-401)" + +msgid "SB low DMA" +msgstr "SB 낮은 DMA" + +msgid "6CH variant (6-channel)" +msgstr "6채널 변형(6채널)" + +msgid "Enable CMS" +msgstr "CMS 사용" + +msgid "Mixer" +msgstr "믹서" + +msgid "High DMA" +msgstr "높은 DMA" + +msgid "Control PC speaker" +msgstr "PC 스피커 제어" + +msgid "Memory size" +msgstr "메모리 크기" + +msgid "EMU8000 Address" +msgstr "EMU8000 주소" + +msgid "IDE Controller" +msgstr "IDE 컨트롤러" + +msgid "Codec" +msgstr "코덱" + +msgid "GUS type" +msgstr "GUS 유형" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "명령 0x04 활성화 \"86Box 종료\"" + +msgid "Display type" +msgstr "디스플레이 유형" + +msgid "Composite type" +msgstr "복합 유형" + +msgid "RGB type" +msgstr "RGB 유형" + +msgid "Line doubling type" +msgstr "라인 두 배 유형" + +msgid "Snow emulation" +msgstr "눈 에뮬레이션" + +msgid "Monitor type" +msgstr "모니터 유형" + +msgid "Character set" +msgstr "문자 집합" + +msgid "XGA type" +msgstr "XGA 유형" + +msgid "Instance" +msgstr "인스턴스" + +msgid "MMIO Address" +msgstr "MMIO 주소" + +msgid "RAMDAC type" +msgstr "램닥 유형" + +msgid "Blend" +msgstr "블렌드" + +msgid "Bilinear filtering" +msgstr "이중선형 필터링" + +msgid "Dithering" +msgstr "디더링" + +msgid "Enable NMI for CGA emulation" +msgstr "CGA 에뮬레이션을 위한 NMI 활성화" + +msgid "Voodoo type" +msgstr "부두 유형" + +msgid "Framebuffer memory size" +msgstr "프레임버퍼 메모리 크기" + +msgid "Texture memory size" +msgstr "텍스처 메모리 크기" + +msgid "Dither subtraction" +msgstr "디더 빼기" + +msgid "Screen Filter" +msgstr "화면 필터" + +msgid "Render threads" +msgstr "렌더 스레드" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "시작 주소" + +msgid "Contiguous Size" +msgstr "연속 크기" + +msgid "I/O Width" +msgstr "I/O 폭" + +msgid "Transfer Speed" +msgstr "전송 속도" + +msgid "EMS mode" +msgstr "EMS 모드" + +msgid "Address for > 2 MB" +msgstr "2MB 이상의 주소" + +msgid "Frame Address" +msgstr "프레임 주소" + +msgid "USA" +msgstr "미국" + +msgid "Danish" +msgstr "덴마크어" + +msgid "Always at selected speed" +msgstr "항상 선택한 속도로" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "BIOS 설정 + 핫키(POST 중 꺼짐)" + +msgid "64 kB starting from F0000" +msgstr "64kB부터 F0000" + +msgid "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "E0000에서 시작하는 128kB(주소 MSB 반전, 마지막 64KB 먼저)" + +msgid "Sine" +msgstr "사인" + +msgid "Triangle" +msgstr "삼각형" + +msgid "Linear" +msgstr "선형" + +msgid "4th Order" +msgstr "4차 주문" + +msgid "7th Order" +msgstr "7차 주문" + +msgid "Non-timed (original)" +msgstr "타이머 없음(원본)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45Hz(JMP2에서 점퍼 없음)" + +msgid "Two" +msgstr "Two" + +msgid "Three" +msgstr "세" + +msgid "Wheel" +msgstr "휠" + +msgid "Five + Wheel" +msgstr "5개 + 휠" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 직렬/SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) 직렬" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "BIOS 비활성화" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2MB" + +msgid "8 MB" +msgstr "8MB" + +msgid "28 MB" +msgstr "28MB" + +msgid "1 MB" +msgstr "1MB" + +msgid "4 MB" +msgstr "4MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16MB" + +msgid "20 MB" +msgstr "20MB" + +msgid "24 MB" +msgstr "24MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "시그마텔 STAC9721T(스테레오)" + +msgid "Classic" +msgstr "클래식" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "합성" + +msgid "Old" +msgstr "Old" + +msgid "New" +msgstr "신규" + +msgid "Color (generic)" +msgstr "색상(일반)" + +msgid "Green Monochrome" +msgstr "녹색 단색" + +msgid "Amber Monochrome" +msgstr "앰버 모노크롬" + +msgid "Gray Monochrome" +msgstr "회색 단색" + +msgid "Color (no brown)" +msgstr "색상(갈색 없음)" + +msgid "Color (IBM 5153)" +msgstr "색상(IBM 5153)" + +msgid "Simple doubling" +msgstr "간단한 두 배로 늘리기" + +msgid "sRGB interpolation" +msgstr "sRGB 보간" + +msgid "Linear interpolation" +msgstr "선형 보간" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "흑백(5151/MDA)(흰색)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "흑백(5151/MDA)(녹색)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "흑백(5151/MDA)(호박색)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "컬러 40x25(5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "컬러 80x25(5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "향상된 색상 - 일반 모드(5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "향상된 색상 - 향상된 모드(5154/ECD)" + +msgid "Green" +msgstr "녹색" + +msgid "Amber" +msgstr "Amber" + +msgid "Gray" +msgstr "회색" + +msgid "Color" +msgstr "색상" + +msgid "U.S. English" +msgstr "미국 영어" + +msgid "Scandinavian" +msgstr "스칸디나비아" + +msgid "Other languages" +msgstr "기타 언어" + +msgid "Bochs latest" +msgstr "Bochs 최신 정보" + +msgid "Mono Non-Interlaced" +msgstr "모노 비인터레이스" + +msgid "Color Interlaced" +msgstr "컬러 인터레이스" + +msgid "Color Non-Interlaced" +msgstr "비인터레이스 컬러" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx 부두 그래픽" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "옵시디언 SB50 + 자수정(TMU 2개)" + +msgid "8-bit" +msgstr "8비트" + +msgid "16-bit" +msgstr "16비트" + +msgid "Standard (150ns)" +msgstr "표준(150ns)" + +msgid "High-Speed (120ns)" +msgstr "고속(120ns)" + +msgid "Enabled" +msgstr "활성화됨" + +msgid "Standard" +msgstr "표준" + +msgid "High-Speed" +msgstr "고속" + +msgid "Stereo LPT DAC" +msgstr "스테레오 LPT DAC" + +msgid "Generic Text Printer" +msgstr "일반 텍스트 프린터" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "일반 ESC/P 도트 매트릭스 프린터" + +msgid "Generic PostScript Printer" +msgstr "일반 포스트스크립트 프린터" + +msgid "Generic PCL5e Printer" +msgstr "일반 PCL5e 프린터" + +msgid "Parallel Line Internet Protocol" +msgstr "병렬 인터넷 프로토콜" + +msgid "Protection Dongle for Savage Quest" +msgstr "새비지 퀘스트용 보호 동글" + +msgid "Serial Passthrough Device" +msgstr "직렬 포트 패스스루 장치" + +msgid "Passthrough Mode" +msgstr "패스스루 모드" + +msgid "Host Serial Device" +msgstr "호스트 직렬 장치" + +msgid "Name of pipe" +msgstr "파이프 이름" + +msgid "Data bits" +msgstr "데이터 비트" + +msgid "Stop bits" +msgstr "비트 중지" + +msgid "Baud Rate of Passthrough" +msgstr "통과 속도" + +msgid "Named Pipe (Server)" +msgstr "네임드 파이프(서버)" + +msgid "Host Serial Passthrough" +msgstr "호스트 직렬 포트 패스스루" + +msgid "Eject %s" +msgstr "%s 꺼내기" + +msgid "&Unmute" +msgstr "음소거 해제(&U)" + +msgid "Softfloat FPU" +msgstr "소프트플로트 FPU" + +msgid "High performance impact" +msgstr "성능에 미치는 영향" + +msgid "RAM Disk (max. speed)" +msgstr "RAM 디스크(최대 속도)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A 클론(ISA)" + +msgid "Vendor" +msgstr "제조사" + +msgid "Generic PC/XT Memory Expansion" +msgstr "일반 PC/XT 메모리 확장 카드" + +msgid "Generic PC/AT Memory Expansion" +msgstr "일반 PC/AT 메모리 확장 카드" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po new file mode 100644 index 000000000..27870db90 --- /dev/null +++ b/src/qt/languages/nl-NL.po @@ -0,0 +1,2131 @@ +msgid "" +msgstr "" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: nl_NL\n" +"X-Source-Language: en_US\n" + +msgid "&Action" +msgstr "&Actie" + +msgid "&Keyboard requires capture" +msgstr "&Keyboard vereist vastleggen" + +msgid "&Right CTRL is left ALT" +msgstr "&Rechtse CTRL is linkse ALT" + +msgid "&Hard Reset..." +msgstr "&Harde Reset..." + +msgid "&Ctrl+Alt+Del\tCtrl+F12" +msgstr "&Ctrl+Alt+Del\tCtrl+F12" + +msgid "Ctrl+Alt+&Esc" +msgstr "Ctrl+Alt+&Esc" + +msgid "&Pause" +msgstr "&Pauze" + +msgid "E&xit..." +msgstr "&Afsluiten..." + +msgid "&View" +msgstr "&Beeld" + +msgid "&Hide status bar" +msgstr "&Statusbalk verbergen" + +msgid "Hide &toolbar" +msgstr "Verberg &toolbar" + +msgid "&Resizeable window" +msgstr "&Venster met aanpasbare grootte" + +msgid "R&emember size && position" +msgstr "&Onthoud grootte && positie" + +msgid "Re&nderer" +msgstr "Re&nderer" + +msgid "&Qt (Software)" +msgstr "&Qt (software)" + +msgid "Qt (&OpenGL)" +msgstr "Qt (&OpenGL)" + +msgid "Open&GL (3.0 Core)" +msgstr "Open&GL (3.0 Core)" + +msgid "&VNC" +msgstr "&VNC" + +msgid "Specify dimensions..." +msgstr "Afmetingen opgeven..." + +msgid "F&orce 4:3 display ratio" +msgstr "F&orceer 4:3 beeldverhouding" + +msgid "&Window scale factor" +msgstr "&Venster schaalfactor" + +msgid "&0.5x" +msgstr "&0,5x" + +msgid "&1x" +msgstr "&1x" + +msgid "1.&5x" +msgstr "1,&5x" + +msgid "&2x" +msgstr "&2x" + +msgid "&3x" +msgstr "&3x" + +msgid "&4x" +msgstr "&4x" + +msgid "&5x" +msgstr "&5x" + +msgid "&6x" +msgstr "&6x" + +msgid "&7x" +msgstr "&7x" + +msgid "&8x" +msgstr "&8x" + +msgid "Filter method" +msgstr "Filtermethode" + +msgid "&Nearest" +msgstr "&Dichtsbijzijnde" + +msgid "&Linear" +msgstr "&Lineair" + +msgid "Hi&DPI scaling" +msgstr "Hi&DPI-schaling" + +msgid "&Fullscreen\tCtrl+Alt+PgUp" +msgstr "&Fullscreen\tCtrl+Alt+PgUp" + +msgid "Fullscreen &stretch mode" +msgstr "Volledig scherm &uitrekmodus" + +msgid "&Full screen stretch" +msgstr "&Volledig scherm uitrekken" + +msgid "&4:3" +msgstr "&4:3" + +msgid "&Square pixels (Keep ratio)" +msgstr "&Vierkante pixels (behoud verhouding)" + +msgid "&Integer scale" +msgstr "&Integerschaal" + +msgid "4:&3 Integer scale" +msgstr "4:&3 integerschaal" + +msgid "E&GA/(S)VGA settings" +msgstr "E&GA/(S)VGA-instellingen" + +msgid "&Inverted VGA monitor" +msgstr "Ge&ïnverteerde VGA-monitor" + +msgid "VGA screen &type" +msgstr "VGA-scherm &type" + +msgid "RGB &Color" +msgstr "RGB &Kleur" + +msgid "&RGB Grayscale" +msgstr "&RGB grijstinten" + +msgid "&Amber monitor" +msgstr "&Amber monitor" + +msgid "&Green monitor" +msgstr "&Groene monitor" + +msgid "&White monitor" +msgstr "&Witte monitor" + +msgid "Grayscale &conversion type" +msgstr "Grijstinten &conversietype" + +msgid "BT&601 (NTSC/PAL)" +msgstr "BT&601 (NTSC/PAL)" + +msgid "BT&709 (HDTV)" +msgstr "BT&709 (HDTV)" + +msgid "&Average" +msgstr "&Gemiddelde" + +msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" +msgstr "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" + +msgid "Change contrast for &monochrome display" +msgstr "Contrast wijzigen voor &monochroom beeldscherm" + +msgid "&Media" +msgstr "&Media" + +msgid "&Tools" +msgstr "&Tools" + +msgid "&Settings..." +msgstr "&Instellingen..." + +msgid "&Update status bar icons" +msgstr "&Statusbalkpictogrammen bijwerken" + +msgid "Take s&creenshot\tCtrl+F11" +msgstr "Maak een schermafbeelding\tCtrl+F11" + +msgid "&Preferences..." +msgstr "&Voorkeuren..." + +msgid "Enable &Discord integration" +msgstr "&Discord integratie inschakelen" + +msgid "Sound &gain..." +msgstr "&Geluidsversterking..." + +msgid "Begin trace\tCtrl+T" +msgstr "Begin traceren\tCtrl+T" + +msgid "End trace\tCtrl+T" +msgstr "Traceren beëindigen\tCtrl+T" + +msgid "&Help" +msgstr "&Help" + +msgid "&Documentation..." +msgstr "&Documentatie..." + +msgid "&About 86Box..." +msgstr "&Over 86Box..." + +msgid "&New image..." +msgstr "&Nieuw image..." + +msgid "&Existing image..." +msgstr "&Bestaande image..." + +msgid "Existing image (&Write-protected)..." +msgstr "Bestaande image (&Schrijfbeveiligd)..." + +msgid "&Record" +msgstr "&Opnemen" + +msgid "&Play" +msgstr "&Play" + +msgid "&Rewind to the beginning" +msgstr "&Terugspoelen naar het begin" + +msgid "&Fast forward to the end" +msgstr "&Snel vooruit naar het einde" + +msgid "E&ject" +msgstr "E&ject" + +msgid "&Image..." +msgstr "&Image..." + +msgid "E&xport to 86F..." +msgstr "E&xporteer naar 86F..." + +msgid "&Mute" +msgstr "&Mute" + +msgid "E&mpty" +msgstr "E&mpty" + +msgid "&Reload previous image" +msgstr "&Herlaad vorige image" + +msgid "&Folder..." +msgstr "&Map..." + +msgid "Target &framerate" +msgstr "Doel &framerate" + +msgid "&Sync with video" +msgstr "&Synchroniseer met video" + +msgid "&25 fps" +msgstr "&25 fps" + +msgid "&30 fps" +msgstr "&30 fps" + +msgid "&50 fps" +msgstr "&50 fps" + +msgid "&60 fps" +msgstr "&60 fps" + +msgid "&75 fps" +msgstr "&75 fps" + +msgid "&VSync" +msgstr "&VSync" + +msgid "&Select shader..." +msgstr "&Selecteer shader..." + +msgid "&Remove shader" +msgstr "&Remove shader" + +msgid "Preferences" +msgstr "Voorkeuren" + +msgid "Sound Gain" +msgstr "Geluidsversterking" + +msgid "New Image" +msgstr "Nieuw image" + +msgid "Settings" +msgstr "Instellingen" + +msgid "Specify Main Window Dimensions" +msgstr "Afmetingen hoofdvenster opgeven" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Annuleren" + +msgid "Save these settings as &global defaults" +msgstr "Sla deze instellingen op als &globale standaardinstellingen" + +msgid "&Default" +msgstr "&Standaard" + +msgid "Language:" +msgstr "Taal:" + +msgid "Icon set:" +msgstr "Pictogrammenset:" + +msgid "Gain" +msgstr "Versterking" + +msgid "File name:" +msgstr "Bestandsnaam:" + +msgid "Disk size:" +msgstr "Schijfgrootte:" + +msgid "RPM mode:" +msgstr "RPM-modus:" + +msgid "Progress:" +msgstr "Vooruitgang:" + +msgid "Width:" +msgstr "Breedte:" + +msgid "Height:" +msgstr "Hoogte:" + +msgid "Lock to this size" +msgstr "Leg vast op deze grootte" + +msgid "Machine type:" +msgstr "Machinetype:" + +msgid "Machine:" +msgstr "Machine:" + +msgid "Configure" +msgstr "Configureren" + +msgid "CPU type:" +msgstr "CPU type:" + +msgid "Speed:" +msgstr "Snelheid:" + +msgid "Frequency:" +msgstr "Frequentie:" + +msgid "FPU:" +msgstr "FPU:" + +msgid "Wait states:" +msgstr "Wachttoestanden:" + +msgid "MB" +msgstr "MB" + +msgid "Memory:" +msgstr "Geheugen:" + +msgid "Time synchronization" +msgstr "Tijdsynchronisatie" + +msgid "Disabled" +msgstr "Uitgeschakeld" + +msgid "Enabled (local time)" +msgstr "Ingeschakeld (lokale tijd)" + +msgid "Enabled (UTC)" +msgstr "Ingeschakeld (UTC)" + +msgid "Dynamic Recompiler" +msgstr "Dynamische Recompiler" + +msgid "Video:" +msgstr "Video:" + +msgid "Video #2:" +msgstr "Video #2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 of 2 graphics" + +msgid "IBM 8514/A Graphics" +msgstr "IBM 8514/A-graphics" + +msgid "XGA Graphics" +msgstr "XGA Graphics" + +msgid "Mouse:" +msgstr "Muis:" + +msgid "Joystick:" +msgstr "Joystick:" + +msgid "Joystick 1..." +msgstr "Joystick 1..." + +msgid "Joystick 2..." +msgstr "Joystick 2..." + +msgid "Joystick 3..." +msgstr "Joystick 3..." + +msgid "Joystick 4..." +msgstr "Joystick 4..." + +msgid "Sound card #1:" +msgstr "Geluidskaart #1:" + +msgid "Sound card #2:" +msgstr "Geluidskaart #2:" + +msgid "Sound card #3:" +msgstr "Geluidskaart #3:" + +msgid "Sound card #4:" +msgstr "Geluidskaart #4:" + +msgid "MIDI Out Device:" +msgstr "MIDI Out-apparaat:" + +msgid "MIDI In Device:" +msgstr "MIDI In-apparaat:" + +msgid "Standalone MPU-401" +msgstr "Standalone MPU-401" + +msgid "Use FLOAT32 sound" +msgstr "Gebruik FLOAT32-geluid" + +msgid "FM synth driver" +msgstr "FM-synthesizer" + +msgid "Nuked (more accurate)" +msgstr "Nuked (nauwkeuriger)" + +msgid "YMFM (faster)" +msgstr "YMFM (sneller)" + +msgid "Network type:" +msgstr "Type netwerk:" + +msgid "PCap device:" +msgstr "PCap-apparaat:" + +msgid "Network adapter:" +msgstr "Netwerkadapter:" + +msgid "COM1 Device:" +msgstr "COM1-apparaat:" + +msgid "COM2 Device:" +msgstr "COM2-apparaat:" + +msgid "COM3 Device:" +msgstr "COM3-apparaat:" + +msgid "COM4 Device:" +msgstr "COM4-apparaat:" + +msgid "LPT1 Device:" +msgstr "LPT1-apparaat:" + +msgid "LPT2 Device:" +msgstr "LPT2-apparaat:" + +msgid "LPT3 Device:" +msgstr "LPT3-apparaat:" + +msgid "LPT4 Device:" +msgstr "LPT4-apparaat:" + +msgid "Serial port 1" +msgstr "Seriële poort 1" + +msgid "Serial port 2" +msgstr "Seriële poort 2" + +msgid "Serial port 3" +msgstr "Seriële poort 3" + +msgid "Serial port 4" +msgstr "Seriële poort 4" + +msgid "Parallel port 1" +msgstr "Parallelle poort 1" + +msgid "Parallel port 2" +msgstr "Parallelle poort 2" + +msgid "Parallel port 3" +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 "Tertiary IDE Controller" +msgstr "Tertiaire IDE-controller" + +msgid "Quaternary IDE Controller" +msgstr "Quaternaire IDE-controller" + +msgid "SCSI" +msgstr "SCSI" + +msgid "Controller 1:" +msgstr "Controller 1:" + +msgid "Controller 2:" +msgstr "Controller 2:" + +msgid "Controller 3:" +msgstr "Controller 3:" + +msgid "Controller 4:" +msgstr "Controller 4:" + +msgid "Cassette" +msgstr "Cassette" + +msgid "Hard disks:" +msgstr "Harde schijven:" + +msgid "&New..." +msgstr "&Nieuw..." + +msgid "&Existing..." +msgstr "&Bestaande..." + +msgid "&Remove" +msgstr "&Verwijderen" + +msgid "Bus:" +msgstr "Bus:" + +msgid "Channel:" +msgstr "Kanaal:" + +msgid "ID:" +msgstr "ID:" + +msgid "&Specify..." +msgstr "&Specificeer..." + +msgid "Sectors:" +msgstr "Sectoren:" + +msgid "Heads:" +msgstr "Heads:" + +msgid "Cylinders:" +msgstr "Cilinders:" + +msgid "Size (MB):" +msgstr "Grootte (MB):" + +msgid "Type:" +msgstr "Type:" + +msgid "Image Format:" +msgstr "Imageformaat:" + +msgid "Block Size:" +msgstr "Blokgrootte:" + +msgid "Floppy drives:" +msgstr "Floppy-schijfstations:" + +msgid "Turbo timings" +msgstr "Turbo timings" + +msgid "Check BPB" +msgstr "Controleer BPB" + +msgid "CD-ROM drives:" +msgstr "CD-ROM-stations:" + +msgid "MO drives:" +msgstr "MO-schijven:" + +msgid "ZIP drives:" +msgstr "ZIP-schijven:" + +msgid "ZIP 250" +msgstr "ZIP 250" + +msgid "ISA RTC:" +msgstr "ISA RTC:" + +msgid "ISA Memory Expansion" +msgstr "ISA-geheugenuitbreiding" + +msgid "Card 1:" +msgstr "Kaart 1:" + +msgid "Card 2:" +msgstr "Kaart 2:" + +msgid "Card 3:" +msgstr "Kaart 3:" + +msgid "Card 4:" +msgstr "Kaart 4:" + +msgid "ISABugger device" +msgstr "ISABugger-apparaat" + +msgid "POST card" +msgstr "POST-kaart" + +msgid "86Box" +msgstr "86Box" + +msgid "Error" +msgstr "Fout" + +msgid "Fatal error" +msgstr "Fatale fout" + +msgid " - PAUSED" +msgstr " - GEPAUZEERD" + +msgid "Press Ctrl+Alt+PgDn to return to windowed mode." +msgstr "Druk op Ctrl+Alt+PgDn om terug te gaan naar de venstermodus." + +msgid "Speed" +msgstr "Snelheid" + +msgid "ZIP %03i %i (%s): %ls" +msgstr "ZIP %03i %i (%s): %ls" + +msgid "ZIP images" +msgstr "ZIP-images" + +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\"." + +msgid "(empty)" +msgstr "(leeg)" + +msgid "All files" +msgstr "Alle bestanden" + +msgid "Turbo" +msgstr "Turbo" + +msgid "On" +msgstr "Aan" + +msgid "Off" +msgstr "Uit" + +msgid "All images" +msgstr "Alle schijfimages" + +msgid "Basic sector images" +msgstr "Basissectorimages" + +msgid "Surface images" +msgstr "Oppervlakte-images" + +msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." +msgstr "Machine \"%hs\" is niet beschikbaar door ontbrekende ROMs in de map roms/machines. Overschakelen naar een beschikbare machine." + +msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." +msgstr "Videokaart \"%hs\" is niet beschikbaar door ontbrekende ROMs in de map roms/video. Overschakel over naar een beschikbare videokaart." + +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Videokaart #2 \"%hs\" is niet beschikbaar door ontbrekende ROMs in de map roms/video. Uitschakel de tweede videokaart." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Het apparaat \"%hs\" is niet beschikbaar door ontbrekende ROMs. Negeer het apparaat." + +msgid "Machine" +msgstr "Machine" + +msgid "Display" +msgstr "Scherm" + +msgid "Input devices" +msgstr "Invoerapparaten" + +msgid "Sound" +msgstr "Geluid" + +msgid "Network" +msgstr "Netwerk" + +msgid "Ports (COM & LPT)" +msgstr "Poorten (COM & LPT)" + +msgid "Storage controllers" +msgstr "Opslagcontrollers" + +msgid "Hard disks" +msgstr "Harde schijven" + +msgid "Floppy & CD-ROM drives" +msgstr "Floppy- en CD-ROM-stations" + +msgid "Other removable devices" +msgstr "Andere verwijderbare apparaten" + +msgid "Other peripherals" +msgstr "Andere randapparatuur" + +msgid "Click to capture mouse" +msgstr "Klik om muis vast te leggen" + +msgid "Press %1 to release mouse" +msgstr "Druk op %1 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" + +msgid "File" +msgstr "Bestand" + +msgid "C" +msgstr "C" + +msgid "H" +msgstr "H" + +msgid "S" +msgstr "S" + +msgid "KB" +msgstr "KB" + +msgid "Could not initialize the video renderer." +msgstr "Kan de videorenderer niet initialiseren." + +msgid "Default" +msgstr "Standaard" + +msgid "%i estat(s) d'espera" +msgstr "%i estat(s) d'espera" + +msgid "Type" +msgstr "Type" + +msgid "No PCap devices found" +msgstr "Geen PCap-apparaten gevonden" + +msgid "Invalid PCap device" +msgstr "Ongeldig PCap-apparaat" + +msgid "2-axis, 2-button joystick(s)" +msgstr "Joystick(s) met 2 assen en 2 knoppen" + +msgid "2-axis, 4-button joystick" +msgstr "Joystick met 2 assen en 4 knoppen" + +msgid "2-axis, 6-button joystick" +msgstr "Joystick met 2 assen en 6 knoppen" + +msgid "2-axis, 8-button joystick" +msgstr "Joystick met 2 assen en 8 knoppen" + +msgid "3-axis, 2-button joystick" +msgstr "Joystick met 3 assen en 2 knoppen" + +msgid "3-axis, 4-button joystick" +msgstr "Joystick met 3 assen en 4 knoppen" + +msgid "4-axis, 4-button joystick" +msgstr "Joystick met 4 assen en 4 knoppen" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control systeem" + +msgid "None" +msgstr "Geen" + +msgid "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CHS: %i, %i, %i)" + +msgid "Floppy %i (%s): %ls" +msgstr "Floppy %i (%s): %ls" + +msgid "Advanced sector images" +msgstr "Geavanceerde sector-images" + +msgid "Flux images" +msgstr "Flux images" + +msgid "Are you sure you want to hard reset the emulated machine?" +msgstr "Weet je zeker dat je de geëmuleerde machine wilt resetten?" + +msgid "Are you sure you want to exit 86Box?" +msgstr "Weet je zeker dat je 86Box wilt verlaten?" + +msgid "Unable to initialize Ghostscript" +msgstr "Kan Ghostscript niet initialiseren" + +msgid "Unable to initialize GhostPCL" +msgstr "Kan GhostPCL niet initialiseren" + +msgid "MO %i (%ls): %ls" +msgstr "MO %i (%ls): %ls" + +msgid "MO images" +msgstr "MO-images" + +msgid "Welcome to 86Box!" +msgstr "Welkom bij 86Box!" + +msgid "Internal device" +msgstr "Intern apparaat" + +msgid "Exit" +msgstr "&Afsluiten" + +msgid "No ROMs found" +msgstr "Geen ROMs gevonden" + +msgid "Do you want to save the settings?" +msgstr "Wil je de instellingen opslaan?" + +msgid "This will hard reset the emulated machine." +msgstr "Dit zal de geëmuleerde machine een hard reset geven." + +msgid "Save" +msgstr "Opslaan" + +msgid "About 86Box" +msgstr "Over 86Box" + +msgid "86Box v" +msgstr "86Box v" + +msgid "An emulator of old computers\n\nAuthors: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." +msgstr "Een emulator van oude computers\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\nMet eerdere bijdragen van Sarah Walker, leilei, JohnElliott, greatpsycho en anderen.\n\nUitgebracht onder de GNU General Public License versie 2 of later. Zie LICENSE voor meer informatie." + +msgid "Hardware not available" +msgstr "Hardware niet beschikbaar" + +msgid "Make sure %1 is installed and that you are on a %1-compatible network connection." +msgstr "Zorg ervoor dat %1 is geïnstalleerd en dat je een %1-compatibele netwerkverbinding hebt." + +msgid "Invalid configuration" +msgstr "Ongeldige configuratie" + +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 is vereist voor automatische conversie van PostScript-bestanden naar PDF.\n\nAlle documenten die naar de generieke PostScript-printer worden gestuurd, worden opgeslagen als PostScript-bestanden (.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 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" + +msgid "Don't exit" +msgstr "Niet afsluiten" + +msgid "Reset" +msgstr "Reset" + +msgid "Don't reset" +msgstr "Niet resetten" + +msgid "CD-ROM images" +msgstr "CD-ROM-images" + +msgid "%1 Device Configuration" +msgstr "%1 Apparaatconfiguratie" + +msgid "Monitor in sleep mode" +msgstr "Monitor in slaapstand" + +msgid "OpenGL Shaders" +msgstr "OpenGL Shaders" + +msgid "OpenGL options" +msgstr "OpenGL-opties" + +msgid "You are loading an unsupported configuration" +msgstr "U laadt een configuratie die niet wordt ondersteund" + +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 "Filteren op CPU type voor de geselecteerde machine is niet mogelijk met de geselecteerde machine.\n\nDit maakt het mogelijk een CPU te kunnen kiezen die anders niet compatible zou zijn met de geselecteerde machine. Je kunt hiermee echter compatibiliteitsproblemen krijgen met de BIOS van de machine of met andere software.\n\nHet inschakelen van deze instelling wordt niet officieel ondersteund en bugrapporten die worden ingediend kunnen als ongeldig worden gesloten." + +msgid "Continue" +msgstr "Doorgaan" + +msgid "Cassette: %s" +msgstr "Cassette: %s" + +msgid "Cassette images" +msgstr "Cassette-images" + +msgid "Cartridge %i: %ls" +msgstr "Cartridge %i: %ls" + +msgid "Cartridge images" +msgstr "Cartridge-images" + +msgid "Error initializing renderer" +msgstr "Fout bij het initialiseren van renderer" + +msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." +msgstr "OpenGL (3.0 Core) renderer kon niet worden geïnitialiseerd. Gebruik een andere renderer." + +msgid "Resume execution" +msgstr "Hervat executie" + +msgid "Pause execution" +msgstr "Pauze executie" + +msgid "Press Ctrl+Alt+Del" +msgstr "Druk op Ctrl+Alt+Del" + +msgid "Press Ctrl+Alt+Esc" +msgstr "Druk op Ctrl+Alt+Esc" + +msgid "Hard reset" +msgstr "Harde reset" + +msgid "ACPI shutdown" +msgstr "ACPI uitschakeling" + +msgid "Hard disk (%1)" +msgstr "Harde schijf (%1)" + +msgid "MFM/RLL or ESDI CD-ROM drives never existed" +msgstr "MFM/RLL of ESDI CD-ROM-stations hebben nooit bestaan" + +msgid "Custom..." +msgstr "Aangepast..." + +msgid "Custom (large)..." +msgstr "Aangepast (groot)..." + +msgid "Add New Hard Disk" +msgstr "Nieuwe harde schijf toevoegen" + +msgid "Add Existing Hard Disk" +msgstr "Bestaande harde schijf toevoegen" + +msgid "HDI disk images cannot be larger than 4 GB." +msgstr "HDI-schijfimages kunnen niet groter zijn dan 4 GB." + +msgid "Disk images cannot be larger than 127 GB." +msgstr "Schijfimages kunnen niet groter zijn dan 127 GB." + +msgid "Hard disk images" +msgstr "Harde schijf-image" + +msgid "Unable to read file" +msgstr "Kan bestand niet lezen" + +msgid "Unable to write file" +msgstr "Kan bestand niet schrijven" + +msgid "HDI or HDX images with a sector size other than 512 are not supported." +msgstr "HDI- of HDX-image met een andere sectorgrootte dan 512 worden niet ondersteund." + +msgid "Disk image file already exists" +msgstr "Schijfimagebestand bestaat al" + +msgid "Please specify a valid file name." +msgstr "Geef een geldige bestandsnaam op." + +msgid "Disk image created" +msgstr "Schijfimage gemaakt" + +msgid "Make sure the file exists and is readable." +msgstr "Controleer of het bestand bestaat en leesbaar is." + +msgid "Make sure the file is being saved to a writable directory." +msgstr "Zorg ervoor dat het bestand wordt opgeslagen in een schrijfbare map." + +msgid "Disk image too large" +msgstr "Schijfimage te groot" + +msgid "Remember to partition and format the newly-created drive." +msgstr "Vergeet niet om de nieuw aangemaakte schijf te partitioneren en te formatteren." + +msgid "The selected file will be overwritten. Are you sure you want to use it?" +msgstr "Het geselecteerde bestand wordt overschreven. Weet u zeker dat u het wilt gebruiken?" + +msgid "Unsupported disk image" +msgstr "Niet-ondersteunde schijfimage" + +msgid "Overwrite" +msgstr "Overschrijven" + +msgid "Don't overwrite" +msgstr "Niet overschrijven" + +msgid "Raw image" +msgstr "Ruw image" + +msgid "HDI image" +msgstr "HDI-image" + +msgid "HDX image" +msgstr "HDX-image" + +msgid "Fixed-size VHD" +msgstr "VHD met vaste grootte" + +msgid "Dynamic-size VHD" +msgstr "VHD met dynamisch grootte" + +msgid "Differencing VHD" +msgstr "Verschil-VHD" + +msgid "(N/A)" +msgstr "(N/A)" + +msgid "Raw image (.img)" +msgstr "Ruw image (.img)" + +msgid "HDI image (.hdi)" +msgstr "HDI-image (.hdi)" + +msgid "HDX image (.hdx)" +msgstr "HDX-image (.hdx)" + +msgid "Fixed-size VHD (.vhd)" +msgstr "VHD met vaste grootte (.vhd)" + +msgid "Dynamic-size VHD (.vhd)" +msgstr "VHD met dynamisch grootte (.vhd)" + +msgid "Differencing VHD (.vhd)" +msgstr "Verschil-VHD (.vhd)" + +msgid "Large blocks (2 MB)" +msgstr "Grote blokken (2 MB)" + +msgid "Small blocks (512 KB)" +msgstr "Kleine blokken (512 KB)" + +msgid "VHD files" +msgstr "VHD-bestanden" + +msgid "Select the parent VHD" +msgstr "Selecteer de bovenliggende 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 "Dit kan betekenen dat de bovenliggende image is gewijzigd nadat de verschil-image is gemaakt.\n\nDit kan ook gebeuren als de imagebestanden zijn verplaatst of gekopieerd, of door een fout in het programma waarmee deze schijf is gemaakt.\n\nWil je de tijdstempels herstellen?" + +msgid "Parent and child disk timestamps do not match" +msgstr "Bovenliggende en onderliggende schijf tijdstempels komen niet overeen" + +msgid "Could not fix VHD timestamp." +msgstr "Kan VHD tijdstempel niet herstellen." + +msgid "MFM/RLL" +msgstr "MFM/RLL" + +msgid "XTA" +msgstr "XTA" + +msgid "ESDI" +msgstr "ESDI" + +msgid "IDE" +msgstr "IDE" + +msgid "ATAPI" +msgstr "ATAPI" + +msgid "CD-ROM %i (%s): %s" +msgstr "CD-ROM %i (%s): %s" + +msgid "160 KB" +msgstr "160 KB" + +msgid "180 KB" +msgstr "180 KB" + +msgid "320 KB" +msgstr "320 KB" + +msgid "360 KB" +msgstr "360 KB" + +msgid "640 KB" +msgstr "640 KB" + +msgid "720 KB" +msgstr "720 KB" + +msgid "1.2 MB" +msgstr "1,2 MB" + +msgid "1.25 MB" +msgstr "1,25 MB" + +msgid "1.44 MB" +msgstr "1,44 MB" + +msgid "DMF (cluster 1024)" +msgstr "DMF (cluster 1024)" + +msgid "DMF (cluster 2048)" +msgstr "DMF (cluster 2048)" + +msgid "2.88 MB" +msgstr "2,88 MB" + +msgid "ZIP 100" +msgstr "ZIP 100" + +msgid "3.5\" 128 MB (ISO 10090)" +msgstr "3,5\" 128 MB (ISO 10090)" + +msgid "3.5\" 230 MB (ISO 13963)" +msgstr "3,5\" 230 MB (ISO 13963)" + +msgid "3.5\" 540 MB (ISO 15498)" +msgstr "3,5\" 540 MB (ISO 15498)" + +msgid "3.5\" 640 MB (ISO 15498)" +msgstr "3,5\" 640 MB (ISO 15498)" + +msgid "3.5\" 1.3 GB (GigaMO)" +msgstr "3,5\" 1,3 GB (GigaMO)" + +msgid "3.5\" 2.3 GB (GigaMO 2)" +msgstr "3,5\" 2,3 GB (GigaMO 2)" + +msgid "5.25\" 600 MB" +msgstr "5,25\" 600 MB" + +msgid "5.25\" 650 MB" +msgstr "5,25\" 650 MB" + +msgid "5.25\" 1 GB" +msgstr "5,25\" 1 GB" + +msgid "5.25\" 1.3 GB" +msgstr "5,25\" 1,3 GB" + +msgid "Perfect RPM" +msgstr "Perfecte RPM" + +msgid "1% below perfect RPM" +msgstr "1% onder perfecte RPM" + +msgid "1.5% below perfect RPM" +msgstr "1,5% onder perfecte RPM" + +msgid "2% below perfect RPM" +msgstr "2% onder perfecte RPM" + +msgid "(System Default)" +msgstr "(Systeemstandaard)" + +msgid "Failed to initialize network driver" +msgstr "Netwerkstuurprogramma niet geïnitialiseerd" + +msgid "The network configuration will be switched to the null driver" +msgstr "De netwerkconfiguratie wordt overgeschakeld naar de nul-driver" + +msgid "Mouse sensitivity:" +msgstr "Muisgevoeligheid:" + +msgid "Select media images from program working directory" +msgstr "Selecteer media-images uit de werkmap van het programma" + +msgid "PIT mode:" +msgstr "PIT-modus:" + +msgid "Auto" +msgstr "Auto" + +msgid "Slow" +msgstr "Langzaam" + +msgid "Fast" +msgstr "Snel" + +msgid "&Auto-pause on focus loss" +msgstr "&Autopauze bij focusverlies" + +msgid "WinBox is no longer supported" +msgstr "WinBox wordt niet langer ondersteund" + +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 "De ontwikkeling van de WinBox manager is gestopt in 2022 door een gebrek aan beheerders. Omdat we onze inspanningen richten op het nog beter maken van 86Box, hebben we de beslissing genomen om WinBox niet langer te ondersteunen als een manager.\n\nEr zullen geen verdere updates worden geleverd door WinBox. Je kunt onjuist gedrag tegenkomen als je het blijft gebruiken met nieuwere versies van 86Box. Alle bugrapporten gerelateerd aan het gedrag van WinBox zullen worden gesloten als ongeldig.\n\nGa naar 86box.net voor een lijst van andere managers die je kunt gebruiken." + +msgid "Generate" +msgstr "Genereren" + +msgid "Joystick configuration" +msgstr "Joystick configuratie " + +msgid "Device" +msgstr "Apparaat" + +msgid "%1 (X axis)" +msgstr "%1 (X-as)" + +msgid "%1 (Y axis)" +msgstr "%1 (Y-as)" + +msgid "MCA devices" +msgstr "MCA-apparaten" + +msgid "List of MCA devices:" +msgstr "Lijst van MCA-apparaten:" + +msgid "Tablet tool" +msgstr "Tablet-hulpmiddel" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Over Qt" + +msgid "MCA devices..." +msgstr "MCA-apparaten..." + +msgid "Show non-primary monitors" +msgstr "Toon niet-primaire monitors" + +msgid "Open screenshots folder..." +msgstr "Map met schermafbeeldingen openen..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Pas fullscreen stretchmodus toe wanneer gemaximaliseerd" + +msgid "Cursor/Puck" +msgstr "Cursor/Puck" + +msgid "Pen" +msgstr "Pen" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Host cd/dvd-station (%1:)" + +msgid "&Connected" +msgstr "&Verbonden" + +msgid "Clear image history" +msgstr "Imagegeschiedenis verwijderen" + +msgid "Create..." +msgstr "Creëer..." + +msgid "previous image" +msgstr "vorige image" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Host CD/DVD-station (%1)" + +msgid "Unknown Bus" +msgstr "Onbekende bus" + +msgid "Null Driver" +msgstr "Null Driver" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Fout bij het openen van \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Fout bij het compileren van vertex shader in bestand \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Fout bij het compileren van fragment shader in bestand \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Fout bij koppelen shaderprogramma in bestand \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 renderer opties" + +msgid "Render behavior" +msgstr "Rendergedrag" + +msgid "Use target framerate:" +msgstr "Gebruik doelframerate:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Onmiddellijk elk frame synchroon met het geëmuleerde beeldscherm renderen.</p><p><span style=" font-style:italic;">Dit is de aanbevolen optie als de gebruikte shaders geen frametime gebruiken voor geanimeerde effecten.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Synchroniseren met video" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Verwijderen" + +msgid "No shader selected" +msgstr "Geen shader geselecteerd" + +msgid "Browse..." +msgstr "Bladeren..." + +msgid "Shader error" +msgstr "Shader-fout" + +msgid "Could not load shaders." +msgstr "Kan shaders niet laden." + +msgid "More information in details." +msgstr "Meer informatie in details." + +msgid "Couldn't create OpenGL context." +msgstr "Kan OpenGL context niet maken." + +msgid "Couldn't switch to OpenGL context." +msgstr "Kan niet overschakelen naar OpenGL context." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "OpenGL versie 3.0 of hoger is vereist. De huidige versie is %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL initialisatie mislukt. Fout %1." + +msgid "Error initializing OpenGL" +msgstr "Fout bij het initialiseren van OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Terugvallen op software rendering.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Toewijzen van geheugen voor uitpakbuffer mislukt.\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>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 "This machine might have been moved or copied." +msgstr "Deze machine is misschien verplaatst of gekopieerd." + +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 "Om een goede netwerkfunctionaliteit te garanderen, moet 86Box weten of deze machine verplaatst of gekopieerd is.\n\nSelecteer \"Ik heb het gekopieerd\" als u het niet zeker weet." + +msgid "I Moved It" +msgstr "Ik heb het verplaatst" + +msgid "I Copied It" +msgstr "Ik heb het gekopieerd" + +msgid "86Box Monitor #" +msgstr "86Box Monitor #" + +msgid "No MCA devices." +msgstr "Geen MCA-apparaten." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Netwerkkaart #1" + +msgid "Network Card #2" +msgstr "Netwerkkaart #2" + +msgid "Network Card #3" +msgstr "Netwerkkaart #3" + +msgid "Network Card #4" +msgstr "Netwerkkaart #4" + +msgid "Mode" +msgstr "Modus" + +msgid "Interface" +msgstr "Interface" + +msgid "Adapter" +msgstr "Adapter" + +msgid "VDE Socket" +msgstr "VDE-socket" + +msgid "86Box Unit Tester" +msgstr "86Box apparaattester" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x Key Card" + +msgid "Serial port passthrough 1" +msgstr "Seriële poort doorvoer 1" + +msgid "Serial port passthrough 2" +msgstr "Seriële poort doorvoer 2" + +msgid "Serial port passthrough 3" +msgstr "Seriële poort doorvoer 3" + +msgid "Serial port passthrough 4" +msgstr "Seriële poort doorvoer 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Renderer-opties..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft busmuis" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft busmuis (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems seriële muis" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft seriële muis" + +msgid "Logitech Serial Mouse" +msgstr "Logitech seriële muis" + +msgid "PS/2 Mouse" +msgstr "PS/2-muis" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (serieel)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "COM] Standaard Hayes-compatibele modem " + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32-emulatie" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32 (nieuwe) emulatie" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32L-emulatie" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LN-emulatie" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML-dochterbord" + +msgid "System MIDI" +msgstr "Systeem MIDI" + +msgid "MIDI Input Device" +msgstr "MIDI-ingangsapparaat" + +msgid "BIOS Address" +msgstr "BIOS-adres" + +msgid "Enable BIOS extension ROM Writes" +msgstr "BIOS-extensie ROM Writes inschakelen" + +msgid "Address" +msgstr "Adres" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS Revisie" + +msgid "Translate 26 -> 17" +msgstr "Vertaal 26 -> 17" + +msgid "Language" +msgstr "Taal" + +msgid "Enable backlight" +msgstr "Backlight inschakelen" + +msgid "Invert colors" +msgstr "Kleuren omkeren" + +msgid "BIOS size" +msgstr "BIOS-grootte" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Geheugenadres C0000-C7FFF toewijzen aan UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Geheugenadres C8000-CFFFF toewijzen aan UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Geheugenadres D0000-D7FFF toewijzen aan UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Geheugenadres D8000-DFFFF toewijzen aan UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Geheugenadres E0000-E7FFF toewijzen aan UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Geheugenadres E8000-EFFFF toewijzen aan UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 Jumper (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI-uitgangsapparaat" + +msgid "MIDI Real time" +msgstr "MIDI real-time" + +msgid "MIDI Thru" +msgstr "MIDI doorvoer" + +msgid "MIDI Clockout" +msgstr "MIDI Clockout" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Output Gain" + +msgid "Chorus" +msgstr "Chorus" + +msgid "Chorus Voices" +msgstr "Chorus-stemmen" + +msgid "Chorus Level" +msgstr "Chorus-niveau" + +msgid "Chorus Speed" +msgstr "Chorus-snelheid" + +msgid "Chorus Depth" +msgstr "Chorus-diepte" + +msgid "Chorus Waveform" +msgstr "Chorus-golfvorm" + +msgid "Reverb" +msgstr "Reverb" + +msgid "Reverb Room Size" +msgstr "Reverbkamer afmetingen" + +msgid "Reverb Damping" +msgstr "Reverbdemping" + +msgid "Reverb Width" +msgstr "Reverbbreedte" + +msgid "Reverb Level" +msgstr "Reverbniveau" + +msgid "Interpolation Method" +msgstr "Interpolatiemethode" + +msgid "Reverb Output Gain" +msgstr "Reverbuitgang Versterking" + +msgid "Reversed stereo" +msgstr "Omgekeerde stereo" + +msgid "Nice ramp" +msgstr "Mooie helling" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Knoppen" + +msgid "Serial Port" +msgstr "Seriële poort" + +msgid "RTS toggle" +msgstr "RTS toggle" + +msgid "Revision" +msgstr "Revisie" + +msgid "Controller" +msgstr "Controller" + +msgid "Show Crosshair" +msgstr "Toon dradenkruis" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC-adres" + +msgid "MAC Address OUI" +msgstr "MAC-adres OUI" + +msgid "Enable BIOS" +msgstr "BIOS inschakelen" + +msgid "Baud Rate" +msgstr "Baud-snelheid" + +msgid "TCP/IP listening port" +msgstr "TCP/IP-luisterpoort" + +msgid "Phonebook File" +msgstr "Telefoonboekbestand" + +msgid "Telnet emulation" +msgstr "Telnet-emulatie" + +msgid "RAM Address" +msgstr "RAM-adres" + +msgid "RAM size" +msgstr "RAM-grootte" + +msgid "Initial RAM size" +msgstr "Oorspronkelijke RAM-grootte" + +msgid "Serial Number" +msgstr "Serienummer" + +msgid "Host ID" +msgstr "Host-ID" + +msgid "FDC Address" +msgstr "FDC Adres" + +msgid "MPU-401 Address" +msgstr "MPU-401 Adres" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "MIDI-ingang ontvangen" + +msgid "Low DMA" +msgstr "Lage DMA" + +msgid "Enable Game port" +msgstr "Game-poort inschakelen" + +msgid "Surround module" +msgstr "Surroundmodule" + +msgid "CODEC" +msgstr "Codec" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Verhoog CODEC interrupt bij CODEC setup (nodig voor sommige stuurprogramma's)" + +msgid "SB Address" +msgstr "SB-adres" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "OPL inschakelen" + +msgid "Receive MIDI input (MPU-401)" +msgstr "MIDI-ingang ontvangen (MPU-401)" + +msgid "SB low DMA" +msgstr "SB lage DMA" + +msgid "6CH variant (6-channel)" +msgstr "6CH-variant (6-kanaals)" + +msgid "Enable CMS" +msgstr "CMS inschakelen" + +msgid "Mixer" +msgstr "Mixer" + +msgid "High DMA" +msgstr "Hoge DMA" + +msgid "Control PC speaker" +msgstr "Bestuur pc-luidspreker" + +msgid "Memory size" +msgstr "Geheugengrootte" + +msgid "EMU8000 Address" +msgstr "EMU8000 Adres" + +msgid "IDE Controller" +msgstr "IDE-controller" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "GUS-type" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Schakel het commando 0x04 \"Exit 86Box\" in" + +msgid "Display type" +msgstr "Scherm type" + +msgid "Composite type" +msgstr "Composite type" + +msgid "RGB type" +msgstr "RGB-type" + +msgid "Line doubling type" +msgstr "Type lijnverdubbeling" + +msgid "Snow emulation" +msgstr "Sneeuwemulatie" + +msgid "Monitor type" +msgstr "Type monitor" + +msgid "Character set" +msgstr "Tekenset" + +msgid "XGA type" +msgstr "XGA-type" + +msgid "Instance" +msgstr "Instantie" + +msgid "MMIO Address" +msgstr "MMIO-adres" + +msgid "RAMDAC type" +msgstr "RAMDAC type" + +msgid "Blend" +msgstr "Mengen" + +msgid "Bilinear filtering" +msgstr "Bilineaire filtering" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "NMI inschakelen voor CGA-emulatie" + +msgid "Voodoo type" +msgstr "Voodoo-type" + +msgid "Framebuffer memory size" +msgstr "Framebuffer geheugengrootte" + +msgid "Texture memory size" +msgstr "Grootte textuurgeheugen" + +msgid "Dither subtraction" +msgstr "Dither aftrekken" + +msgid "Screen Filter" +msgstr "Schermfilter" + +msgid "Render threads" +msgstr "Render threads" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Startadres" + +msgid "Contiguous Size" +msgstr "Aaneengesloten grootte" + +msgid "I/O Width" +msgstr "I/O-breedte" + +msgid "Transfer Speed" +msgstr "Overdrachtssnelheid" + +msgid "EMS mode" +msgstr "EMS-modus" + +msgid "Address for > 2 MB" +msgstr "Adres voor > 2 MB" + +msgid "Frame Address" +msgstr "Frameadres" + +msgid "USA" +msgstr "USA" + +msgid "Danish" +msgstr "Deens" + +msgid "Always at selected speed" +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 "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "128 kB vanaf E0000 (geïnverteerd MSB adres, laatste 64KB eerst)" + +msgid "Sine" +msgstr "Sinus" + +msgid "Triangle" +msgstr "Driehoek" + +msgid "Linear" +msgstr "Lineair" + +msgid "4th Order" +msgstr "4e Orde" + +msgid "7th Order" +msgstr "7e Orde" + +msgid "Non-timed (original)" +msgstr "Niet-getimed (origineel)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 niet gezet)" + +msgid "Two" +msgstr "Twee" + +msgid "Three" +msgstr "Drie" + +msgid "Wheel" +msgstr "Wiel" + +msgid "Five + Wheel" +msgstr "Vijf + Wiel" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 Serieel / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) Serieel" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "BIOS uitschakelen" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klassiek" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Composite" + +msgid "Old" +msgstr "Oud" + +msgid "New" +msgstr "Nieuw" + +msgid "Color (generic)" +msgstr "Kleur (algemeen)" + +msgid "Green Monochrome" +msgstr "Groen monochroom" + +msgid "Amber Monochrome" +msgstr "Amber Monochroom" + +msgid "Gray Monochrome" +msgstr "Grijs monochroom" + +msgid "Color (no brown)" +msgstr "Kleur (geen bruin)" + +msgid "Color (IBM 5153)" +msgstr "Kleur (IBM 5153)" + +msgid "Simple doubling" +msgstr "Eenvoudige verdubbeling" + +msgid "sRGB interpolation" +msgstr "sRGB-interpolatie" + +msgid "Linear interpolation" +msgstr "Lineaire interpolatie" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monochroom (5151/MDA) (wit)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monochroom (5151/MDA) (groen)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monochroom (5151/MDA) (amber)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Kleur 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Kleur 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Verbeterde kleur - normale modus (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Verbeterde kleur - Verbeterde modus (5154/ECD)" + +msgid "Green" +msgstr "Groen" + +msgid "Amber" +msgstr "Amber" + +msgid "Gray" +msgstr "Grijs" + +msgid "Color" +msgstr "Kleur" + +msgid "U.S. English" +msgstr "Amerikaans Engels" + +msgid "Scandinavian" +msgstr "Scandinavisch" + +msgid "Other languages" +msgstr "Andere talen" + +msgid "Bochs latest" +msgstr "Bochs nieuwste" + +msgid "Mono Non-Interlaced" +msgstr "Mono Non-Interlaced" + +msgid "Color Interlaced" +msgstr "Kleur interlaced" + +msgid "Color Non-Interlaced" +msgstr "Kleur non-interlaced" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx Voodoo Graphics" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU's)" + +msgid "8-bit" +msgstr "8-bit" + +msgid "16-bit" +msgstr "16-bit" + +msgid "Standard (150ns)" +msgstr "Standaard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Hoge snelheid (120ns)" + +msgid "Enabled" +msgstr "Ingeschakeld" + +msgid "Standard" +msgstr "Standaard" + +msgid "High-Speed" +msgstr "Hoge snelheid" + +msgid "Stereo LPT DAC" +msgstr "Stereo LPT DAC" + +msgid "Generic Text Printer" +msgstr "Generieke tekstprinter" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Generieke ESC/P dot-matrix-printer" + +msgid "Generic PostScript Printer" +msgstr "Generieke PostScript-printer" + +msgid "Generic PCL5e Printer" +msgstr "Generieke PCL5e-printer" + +msgid "Parallel Line Internet Protocol" +msgstr "Internetprotocol voor parallelle lijnen" + +msgid "Protection Dongle for Savage Quest" +msgstr "Beschermingsdongle voor Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Serieel doorvoerapparaat" + +msgid "Passthrough Mode" +msgstr "Doorgeefmodus" + +msgid "Host Serial Device" +msgstr "Host Serieel Apparaat" + +msgid "Name of pipe" +msgstr "Naam van de pipe" + +msgid "Data bits" +msgstr "Databits" + +msgid "Stop bits" +msgstr "Stopbits" + +msgid "Baud Rate of Passthrough" +msgstr "Baud-snelheid van doorvoer" + +msgid "Named Pipe (Server)" +msgstr "Named Pipe (Server)" + +msgid "Host Serial Passthrough" +msgstr "Host seriële doorgave" + +msgid "Eject %s" +msgstr "Uitwerpen %s" + +msgid "&Unmute" +msgstr "&Geluid aanzetten" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Hoge prestatie-impact" + +msgid "RAM Disk (max. speed)" +msgstr "RAM-schijf (max. snelheid)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A-kloon (ISA)" + +msgid "Vendor" +msgstr "Verkoper" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Generieke PC/XT geheugenuitbreiding" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Generieke PC/AT geheugenuitbreiding" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 993e6633a..e42904458 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -115,10 +115,10 @@ msgid "&Fullscreen\tCtrl+Alt+PgUp" msgstr "&Pełny ekran\tCtrl+Alt+PgUp" msgid "Fullscreen &stretch mode" -msgstr "Fullscreen &stretch mode" +msgstr "Tryb rozciągania na pełnym ekranie" msgid "&Full screen stretch" -msgstr "&Tryb rozciągania na pełnym ekranie" +msgstr "&Rozciągnij na pełny ekran" msgid "&4:3" msgstr "&4:3" @@ -390,8 +390,11 @@ msgstr "Dynamiczny rekompilator" msgid "Video:" msgstr "Wideo:" -msgid "Voodoo Graphics" -msgstr "Grafika Voodoo" +msgid "Video #2:" +msgstr "Wideo 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Grafika Voodoo 1 czy 2" msgid "IBM 8514/A Graphics" msgstr "Grafika IBM 8514/A" @@ -684,6 +687,12 @@ msgstr "Maszyna \"%hs\" nie jest dostępna, ponieważ brakuje obrazów ROM w kat 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." +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." + +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." + msgid "Machine" msgstr "Maszyna" @@ -762,17 +771,26 @@ msgstr "Nie znaleziono urządzeń PCap" msgid "Invalid PCap device" msgstr "Nieprawidłowe urządzenie PCap" -msgid "Standard 2-button joystick(s)" -msgstr "Standardowe joysticki 2-przyciskowe" +msgid "2-axis, 2-button joystick(s)" +msgstr "Joysticki 2-osiowe, 2-przyciskowe" -msgid "Standard 4-button joystick" -msgstr "Standardowy joystick 4-przyciskowy" +msgid "2-axis, 4-button joystick" +msgstr "Joystick 2-osiowy, 4-przyciskowy" -msgid "Standard 6-button joystick" -msgstr "Standardowy joystick 6-przyciskowy" +msgid "2-axis, 6-button joystick" +msgstr "Joystick 2-osiowy, 6-przyciskowy" -msgid "Standard 8-button joystick" -msgstr "Standardowy joystick 8-przyciskowy" +msgid "2-axis, 8-button joystick" +msgstr "Joystick 2-osiowy, 8-przyciskowy" + +msgid "3-axis, 2-button joystick" +msgstr "Joystick 3-osiowy, 2-przyciskowy" + +msgid "3-axis, 4-button joystick" +msgstr "Joystick 3-osiowy, 4-przyciskowy" + +msgid "4-axis, 4-button joystick" +msgstr "Joystick 4-osiowy, 4-przyciskowy" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Jesteś pewien że chcesz zakończyć 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Nie można zainicjować Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Nie można zainicjować GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Obrazy MO" msgid "Welcome to 86Box!" msgstr "Witamy w 86Box!" -msgid "Internal controller" -msgstr "Kontroler wewnętrzny" +msgid "Internal device" +msgstr "Urządzenie wewnętrzne" msgid "Exit" msgstr "Zakończ" @@ -841,7 +862,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\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, i inni.\n\nPrzetłumaczony przez: Fanta-Shokata\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać więcej informacji." +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." msgid "Hardware not available" msgstr "Sprzęt niedostępny" @@ -853,7 +874,10 @@ msgid "Invalid configuration" msgstr "Nieprawidłowa konfiguracja" 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 jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do ogólnej drukarki PostScript zostaną zapisane jako pliki PostScript (.ps)." +msgstr "%1 jest wymagany do automatycznej konwersji plików PostScript do PDF.\n\nDokumenty wysłane do generycznej drukarki PostScript zostaną zapisane jako pliki 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 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" @@ -999,6 +1023,27 @@ msgstr "Nadpisz" msgid "Don't overwrite" msgstr "Nie nadpisuj" +msgid "Raw image" +msgstr "Obraz surowy" + +msgid "HDI image" +msgstr "Obraz HDI" + +msgid "HDX image" +msgstr "Obraz HDX" + +msgid "Fixed-size VHD" +msgstr "VHD o stałym rozmiarze" + +msgid "Dynamic-size VHD" +msgstr "VHD o dynamicznym rozmiarze" + +msgid "Differencing VHD" +msgstr "VHD różnicujący" + +msgid "(N/A)" +msgstr "(Bez)" + msgid "Raw image (.img)" msgstr "Obraz surowy (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1,2 MB" @@ -1172,3 +1217,915 @@ 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." + +msgid "Generate" +msgstr "Generuj" + +msgid "Joystick configuration" +msgstr "Konfiguracja joysticka" + +msgid "Device" +msgstr "Urządzenie" + +msgid "%1 (X axis)" +msgstr "%1 (oś X)" + +msgid "%1 (Y axis)" +msgstr "%1 (oś Y)" + +msgid "MCA devices" +msgstr "Urządzenia MCA" + +msgid "List of MCA devices:" +msgstr "Lista urządzeń MCA:" + +msgid "Tablet tool" +msgstr "Narzędzie do tabletów" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "O Qt" + +msgid "MCA devices..." +msgstr "Urządzenia MCA..." + +msgid "Show non-primary monitors" +msgstr "Pokaż monitory inne niż podstawowe" + +msgid "Open screenshots folder..." +msgstr "Otwórz folder zrzutów ekranu..." + +msgid "Apply 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 "Pen" +msgstr "Pióro" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Napęd CD/DVD hosta (%1:)" + +msgid "&Connected" +msgstr "&Connected" + +msgid "Clear image history" +msgstr "Wyczyść historię obrazów" + +msgid "Create..." +msgstr "Stwórz..." + +msgid "previous image" +msgstr "poprzedni obraz" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Napęd CD/DVD hosta (%1)" + +msgid "Unknown Bus" +msgstr "Nieznana magistrala" + +msgid "Null Driver" +msgstr "Null Driver" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Błąd otwarcia \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Błąd kompilacji shadera wierzchołków w pliku \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Błąd kompilacji shadera fragmentów w pliku \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Błąd łączenia programu shader w pliku \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opcje renderowania OpenGL 3.0" + +msgid "Render behavior" +msgstr "Zachowanie renderowania" + +msgid "Use target framerate:" +msgstr "Użyj docelowej liczby klatek na sekundę:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Renderuj każdą klatkę natychmiast, w synchronizacji z emulowanym wyświetlaczem.</p><p><span style=" font-style:italic;">Jest to zalecana opcja, jeśli używane shadery nie wykorzystują frametime do animowanych efektów.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Zsynchronizuj z wideo" + +msgid "Shaders" +msgstr "Shadery" + +msgid "Remove" +msgstr "Usuń" + +msgid "No shader selected" +msgstr "Nie wybrano shadera" + +msgid "Browse..." +msgstr "Przeglądaj..." + +msgid "Shader error" +msgstr "Błąd shadera" + +msgid "Could not load shaders." +msgstr "Nie można załadować shaderów." + +msgid "More information in details." +msgstr "Więcej informacji w szczegółach." + +msgid "Couldn't create OpenGL context." +msgstr "Nie można utworzyć kontekstu OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Nie można przełączyć na kontekst OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Wymagana jest wersja OpenGL 3.0 lub wyższa. Aktualna wersja to %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Inicjalizacja OpenGL nie powiodła się. Błąd %1." + +msgid "Error initializing OpenGL" +msgstr "Błąd inicjalizacji OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Powrót do renderowania oprogramowania.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Przydzielenie pamięci dla bufora rozpakowywania nie powiodło się.\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>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 "This machine might have been moved or copied." +msgstr "To urządzenie mogło zostać przeniesione lub skopiowane." + +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 "Aby zapewnić prawidłową funkcjonalność sieci, 86Box musi wiedzieć, czy to urządzenie zostało przeniesione lub skopiowane.\n\nW przypadku braku pewności, wybrać opcję \"Zostało skopiowane\"." + +msgid "I Moved It" +msgstr "Zostało przeniesione" + +msgid "I Copied It" +msgstr "Zostało skopiowane" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Brak urządzeń MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Karta sieciowa 1" + +msgid "Network Card #2" +msgstr "Karta sieciowa 2" + +msgid "Network Card #3" +msgstr "Karta sieciowa 3" + +msgid "Network Card #4" +msgstr "Karta sieciowa 4" + +msgid "Mode" +msgstr "Tryb" + +msgid "Interface" +msgstr "Interfejs" + +msgid "Adapter" +msgstr "Adapter" + +msgid "VDE Socket" +msgstr "Gniazdo VDE" + +msgid "86Box Unit Tester" +msgstr "Tester urządzeń 86Box" + +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" + +msgid "Serial port passthrough 2" +msgstr "Przełączanie portu szeregowego 2" + +msgid "Serial port passthrough 3" +msgstr "Przełączanie portu szeregowego 3" + +msgid "Serial port passthrough 4" +msgstr "Przełączanie portu szeregowego 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Opcje renderowania..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Mysz magistralna Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Mysz magistralna Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mysz szeregowa Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Mysz szeregowa Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Mysz szeregowa Logitech" + +msgid "PS/2 Mouse" +msgstr "Mysz PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (szeregowa)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Standardowy modem zgodny z Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulacja Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulacja Roland MT-32 (nowego)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulacja Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulacja Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Płyta córka OPL4-ML" + +msgid "System MIDI" +msgstr "System MIDI" + +msgid "MIDI Input Device" +msgstr "Urządzenie wejściowe MIDI" + +msgid "BIOS Address" +msgstr "Adres BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Włączenie zapisu do pamięci ROM rozszerzenia BIOS" + +msgid "Address" +msgstr "Adres" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Wersja BIOS-u" + +msgid "Translate 26 -> 17" +msgstr "Przetłumacz 26 -> 17" + +msgid "Language" +msgstr "Język" + +msgid "Enable backlight" +msgstr "Włącz podświetlenie" + +msgid "Invert colors" +msgstr "Odwracanie kolorów" + +msgid "BIOS size" +msgstr "Rozmiar BIOS-u" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapowanie C0000-C7FFF jako UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapowanie C8000-CFFFF jako UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapowanie D0000-D7FFF jako UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapowanie D8000-DFFFF jako UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapowanie E0000-E7FFF jako UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapowanie E8000-EFFFF jako UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Zworka JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Urządzenie wyjściowe MIDI" + +msgid "MIDI Real time" +msgstr "MIDI w czasie rzeczywistym" + +msgid "MIDI Thru" +msgstr "Przejście wejścia MIDI" + +msgid "MIDI Clockout" +msgstr "Wyjście zegara MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Wzmocnienie wyjściowe" + +msgid "Chorus" +msgstr "Chór" + +msgid "Chorus Voices" +msgstr "Głosy chóru" + +msgid "Chorus Level" +msgstr "Poziom chóru" + +msgid "Chorus Speed" +msgstr "Prędkość chóru" + +msgid "Chorus Depth" +msgstr "Głębokość chóru" + +msgid "Chorus Waveform" +msgstr "Kształt fali chóru" + +msgid "Reverb" +msgstr "Pogłos" + +msgid "Reverb Room Size" +msgstr "Rozmiar pomieszczenia pogłosu" + +msgid "Reverb Damping" +msgstr "Tłumienie pogłosu" + +msgid "Reverb Width" +msgstr "Szerokość pogłosu" + +msgid "Reverb Level" +msgstr "Poziom pogłosu" + +msgid "Interpolation Method" +msgstr "Metoda interpolacji" + +msgid "Reverb Output Gain" +msgstr "Wzmocnienie sygnału wyjściowego pogłosu" + +msgid "Reversed stereo" +msgstr "Odwrócone stereo" + +msgid "Nice ramp" +msgstr "Niezła rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Przyciski" + +msgid "Serial Port" +msgstr "Port szeregowy" + +msgid "RTS toggle" +msgstr "Przełącznik RTS" + +msgid "Revision" +msgstr "Rewizja" + +msgid "Controller" +msgstr "Kontroler" + +msgid "Show Crosshair" +msgstr "Pokaż celownik" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Adres MAC" + +msgid "MAC Address OUI" +msgstr "OUI adresu MAC" + +msgid "Enable BIOS" +msgstr "Włącz BIOS" + +msgid "Baud Rate" +msgstr "Szybkość transmisji" + +msgid "TCP/IP listening port" +msgstr "Port nasłuchiwania TCP/IP" + +msgid "Phonebook File" +msgstr "Plik książki telefonicznej" + +msgid "Telnet emulation" +msgstr "Emulacja Telnet" + +msgid "RAM Address" +msgstr "Adres RAM" + +msgid "RAM size" +msgstr "Rozmiar pamięci RAM" + +msgid "Initial RAM size" +msgstr "Początkowy rozmiar pamięci RAM" + +msgid "Serial Number" +msgstr "Numer seryjny" + +msgid "Host ID" +msgstr "Identyfikator hosta" + +msgid "FDC Address" +msgstr "Adres FDC" + +msgid "MPU-401 Address" +msgstr "Adres MPU-401" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "Odbiór sygnału wejściowego MIDI" + +msgid "Low DMA" +msgstr "Niski poziom DMA" + +msgid "Enable Game port" +msgstr "Włącz port gier" + +msgid "Surround module" +msgstr "Moduł Surround" + +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)" + +msgid "SB Address" +msgstr "Adres SB" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "Włącz OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Odbiór wejścia MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "SB low DMA" + +msgid "6CH variant (6-channel)" +msgstr "Wariant 6CH (6-kanałowy)" + +msgid "Enable CMS" +msgstr "Włącz CMS" + +msgid "Mixer" +msgstr "Mikser" + +msgid "High DMA" +msgstr "Wysokie DMA" + +msgid "Control PC speaker" +msgstr "Głośnik komputera sterującego" + +msgid "Memory size" +msgstr "Rozmiar pamięci" + +msgid "EMU8000 Address" +msgstr "Adres EMU8000" + +msgid "IDE Controller" +msgstr "Kontroler IDE" + +msgid "Codec" +msgstr "Kodek" + +msgid "GUS type" +msgstr "Typ GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Włącz polecenie 0x04 \"Wyjdź z 86Box\"" + +msgid "Display type" +msgstr "Typ wyświetlacza" + +msgid "Composite type" +msgstr "Typ kompozytowy" + +msgid "RGB type" +msgstr "Typ RGB" + +msgid "Line doubling type" +msgstr "Typ podwojenia linii" + +msgid "Snow emulation" +msgstr "Emulacja śniegu" + +msgid "Monitor type" +msgstr "Typ monitora" + +msgid "Character set" +msgstr "Zestaw znaków" + +msgid "XGA type" +msgstr "Typ XGA" + +msgid "Instance" +msgstr "Instancja" + +msgid "MMIO Address" +msgstr "Adres MMIO" + +msgid "RAMDAC type" +msgstr "Typ RAMDAC" + +msgid "Blend" +msgstr "Mieszanka" + +msgid "Bilinear filtering" +msgstr "Filtrowanie dwuliniowe" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Włącz NMI dla emulacji CGA" + +msgid "Voodoo type" +msgstr "Typ Voodoo" + +msgid "Framebuffer memory size" +msgstr "Rozmiar pamięci bufora ramki" + +msgid "Texture memory size" +msgstr "Rozmiar pamięci tekstur" + +msgid "Dither subtraction" +msgstr "Odejmowanie ditheru" + +msgid "Screen Filter" +msgstr "Filtr ekranowy" + +msgid "Render threads" +msgstr "Wątki renderowania" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Adres początkowy" + +msgid "Contiguous Size" +msgstr "Przyległy rozmiar" + +msgid "I/O Width" +msgstr "Szerokość wejścia/wyjścia" + +msgid "Transfer Speed" +msgstr "Prędkość transferu" + +msgid "EMS mode" +msgstr "Tryb EMS" + +msgid "Address for > 2 MB" +msgstr "Adres dla > 2 MB" + +msgid "Frame Address" +msgstr "Adres ramki" + +msgid "USA" +msgstr "USA" + +msgid "Danish" +msgstr "Duński" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusoidalny" + +msgid "Triangle" +msgstr "Trójkątny" + +msgid "Linear" +msgstr "Liniowa" + +msgid "4th Order" +msgstr "4. rzędu" + +msgid "7th Order" +msgstr "7. rzędu" + +msgid "Non-timed (original)" +msgstr "Bez timera (oryginał)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (bez zworki na JMP2)" + +msgid "Two" +msgstr "Dwa" + +msgid "Three" +msgstr "Trzy" + +msgid "Wheel" +msgstr "Koło" + +msgid "Five + Wheel" +msgstr "Five + Wheel" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 szeregowa / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) szeregowa" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Wyłącz BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klasyczny" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Kompozyt" + +msgid "Old" +msgstr "Stary" + +msgid "New" +msgstr "Nowość" + +msgid "Color (generic)" +msgstr "Kolor (generyczny)" + +msgid "Green Monochrome" +msgstr "Zielony monochromatyczny" + +msgid "Amber Monochrome" +msgstr "Bursztynowy monochromatyczny" + +msgid "Gray Monochrome" +msgstr "Szary monochromatyczny" + +msgid "Color (no brown)" +msgstr "Kolor (bez brązowego)" + +msgid "Color (IBM 5153)" +msgstr "Kolor (IBM 5153)" + +msgid "Simple doubling" +msgstr "Proste podwojenie" + +msgid "sRGB interpolation" +msgstr "Interpolacja sRGB" + +msgid "Linear interpolation" +msgstr "Interpolacja liniowa" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monochromatyczny (5151/MDA) (biały)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monochromatyczny (5151/MDA) (zielony)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monochromatyczny (5151/MDA) (bursztynowy)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Kolor 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Kolor 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Rozszerzone kolory - tryb normalny (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Rozszerzony kolor - tryb rozszerzony (5154/ECD)" + +msgid "Green" +msgstr "Zielony" + +msgid "Amber" +msgstr "Bursztynowy" + +msgid "Gray" +msgstr "Szary" + +msgid "Color" +msgstr "Kolor" + +msgid "U.S. English" +msgstr "Amerykański angielski" + +msgid "Scandinavian" +msgstr "Skandynawski" + +msgid "Other languages" +msgstr "Inne języki" + +msgid "Bochs latest" +msgstr "Bochs najnowsze" + +msgid "Mono Non-Interlaced" +msgstr "Mono bez przeplotu" + +msgid "Color Interlaced" +msgstr "Kolor z przeplotem" + +msgid "Color Non-Interlaced" +msgstr "Kolor bez przeplotu" + +msgid "3Dfx Voodoo Graphics" +msgstr "Grafika 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsydian SB50 + Ametyst (2 jednostki TMU)" + +msgid "8-bit" +msgstr "8-bitowy" + +msgid "16-bit" +msgstr "16-bitowy" + +msgid "Standard (150ns)" +msgstr "Standard (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Wysoka prędkość (120ns)" + +msgid "Enabled" +msgstr "Włączone" + +msgid "Standard" +msgstr "Standard" + +msgid "High-Speed" +msgstr "Wysoka prędkość" + +msgid "Stereo LPT DAC" +msgstr "Stereofoniczny przetwornik cyfrowo-analogowy LPT" + +msgid "Generic Text Printer" +msgstr "Generyczna drukarka tekstowa" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Generyczna drukarka igłowa ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Generyczna drukarka PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Generyczna drukarka PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Protokół internetowy linii równoległej" + +msgid "Protection Dongle for Savage Quest" +msgstr "Klucz ochronny dla Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Urządzenie przelotowe portu szeregowego" + +msgid "Passthrough Mode" +msgstr "Tryb przelotowy" + +msgid "Host Serial Device" +msgstr "Urządzenie szeregowe hosta" + +msgid "Name of pipe" +msgstr "Nazwa rury" + +msgid "Data bits" +msgstr "Bity danych" + +msgid "Stop bits" +msgstr "Bity stopu" + +msgid "Baud Rate of Passthrough" +msgstr "Szybkość transmisji Passthrough" + +msgid "Named Pipe (Server)" +msgstr "Nazwana rura (serwer)" + +msgid "Host Serial Passthrough" +msgstr "Przejście przez port szeregowy hosta" + +msgid "Eject %s" +msgstr "Wyjmij %s" + +msgid "&Unmute" +msgstr "&Wycisz" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Wysoki wpływ na wydajność" + +msgid "RAM Disk (max. speed)" +msgstr "Dysk RAM (maks. prędkość)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Klon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Producent" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Generyczne rozszerzenie pamięci PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Generyczne rozszerzenie pamięci PC/AT" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 642031e9a..de1bcd544 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -13,7 +13,7 @@ msgid "&Keyboard requires capture" msgstr "&Teclado requer captura" msgid "&Right CTRL is left ALT" -msgstr "CTRL &direito é o ALT esquerdo" +msgstr "&CTRL direito é o ALT esquerdo" msgid "&Hard Reset..." msgstr "&Reinicialização completa..." @@ -118,13 +118,13 @@ msgid "Fullscreen &stretch mode" msgstr "Modo de &redimensionamento da tela cheia" msgid "&Full screen stretch" -msgstr "&Tela cheia esticada" +msgstr "&Tela cheia redimensionada" msgid "&4:3" msgstr "&4:3" msgid "&Square pixels (Keep ratio)" -msgstr "Pixel&s quadrados (manter proporção)" +msgstr "Píxeis &quadrados (manter proporção)" msgid "&Integer scale" msgstr "&Redimensionamento com valores inteiros" @@ -133,7 +133,7 @@ msgid "4:&3 Integer scale" msgstr "Redimensionamento com valores inteiros 4:&3" msgid "E&GA/(S)VGA settings" -msgstr "Configurações E&GA/(S)VGA" +msgstr "Configurações de E&GA/(S)VGA" msgid "&Inverted VGA monitor" msgstr "Monitor VGA &invertido" @@ -142,7 +142,7 @@ msgid "VGA screen &type" msgstr "&Tipo de tela VGA" msgid "RGB &Color" -msgstr "&Cores RGB" +msgstr "&Cor RGB" msgid "&RGB Grayscale" msgstr "Tons de cinza &RGB" @@ -202,7 +202,7 @@ msgid "Begin trace\tCtrl+T" msgstr "Inicio do rastreamento\tCtrl+T" msgid "End trace\tCtrl+T" -msgstr "Fim do rastreamento\tCtrl+T" +msgstr "Finalizar rastreamento\tCtrl+T" msgid "&Help" msgstr "&Ajuda" @@ -220,7 +220,7 @@ msgid "&Existing image..." msgstr "&Imagem existente..." msgid "Existing image (&Write-protected)..." -msgstr "Imagem existente (&protegida contra escrita)..." +msgstr "Imagem existente (&protegida contra gravação)..." msgid "&Record" msgstr "&Gravar" @@ -229,7 +229,7 @@ msgid "&Play" msgstr "&Reproduzir" msgid "&Rewind to the beginning" -msgstr "&Rebobinar até o começo" +msgstr "Re&troceder até o começo" msgid "&Fast forward to the end" msgstr "&Avançar até o fim" @@ -244,7 +244,7 @@ msgid "E&xport to 86F..." msgstr "E&xportar para 86F..." msgid "&Mute" -msgstr "&Sem som" +msgstr "&Silenciar" msgid "E&mpty" msgstr "&Vazio" @@ -256,7 +256,7 @@ msgid "&Folder..." msgstr "&Pasta..." msgid "Target &framerate" -msgstr "&Taxa de quadro pretendida" +msgstr "&Taxa de quadros pretendida" msgid "&Sync with video" msgstr "&Sincronizar com vídeo" @@ -298,7 +298,7 @@ msgid "Settings" msgstr "Configurações" msgid "Specify Main Window Dimensions" -msgstr "Especifique as dimensões da janela principal" +msgstr "Especificar dimensões da janela principal" msgid "OK" msgstr "OK" @@ -307,7 +307,7 @@ msgid "Cancel" msgstr "Cancelar" msgid "Save these settings as &global defaults" -msgstr "Usar estas configurações como &padrões globais" +msgstr "Salvar estas configurações como &padrões globais" msgid "&Default" msgstr "&Padrão" @@ -316,7 +316,7 @@ msgid "Language:" msgstr "Idioma:" msgid "Icon set:" -msgstr "Pacote de ícones:" +msgstr "Conjunto de ícones:" msgid "Gain" msgstr "Ganho" @@ -373,7 +373,7 @@ msgid "Memory:" msgstr "Memória:" msgid "Time synchronization" -msgstr "Sincronização da hora" +msgstr "Sincronização de hora" msgid "Disabled" msgstr "Desativar" @@ -390,8 +390,11 @@ msgstr "Recompilador dinâmico" msgid "Video:" msgstr "Vídeo:" -msgid "Voodoo Graphics" -msgstr "3DFX Voodoo" +msgid "Video #2:" +msgstr "Vídeo 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Gráficos Voodoo 1 ou 2" msgid "IBM 8514/A Graphics" msgstr "Gráficos IBM 8514/A" @@ -436,7 +439,7 @@ msgid "MIDI In Device:" msgstr "Disp. de entrada MIDI:" msgid "Standalone MPU-401" -msgstr "MPU-401 autônomo" +msgstr "MPU-401 independente" msgid "Use FLOAT32 sound" msgstr "Usar som FLOAT32" @@ -673,7 +676,7 @@ msgid "All images" msgstr "Todas as imagens" msgid "Basic sector images" -msgstr "Imagens de setor básico" +msgstr "Imagens de setores básicos" msgid "Surface images" msgstr "Imagens de superfície" @@ -684,6 +687,12 @@ msgstr "A máquina \"%hs\" não está disponível devido à falta de ROMs no dir msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "A placa de vídeo \"%hs\" não está disponível devido à falta de ROMs no diretório roms/video. Mudando para uma placa de vídeo disponível." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "A placa de vídeo 2 \"%hs\" não está disponível devido à falta de ROMs no diretório roms/video. Desativando a segunda placa vídeo." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "O dispositivo \"%hs\" não está disponível devido à falta de ROMs. Ignorando o dispositivo." + msgid "Machine" msgstr "Máquina" @@ -762,17 +771,26 @@ msgstr "Nenhum dispositivo PCap encontrado" msgid "Invalid PCap device" msgstr "Dispositivo PCap inválido" -msgid "Standard 2-button joystick(s)" -msgstr "Joystick padrão de 2 botões" +msgid "2-axis, 2-button joystick(s)" +msgstr "Joystick(s) de 2 eixos, 2 botões" -msgid "Standard 4-button joystick" -msgstr "Joystick padrão de 4 botões" +msgid "2-axis, 4-button joystick" +msgstr "Joystick de 2 eixos, 4 botões" -msgid "Standard 6-button joystick" -msgstr "Joystick padrão de 6 botões" +msgid "2-axis, 6-button joystick" +msgstr "Joystick de 2 eixos, 6 botões" -msgid "Standard 8-button joystick" -msgstr "Joystick padrão de 8 botões" +msgid "2-axis, 8-button joystick" +msgstr "Joystick de 2 eixos, 8 botões" + +msgid "3-axis, 2-button joystick" +msgstr "Joystick padrão de 3 eixos, 2 botões" + +msgid "3-axis, 4-button joystick" +msgstr "Joystick padrão de 3 eixos, 4 botões" + +msgid "4-axis, 4-button joystick" +msgstr "Joystick padrão de 4 eixos, 4 botões" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -784,10 +802,10 @@ msgid "Thrustmaster Flight Control System" msgstr "Sistema de Controle de Voo Thrustmaster" msgid "None" -msgstr "Nada" +msgstr "Nenhum" msgid "%u MB (CHS: %i, %i, %i)" -msgstr "%u MB (CHS: %i, %i, %i)" +msgstr "%u MB (CCS: %i, %i, %i)" msgid "Floppy %i (%s): %ls" msgstr "Disquete %i (%s): %ls" @@ -805,7 +823,10 @@ msgid "Are you sure you want to exit 86Box?" msgstr "Tem certeza de que deseja sair do 86Box?" msgid "Unable to initialize Ghostscript" -msgstr "Não é possível inicializar o Ghostscript" +msgstr "Não foi possível inicializar o Ghostscript" + +msgid "Unable to initialize GhostPCL" +msgstr "Não foi possível inicializar o GhostPCL" msgid "MO %i (%ls): %ls" msgstr "Magneto-óptico %i (%ls): %ls" @@ -816,14 +837,14 @@ msgstr "Imagens magneto-ópticas" msgid "Welcome to 86Box!" msgstr "Bem-vindo ao 86Box!" -msgid "Internal controller" -msgstr "Controlador interno" +msgid "Internal device" +msgstr "Dispositivo interno" msgid "Exit" msgstr "Sair" msgid "No ROMs found" -msgstr "Nenhum ROM encontrada" +msgstr "Nenhuma ROM encontrada" msgid "Do you want to save the settings?" msgstr "Você deseja salvar as configurações?" @@ -841,7 +862,7 @@ msgid "86Box v" 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\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." +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\n\nLançado sob a Licença Pública Geral GNU, versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." msgid "Hardware not available" msgstr "Hardware não disponível" @@ -855,6 +876,9 @@ msgstr "Configuração inválida" 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 é necessário para a conversão automática de arquivos PostScript para PDF.\n\nQualquer documento enviado para a impressora genérica PostScript será salvo como arquivos PostScript (.ps)." +msgid "%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" @@ -889,7 +913,7 @@ msgid "You are loading an unsupported configuration" msgstr "Você está carregando uma configuração não suportada" msgid "CPU type filtering based on selected machine is disabled for this emulated machine.\n\nThis makes it possible to choose a CPU that is otherwise incompatible with the selected machine. However, you may run into incompatibilities with the machine BIOS or other software.\n\nEnabling this setting is not officially supported and any bug reports filed may be closed as invalid." -msgstr "A filtragem do tipo CPU baseada na máquina selecionada é desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que de outra forma seria incompatível com a máquina selecionada. Entretanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada e qualquer relatório de erro arquivado pode ser fechado como inválido." +msgstr "A filtragem do tipo de CPU baseada na máquina selecionada está desativada para esta máquina emulada.\n\nIsto torna possível escolher uma CPU que, de outra forma, seria incompatível com a máquina selecionada. No entanto, você pode encontrar incompatibilidades com a BIOS da máquina ou outro software.\n\nA ativação desta configuração não é oficialmente suportada, e qualquer relatório de erro arquivado pode ser fechado como inválido." msgid "Continue" msgstr "Continuar" @@ -999,6 +1023,27 @@ msgstr "Sobrescrever" msgid "Don't overwrite" msgstr "Não sobrescrever" +msgid "Raw image" +msgstr "Imagem bruta" + +msgid "HDI image" +msgstr "Imagem HDI" + +msgid "HDX image" +msgstr "Imagem HDX" + +msgid "Fixed-size VHD" +msgstr "VHD de tamanho fixo" + +msgid "Dynamic-size VHD" +msgstr "VHD de tamanho dinâmico" + +msgid "Differencing VHD" +msgstr "VHD diferencial" + +msgid "(N/A)" +msgstr "(N/D)" + msgid "Raw image (.img)" msgstr "Imagem bruta (.img)" @@ -1030,13 +1075,13 @@ msgid "Select the parent VHD" msgstr "Selecione o VHD pai" 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 "Isto pode significar que a imagem de origem foi modificada após a criação da imagem diferencial.\n\nTambém pode acontecer caso os arquivos de imagem tenham sido movidos ou copiados, ou por um erro no programa que criou este disco.\n\nVocê quer consertar os marcadores de tempo?" +msgstr "Isto pode significar que a imagem original foi modificada após a criação da imagem diferencial.\n\nIsso também pode ocorrer se os arquivos de imagem tiverem sido movidos ou copiados, ou por um erro no programa que criou este disco.\n\nVocê deseja corrigir os marcadores de tempo?" msgid "Parent and child disk timestamps do not match" -msgstr "A data/hora dos arquivos de pais e filhos não correspondem" +msgstr "Os marcadores de tempo do disco pai e do disco filho não coincidem" msgid "Could not fix VHD timestamp." -msgstr "Não foi possível consertar o carimbo de data/hora da VHD." +msgstr "Não foi possível corrigir o marcador de tempo do VHD." msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1126,16 +1171,16 @@ msgid "5.25\" 1.3 GB" msgstr "5.25\" 1.3 GB" msgid "Perfect RPM" -msgstr "RPM perfeita" +msgstr "Rotação ideal" msgid "1% below perfect RPM" -msgstr "1% abaixo das RPM perfeita" +msgstr "1% abaixo da rotação ideal" msgid "1.5% below perfect RPM" -msgstr "1.5% abaixo das RPM perfeita" +msgstr "1.5% abaixo da rotação ideal" msgid "2% below perfect RPM" -msgstr "2% abaixo das RPM perfeita" +msgstr "2% abaixo da rotação ideal" msgid "(System Default)" msgstr "(Padrão do sistema)" @@ -1147,7 +1192,7 @@ msgid "The network configuration will be switched to the null driver" msgstr "A configuração de rede será alterada para o driver nulo" msgid "Mouse sensitivity:" -msgstr "Sensibilidade do rato:" +msgstr "Sensibilidade do mouse:" msgid "Select media images from program working directory" msgstr "Selecione imagens de mídia do diretório de trabalho do programa" @@ -1171,4 +1216,916 @@ msgid "WinBox is no longer supported" msgstr "O WinBox não é mais suportado" 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 "O desenvolvimento do gerenciador WinBox foi interrompido em 2022 devido à falta de mantenedores. Conforme direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não oferecer mais suporte ao WinBox como gerenciador.\n\nAtualizações não serão mais fornecidas através do WinBox, e você poderá encontrar comportamentos incorretos caso continue a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de bugs relacionados ao comportamento do WinBox serão fechados como inválidos.\n\nAcesse 86box.net para obter uma lista de outros gerenciadores que você pode usar." +msgstr "O desenvolvimento do gerenciador WinBox foi interrompido em 2022 devido à falta de mantenedores. À medida que direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não oferecer mais suporte ao WinBox como gerenciador.\n\nNão serão mais fornecidas atualizações através do WinBox, e você poderá encontrar comportamentos incorretos caso continue a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de erros relacionados ao comportamento do WinBox serão fechados como inválidos.\n\nAcesse 86box.net para obter uma lista de outros gerenciadores que você pode usar." + +msgid "Generate" +msgstr "Gerar" + +msgid "Joystick configuration" +msgstr "Configuração do joystick" + +msgid "Device" +msgstr "Dispositivo" + +msgid "%1 (X axis)" +msgstr "%1 (eixo X)" + +msgid "%1 (Y axis)" +msgstr "%1 (eixo Y)" + +msgid "MCA devices" +msgstr "Dispositivos MCA" + +msgid "List of MCA devices:" +msgstr "Lista de dispositivos MCA:" + +msgid "Tablet tool" +msgstr "Ferramenta para tablet" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Sobre o Qt" + +msgid "MCA devices..." +msgstr "Dispositivos MCA..." + +msgid "Show non-primary monitors" +msgstr "Mostrar monitores não primários" + +msgid "Open screenshots folder..." +msgstr "Abrir pasta de capturas de tela..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Aplicar modo de ampliação em tela cheia quando maximizado" + +msgid "Cursor/Puck" +msgstr "Cursor/Puck" + +msgid "Pen" +msgstr "Caneta" + +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 "Create..." +msgstr "Criar..." + +msgid "previous image" +msgstr "imagem anterior" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Unidade de CD/DVD do anfitrião (%1)" + +msgid "Unknown Bus" +msgstr "Barramento desconhecido" + +msgid "Null Driver" +msgstr "Driver nulo" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Erro ao abrir \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Erro ao compilar o sombreador de vértice no arquivo \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Erro ao compilar o fragment shader no arquivo \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Erro ao vincular o programa de shader no arquivo \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opções do renderizador OpenGL 3.0" + +msgid "Render behavior" +msgstr "Comportamento de renderização" + +msgid "Use target framerate:" +msgstr "Usar taxa de quadros pretendida:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Renderize cada quadro imediatamente, em sincronia com a tela emulada.</p><p><span style=" font-style:italic;">Essa é a opção recomendada se os shaders em uso não utilizarem o frametime para efeitos animados.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sincronizar com o vídeo" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Remover" + +msgid "No shader selected" +msgstr "Nenhum shader selecionado" + +msgid "Browse..." +msgstr "Procurar..." + +msgid "Shader error" +msgstr "Erro do sombreador" + +msgid "Could not load shaders." +msgstr "Não foi possível carregar os shaders." + +msgid "More information in details." +msgstr "Mais informações em detalhes." + +msgid "Couldn't create OpenGL context." +msgstr "Não foi possível criar o contexto OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Não foi possível alternar para o contexto OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "É necessária a versão 3.0 ou superior do OpenGL. A versão atual é %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Falha na inicialização do OpenGL. Erro %1." + +msgid "Error initializing OpenGL" +msgstr "Erro ao inicializar o OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Voltando à renderização de software.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Falha na alocação de memória para o buffer de descompactação.\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>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 "This machine might have been moved or copied." +msgstr "Essa máquina pode ter sido movida ou copiada." + +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 "Para garantir a funcionalidade adequada da rede, o 86Box precisa saber se essa máquina foi movida ou copiada.\n\nSelecione \"A copiei\" se não tiver certeza." + +msgid "I Moved It" +msgstr "O movi" + +msgid "I Copied It" +msgstr "A copiei" + +msgid "86Box Monitor #" +msgstr "Monitor 86Box " + +msgid "No MCA devices." +msgstr "Nenhum dispositivo MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Placa de rede 1" + +msgid "Network Card #2" +msgstr "Placa de rede 2" + +msgid "Network Card #3" +msgstr "Placa de rede 3" + +msgid "Network Card #4" +msgstr "Placa de rede 4" + +msgid "Mode" +msgstr "Modo" + +msgid "Interface" +msgstr "Interface" + +msgid "Adapter" +msgstr "Adaptador" + +msgid "VDE Socket" +msgstr "Soquete VDE" + +msgid "86Box Unit Tester" +msgstr "Testador de unidade 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Cartão de Autenticação Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Passagem de porta serial 1" + +msgid "Serial port passthrough 2" +msgstr "Passagem de porta serial 2" + +msgid "Serial port passthrough 3" +msgstr "Passagem de porta serial 3" + +msgid "Serial port passthrough 4" +msgstr "Passagem de porta serial 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Opções do renderizador..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Mouse de barramento Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Mouse de barramento Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse serial Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Mouse serial Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Mouse serial Logitech" + +msgid "PS/2 Mouse" +msgstr "Mouse PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (serial)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Modem padrão compatível com Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulação do Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulação do Roland MT-32 (novo)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulação do Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulação do Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Placa Filha OPL4-ML" + +msgid "System MIDI" +msgstr "Sistema MIDI" + +msgid "MIDI Input Device" +msgstr "Dispositivo de entrada MIDI" + +msgid "BIOS Address" +msgstr "Endereço do BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Habilitar gravações na ROM de extensão do BIOS" + +msgid "Address" +msgstr "Endereço" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revisão do BIOS" + +msgid "Translate 26 -> 17" +msgstr "Traduzir 26 -> 17" + +msgid "Language" +msgstr "Idioma" + +msgid "Enable backlight" +msgstr "Ativar luz de fundo" + +msgid "Invert colors" +msgstr "Inverter cores" + +msgid "BIOS size" +msgstr "Tamanho do BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapear C0000-C7FFF como UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapear C8000-CFFFF como UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapear D0000-D7FFF como UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapear D8000-DFFFF como UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapear E0000-E7FFF como UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapear E8000-EFFFF como UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Jumper JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Dispositivo de saída MIDI" + +msgid "MIDI Real time" +msgstr "MIDI em tempo real" + +msgid "MIDI Thru" +msgstr "Passagem da entrada MIDI" + +msgid "MIDI Clockout" +msgstr "Saída do relógio MIDI" + +msgid "SoundFont" +msgstr "Fonte de som" + +msgid "Output Gain" +msgstr "Ganho de saída" + +msgid "Chorus" +msgstr "Coro" + +msgid "Chorus Voices" +msgstr "Vozes do coro" + +msgid "Chorus Level" +msgstr "Nível do coro" + +msgid "Chorus Speed" +msgstr "Velocidade do coro" + +msgid "Chorus Depth" +msgstr "Profundidade do coro" + +msgid "Chorus Waveform" +msgstr "Forma de onda do coro" + +msgid "Reverb" +msgstr "Reverberação" + +msgid "Reverb Room Size" +msgstr "Tamanho da sala de reverberação" + +msgid "Reverb Damping" +msgstr "Amortecimento de reverberação" + +msgid "Reverb Width" +msgstr "Largura de reverberação" + +msgid "Reverb Level" +msgstr "Nível de reverberação" + +msgid "Interpolation Method" +msgstr "Método de interpolação" + +msgid "Reverb Output Gain" +msgstr "Ganho da saída da reverberação" + +msgid "Reversed stereo" +msgstr "Estéreo invertido" + +msgid "Nice ramp" +msgstr "Bela rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Botões" + +msgid "Serial Port" +msgstr "Porta serial" + +msgid "RTS toggle" +msgstr "Alternância de RTS" + +msgid "Revision" +msgstr "Revisão" + +msgid "Controller" +msgstr "Controlador" + +msgid "Show Crosshair" +msgstr "Mostrar mira" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Endereço MAC" + +msgid "MAC Address OUI" +msgstr "OUI do Endereço MAC" + +msgid "Enable BIOS" +msgstr "Habilitar BIOS" + +msgid "Baud Rate" +msgstr "Taxa de transmissão" + +msgid "TCP/IP listening port" +msgstr "Porta de escuta TCP/IP" + +msgid "Phonebook File" +msgstr "Arquivo de lista telefônica" + +msgid "Telnet emulation" +msgstr "Emulação Telnet" + +msgid "RAM Address" +msgstr "Endereço da RAM" + +msgid "RAM size" +msgstr "Tamanho da RAM" + +msgid "Initial RAM size" +msgstr "Tamanho inicial da RAM" + +msgid "Serial Number" +msgstr "Número de série" + +msgid "Host ID" +msgstr "ID do host" + +msgid "FDC Address" +msgstr "Endereço da FDC" + +msgid "MPU-401 Address" +msgstr "Endereço da MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Receber entrada MIDI" + +msgid "Low DMA" +msgstr "DMA baixo" + +msgid "Enable Game port" +msgstr "Ativar a porta do jogo" + +msgid "Surround module" +msgstr "Módulo surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Aumentar a interrupção do CODEC na configuração do CODEC (necessário para alguns drivers)" + +msgid "SB Address" +msgstr "Endereço do SB" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "Ativar OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Receber entrada MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "DMA baixo SB" + +msgid "6CH variant (6-channel)" +msgstr "Variante 6CH (6 canais)" + +msgid "Enable CMS" +msgstr "Ativar o CMS" + +msgid "Mixer" +msgstr "Misturador" + +msgid "High DMA" +msgstr "DMA alto" + +msgid "Control PC speaker" +msgstr "Controlar alto-falante do PC" + +msgid "Memory size" +msgstr "Tamanho da memória" + +msgid "EMU8000 Address" +msgstr "Endereço da EMU8000" + +msgid "IDE Controller" +msgstr "Controlador IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Tipo de GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Ativar o comando 0x04 \"Sair do 86Box\"" + +msgid "Display type" +msgstr "Tipo de tela" + +msgid "Composite type" +msgstr "Tipo de composto" + +msgid "RGB type" +msgstr "Tipo de RGB" + +msgid "Line doubling type" +msgstr "Tipo de duplicação de linha" + +msgid "Snow emulation" +msgstr "Emulação de neve" + +msgid "Monitor type" +msgstr "Tipo de monitor" + +msgid "Character set" +msgstr "Conjunto de caracteres" + +msgid "XGA type" +msgstr "Tipo de XGA" + +msgid "Instance" +msgstr "Instância" + +msgid "MMIO Address" +msgstr "Endereço da MMIO" + +msgid "RAMDAC type" +msgstr "Tipo de RAMDAC" + +msgid "Blend" +msgstr "Mistura" + +msgid "Bilinear filtering" +msgstr "Filtragem bilinear" + +msgid "Dithering" +msgstr "Pontilhamento" + +msgid "Enable NMI for CGA emulation" +msgstr "Ativar NMI para emulação CGA" + +msgid "Voodoo type" +msgstr "Tipo de Voodoo" + +msgid "Framebuffer memory size" +msgstr "Tamanho da memória do framebuffer" + +msgid "Texture memory size" +msgstr "Tamanho da memória da textura" + +msgid "Dither subtraction" +msgstr "Subtração de pontilhado" + +msgid "Screen Filter" +msgstr "Filtro de tela" + +msgid "Render threads" +msgstr "Threads de renderização" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Endereço inicial" + +msgid "Contiguous Size" +msgstr "Tamanho contíguo" + +msgid "I/O Width" +msgstr "Largura de E/S" + +msgid "Transfer Speed" +msgstr "Velocidade de transferência" + +msgid "EMS mode" +msgstr "Modo EMS" + +msgid "Address for > 2 MB" +msgstr "Endereço para > 2 MB" + +msgid "Frame Address" +msgstr "Endereço do quadro" + +msgid "USA" +msgstr "EUA" + +msgid "Danish" +msgstr "Dinamarquês" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Senoidal" + +msgid "Triangle" +msgstr "Triangular" + +msgid "Linear" +msgstr "Linear" + +msgid "4th Order" +msgstr "De 4ª ordem" + +msgid "7th Order" +msgstr "De 7º order" + +msgid "Non-timed (original)" +msgstr "Sem cronômetro (original)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (sem jumper em JMP2)" + +msgid "Two" +msgstr "Dois" + +msgid "Three" +msgstr "Três" + +msgid "Wheel" +msgstr "Roda" + +msgid "Five + Wheel" +msgstr "Cinco + roda" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 Serial / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) Serial" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Desativar o BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (estéreo)" + +msgid "Classic" +msgstr "Clássico" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Composto" + +msgid "Old" +msgstr "Antiga" + +msgid "New" +msgstr "Novo" + +msgid "Color (generic)" +msgstr "Colorido (genérico)" + +msgid "Green Monochrome" +msgstr "Monocromático verde" + +msgid "Amber Monochrome" +msgstr "Monocromático âmbar" + +msgid "Gray Monochrome" +msgstr "Monocromático cinza" + +msgid "Color (no brown)" +msgstr "Colorido (sem marrom)" + +msgid "Color (IBM 5153)" +msgstr "Colorido (IBM 5153)" + +msgid "Simple doubling" +msgstr "Duplicação simples" + +msgid "sRGB interpolation" +msgstr "Interpolação sRGB" + +msgid "Linear interpolation" +msgstr "Interpolação linear" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monocromático (5151/MDA) (branco)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monocromático (5151/MDA) (verde)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monocromático (5151/MDA) (âmbar)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Colorido 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Colorido 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Colorido aprimorado - Modo normal (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Colorido aprimorado - Modo aprimorado (5154/ECD)" + +msgid "Green" +msgstr "Verde" + +msgid "Amber" +msgstr "Âmbar" + +msgid "Gray" +msgstr "Cinza" + +msgid "Color" +msgstr "Colorido" + +msgid "U.S. English" +msgstr "Inglês Americano" + +msgid "Scandinavian" +msgstr "Escandinavo" + +msgid "Other languages" +msgstr "Outros idiomas" + +msgid "Bochs latest" +msgstr "Bochs mais recente" + +msgid "Mono Non-Interlaced" +msgstr "Monocromático não entrelaçado" + +msgid "Color Interlaced" +msgstr "Colorido entrelaçado" + +msgid "Color Non-Interlaced" +msgstr "Colorido não entrelaçado" + +msgid "3Dfx Voodoo Graphics" +msgstr "Gráficos 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 unidades TMU)" + +msgid "8-bit" +msgstr "8 bits" + +msgid "16-bit" +msgstr "16 bits" + +msgid "Standard (150ns)" +msgstr "Padrão (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Alta velocidade (120 ns)" + +msgid "Enabled" +msgstr "Ativado" + +msgid "Standard" +msgstr "Padrão" + +msgid "High-Speed" +msgstr "Alta velocidade" + +msgid "Stereo LPT DAC" +msgstr "DAC LPT estéreo" + +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" + +msgid "Generic PostScript Printer" +msgstr "Impressora PostScript genérica" + +msgid "Generic PCL5e Printer" +msgstr "Impressora PCL5e genérica" + +msgid "Parallel Line Internet Protocol" +msgstr "Protocolo de Internet de linha paralela" + +msgid "Protection Dongle for Savage Quest" +msgstr "Dongle de proteção para Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Dispositivo de passagem de porta serial" + +msgid "Passthrough Mode" +msgstr "Modo de passagem" + +msgid "Host Serial Device" +msgstr "Dispositivo serial host" + +msgid "Name of pipe" +msgstr "Nome do tubo" + +msgid "Data bits" +msgstr "Bits de dados" + +msgid "Stop bits" +msgstr "Bits de parada" + +msgid "Baud Rate of Passthrough" +msgstr "Taxa de transmissão de passagem" + +msgid "Named Pipe (Server)" +msgstr "Tubo nomeado (servidor)" + +msgid "Host Serial Passthrough" +msgstr "Passagem da porta serial do host" + +msgid "Eject %s" +msgstr "Ejetar %s" + +msgid "&Unmute" +msgstr "&Reativar som" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Alto impacto no desempenho" + +msgid "RAM Disk (max. speed)" +msgstr "Disco RAM (velocidade máxima)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Clone IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Fabricante" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Expansão de memória genérica PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Expansão de memória genérica PC/AT" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 3aa004e83..d4c8bf170 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -115,10 +115,10 @@ msgid "&Fullscreen\tCtrl+Alt+PgUp" msgstr "E&crã cheio\tCtrl+Alt+PgUp" msgid "Fullscreen &stretch mode" -msgstr "Modo &de estiramento em ecrã cheio" +msgstr "Modo &de estiramento na tela cheia" msgid "&Full screen stretch" -msgstr "&Estiramento em ecrã cheio" +msgstr "&Estiramento na tela cheia" msgid "&4:3" msgstr "&4:3" @@ -244,7 +244,7 @@ msgid "E&xport to 86F..." msgstr "E&xportar para 86F..." msgid "&Mute" -msgstr "&Mute" +msgstr "&Desativar som" msgid "E&mpty" msgstr "&CDROM vazio" @@ -390,8 +390,11 @@ msgstr "Recompilador dinâmico" msgid "Video:" msgstr "Vídeo:" -msgid "Voodoo Graphics" -msgstr "Gráficos Voodoo" +msgid "Video #2:" +msgstr "Vídeo 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Gráficos Voodoo 1 ou 2" msgid "IBM 8514/A Graphics" msgstr "Gráficos IBM 8514/A" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Erro fatal" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - EM PAUSA" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Pressione Ctrl+Alt+PgDn para voltar ao modo de janela." @@ -684,6 +687,12 @@ msgstr "A máquina \"%hs\" não está disponível devido à falta de ROMs na pas msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "A placa vídeo \"%hs\" não está disponível devido à falta de ROMs na pasta roms/video. A mudar para uma placa vídeo disponível." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "A placa vídeo 2 \"%hs\" não está disponível devido à falta de ROMs na pasta roms/video. A desativar a segunda placa vídeo." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "O dispositivo \"%hs\" não está disponível devido à falta de ROMs A ignorar o dispositivo." + msgid "Machine" msgstr "Máquina" @@ -762,17 +771,26 @@ msgstr "Não foi encontrado um dispositivo PCap" msgid "Invalid PCap device" msgstr "Dispositivo PCap inválido" -msgid "Standard 2-button joystick(s)" -msgstr "Joystick(s) standard de 2 botões" +msgid "2-axis, 2-button joystick(s)" +msgstr "Joystick(s) de 2 eixos, 2 botões" -msgid "Standard 4-button joystick" -msgstr "Joystick(s) standard de 4 botões" +msgid "2-axis, 4-button joystick" +msgstr "Joystick de 2 eixos, 4 botões" -msgid "Standard 6-button joystick" -msgstr "Joystick(s) standard de 6 botões" +msgid "2-axis, 6-button joystick" +msgstr "Joystick de 2 eixos, 6 botões" -msgid "Standard 8-button joystick" -msgstr "Joystick(s) standard de 8 botões" +msgid "2-axis, 8-button joystick" +msgstr "Joystick de 2 eixos, 8 botões" + +msgid "3-axis, 2-button joystick" +msgstr "Joystick de 3 eixos, 2 botões" + +msgid "3-axis, 4-button joystick" +msgstr "Joystick de 3 eixos, 4 botões" + +msgid "4-axis, 4-button joystick" +msgstr "Joystick de 4 eixos, 4 botões" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Tem a certeza de que quer sair do 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Não foi possível inicializar o Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Não foi possível inicializar o GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "Magneto-óptico %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Imagens magneto-ópticas" msgid "Welcome to 86Box!" msgstr "Bem-vindos ao 86Box!" -msgid "Internal controller" -msgstr "Controlador interno" +msgid "Internal device" +msgstr "Dispositivo integrado" msgid "Exit" msgstr "Sair" @@ -841,7 +862,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 "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." +msgstr "Um emulador de computadores antigos\n\nAutores: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nCom contribuições anteriores de Sarah Walker, leilei, JohnElliott, greatpsycho e outros.\n\nUsado sob a licença GNU General Public License versão 2 ou posterior. Veja o ficheiro LICENSE para mais informações." msgid "Hardware not available" msgstr "Hardware não disponível" @@ -855,8 +876,11 @@ msgstr "Configuração inválida" 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 é requerido para a conversão automática de ficheiros PostScript para ficheiros PDF.\n\nQualquer documento enviado para a impressora PostScript genérica será gravado como um ficheiro PostScript (.ps)." +msgid "%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 ecrã cheio" +msgstr "A entrar no modo de tela cheia" msgid "Don't show this message again" msgstr "Não mostrar mais esta mensagem" @@ -999,6 +1023,27 @@ msgstr "Sobrescrever" msgid "Don't overwrite" msgstr "Não sobrescrever" +msgid "Raw image" +msgstr "Imagem bruta" + +msgid "HDI image" +msgstr "Imagem HDI" + +msgid "HDX image" +msgstr "Imagem HDX" + +msgid "Fixed-size VHD" +msgstr "VHD com tamanho fixo" + +msgid "Dynamic-size VHD" +msgstr "VHD com tamanho dinâmico" + +msgid "Differencing VHD" +msgstr "VHD diferenciador" + +msgid "(N/A)" +msgstr "(N/D)" + msgid "Raw image (.img)" msgstr "Imagem bruta (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "O WinBox não é mais suportado" 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 "O desenvolvimento do gerenciador WinBox parou em 2022 devido à falta de mantenedores. Como direcionamos nossos esforços para tornar o 86Box ainda melhor, tomamos a decisão de não mais suportar o WinBox como um gerenciador.\n\nNão serão fornecidas mais actualizações através do WinBox, e poderá encontrar um comportamento incorreto se continuar a usá-lo com versões mais recentes do 86Box. Quaisquer relatórios de erros relacionados com o comportamento do WinBox serão fechados como inválidos.\n\nVá a 86box.net para uma lista de outros gestores que pode utilizar." + +msgid "Generate" +msgstr "Gerar" + +msgid "Joystick configuration" +msgstr "Configuração do joystick" + +msgid "Device" +msgstr "Dispositivo" + +msgid "%1 (X axis)" +msgstr "%1 (eixo X)" + +msgid "%1 (Y axis)" +msgstr "%1 (eixo Y)" + +msgid "MCA devices" +msgstr "Dispositivos MCA" + +msgid "List of MCA devices:" +msgstr "Lista de dispositivos MCA:" + +msgid "Tablet tool" +msgstr "Ferramenta para tablet" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Acerca do Qt" + +msgid "MCA devices..." +msgstr "Dispositivos MCA..." + +msgid "Show non-primary monitors" +msgstr "Mostrar monitores não primários" + +msgid "Open screenshots folder..." +msgstr "Abrir a pasta de capturas de ecrã..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Aplicar o modo de estiramento na tela cheia quando maximizado" + +msgid "Cursor/Puck" +msgstr "Cursor/Puck" + +msgid "Pen" +msgstr "Caneta" + +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 "Create..." +msgstr "Criar..." + +msgid "previous image" +msgstr "imagem anterior" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Unidade de CD/DVD do anfitrião (%1)" + +msgid "Unknown Bus" +msgstr "Autocarro desconhecido" + +msgid "Null Driver" +msgstr "Condutor nulo" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Erro ao abrir \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Erro ao compilar o sombreador de vértice no ficheiro \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Erro ao compilar o shader de fragmento no ficheiro \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Erro ao ligar o programa de shader no ficheiro \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Opções do renderizador OpenGL 3.0" + +msgid "Render behavior" +msgstr "Comportamento de renderização" + +msgid "Use target framerate:" +msgstr "Utilizar a taxa de quadros de destino:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Renderiza cada frame imediatamente, em sincronia com o ecrã emulado.</p><p><span style=" font-style:italic;">Esta é a opção recomendada se os shaders em uso não utilizam frametime para efeitos animados.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sincronizar com vídeo" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Remover" + +msgid "No shader selected" +msgstr "Nenhum sombreador selecionado" + +msgid "Browse..." +msgstr "Navegar..." + +msgid "Shader error" +msgstr "Erro de shader" + +msgid "Could not load shaders." +msgstr "Não foi possível carregar os shaders." + +msgid "More information in details." +msgstr "Mais informações em pormenor." + +msgid "Couldn't create OpenGL context." +msgstr "Não foi possível criar o contexto OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Não foi possível mudar para o contexto OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "É necessária a versão 3.0 ou superior do OpenGL. A versão atual é %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Falha na inicialização do OpenGL. Erro %1." + +msgid "Error initializing OpenGL" +msgstr "Erro ao inicializar o OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Recuando para a renderização de software." + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Falha na atribuição de memória para a memória intermédia de descompactação.\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>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 "This machine might have been moved or copied." +msgstr "Esta máquina pode ter sido deslocada ou copiada." + +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 "Para garantir a funcionalidade de rede adequada, o 86Box precisa de saber se esta máquina foi movida ou copiada.\n\nSeleccione \"Copiei-a\" se não tiver a certeza." + +msgid "I Moved It" +msgstr "Movi-a" + +msgid "I Copied It" +msgstr "Copiei-a" + +msgid "86Box Monitor #" +msgstr "Monitor 86Box " + +msgid "No MCA devices." +msgstr "Não há dispositivos MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Placa de rede 1" + +msgid "Network Card #2" +msgstr "Placa de rede 2" + +msgid "Network Card #3" +msgstr "Placa de rede 3" + +msgid "Network Card #4" +msgstr "Placa de rede 4" + +msgid "Mode" +msgstr "Modo" + +msgid "Interface" +msgstr "Interface" + +msgid "Adapter" +msgstr "Adaptador" + +msgid "VDE Socket" +msgstr "Tomada VDE" + +msgid "86Box Unit Tester" +msgstr "Testador de unidades 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Cartão-chave do Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Passagem da porta de série 1" + +msgid "Serial port passthrough 2" +msgstr "Passagem da porta de série 2" + +msgid "Serial port passthrough 3" +msgstr "Passagem da porta de série 3" + +msgid "Serial port passthrough 4" +msgstr "Passagem da porta de série 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Sistemas de visão Melhorador LBA" + +msgid "Renderer options..." +msgstr "Opções do renderizador..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Rato Logitech/Microsoft Bus" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Rato Microsoft Bus (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Sistemas de ratos Rato de série" + +msgid "Microsoft Serial Mouse" +msgstr "Rato de série Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Rato de série Logitech" + +msgid "PS/2 Mouse" +msgstr "Rato PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (série)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Modem padrão compatível com Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulação do Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulação do Roland MT-32 (novo)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulação Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulação Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Placa filha OPL4-ML" + +msgid "System MIDI" +msgstr "Sistema MIDI" + +msgid "MIDI Input Device" +msgstr "Dispositivo de entrada MIDI" + +msgid "BIOS Address" +msgstr "Endereço da BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Ativar as escritas de ROM de extensão da BIOS" + +msgid "Address" +msgstr "Endereço" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revisão da BIOS" + +msgid "Translate 26 -> 17" +msgstr "Traduzir 26 -> 17" + +msgid "Language" +msgstr "Língua" + +msgid "Enable backlight" +msgstr "Ativar a retroiluminação" + +msgid "Invert colors" +msgstr "Inverter cores" + +msgid "BIOS size" +msgstr "Tamanho da BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapear C0000-C7FFF como UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapear C8000-CFFFF como UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapear D0000-D7FFF como UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapear D8000-DFFFF como UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapear E0000-E7FFF como UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapear E8000-EFFFF como UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Jumper JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Dispositivo de saída MIDI" + +msgid "MIDI Real time" +msgstr "MIDI em tempo real" + +msgid "MIDI Thru" +msgstr "Passagem da entrada MIDI" + +msgid "MIDI Clockout" +msgstr "Saída do relógio MIDI" + +msgid "SoundFont" +msgstr "Fonte de som" + +msgid "Output Gain" +msgstr "Ganho de saída" + +msgid "Chorus" +msgstr "Coro" + +msgid "Chorus Voices" +msgstr "Vozes do coro" + +msgid "Chorus Level" +msgstr "Nível de coro" + +msgid "Chorus Speed" +msgstr "Velocidade do coro" + +msgid "Chorus Depth" +msgstr "Profundidade do coro" + +msgid "Chorus Waveform" +msgstr "Forma de onda do coro" + +msgid "Reverb" +msgstr "Reverberação" + +msgid "Reverb Room Size" +msgstr "Tamanho da sala de reverberação" + +msgid "Reverb Damping" +msgstr "Amortecimento de reverberação" + +msgid "Reverb Width" +msgstr "Largura de reverberação" + +msgid "Reverb Level" +msgstr "Nível de reverberação" + +msgid "Interpolation Method" +msgstr "Método de interpolação" + +msgid "Reverb Output Gain" +msgstr "Ganho da saída do reverb" + +msgid "Reversed stereo" +msgstr "Estéreo invertido" + +msgid "Nice ramp" +msgstr "Bela rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Botões" + +msgid "Serial Port" +msgstr "Porta de série" + +msgid "RTS toggle" +msgstr "Alternância RTS" + +msgid "Revision" +msgstr "Revisão" + +msgid "Controller" +msgstr "Controlador" + +msgid "Show Crosshair" +msgstr "Mostrar mira" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Endereço MAC" + +msgid "MAC Address OUI" +msgstr "OUI do endereço MAC" + +msgid "Enable BIOS" +msgstr "Ativar a BIOS" + +msgid "Baud Rate" +msgstr "Taxa de transmissão" + +msgid "TCP/IP listening port" +msgstr "Porta de escuta TCP/IP" + +msgid "Phonebook File" +msgstr "Ficheiro da lista telefónica" + +msgid "Telnet emulation" +msgstr "Emulação Telnet" + +msgid "RAM Address" +msgstr "Endereço RAM" + +msgid "RAM size" +msgstr "Tamanho da RAM" + +msgid "Initial RAM size" +msgstr "Tamanho inicial da RAM" + +msgid "Serial Number" +msgstr "Número de série" + +msgid "Host ID" +msgstr "ID do anfitrião" + +msgid "FDC Address" +msgstr "Endereço da FDC" + +msgid "MPU-401 Address" +msgstr "Endereço MPU-401" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "Receber entrada MIDI" + +msgid "Low DMA" +msgstr "DMA baixo" + +msgid "Enable Game port" +msgstr "Ativar a porta de jogos" + +msgid "Surround module" +msgstr "Módulo Surround" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Ativar a interrupção do CODEC na configuração do CODEC (necessário para alguns controladores)" + +msgid "SB Address" +msgstr "Endereço SB" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "Ativar OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Receber entrada MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "SB baixo DMA" + +msgid "6CH variant (6-channel)" +msgstr "Variante 6CH (6 canais)" + +msgid "Enable CMS" +msgstr "Ativar CMS" + +msgid "Mixer" +msgstr "Misturador" + +msgid "High DMA" +msgstr "DMA elevado" + +msgid "Control PC speaker" +msgstr "Controlo do altifalante do PC" + +msgid "Memory size" +msgstr "Tamanho da memória" + +msgid "EMU8000 Address" +msgstr "Endereço da EMU8000" + +msgid "IDE Controller" +msgstr "Controlador IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Tipo GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Ativar o comando 0x04 \"Sair do 86Box\"" + +msgid "Display type" +msgstr "Tipo de ecrã" + +msgid "Composite type" +msgstr "Tipo composto" + +msgid "RGB type" +msgstr "Tipo RGB" + +msgid "Line doubling type" +msgstr "Tipo de duplicação de linha" + +msgid "Snow emulation" +msgstr "Emulação de neve" + +msgid "Monitor type" +msgstr "Tipo de monitor" + +msgid "Character set" +msgstr "Conjunto de caracteres" + +msgid "XGA type" +msgstr "Tipo XGA" + +msgid "Instance" +msgstr "Instância" + +msgid "MMIO Address" +msgstr "Endereço MMIO" + +msgid "RAMDAC type" +msgstr "Tipo de RAMDAC" + +msgid "Blend" +msgstr "Mistura" + +msgid "Bilinear filtering" +msgstr "Filtragem bilinear" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Ativar NMI para emulação CGA" + +msgid "Voodoo type" +msgstr "Tipo Voodoo" + +msgid "Framebuffer memory size" +msgstr "Tamanho da memória do framebuffer" + +msgid "Texture memory size" +msgstr "Tamanho da memória da textura" + +msgid "Dither subtraction" +msgstr "Subtração de dither" + +msgid "Screen Filter" +msgstr "Filtro de tela" + +msgid "Render threads" +msgstr "Renderizar threads" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Endereço inicial" + +msgid "Contiguous Size" +msgstr "Tamanho contíguo" + +msgid "I/O Width" +msgstr "Largura de E/S" + +msgid "Transfer Speed" +msgstr "Velocidade de transferência" + +msgid "EMS mode" +msgstr "Modo EMS" + +msgid "Address for > 2 MB" +msgstr "Endereço para > 2 MB" + +msgid "Frame Address" +msgstr "Endereço do quadro" + +msgid "USA" +msgstr "EUA" + +msgid "Danish" +msgstr "Dinamarquesa" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusoidal" + +msgid "Triangle" +msgstr "Triangular" + +msgid "Linear" +msgstr "Linear" + +msgid "4th Order" +msgstr "De 4ª ordem" + +msgid "7th Order" +msgstr "De 7ª ordem" + +msgid "Non-timed (original)" +msgstr "Sem temporizador (original)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (sem jumper em JMP2)" + +msgid "Two" +msgstr "Dois" + +msgid "Three" +msgstr "Três" + +msgid "Wheel" +msgstr "Roda" + +msgid "Five + Wheel" +msgstr "Cinco + Roda" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 série / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) série" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Desativar a BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (estéreo)" + +msgid "Classic" +msgstr "Clássico" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Compósito" + +msgid "Old" +msgstr "Antigo" + +msgid "New" +msgstr "Novo" + +msgid "Color (generic)" +msgstr "Cor (genérico)" + +msgid "Green Monochrome" +msgstr "Monocromático verde" + +msgid "Amber Monochrome" +msgstr "Monocromático âmbar" + +msgid "Gray Monochrome" +msgstr "Monocromático cinzento" + +msgid "Color (no brown)" +msgstr "Cor (sem castanho)" + +msgid "Color (IBM 5153)" +msgstr "Cor (IBM 5153)" + +msgid "Simple doubling" +msgstr "Duplicação simples" + +msgid "sRGB interpolation" +msgstr "interpolação sRGB" + +msgid "Linear interpolation" +msgstr "Interpolação linear" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monocromático (5151/MDA) (branco)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monocromático (5151/MDA) (verde)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monocromático (5151/MDA) (âmbar)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Cor 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Cor 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Cor melhorada - Modo normal (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Cor melhorada - Modo melhorado (5154/ECD)" + +msgid "Green" +msgstr "Verde" + +msgid "Amber" +msgstr "Âmbar" + +msgid "Gray" +msgstr "Cinzento" + +msgid "Color" +msgstr "Cor" + +msgid "U.S. English" +msgstr "Inglês dos E.U.A." + +msgid "Scandinavian" +msgstr "Escandinavo" + +msgid "Other languages" +msgstr "Outros idiomas" + +msgid "Bochs latest" +msgstr "Bochs mais recente" + +msgid "Mono Non-Interlaced" +msgstr "Monocromático não entrelaçado" + +msgid "Color Interlaced" +msgstr "Cor entrelaçado" + +msgid "Color Non-Interlaced" +msgstr "Cor não entrelaçado" + +msgid "3Dfx Voodoo Graphics" +msgstr "Gráficos 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 unidades TMU)" + +msgid "8-bit" +msgstr "8 bits" + +msgid "16-bit" +msgstr "16 bits" + +msgid "Standard (150ns)" +msgstr "Padrão (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Alta velocidade (120ns)" + +msgid "Enabled" +msgstr "Ativado" + +msgid "Standard" +msgstr "Padrão" + +msgid "High-Speed" +msgstr "Alta velocidade" + +msgid "Stereo LPT DAC" +msgstr "DAC LPT estéreo" + +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" + +msgid "Generic PostScript Printer" +msgstr "Impressora PostScript genérica" + +msgid "Generic PCL5e Printer" +msgstr "Impressora genérica PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Protocolo Internet de linha paralela" + +msgid "Protection Dongle for Savage Quest" +msgstr "Dongle de proteção para Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Dispositivo de passagem de porta de série" + +msgid "Passthrough Mode" +msgstr "Modo de passagem" + +msgid "Host Serial Device" +msgstr "Dispositivo de série anfitrião" + +msgid "Name of pipe" +msgstr "Nome do tubo" + +msgid "Data bits" +msgstr "Bits de dados" + +msgid "Stop bits" +msgstr "Bits de paragem" + +msgid "Baud Rate of Passthrough" +msgstr "Taxa de transmissão de passagem" + +msgid "Named Pipe (Server)" +msgstr "Tubo nomeado (servidor)" + +msgid "Host Serial Passthrough" +msgstr "Passagem da porta de série do anfitrião" + +msgid "Eject %s" +msgstr "Ejetar %s" + +msgid "&Unmute" +msgstr "&Reativar som" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Elevado impacto no desempenho" + +msgid "RAM Disk (max. speed)" +msgstr "Disco RAM (velocidade máxima)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Clone IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Fabricante" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Expansão de memória genérica PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Expansão de memória genérica PC/AT" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index eb3c89174..a2e352faa 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -39,9 +39,6 @@ msgstr "&Скрыть строку состояния" msgid "Hide &toolbar" msgstr "С&крыть панель инструментов" -msgid "Show non-primary monitors" -msgstr "&Показывать неосновные мониторы" - msgid "&Resizeable window" msgstr "&Изменяемый размер окна" @@ -63,30 +60,6 @@ msgstr "Open&GL (3.0)" msgid "&VNC" msgstr "&VNC" -msgid "Renderer options..." -msgstr "Параметры рендеринга..." - -msgid "OpenGL 3.0 renderer options" -msgstr "Параметры рендеринга OpenGL 3.0" - -msgid "Render behavior" -msgstr "Режим рендеринга" - -msgid "Synchronize with video" -msgstr "Синхронизировать с видео" - -msgid "Use target framerate:" -msgstr "Использовать целевую частоту кадров:" - -msgid "VSync" -msgstr "Вертикальная синхронизация" - -msgid "Shaders" -msgstr "Шейдеры" - -msgid "No shader selected" -msgstr "Шейдер не выбран" - msgid "Specify dimensions..." msgstr "&Указать размеры главного окна..." @@ -159,9 +132,6 @@ msgstr "&Целочисленное масштабирование" msgid "4:&3 Integer scale" msgstr "4:&3 Целочисленное масштабирование" -msgid "Apply fullscreen stretch mode when maximized" -msgstr "Применить полноэкранный режим растяжения при разворачивании окна" - msgid "E&GA/(S)VGA settings" msgstr "Настройки E&GA/(S)VGA" @@ -228,9 +198,6 @@ msgstr "Включить интеграцию &Discord" msgid "Sound &gain..." msgstr "&Усиление звука..." -msgid "Open screenshots folder..." -msgstr "Открыть папку скриншотов..." - msgid "Begin trace\tCtrl+T" msgstr "Начать трассировку\tCtrl+T" @@ -270,9 +237,6 @@ msgstr "&Перемотка в конец" msgid "E&ject" msgstr "И&звлечь" -msgid "Eject %s" -msgstr "Извлечь %s" - msgid "&Image..." msgstr "&Образ..." @@ -282,9 +246,6 @@ msgstr "Э&кспорт в 86F..." msgid "&Mute" msgstr "О&тключить звук" -msgid "&Unmute" -msgstr "В&ключить звук" - msgid "E&mpty" msgstr "П&устой" @@ -432,8 +393,8 @@ msgstr "Видеокарта 1:" msgid "Video #2:" msgstr "Видеокарта 2:" -msgid "Voodoo Graphics" -msgstr "Ускоритель Voodoo" +msgid "Voodoo 1 or 2 Graphics" +msgstr "Ускоритель Voodoo 1 или 2" msgid "IBM 8514/A Graphics" msgstr "Ускоритель IBM 8514/A" @@ -501,30 +462,6 @@ msgstr "Устройство PCap:" msgid "Network adapter:" msgstr "Сетевая карта:" -msgid "Network Card #1" -msgstr "Сетевая карта 1:" - -msgid "Network Card #2" -msgstr "Сетевая карта 2:" - -msgid "Network Card #3" -msgstr "Сетевая карта 3:" - -msgid "Network Card #4" -msgstr "Сетевая карта 4:" - -msgid "Mode" -msgstr "Режим:" - -msgid "Interface" -msgstr "Интерфейс:" - -msgid "Adapter" -msgstr "Адаптер:" - -msgid "VDE Socket" -msgstr "VDE Socket:" - msgid "COM1 Device:" msgstr "Устройство COM1:" @@ -561,18 +498,6 @@ msgstr "Последовательный порт COM3" msgid "Serial port 4" msgstr "Последовательный порт COM4" -msgid "Serial port passthrough 1" -msgstr "Сквозной последовательный порт COM1" - -msgid "Serial port passthrough 2" -msgstr "Сквозной последовательный порт COM2" - -msgid "Serial port passthrough 3" -msgstr "Сквозной последовательный порт COM3" - -msgid "Serial port passthrough 4" -msgstr "Сквозной последовательный порт COM4" - msgid "Parallel port 1" msgstr "Параллельный порт LPT1" @@ -624,15 +549,9 @@ msgstr "&Создать..." msgid "&Existing..." msgstr "&Выбрать..." -msgid "Browse..." -msgstr "Выбрать..." - msgid "&Remove" msgstr "&Удалить" -msgid "Remove" -msgstr "Удалить" - msgid "Bus:" msgstr "Шина:" @@ -711,9 +630,6 @@ msgstr "Устройство ISABugger" msgid "POST card" msgstr "Карта POST" -msgid "86Box Unit Tester" -msgstr "Модульный Тестер 86Box" - msgid "86Box" msgstr "86Box" @@ -744,9 +660,6 @@ msgstr "86Box не смог найти ни одного подходящего msgid "(empty)" msgstr "(пусто)" -msgid "Clear image history" -msgstr "Очистить историю образов" - msgid "All files" msgstr "Все файлы" @@ -774,6 +687,12 @@ msgstr "Системная плата \"%hs\" недоступна из-за о msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Видеокарта \"%hs\" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/video. Переключение на доступную видеокарту." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Видеокарта 2 \"%hs\" недоступна из-за отсутствия файла её ПЗУ в каталоге roms/video. Вторая видеокарта отключена." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Устройство \"%hs\" недоступно из-за отсутствия файла его ПЗУ. Устройство проигнорировано." + msgid "Machine" msgstr "Компьютер" @@ -831,9 +750,6 @@ msgstr "H" msgid "S" msgstr "S" -msgid "MiB" -msgstr "МиБ" - msgid "KB" msgstr "КБ" @@ -855,17 +771,26 @@ msgstr "Устройства PCap не найдены" msgid "Invalid PCap device" msgstr "Неверное устройство PCap" -msgid "Standard 2-button joystick(s)" -msgstr "Стандартный 2-кнопочный джойстик" +msgid "2-axis, 2-button joystick(s)" +msgstr "2-осевой, 2-кнопочный джойстик" -msgid "Standard 4-button joystick" -msgstr "Стандартный 4-кнопочный джойстик" +msgid "2-axis, 4-button joystick" +msgstr "2-осевой, 4-кнопочный джойстик" -msgid "Standard 6-button joystick" -msgstr "Стандартный 6-кнопочный джойстик" +msgid "2-axis, 6-button joystick" +msgstr "2-осевой, 6-кнопочный джойстик" -msgid "Standard 8-button joystick" -msgstr "Стандартный 8-кнопочный джойстик" +msgid "2-axis, 8-button joystick" +msgstr "2-осевой, 8-кнопочный джойстик" + +msgid "3-axis, 2-button joystick" +msgstr "3-осевой, 2-кнопочный джойстик" + +msgid "3-axis, 4-button joystick" +msgstr "3-осевой, 4-кнопочный джойстик" + +msgid "4-axis, 4-button joystick" +msgstr "4-осевой, 4-кнопочный джойстик" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -900,6 +825,9 @@ msgstr "Вы уверены, что хотите выйти из 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Невозможно инициализировать Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Невозможно инициализировать GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "Магнитооптический %i (%ls): %ls" @@ -909,8 +837,8 @@ msgstr "Образы магнитооптических дисков" msgid "Welcome to 86Box!" msgstr "Добро пожаловать в 86Box!" -msgid "Internal controller" -msgstr "Встроенный контроллер" +msgid "Internal device" +msgstr "Встроенное устройство" msgid "Exit" msgstr "Выход" @@ -934,7 +862,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 "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." +msgstr "Эмулятор старых компьютеров\n\nАвторы: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nС предыдущими основными материалами от Sarah Walker, leilei, JohnElliott, greatpsycho и других.\n\nВыпускается под лицензией GNU General Public License версии 2 или более поздней. Дополнительную информацию см. в файле LICENSE." msgid "Hardware not available" msgstr "Оборудование недоступно" @@ -946,7 +874,10 @@ msgid "Invalid configuration" msgstr "Недопустимая конфигурация" 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 "Для автоматического преобразования файлов PostScript в PDF требуется %1.\n\nВсе документы, отправленные на общий принтер PostScript, будут сохранены в виде файлов PostScript (.ps)." +msgstr "Для автоматического преобразования файлов PostScript в PDF требуется %1.\n\nВсе документы, отправленные на стандартный принтер PostScript, будут сохранены в виде файлов 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 Language (.pcl) files." +msgstr "Для автоматического преобразования файлов PCL в PDF требуется %1.\n\nВсе документы, отправленные на стандартный принтер PCL, будут сохранены в виде файлов Printer Command Language (.pcl)." msgid "Entering fullscreen mode" msgstr "Вход в полноэкранный режим" @@ -1092,6 +1023,27 @@ msgstr "Перезаписать" msgid "Don't overwrite" msgstr "Не перезаписывать" +msgid "Raw image" +msgstr "RAW образ" + +msgid "HDI image" +msgstr "Образ HDI" + +msgid "HDX image" +msgstr "Образ HDX" + +msgid "Fixed-size VHD" +msgstr "Образ VHD фиксированного размера" + +msgid "Dynamic-size VHD" +msgstr "Образ VHD динамического размера" + +msgid "Differencing VHD" +msgstr "Дифференцированный образ VHD" + +msgid "(N/A)" +msgstr "(Нет)" + msgid "Raw image (.img)" msgstr "RAW образ (.img)" @@ -1102,10 +1054,10 @@ msgid "HDX image (.hdx)" msgstr "Образ HDX (.hdx)" msgid "Fixed-size VHD (.vhd)" -msgstr "VHD фиксированного размера (.vhd)" +msgstr "Образ VHD фиксированного размера (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "VHD динамического размера (.vhd)" +msgstr "Образ VHD динамического размера (.vhd)" msgid "Differencing VHD (.vhd)" msgstr "Дифференцированный образ VHD (.vhd)" @@ -1149,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 кБ" +msgid "160 KB" +msgstr "160 КБ" -msgid "180 kB" -msgstr "180 кБ" +msgid "180 KB" +msgstr "180 КБ" -msgid "320 kB" -msgstr "320 кБ" +msgid "320 KB" +msgstr "320 КБ" -msgid "360 kB" -msgstr "360 кБ" +msgid "360 KB" +msgstr "360 КБ" -msgid "640 kB" -msgstr "640 кБ" +msgid "640 KB" +msgstr "640 КБ" -msgid "720 kB" -msgstr "720 кБ" +msgid "720 KB" +msgstr "720 КБ" msgid "1.2 MB" msgstr "1.2 МБ" @@ -1265,3 +1217,921 @@ msgstr "WinBox больше не поддерживается" 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 прекратилась в 2022 году из-за отсутствия сопровождающих. Поскольку мы направляем наши усилия на то, чтобы сделать 86Box еще лучше, мы приняли решение больше не поддерживать WinBox в качестве менеджера.\n\nWinBox больше не будет обновляться, и вы можете столкнуться с некорректным поведением, если продолжите использовать его с новыми версиями 86Box. Любые сообщения об ошибках, связанных с поведением WinBox, будут закрыты как недействительные.\n\nПерейдите на сайт 86box.net для получения списка других менеджеров, которые вы можете использовать." + +msgid "Generate" +msgstr "Создать" + +msgid "Joystick configuration" +msgstr "Конфигурация джойстика" + +msgid "Device" +msgstr "Устройство" + +msgid "%1 (X axis)" +msgstr "%1 (ось X)" + +msgid "%1 (Y axis)" +msgstr "%1 (ось Y)" + +msgid "MCA devices" +msgstr "Устройства MCA" + +msgid "List of MCA devices:" +msgstr "Список устройств MCA:" + +msgid "Tablet tool" +msgstr "Планшетный инструмент" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "О Qt" + +msgid "MCA devices..." +msgstr "Устройства MCA..." + +msgid "Show non-primary monitors" +msgstr "&Показывать неосновные мониторы" + +msgid "Open screenshots folder..." +msgstr "Открыть папку скриншотов..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Применить полноэкранный режим растяжения при разворачивании окна" + +msgid "Cursor/Puck" +msgstr "Курсор/шайба" + +msgid "Pen" +msgstr "Ручка" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Главный CD/DVD-привод (%1:)" + +msgid "&Connected" +msgstr "&Connected" + +msgid "Clear image history" +msgstr "Очистить историю образов" + +msgid "Create..." +msgstr "Создайте..." + +msgid "previous image" +msgstr "предыдущее изображение" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Главный CD/DVD-привод (%1)" + +msgid "Unknown Bus" +msgstr "Неизвестная шина" + +msgid "Null Driver" +msgstr "Нулевой драйвер" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Ошибка при открытии \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Ошибка компиляции вершинного шейдера в файле \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Ошибка компиляции фрагментного шейдера в файле \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Ошибка компоновки программы шейдера в файле \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Параметры рендеринга OpenGL 3.0" + +msgid "Render behavior" +msgstr "Режим рендеринга" + +msgid "Use target framerate:" +msgstr "Использовать целевую частоту кадров:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "Вертикальная синхронизация" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Рендерить каждый кадр немедленно, синхронно с эмулируемым дисплеем.</p><p><span style="font-style:italic;">Это рекомендуемый вариант, если используемые шейдеры не используют время кадров для анимированных эффектов.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Синхронизация с видео" + +msgid "Shaders" +msgstr "Шейдеры" + +msgid "Remove" +msgstr "Удалить" + +msgid "No shader selected" +msgstr "Шейдер не выбран" + +msgid "Browse..." +msgstr "Обзор..." + +msgid "Shader error" +msgstr "Ошибка шейдера" + +msgid "Could not load shaders." +msgstr "Не удалось загрузить шейдеры." + +msgid "More information in details." +msgstr "Более подробная информация в деталях." + +msgid "Couldn't create OpenGL context." +msgstr "Не удалось создать контекст OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Не удалось переключиться на контекст OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Требуется OpenGL версии 3.0 или выше. Текущая версия %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Не удалось выполнить инициализацию OpenGL. Ошибка %1." + +msgid "Error initializing OpenGL" +msgstr "Ошибка инициализации OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Переключение на программный рендеринг.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +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 "This machine might have been moved or copied." +msgstr "Возможно, эта машина была перемещена или скопирована." + +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 "Чтобы обеспечить правильную работу сети, 86Box должен знать, была ли эта машина перемещена или скопирована.\n\nЕсли вы не уверены, выберите \"Скопирована\"." + +msgid "I Moved It" +msgstr "Перемещена" + +msgid "I Copied It" +msgstr "Скопирована" + +msgid "86Box Monitor #" +msgstr "86Box Monitor #" + +msgid "No MCA devices." +msgstr "Нет устройств MCA." + +msgid "MiB" +msgstr "МиБ" + +msgid "Network Card #1" +msgstr "Сетевая карта 1" + +msgid "Network Card #2" +msgstr "Сетевая карта 2" + +msgid "Network Card #3" +msgstr "Сетевая карта 3" + +msgid "Network Card #4" +msgstr "Сетевая карта 4" + +msgid "Mode" +msgstr "Режим" + +msgid "Interface" +msgstr "Интерфейс" + +msgid "Adapter" +msgstr "Адаптер" + +msgid "VDE Socket" +msgstr "VDE сокет" + +msgid "86Box Unit Tester" +msgstr "Модульный Тестер 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Карта ключей Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Сквозной последовательный порт COM1" + +msgid "Serial port passthrough 2" +msgstr "Сквозной последовательный порт COM2" + +msgid "Serial port passthrough 3" +msgstr "Сквозной последовательный порт COM3" + +msgid "Serial port passthrough 4" +msgstr "Сквозной последовательный порт COM4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Параметры рендеринга..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Шинная мышь Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Шинная мышь Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Последовательная мышь Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Последовательная мышь Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Последовательная мышь Logitech" + +msgid "PS/2 Mouse" +msgstr "Мышь PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (последовательная)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Стандартный Hayes-совместимый модем" + +msgid "Roland MT-32 Emulation" +msgstr "Эмуляция Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Эмуляция Roland MT-32 (Новый)" + +msgid "Roland CM-32L Emulation" +msgstr "Эмуляция Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Эмуляция Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Дочерняя плата OPL4-ML" + +msgid "System MIDI" +msgstr "Системный MIDI" + +msgid "MIDI Input Device" +msgstr "Устройство ввода MIDI" + +msgid "BIOS Address" +msgstr "Адрес BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Разрешить запись в ПЗУ расширения BIOS" + +msgid "Address" +msgstr "Адрес" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Версия BIOS" + +msgid "Translate 26 -> 17" +msgstr "Перевести 26 -> 17" + +msgid "Language" +msgstr "Язык" + +msgid "Enable backlight" +msgstr "Включить подсветку" + +msgid "Invert colors" +msgstr "Инвертировать цвета" + +msgid "BIOS size" +msgstr "Размер BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Отображение C0000-C7FFF в качестве UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Отображение C8000-CFFFF в качестве UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Отображение D0000-D7FFF в качестве UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Отображение D8000-DFFFF в качестве UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Отображение E0000-E7FFF в качестве UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Отображение E8000-EFFFF в качестве UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Джампер JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Устройство вывода MIDI" + +msgid "MIDI Real time" +msgstr "MIDI в реальном времени" + +msgid "MIDI Thru" +msgstr "Пропускание MIDI-входа" + +msgid "MIDI Clockout" +msgstr "MIDI Clockout" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Усиление выхода" + +msgid "Chorus" +msgstr "Хорус" + +msgid "Chorus Voices" +msgstr "Голоса хоруса" + +msgid "Chorus Level" +msgstr "Уровень хоруса" + +msgid "Chorus Speed" +msgstr "Скорость хоруса" + +msgid "Chorus Depth" +msgstr "Глубина хоруса" + +msgid "Chorus Waveform" +msgstr "Форма волны хоруса" + +msgid "Reverb" +msgstr "Реверберация" + +msgid "Reverb Room Size" +msgstr "Размер комнаты реверберации" + +msgid "Reverb Damping" +msgstr "Демпфирование реверберации" + +msgid "Reverb Width" +msgstr "Ширина реверберации" + +msgid "Reverb Level" +msgstr "Уровень реверберации" + +msgid "Interpolation Method" +msgstr "Метод интерполяции" + +msgid "Reverb Output Gain" +msgstr "Усиление выходного сигнала ревербератора" + +msgid "Reversed stereo" +msgstr "Реверс стерео" + +msgid "Nice ramp" +msgstr "Nice ramp" + +msgid "Hz" +msgstr "Гц" + +msgid "Buttons" +msgstr "Кнопки" + +msgid "Serial Port" +msgstr "Последовательный порт" + +msgid "RTS toggle" +msgstr "Переключатель RTS" + +msgid "Revision" +msgstr "Версия" + +msgid "Controller" +msgstr "Контроллер" + +msgid "Show Crosshair" +msgstr "Показать перекрестие" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC-адрес" + +msgid "MAC Address OUI" +msgstr "OUI MAC-адреса" + +msgid "Enable BIOS" +msgstr "Включить BIOS" + +msgid "Baud Rate" +msgstr "Скорость передачи данных" + +msgid "TCP/IP listening port" +msgstr "Порт прослушивания TCP/IP" + +msgid "Phonebook File" +msgstr "Файл телефонной книги" + +msgid "Telnet emulation" +msgstr "Эмуляция Telnet" + +msgid "RAM Address" +msgstr "Адрес оперативной памяти" + +msgid "RAM size" +msgstr "Объем оперативной памяти" + +msgid "Initial RAM size" +msgstr "Начальный размер оперативной памяти" + +msgid "Serial Number" +msgstr "Серийный номер" + +msgid "Host ID" +msgstr "Идентификатор хоста" + +msgid "FDC Address" +msgstr "Адрес FDC" + +msgid "MPU-401 Address" +msgstr "Адрес MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Включить MIDI-вход" + +msgid "Low DMA" +msgstr "Низкий DMA" + +msgid "Enable Game port" +msgstr "Включить игровой порт" + +msgid "Surround module" +msgstr "Модуль объемного звучания" + +msgid "CODEC" +msgstr "КОДЕК" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Поднимать прерывание CODEC при настройке CODEC (необходимо некоторым драйверам)." + +msgid "SB Address" +msgstr "Адрес SB" + +msgid "WSS IRQ" +msgstr "IRQ WSS" + +msgid "WSS DMA" +msgstr "DMA WSS" + +msgid "Enable OPL" +msgstr "Включить OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Включить MIDI-вход (MPU-401)" + +msgid "SB low DMA" +msgstr "Низкий DMA SB" + +msgid "6CH variant (6-channel)" +msgstr "Вариант 6CH (6-канальный)" + +msgid "Enable CMS" +msgstr "Включить CMS" + +msgid "Mixer" +msgstr "Смеситель" + +msgid "High DMA" +msgstr "Высокий DMA" + +msgid "Control PC speaker" +msgstr "Управление динамиком ПК" + +msgid "Memory size" +msgstr "Объем памяти" + +msgid "EMU8000 Address" +msgstr "Адрес EMU8000" + +msgid "IDE Controller" +msgstr "Контроллер IDE" + +msgid "Codec" +msgstr "Кодек" + +msgid "GUS type" +msgstr "Тип GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Включить команду 0x04 \"Выход 86Box\"." + +msgid "Display type" +msgstr "Тип дисплея" + +msgid "Composite type" +msgstr "Тип композитного видео" + +msgid "RGB type" +msgstr "Тип видео RGB" + +msgid "Line doubling type" +msgstr "Тип удвоения линии" + +msgid "Snow emulation" +msgstr "Эмуляция снега" + +msgid "Monitor type" +msgstr "Тип монитора" + +msgid "Character set" +msgstr "Набор символов" + +msgid "XGA type" +msgstr "Тип XGA" + +msgid "Instance" +msgstr "Экземпляр" + +msgid "MMIO Address" +msgstr "Адрес MMIO" + +msgid "RAMDAC type" +msgstr "Тип RAMDAC" + +msgid "Blend" +msgstr "Смесь" + +msgid "Bilinear filtering" +msgstr "Билинейная фильтрация" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Включение NMI для эмуляции CGA" + +msgid "Voodoo type" +msgstr "Тип Вуду" + +msgid "Framebuffer memory size" +msgstr "Размер памяти фреймбуфера" + +msgid "Texture memory size" +msgstr "Размер памяти текстур" + +msgid "Dither subtraction" +msgstr "Вычитание с вычитанием" + +msgid "Screen Filter" +msgstr "Фильтр экрана" + +msgid "Render threads" +msgstr "Потоки рендеринга" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Стартовый адрес" + +msgid "Contiguous Size" +msgstr "Смежный размер" + +msgid "I/O Width" +msgstr "Ширина ввода/вывода" + +msgid "Transfer Speed" +msgstr "Скорость передачи данных" + +msgid "EMS mode" +msgstr "Режим EMS" + +msgid "Address for > 2 MB" +msgstr "Адрес для > 2 МБ" + +msgid "Frame Address" +msgstr "Адрес кадра" + +msgid "USA" +msgstr "США" + +msgid "Danish" +msgstr "Датский" + +msgid "Always at selected speed" +msgstr "Всегда на выбранной скорости" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "Настройка BIOS + горячие клавиши (отключается во время POST)" + +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 "Sine" +msgstr "Синусоидальная" + +msgid "Triangle" +msgstr "Треугольная" + +msgid "Linear" +msgstr "Линейный" + +msgid "4th Order" +msgstr "4-го порядка" + +msgid "7th Order" +msgstr "7-го порядка" + +msgid "Non-timed (original)" +msgstr "Без таймера (оригинал)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Гц (без джампера на JMP2)" + +msgid "Two" +msgstr "Два" + +msgid "Three" +msgstr "Три" + +msgid "Wheel" +msgstr "Колесо" + +msgid "Five + Wheel" +msgstr "Пять + колесо" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 последовательная / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) последовательная" + +msgid "8 KB" +msgstr "8 КБ" + +msgid "32 KB" +msgstr "32 КБ" + +msgid "16 KB" +msgstr "16 КБ" + +msgid "64 KB" +msgstr "64 КБ" + +msgid "Disable BIOS" +msgstr "Отключить BIOS" + +msgid "512 KB" +msgstr "512 КБ" + +msgid "2 MB" +msgstr "2 МБ" + +msgid "8 MB" +msgstr "8 МБ" + +msgid "28 MB" +msgstr "28 МБ" + +msgid "1 MB" +msgstr "1 МБ" + +msgid "4 MB" +msgstr "4 МБ" + +msgid "12 MB" +msgstr "12 МБ" + +msgid "16 MB" +msgstr "16 МБ" + +msgid "20 MB" +msgstr "20 МБ" + +msgid "24 MB" +msgstr "24 МБ" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (стерео)" + +msgid "Classic" +msgstr "Классический" + +msgid "256 KB" +msgstr "256 КБ" + +msgid "Composite" +msgstr "Композитное видео" + +msgid "Old" +msgstr "Старый" + +msgid "New" +msgstr "Новый" + +msgid "Color (generic)" +msgstr "Цветной (стандартный)" + +msgid "Green Monochrome" +msgstr "Зеленый монохромный" + +msgid "Amber Monochrome" +msgstr "Янтарный монохромный" + +msgid "Gray Monochrome" +msgstr "Серый монохромный" + +msgid "Color (no brown)" +msgstr "Цветной (без коричневого)" + +msgid "Color (IBM 5153)" +msgstr "Цветной (IBM 5153)" + +msgid "Simple doubling" +msgstr "Простое удвоение" + +msgid "sRGB interpolation" +msgstr "Интерполяция sRGB" + +msgid "Linear interpolation" +msgstr "Линейная интерполяция" + +msgid "128 KB" +msgstr "128 КБ" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Монохромный (5151/MDA) (белый)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Монохромный (5151/MDA) (зеленый)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Монохромный (5151/MDA) (янтарный)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Цветной 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Цветной 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Улучшенный цветной - нормальный режим (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Улучшенный цветной - улучшенный режим (5154/ECD)" + +msgid "Green" +msgstr "Зеленый" + +msgid "Amber" +msgstr "Янтарный" + +msgid "Gray" +msgstr "Серый" + +msgid "Color" +msgstr "Цветной" + +msgid "U.S. English" +msgstr "Английский США" + +msgid "Scandinavian" +msgstr "Скандинавский" + +msgid "Other languages" +msgstr "Другие языки" + +msgid "Bochs latest" +msgstr "Bochs последний" + +msgid "Mono Non-Interlaced" +msgstr "Монохромный без чересстрочной развертки" + +msgid "Color Interlaced" +msgstr "Цветной с чересстрочной разверткой" + +msgid "Color Non-Interlaced" +msgstr "Цветной без чересстрочной развертки" + +msgid "3Dfx Voodoo Graphics" +msgstr "Ускоритель 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8-бит" + +msgid "16-bit" +msgstr "16-бит" + +msgid "Standard (150ns)" +msgstr "Стандартный (150 нс)" + +msgid "High-Speed (120ns)" +msgstr "Высокоскоростной (120 нс)" + +msgid "Enabled" +msgstr "Включено" + +msgid "Standard" +msgstr "Стандарт" + +msgid "High-Speed" +msgstr "Высокоскоростной" + +msgid "Stereo LPT DAC" +msgstr "Стереофонический ЦАП LPT" + +msgid "Generic Text Printer" +msgstr "Стандартный текстовый принтер" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Стандартный матричный принтер ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Стандартный принтер PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Стандартный принтер PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Parallel Line Internet Protocol" + +msgid "Protection Dongle for Savage Quest" +msgstr "Защитный донгл для Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Устройство прохода через последовательный порт" + +msgid "Passthrough Mode" +msgstr "Проходной режим" + +msgid "Host Serial Device" +msgstr "Последовательное устройство хоста" + +msgid "Name of pipe" +msgstr "Название пайпа" + +msgid "Data bits" +msgstr "Биты данных" + +msgid "Stop bits" +msgstr "Стоп-биты" + +msgid "Baud Rate of Passthrough" +msgstr "Скорость передачи данных через канал" + +msgid "Named Pipe (Server)" +msgstr "Именованный пайп (Сервер)" + +msgid "Host Serial Passthrough" +msgstr "Последовательный порт хоста" + +msgid "Eject %s" +msgstr "Извлечь %s" + +msgid "&Unmute" +msgstr "В&ключить звук" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Сильное влияние на производительность" + +msgid "RAM Disk (max. speed)" +msgstr "RAM-диск (макс. скорость)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Клон IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Производитель" + +msgid "30 Hz (JMP2 = 1)" +msgstr "30 Гц (JMP2 = 1)" + +msgid "60 Hz (JMP2 = 2)" +msgstr "60 Гц (JMP2 = 2)" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Стандартное расширение памяти PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Стандартное расширение памяти PC/AT" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 8aeb0f082..6b2074d47 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -390,8 +390,11 @@ msgstr "Dynamický prekladač" msgid "Video:" msgstr "Grafika:" -msgid "Voodoo Graphics" -msgstr "Použiť grafický akcelerátor Voodoo" +msgid "Video #2:" +msgstr "Grafika 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Grafický akcelerátor Voodoo 1 alebo 2" msgid "IBM 8514/A Graphics" msgstr "Grafika IBM 8514/A" @@ -684,6 +687,12 @@ msgstr "Počítač \"%hs\" ie je dostupný, pretože chýba obraz jeho pamäte R msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Video adaptér \"%hs\" nie je dostupný, pretože chýba obraz jeho pamäte ROM v zložke \"roms/video\". Konfigurácia sa prepne na iný dostupný adaptér." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Video adaptér 2 \"%hs\" nie je dostupný, pretože chýba obraz jeho pamäte ROM v zložke \"roms/video\". Druhá grafická karta sa zakáže." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Zariadenie \"%hs\" nie je dostupné, pretože chýba obraz jeho pamäte ROM. Zariadenie sa ignoruje." + msgid "Machine" msgstr "Počítač" @@ -762,17 +771,26 @@ msgstr "Neboli nájdené žiadne PCap zariadenia" msgid "Invalid PCap device" msgstr "Neplatné PCap zariadenie" -msgid "Standard 2-button joystick(s)" -msgstr "Štandardný 2tlačidlový joystick" +msgid "2-axis, 2-button joystick(s)" +msgstr "2-osový, 2-tlačidlový joystick" -msgid "Standard 4-button joystick" -msgstr "Štandardný 4tlačidlový joystick" +msgid "2-axis, 4-button joystick" +msgstr "2-osový, 4-tlačidlový joystick" -msgid "Standard 6-button joystick" -msgstr "Štandardný 6tlačidlový joystick" +msgid "2-axis, 6-button joystick" +msgstr "2-osový, 6-tlačidlový joystick" -msgid "Standard 8-button joystick" -msgstr "Štandardný 8tlačidlový joystick" +msgid "2-axis, 8-button joystick" +msgstr "2-osový, 8-tlačidlový joystick" + +msgid "3-axis, 2-button joystick" +msgstr "3-osový, 2-tlačidlový joystick" + +msgid "3-axis, 4-button joystick" +msgstr "3-osový, 4-tlačidlový joystick" + +msgid "4-axis, 4-button joystick" +msgstr "4-osový, 4-tlačidlový joystick" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Naozaj chcete ukončiť 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Nastala chyba pri inicializácii knižnice Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Nastala chyba pri inicializácii knižnice GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Obrazy MO" msgid "Welcome to 86Box!" msgstr "Vitajte v programe 86Box!" -msgid "Internal controller" -msgstr "Vstavaný radič" +msgid "Internal device" +msgstr "Vstavané zariadenie" msgid "Exit" msgstr "Ukončiť" @@ -841,7 +862,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 "Emulátor starých počítačov\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nZverejnené pod licenciou GNU General Public License verzie 2 alebo novšej. Pozri súbor LICENSE pre viac informácií." +msgstr "Emulátor starých počítačov\n\nAutori: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nS predchádzajúcimi hlavnými príspevkami od Sarah Walker, leilei, JohnElliott, greatpsycho a ďalších.\n\nZverejnené pod licenciou GNU General Public License verzie 2 alebo novšej. Pozri súbor LICENSE pre viac informácií." msgid "Hardware not available" msgstr "Hardvér nie je dostupný" @@ -855,6 +876,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." +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" @@ -999,6 +1023,27 @@ msgstr "Prepísať" msgid "Don't overwrite" msgstr "Neprepisovať" +msgid "Raw image" +msgstr "Surový obraz" + +msgid "HDI image" +msgstr "HDI obraz" + +msgid "HDX image" +msgstr "HDX obraz" + +msgid "Fixed-size VHD" +msgstr "VHD s pevnou veľkosťou" + +msgid "Dynamic-size VHD" +msgstr "VHD s dynamickou veľkosťou" + +msgid "Differencing VHD" +msgstr "Rozdielový VHD" + +msgid "(N/A)" +msgstr "(Žiadne)" + msgid "Raw image (.img)" msgstr "Surový obraz (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBox už nie je podporovaný" 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 "Vývoj správcu WinBox sa zastavil v roku 2022 z dôvodu nedostatku správcov. Keďže naše úsilie smerujeme k ešte lepšiemu systému 86Box, rozhodli sme sa, že správca WinBox už nebude podporovaný.\n\nProstredníctvom WinBoxu nebudú poskytované žiadne ďalšie aktualizácie a v prípade, že ho budete naďalej používať s novšími verziami programu 86Box, môžete sa stretnúť s nesprávnym správaním. Všetky hlásenia o chybách týkajúce sa správania WinBoxu budú uzavreté ako neplatné.\n\nNa stránke 86box.net nájdete zoznam iných správcov, ktoré môžete používať." + +msgid "Generate" +msgstr "Generovať" + +msgid "Joystick configuration" +msgstr "Konfigurácia joysticku" + +msgid "Device" +msgstr "Zariadenie" + +msgid "%1 (X axis)" +msgstr "%1 (os X)" + +msgid "%1 (Y axis)" +msgstr "%1 (os Y)" + +msgid "MCA devices" +msgstr "Zariadenia MCA" + +msgid "List of MCA devices:" +msgstr "Zoznam zariadení MCA:" + +msgid "Tablet tool" +msgstr "Nástroj pre tablety" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "O Qt" + +msgid "MCA devices..." +msgstr "Zariadenia MCA..." + +msgid "Show non-primary monitors" +msgstr "Zobrazenie iných ako primárnych monitorov" + +msgid "Open screenshots folder..." +msgstr "Otvorte priečinok so snímkami obrazovky..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Použitie režimu roztiahnutia na celú obrazovku pri maximalizácii" + +msgid "Cursor/Puck" +msgstr "Kurzor/Puck" + +msgid "Pen" +msgstr "Pero" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Hostiteľská jednotka CD/DVD (%1:)" + +msgid "&Connected" +msgstr "&Connected" + +msgid "Clear image history" +msgstr "Vymazanie histórie obrázkov" + +msgid "Create..." +msgstr "Vytvorte..." + +msgid "previous image" +msgstr "predchádzajúca snímka" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Hostiteľská jednotka CD/DVD (%1)" + +msgid "Unknown Bus" +msgstr "Neznáma zbernica" + +msgid "Null Driver" +msgstr "Nulový ovládač" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Chyba pri otváraní \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Chyba kompilácie vertex shadera v súbore \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Chyba kompilácie fragment shadera v súbore \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Chyba pri prepojení shader programu v súbore \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Možnosti vykresľovania OpenGL 3.0" + +msgid "Render behavior" +msgstr "Správanie pri vykresľovaní" + +msgid "Use target framerate:" +msgstr "Použite cieľovú snímkovú frekvenciu:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Okamžite vykresliť každú snímku v synchronizácii s emulovaným displejom.</p><p><span style=" font-style:italic;">Toto je odporúčaná možnosť, ak používané shadery nevyužívajú frametime pre animované efekty.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Synchronizovať s obrazom" + +msgid "Shaders" +msgstr "Shadery" + +msgid "Remove" +msgstr "Odstránenie stránky" + +msgid "No shader selected" +msgstr "Nie je vybraný žiadny tieňovač" + +msgid "Browse..." +msgstr "Prehľadávať..." + +msgid "Shader error" +msgstr "Chyba shadera" + +msgid "Could not load shaders." +msgstr "Nepodarilo sa načítať shadery." + +msgid "More information in details." +msgstr "Viac informácií v detailoch." + +msgid "Couldn't create OpenGL context." +msgstr "Nepodarilo sa vytvoriť kontext OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Nepodarilo sa prepnúť na kontext OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Vyžaduje sa verzia OpenGL 3.0 alebo vyššia. Aktuálna verzia je %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Inicializácia OpenGL zlyhala. Chyba %1." + +msgid "Error initializing OpenGL" +msgstr "Chyba pri inicializácii OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Návrat k softvérovému vykresľovaniu.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Alokácia pamäte pre rozbaľovaciu vyrovnávaciu pamäť zlyhala.\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>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 "This machine might have been moved or copied." +msgstr "Tento stroj mohol byť premiestnený alebo skopírovaný." + +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 "Aby sa zabezpečila správna funkčnosť siete, 86Box potrebuje vedieť, či bol tento počítač presunutý alebo skopírovaný.\n\nAk si nie ste istí, vyberte možnosť \"Skopíroval som ho." + +msgid "I Moved It" +msgstr "Presunul som ho" + +msgid "I Copied It" +msgstr "Skopíroval som ho" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Žiadne zariadenia MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Sieťová karta 1" + +msgid "Network Card #2" +msgstr "Sieťová karta 2" + +msgid "Network Card #3" +msgstr "Sieťová karta 3" + +msgid "Network Card #4" +msgstr "Sieťová karta 4" + +msgid "Mode" +msgstr "Režim" + +msgid "Interface" +msgstr "Rozhranie" + +msgid "Adapter" +msgstr "Adaptér" + +msgid "VDE Socket" +msgstr "Zásuvka VDE" + +msgid "86Box Unit Tester" +msgstr "86Box Unit Tester" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Kľúčová karta Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Priechod sériového portu 1" + +msgid "Serial port passthrough 2" +msgstr "Priechod sériového portu 2" + +msgid "Serial port passthrough 3" +msgstr "Priechod sériového portu 3" + +msgid "Serial port passthrough 4" +msgstr "Priechod cez sériový port 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Možnosti vykresľovača..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Zbernicová myš Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Zbernicová myš Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Zbernicová myš Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Sériová myš Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Sériová myš Logitech" + +msgid "PS/2 Mouse" +msgstr "Myš PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (sériová)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Štandardný modem kompatibilný s Hayesom" + +msgid "Roland MT-32 Emulation" +msgstr "Emulácia Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulácia Roland MT-32 (nová)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulácia Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulácia Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Dcérska doska OPL4-ML" + +msgid "System MIDI" +msgstr "Systém MIDI" + +msgid "MIDI Input Device" +msgstr "Vstupné zariadenie MIDI" + +msgid "BIOS Address" +msgstr "Adresa BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Povolenie zápisu do pamäte ROM s rozšírením BIOS" + +msgid "Address" +msgstr "Adresa" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revízia systému BIOS" + +msgid "Translate 26 -> 17" +msgstr "Preložiť 26 -> 17" + +msgid "Language" +msgstr "Jazyk" + +msgid "Enable backlight" +msgstr "Povolenie podsvietenia" + +msgid "Invert colors" +msgstr "Invertovanie farieb" + +msgid "BIOS size" +msgstr "Veľkosť systému BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Mapa C0000-C7FFF ako UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Mapa C8000-CFFFF ako UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Mapa D0000-D7FFF ako UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Mapa D8000-DFFFF ako UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Mapa E0000-E7FFF ako UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Mapa E8000-EFFFF ako UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Prepojka JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Výstupné zariadenie MIDI" + +msgid "MIDI Real time" +msgstr "MIDI v reálnom čase" + +msgid "MIDI Thru" +msgstr "Priechodnosť vstupu MIDI" + +msgid "MIDI Clockout" +msgstr "Výstup hodín MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Zosilnenie výstupu" + +msgid "Chorus" +msgstr "Zbor" + +msgid "Chorus Voices" +msgstr "Hlasy zboru" + +msgid "Chorus Level" +msgstr "Úroveň zboru" + +msgid "Chorus Speed" +msgstr "Rýchlosť zboru" + +msgid "Chorus Depth" +msgstr "Hĺbka zboru" + +msgid "Chorus Waveform" +msgstr "Priebeh zboru" + +msgid "Reverb" +msgstr "Dozvuk" + +msgid "Reverb Room Size" +msgstr "Veľkosť dozvukovej miestnosti" + +msgid "Reverb Damping" +msgstr "Tlmenie dozvuku" + +msgid "Reverb Width" +msgstr "Šírka dozvuku" + +msgid "Reverb Level" +msgstr "Úroveň dozvuku" + +msgid "Interpolation Method" +msgstr "Metóda interpolácie" + +msgid "Reverb Output Gain" +msgstr "Zosilnenie výstupu dozvuku" + +msgid "Reversed stereo" +msgstr "Obrátené stereo" + +msgid "Nice ramp" +msgstr "Pekná rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Tlačidlá" + +msgid "Serial Port" +msgstr "Sériový port" + +msgid "RTS toggle" +msgstr "Prepínač RTS" + +msgid "Revision" +msgstr "Revízia" + +msgid "Controller" +msgstr "Ovládač" + +msgid "Show Crosshair" +msgstr "Zobrazenie kríža" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Adresa MAC" + +msgid "MAC Address OUI" +msgstr "Adresa MAC OUI" + +msgid "Enable BIOS" +msgstr "Povolenie systému BIOS" + +msgid "Baud Rate" +msgstr "Prenosová rýchlosť" + +msgid "TCP/IP listening port" +msgstr "Počúvajúci port TCP/IP" + +msgid "Phonebook File" +msgstr "Súbor telefónneho zoznamu" + +msgid "Telnet emulation" +msgstr "Emulácia siete Telnet" + +msgid "RAM Address" +msgstr "Adresa pamäte RAM" + +msgid "RAM size" +msgstr "Veľkosť pamäte RAM" + +msgid "Initial RAM size" +msgstr "Počiatočná veľkosť pamäte RAM" + +msgid "Serial Number" +msgstr "Sériové číslo" + +msgid "Host ID" +msgstr "ID hostiteľa" + +msgid "FDC Address" +msgstr "Adresa FDC" + +msgid "MPU-401 Address" +msgstr "Adresa MPU-401" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "Príjem vstupu MIDI" + +msgid "Low DMA" +msgstr "Nízka hodnota DMA" + +msgid "Enable Game port" +msgstr "Povolenie herného portu" + +msgid "Surround module" +msgstr "Surround modul" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Zvýšenie prerušenia CODEC pri nastavení CODEC (potrebné v niektorých ovládačoch)" + +msgid "SB Address" +msgstr "Adresa SB" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "Povolenie OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Príjem vstupu MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "SB low DMA" + +msgid "6CH variant (6-channel)" +msgstr "Variant 6CH (6-kanálový)" + +msgid "Enable CMS" +msgstr "Povolenie CMS" + +msgid "Mixer" +msgstr "Mixér" + +msgid "High DMA" +msgstr "Vysoký DMA" + +msgid "Control PC speaker" +msgstr "Ovládací reproduktor PC" + +msgid "Memory size" +msgstr "Veľkosť pamäte" + +msgid "EMU8000 Address" +msgstr "Adresa EMU8000" + +msgid "IDE Controller" +msgstr "Radič IDE" + +msgid "Codec" +msgstr "Kodek" + +msgid "GUS type" +msgstr "Typ GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Povolenie príkazu 0x04 \"Ukončiť 86Box\"" + +msgid "Display type" +msgstr "Typ displeja" + +msgid "Composite type" +msgstr "Kompozitný typ" + +msgid "RGB type" +msgstr "Typ RGB" + +msgid "Line doubling type" +msgstr "Typ zdvojenia linky" + +msgid "Snow emulation" +msgstr "Emulácia snehu" + +msgid "Monitor type" +msgstr "Typ monitora" + +msgid "Character set" +msgstr "Súbor znakov" + +msgid "XGA type" +msgstr "Typ XGA" + +msgid "Instance" +msgstr "Inštancia" + +msgid "MMIO Address" +msgstr "Adresa MMIO" + +msgid "RAMDAC type" +msgstr "Typ RAMDAC" + +msgid "Blend" +msgstr "Zmes" + +msgid "Bilinear filtering" +msgstr "Bilineárne filtrovanie" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "Povolenie NMI pre emuláciu CGA" + +msgid "Voodoo type" +msgstr "Typ Voodoo" + +msgid "Framebuffer memory size" +msgstr "Veľkosť pamäte Framebuffer" + +msgid "Texture memory size" +msgstr "Veľkosť pamäte textúr" + +msgid "Dither subtraction" +msgstr "Odčítanie ditheru" + +msgid "Screen Filter" +msgstr "Filter obrazovky" + +msgid "Render threads" +msgstr "Vlákna vykresľovania" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Počiatočná adresa" + +msgid "Contiguous Size" +msgstr "Súvislá veľkosť" + +msgid "I/O Width" +msgstr "Šírka I/O" + +msgid "Transfer Speed" +msgstr "Rýchlosť prenosu" + +msgid "EMS mode" +msgstr "Režim EMS" + +msgid "Address for > 2 MB" +msgstr "Adresa pre > 2 MB" + +msgid "Frame Address" +msgstr "Adresa rámu" + +msgid "USA" +msgstr "Spojené štáty" + +msgid "Danish" +msgstr "Dánsky" + +msgid "Always at selected speed" +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 "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 "Sine" +msgstr "Sinusový" + +msgid "Triangle" +msgstr "Trojuholníkový" + +msgid "Linear" +msgstr "Lineárna" + +msgid "4th Order" +msgstr "4. rádu" + +msgid "7th Order" +msgstr "7. rádu" + +msgid "Non-timed (original)" +msgstr "Bez časovača (originál)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (bez prepojky na JMP2)" + +msgid "Two" +msgstr "Dve stránky" + +msgid "Three" +msgstr "Tri" + +msgid "Wheel" +msgstr "Koleso" + +msgid "Five + Wheel" +msgstr "Päť + koleso" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 sériová / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) sériová" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Zakázať BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klasické" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Kompozitný" + +msgid "Old" +msgstr "Staré" + +msgid "New" +msgstr "Nový" + +msgid "Color (generic)" +msgstr "Farebný (všeobecný)" + +msgid "Green Monochrome" +msgstr "Zelený jednofarebný" + +msgid "Amber Monochrome" +msgstr "Oranžový jednofarebný" + +msgid "Gray Monochrome" +msgstr "Šedý jednofarebný" + +msgid "Color (no brown)" +msgstr "Farebný (bez hnedej)" + +msgid "Color (IBM 5153)" +msgstr "Farebný (IBM 5153)" + +msgid "Simple doubling" +msgstr "Jednoduché zdvojenie" + +msgid "sRGB interpolation" +msgstr "Interpolácia sRGB" + +msgid "Linear interpolation" +msgstr "Lineárna interpolácia" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Jednofarebný (5151/MDA) (biely)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Jednofarebný (5151/MDA) (zelený)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Jednofarebný (5151/MDA) (oranžový)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Farebný 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Farebný 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Rozšírený farebný - normálny režim (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Rozšírený farebný - rozšírený režim (5154/ECD)" + +msgid "Green" +msgstr "Zelený" + +msgid "Amber" +msgstr "Oranžový" + +msgid "Gray" +msgstr "Šedý" + +msgid "Color" +msgstr "Farebný" + +msgid "U.S. English" +msgstr "Americká angličtina" + +msgid "Scandinavian" +msgstr "Škandinávske" + +msgid "Other languages" +msgstr "Ostatné jazyky" + +msgid "Bochs latest" +msgstr "Bochs najnovšie" + +msgid "Mono Non-Interlaced" +msgstr "Mono bez prelínania" + +msgid "Color Interlaced" +msgstr "Farebné prelínanie" + +msgid "Color Non-Interlaced" +msgstr "Farba bez prelínania" + +msgid "3Dfx Voodoo Graphics" +msgstr "Grafický akcelerátor 3dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 zariadenia TMU)" + +msgid "8-bit" +msgstr "8-bitové" + +msgid "16-bit" +msgstr "16-bitové" + +msgid "Standard (150ns)" +msgstr "Štandardné (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Vysoká rýchlosť (120ns)" + +msgid "Enabled" +msgstr "Povolené" + +msgid "Standard" +msgstr "Štandard" + +msgid "High-Speed" +msgstr "Vysokorýchlostný" + +msgid "Stereo LPT DAC" +msgstr "Stereofónny prevodník LPT DAC" + +msgid "Generic Text Printer" +msgstr "Generická textová tlačiareň" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Generická ihličková tlačiareň ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Generická tlačiareň PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Generická tlačiareň PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Internetový protokol paralelnej linky" + +msgid "Protection Dongle for Savage Quest" +msgstr "Ochranný kľúč pre Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Zariadenie priechodu sériového portu" + +msgid "Passthrough Mode" +msgstr "Režim priechodu" + +msgid "Host Serial Device" +msgstr "Hostiteľské sériové zariadenie" + +msgid "Name of pipe" +msgstr "Názov potrubia" + +msgid "Data bits" +msgstr "Dátové bity" + +msgid "Stop bits" +msgstr "Stop bity" + +msgid "Baud Rate of Passthrough" +msgstr "Prenosová rýchlosť priechodu" + +msgid "Named Pipe (Server)" +msgstr "Pomenované potrubie (server)" + +msgid "Host Serial Passthrough" +msgstr "Priechod sériového portu hostiteľa" + +msgid "Eject %s" +msgstr "Vystrihnúť %s" + +msgid "&Unmute" +msgstr "&Roztíšiť" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Vysoký vplyv na výkon" + +msgid "RAM Disk (max. speed)" +msgstr "Disk RAM (max. rýchlosť)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Klon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Výrobca" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Všeobecné rozšírenie pamäte PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Všeobecné rozšírenie pamäte PC/AT" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 2a4b68e46..9d8ccaaf9 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -235,7 +235,7 @@ msgid "&Fast forward to the end" msgstr "Preskoči na konec" msgid "E&ject" -msgstr "Izvrzi" +msgstr "I&zvrzi" msgid "&Image..." msgstr "Slika..." @@ -390,14 +390,17 @@ msgstr "Dinamični prevajalnik" msgid "Video:" msgstr "Video:" -msgid "Voodoo Graphics" -msgstr "Voodoo grafika" +msgid "Video #2:" +msgstr "Video 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Grafika Voodoo 1 ali 2" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A grafika" +msgstr "Grafika IBM 8514/A" msgid "XGA Graphics" -msgstr "XGA grafika" +msgstr "Grafika XGA" msgid "Mouse:" msgstr "Miška:" @@ -607,7 +610,7 @@ msgid "ISA RTC:" msgstr "Ura v realnem času ISA:" msgid "ISA Memory Expansion" -msgstr "Razširitev spomina ISA" +msgstr "Razširitev pomnilnika ISA" msgid "Card 1:" msgstr "Kartica 1:" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Kritična napaka" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - ZAUSTAVLJEN" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Pritisnite Ctrl+Alt+PgDn za povratek iz celozaslonskega načina." @@ -682,7 +685,13 @@ msgid "Machine \"%hs\" is not available due to missing ROMs in the roms/machines msgstr "Sistem \"%hs\" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/machines. Preklapljam na drug sistem, ki je na voljo." msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." -msgstr "Grafična kartica \"%hs\" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Preklapljam na drugo grafično kartico, ki je na voljo.." +msgstr "Grafična kartica \"%hs\" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Preklapljam na drugo grafično kartico, ki je na voljo." + +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Grafična kartica 2 \"%hs\" ni na voljo zaradi manjkajočih ROM-ov v mapi roms/video. Onemogočam drugo grafično kartico." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Naprava \"%hs\" ni na voljo zaradi manjkajočih ROM-ov. Preziram napravo." msgid "Machine" msgstr "Sistem" @@ -745,7 +754,7 @@ msgid "KB" msgstr "KB" msgid "Could not initialize the video renderer." -msgstr "Ne morem inicializirati pogona upodabljanja." +msgstr "Ne morem inicializirati sistema za upodabljanje." msgid "Default" msgstr "Privzeto" @@ -762,17 +771,26 @@ msgstr "Nobena naprava PCap ni bila najdena" msgid "Invalid PCap device" msgstr "Neveljavna naprava PCap" -msgid "Standard 2-button joystick(s)" -msgstr "Standardna krmilna palica z 2 gumboma" +msgid "2-axis, 2-button joystick(s)" +msgstr "Igralna palica z 2 osema, 2 gumboma" -msgid "Standard 4-button joystick" -msgstr "Standardna krmilna palica s 4 gumbi" +msgid "2-axis, 4-button joystick" +msgstr "Igralna palica z 2 osema, 4 gumbi" -msgid "Standard 6-button joystick" -msgstr "Standardna krmilna palica s 6 gumbi" +msgid "2-axis, 6-button joystick" +msgstr "Igralna palica z 2 osema, 6 gumbi" -msgid "Standard 8-button joystick" -msgstr "Standardna krmilna palica z 8 gumbi" +msgid "2-axis, 8-button joystick" +msgstr "Igralna palica z 2 osema, 8 gumbi" + +msgid "3-axis, 2-button joystick" +msgstr "Igralna palica s 3 osmi, 2 gumboma" + +msgid "3-axis, 4-button joystick" +msgstr "Igralna palica z 3 osmi, 4 gumbi" + +msgid "4-axis, 4-button joystick" +msgstr "Igralna palica z 4 osmi, 4 gumbi" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Ste prepričani, da želite zapreti 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Ne morem inicializirati Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Ne morem inicializirati GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Slike MO" msgid "Welcome to 86Box!" msgstr "Dobrodošli v 86Box!" -msgid "Internal controller" -msgstr "Notranji krmilnik" +msgid "Internal device" +msgstr "Vgrajena naprava" msgid "Exit" msgstr "Izhod" @@ -841,7 +862,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 starih računalnikov\n\nAvtorji: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho in drugi.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." +msgstr "Emulator starih računalnikov\n\nAvtorji: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nS prejšnjimi prispevki Sarah Walker, leilei, JohnElliott, greatpsycho in drugih.\n\nIzdano pod licenco GNU General Public License različica 2 ali novejša. Glej datoteko LICENSE za več informacij." msgid "Hardware not available" msgstr "Strojna oprema ni na voljo" @@ -853,7 +874,10 @@ msgid "Invalid configuration" 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 PostScript datotek v PDF.\n\nVsi dokumenti, poslani generičnemu PostScript tiskalniku bodo shranjeni kot PostScript (.ps) datoteke." +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." +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" @@ -999,6 +1023,27 @@ msgstr "Prepiši" msgid "Don't overwrite" msgstr "Ne prepiši" +msgid "Raw image" +msgstr "Surova slika" + +msgid "HDI image" +msgstr "Slika HDI" + +msgid "HDX image" +msgstr "Slika HDX" + +msgid "Fixed-size VHD" +msgstr "VHD fiksne velikosti" + +msgid "Dynamic-size VHD" +msgstr "Dinamičen VHD" + +msgid "Differencing VHD" +msgstr "Diferencialni VHD" + +msgid "(N/A)" +msgstr "(Ni na voljo)" + msgid "Raw image (.img)" msgstr "Surova slika (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBox ni več podprt" 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 "Razvoj upravitelja WinBox se je leta 2022 ustavil zaradi pomanjkanja vzdrževalcev. Ker svoja prizadevanja usmerjamo v še boljše delovanje programa 86Box, smo se odločili, da programa WinBox kot upravitelja ne bomo več podpirali.\n\nWinBox ne bo več zagotavljal posodobitev, če ga boste še naprej uporabljali z novejšimi različicami programa 86Box, pa lahko naletite na nepravilno obnašanje. Vsa poročila o napakah, povezana z obnašanjem programa WinBox, bodo zaprta kot neveljavna.\n\nZa seznam drugih upraviteljev, ki jih lahko uporabite, obiščite spletno stran 86box.net." + +msgid "Generate" +msgstr "Ustvarjanje" + +msgid "Joystick configuration" +msgstr "Konfiguracija igralne palice" + +msgid "Device" +msgstr "Naprava" + +msgid "%1 (X axis)" +msgstr "%1 (os X)" + +msgid "%1 (Y axis)" +msgstr "%1 (os Y)" + +msgid "MCA devices" +msgstr "Naprave MCA" + +msgid "List of MCA devices:" +msgstr "Seznam naprav MCA:" + +msgid "Tablet tool" +msgstr "Orodje za tablico" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "O programu Qt" + +msgid "MCA devices..." +msgstr "Naprave MCA..." + +msgid "Show non-primary monitors" +msgstr "Prikaži neprimarne monitorje" + +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 "Cursor/Puck" +msgstr "Kazalec/ključ" + +msgid "Pen" +msgstr "Pisalo" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Pogon CD/DVD gostitelja (%1:)" + +msgid "&Connected" +msgstr "&Povezan" + +msgid "Clear image history" +msgstr "Jasna zgodovina slik" + +msgid "Create..." +msgstr "Ustvari..." + +msgid "previous image" +msgstr "zadnja slika" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Pogon CD/DVD gostitelja (%1)" + +msgid "Unknown Bus" +msgstr "Neznano vodilo" + +msgid "Null Driver" +msgstr "Ničelni gonilnik" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Napaka pri odpiranju \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Napaka pri sestavljanju senčilnika vrhov v datoteki \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Napaka pri sestavljanju shaderja fragmentov v datoteki \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Napaka pri povezovanju programa shader v datoteki \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Možnosti sistema za upodabljanje OpenGL 3.0" + +msgid "Render behavior" +msgstr "Obnašanje pri upodabljanju" + +msgid "Use target framerate:" +msgstr "Uporabi ciljno št. sličic na sekundo:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Vsako sličico prikažite takoj, sinhronizirano z emuliranim zaslonom.</p><p><span style=" font-style:italic;">To je priporočljiva možnost, če uporabljeni senčilniki ne uporabljajo časa okvirja za animirane učinke.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Sinhroniziraj z videom" + +msgid "Shaders" +msgstr "Senčilniki" + +msgid "Remove" +msgstr "Odstrani" + +msgid "No shader selected" +msgstr "Ni izbran noben senčnik" + +msgid "Browse..." +msgstr "Brskaj..." + +msgid "Shader error" +msgstr "Napaka senčilnika" + +msgid "Could not load shaders." +msgstr "Ni bilo mogoče naložiti senčilnikov." + +msgid "More information in details." +msgstr "Več informacij v podrobnostih." + +msgid "Couldn't create OpenGL context." +msgstr "Ni bilo mogoče ustvariti konteksta OpenGL." + +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" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Inicializacija OpenGL ni uspela. Napaka %1." + +msgid "Error initializing OpenGL" +msgstr "Napaka pri inicializaciji OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Vrnitev k programskemu upodabljanju.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Dodelitev pomnilnika za razpakirni predpomnilnik ni uspela.\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>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 "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\"." + +msgid "I Moved It" +msgstr "Premaknil sem jo" + +msgid "I Copied It" +msgstr "Kopiral sem jo" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "Ni naprav MCA." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Omrežna kartica 1" + +msgid "Network Card #2" +msgstr "Omrežna kartica 2" + +msgid "Network Card #3" +msgstr "Omrežna kartica 3" + +msgid "Network Card #4" +msgstr "Omrežna kartica 4" + +msgid "Mode" +msgstr "Način" + +msgid "Interface" +msgstr "Vmesnik" + +msgid "Adapter" +msgstr "Adapter" + +msgid "VDE Socket" +msgstr "Vtičnica VDE" + +msgid "86Box Unit Tester" +msgstr "Tester enote 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x Key Card" + +msgid "Serial port passthrough 1" +msgstr "Prepust za serijska vrata 1" + +msgid "Serial port passthrough 2" +msgstr "Prepust za serijska vrata 2" + +msgid "Serial port passthrough 3" +msgstr "Prepust za serijska vrata 3" + +msgid "Serial port passthrough 4" +msgstr "Prepust za serijska vrata 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Možnosti sistema za upodabljanje..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Miška na vodilu Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Miška na vodilu Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Serijska miška Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Serijska miška Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Serijska miška Logitech" + +msgid "PS/2 Mouse" +msgstr "Miška PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (serijska)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Standardni modem v skladu s standardom Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Emulacija Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Emulacija Roland MT-32 (novo)" + +msgid "Roland CM-32L Emulation" +msgstr "Emulacija Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Emulacija Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Hčerinska plošča OPL4-ML" + +msgid "System MIDI" +msgstr "Sistem MIDI" + +msgid "MIDI Input Device" +msgstr "Vhodna naprava MIDI" + +msgid "BIOS Address" +msgstr "Naslov BIOS-a" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Omogočanje razširitve BIOS-a ROM piše" + +msgid "Address" +msgstr "Naslov" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Revizija BIOS-a" + +msgid "Translate 26 -> 17" +msgstr "Prevesti 26 -> 17" + +msgid "Language" +msgstr "Jezik" + +msgid "Enable backlight" +msgstr "Omogoči osvetlitev ozadja" + +msgid "Invert colors" +msgstr "Invertiraj barve" + +msgid "BIOS size" +msgstr "Velikost BIOS-a" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Zemljevid C0000-C7FFF kot UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Zemljevid C8000-CFFFF kot UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Zemljevid D0000-D7FFF kot UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Zemljevid D8000-DFFFF kot UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Zemljevid E0000-E7FFF kot UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Zemljevid E8000-EFFFF kot UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 Jumper (JIM)" + +msgid "MIDI Output Device" +msgstr "Izhodna naprava MIDI" + +msgid "MIDI Real time" +msgstr "MIDI v realnem času" + +msgid "MIDI Thru" +msgstr "Prepust vhoda MIDI" + +msgid "MIDI Clockout" +msgstr "Izhod ure MIDI" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Ojačanje izhoda" + +msgid "Chorus" +msgstr "Zbor" + +msgid "Chorus Voices" +msgstr "Glasovi zbora" + +msgid "Chorus Level" +msgstr "Raven zbora" + +msgid "Chorus Speed" +msgstr "Hitrost zbora" + +msgid "Chorus Depth" +msgstr "Globina zbora" + +msgid "Chorus Waveform" +msgstr "Valovna oblika zbora" + +msgid "Reverb" +msgstr "Odmev" + +msgid "Reverb Room Size" +msgstr "Velikost prostora za odmev" + +msgid "Reverb Damping" +msgstr "Dušenje odmeva" + +msgid "Reverb Width" +msgstr "Širina odmeva" + +msgid "Reverb Level" +msgstr "Raven odmeva" + +msgid "Interpolation Method" +msgstr "Metoda interpolacije" + +msgid "Reverb Output Gain" +msgstr "Ojačanje izhoda odmeva" + +msgid "Reversed stereo" +msgstr "Obrnjeni stereo" + +msgid "Nice ramp" +msgstr "Lepa rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Gumbi" + +msgid "Serial Port" +msgstr "Serijska vrata" + +msgid "RTS toggle" +msgstr "Preklapljanje RTS" + +msgid "Revision" +msgstr "Revizija" + +msgid "Controller" +msgstr "Krmilnik" + +msgid "Show Crosshair" +msgstr "Prikaži križišče" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Naslov MAC" + +msgid "MAC Address OUI" +msgstr "OUI naslova MAC" + +msgid "Enable BIOS" +msgstr "Omogoči BIOS" + +msgid "Baud Rate" +msgstr "Hitrost Baud" + +msgid "TCP/IP listening port" +msgstr "Vrata TCP/IP za poslušanje" + +msgid "Phonebook File" +msgstr "Datoteka s telefonskim imenikom" + +msgid "Telnet emulation" +msgstr "Emulacija Telneta" + +msgid "RAM Address" +msgstr "Naslov RAM" + +msgid "RAM size" +msgstr "Velikost pomnilnika RAM" + +msgid "Initial RAM size" +msgstr "Začetna velikost pomnilnika RAM" + +msgid "Serial Number" +msgstr "Serijska številka" + +msgid "Host ID" +msgstr "ID gostitelja" + +msgid "FDC Address" +msgstr "Naslov FDC" + +msgid "MPU-401 Address" +msgstr "MPU-401 Naslov" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "Sprejemaj vhod MIDI" + +msgid "Low DMA" +msgstr "Nizki DMA" + +msgid "Enable Game port" +msgstr "Omogočanje igralnih vrat" + +msgid "Surround module" +msgstr "Prostorski modul" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Dvigni prekinitev za CODEC ob nastavitvi CODEC-a (to potrebujejo nekateri gonilniki)" + +msgid "SB Address" +msgstr "Naslov SB" + +msgid "WSS IRQ" +msgstr "IRQ WSS" + +msgid "WSS DMA" +msgstr "DMA WSS" + +msgid "Enable OPL" +msgstr "Omogoči OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Sprejemaj vhod MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "Nizki DMA SB" + +msgid "6CH variant (6-channel)" +msgstr "Različica 6CH (6-kanalni)" + +msgid "Enable CMS" +msgstr "Omogoči CMS" + +msgid "Mixer" +msgstr "Mešalnik" + +msgid "High DMA" +msgstr "Visoki DMA" + +msgid "Control PC speaker" +msgstr "Nadzoruj zvočnik računalnika" + +msgid "Memory size" +msgstr "Velikost pomnilnika" + +msgid "EMU8000 Address" +msgstr "Naslov EMU8000" + +msgid "IDE Controller" +msgstr "Krmilnik IDE" + +msgid "Codec" +msgstr "Kodek" + +msgid "GUS type" +msgstr "Tip GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Omogoči ukaz 0x04 \"Zapusti 86Box\"" + +msgid "Display type" +msgstr "Vrsta zaslona" + +msgid "Composite type" +msgstr "Vsta kompozitnega zaslona" + +msgid "RGB type" +msgstr "Vrsta RGB zaslona" + +msgid "Line doubling type" +msgstr "Vrsta podvojitve črt" + +msgid "Snow emulation" +msgstr "Emulacija snega" + +msgid "Monitor type" +msgstr "Vrsta monitorja" + +msgid "Character set" +msgstr "Nabor znakov" + +msgid "XGA type" +msgstr "Tip kartice XGA" + +msgid "Instance" +msgstr "Primer" + +msgid "MMIO Address" +msgstr "Naslov MMIO" + +msgid "RAMDAC type" +msgstr "Vrsta čipa RAMDAC" + +msgid "Blend" +msgstr "Mešanica" + +msgid "Bilinear filtering" +msgstr "Bilinearno filtriranje" + +msgid "Dithering" +msgstr "Barvno stresanje" + +msgid "Enable NMI for CGA emulation" +msgstr "Omogočite NMI za emulacijo CGA" + +msgid "Voodoo type" +msgstr "Tip kartice Voodoo" + +msgid "Framebuffer memory size" +msgstr "Velikost pomnilnika predpomnilnika okvirja" + +msgid "Texture memory size" +msgstr "Velikost pomnilnika tekstur" + +msgid "Dither subtraction" +msgstr "Odštevanje barvnega stresanja" + +msgid "Screen Filter" +msgstr "Filter zaslona" + +msgid "Render threads" +msgstr "Nitke za upodabljanje" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Začetni naslov" + +msgid "Contiguous Size" +msgstr "Pripadajoča velikost" + +msgid "I/O Width" +msgstr "Širina V/I" + +msgid "Transfer Speed" +msgstr "Hitrost prenosa" + +msgid "EMS mode" +msgstr "Način EMS" + +msgid "Address for > 2 MB" +msgstr "Naslov za > 2 MB" + +msgid "Frame Address" +msgstr "Naslov okvirja" + +msgid "USA" +msgstr "ZDA" + +msgid "Danish" +msgstr "Danski" + +msgid "Always at selected speed" +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 "128 kB starting from E0000 (address MSB inverted, last 64KB first)" +msgstr "128 kB od E0000 (MSB naslova invertiran, najprej zadnjih 64 kB)" + +msgid "Sine" +msgstr "Sinusna" + +msgid "Triangle" +msgstr "Trikotna" + +msgid "Linear" +msgstr "Linearna" + +msgid "4th Order" +msgstr "4. reda" + +msgid "7th Order" +msgstr "7. reda" + +msgid "Non-timed (original)" +msgstr "Brez časovnika (izvirnik)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (brez mostička na JMP2)" + +msgid "Two" +msgstr "Dva" + +msgid "Three" +msgstr "Tri" + +msgid "Wheel" +msgstr "Kolesa" + +msgid "Five + Wheel" +msgstr "Pet + kolo" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 serijska / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) serijska" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Onemogoči BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klasični" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Kompozitni" + +msgid "Old" +msgstr "Stari" + +msgid "New" +msgstr "Novi" + +msgid "Color (generic)" +msgstr "Barvni (generični)" + +msgid "Green Monochrome" +msgstr "Zeleni enobvarni" + +msgid "Amber Monochrome" +msgstr "Jantarni enobarvni" + +msgid "Gray Monochrome" +msgstr "Sivi enobarvni" + +msgid "Color (no brown)" +msgstr "Barvni (brez rjave)" + +msgid "Color (IBM 5153)" +msgstr "Barvni (IBM 5153)" + +msgid "Simple doubling" +msgstr "Enostavno podvajanje" + +msgid "sRGB interpolation" +msgstr "Interpolacija sRGB" + +msgid "Linear interpolation" +msgstr "Linearna interpolacija" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Enobarvni (5151/MDA) (beli)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Enobarvni (5151/MDA) (zeleni)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Enobarvni (5151/MDA) (jantarni)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Barvni 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Barvni 80x25 (5153/CGA)" + +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)" + +msgid "Green" +msgstr "Zeleni" + +msgid "Amber" +msgstr "Jantarni" + +msgid "Gray" +msgstr "Sivi" + +msgid "Color" +msgstr "Barvni" + +msgid "U.S. English" +msgstr "Ameriška angleščina" + +msgid "Scandinavian" +msgstr "Skandinavščina" + +msgid "Other languages" +msgstr "Drugi jeziki" + +msgid "Bochs latest" +msgstr "Bochs najnovejše" + +msgid "Mono Non-Interlaced" +msgstr "Enobarvni brez prepletanja" + +msgid "Color Interlaced" +msgstr "Barvni s prepletanjem" + +msgid "Color Non-Interlaced" +msgstr "Barvni brez prepletanja" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx Voodoo Graphics" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 enoti TMU)" + +msgid "8-bit" +msgstr "8-bitni" + +msgid "16-bit" +msgstr "16-bitni" + +msgid "Standard (150ns)" +msgstr "Standardna (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Visoka hitrost (120ns)" + +msgid "Enabled" +msgstr "Omogočeno" + +msgid "Standard" +msgstr "Standardni" + +msgid "High-Speed" +msgstr "Visoke hitrosti" + +msgid "Stereo LPT DAC" +msgstr "Stereo DAC LPT" + +msgid "Generic Text Printer" +msgstr "Generični besedilni tiskalnik" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Generični matrični tiskalnik ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Generični tiskalnik PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Generični tiskalnik PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Internetni protokol za paralelno linijo" + +msgid "Protection Dongle for Savage Quest" +msgstr "Zaščitni ključek za Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Naprava za prepust serijskih vrat" + +msgid "Passthrough Mode" +msgstr "Način prepusta" + +msgid "Host Serial Device" +msgstr "Gostiteljska serijska naprava" + +msgid "Name of pipe" +msgstr "Ime cevi" + +msgid "Data bits" +msgstr "Podatkovni biti" + +msgid "Stop bits" +msgstr "Stop biti" + +msgid "Baud Rate of Passthrough" +msgstr "Baudna hitrost prepusta" + +msgid "Named Pipe (Server)" +msgstr "Poimenovana cev (Strežnik)" + +msgid "Host Serial Passthrough" +msgstr "Prepustno serijskih vrat gostitelja" + +msgid "Eject %s" +msgstr "Izvrzi %s" + +msgid "&Unmute" +msgstr "&Vklopi zvok" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Visok učinek na hitrost delovanja" + +msgid "RAM Disk (max. speed)" +msgstr "Pogon RAM (največja hitrost)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Klon IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Proizvajalec" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Generična razširitev pomnilnika PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Generična razširitev pomnilnika PC/AT" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index ada5ff87f..288412154 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -7,7 +7,7 @@ msgstr "" "X-Source-Language: en_US\n" msgid "&Action" -msgstr "&Komutlar" +msgstr "&Eylem" msgid "&Keyboard requires capture" msgstr "&Klavye sadece fare yakalandığında çalışsın" @@ -16,28 +16,28 @@ msgid "&Right CTRL is left ALT" msgstr "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla" msgid "&Hard Reset..." -msgstr "&Makineyi yeniden başlat..." +msgstr "Yeniden başlamaya &zorla" msgid "&Ctrl+Alt+Del\tCtrl+F12" msgstr "&Ctrl+Alt+Del\tCtrl+F12" msgid "Ctrl+Alt+&Esc" -msgstr "Ctrl+Alt+&Esc" +msgstr "Ctrl+&Alt+Esc" msgid "&Pause" msgstr "&Duraklat" msgid "E&xit..." -msgstr "Emülatörden &çık..." +msgstr "&Çıkış..." msgid "&View" -msgstr "&Görüntüleme" +msgstr "&Görünüm" msgid "&Hide status bar" msgstr "&Durum çubuğunu gizle" msgid "Hide &toolbar" -msgstr "Hide &toolbar" +msgstr "Araç &çubuğunu gizle" msgid "&Resizeable window" msgstr "&Yeniden boyutlandırılabilir pencere" @@ -55,7 +55,7 @@ msgid "Qt (&OpenGL)" msgstr "Qt (&OpenGL)" msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0 Core)" +msgstr "OpenG&L (3.0 bazlı)" msgid "&VNC" msgstr "&VNC" @@ -64,7 +64,7 @@ msgid "Specify dimensions..." msgstr "Pencere &boyutunu belirle..." msgid "F&orce 4:3 display ratio" -msgstr "&4:3 görüntüleme oranına zorla" +msgstr "4:3 görüntü oranına &zorla" msgid "&Window scale factor" msgstr "Pencere &ölçek çarpanı" @@ -100,22 +100,22 @@ msgid "&8x" msgstr "&8x" msgid "Filter method" -msgstr "&Filtre metodu" +msgstr "&Filtreleme yöntemi" msgid "&Nearest" -msgstr "&Nearest (En yakın)" +msgstr "&En yakın" msgid "&Linear" -msgstr "&Linear (Doğrusal)" +msgstr "Doğ&rusal" msgid "Hi&DPI scaling" -msgstr "Hi&DPI ölçeklemesi" +msgstr "HiDPI ölçekle&mesi" msgid "&Fullscreen\tCtrl+Alt+PgUp" -msgstr "&Tam ekran\tCtrl+Alt+PgUp" +msgstr "Tam ekran\tCtrl+Alt+Pg&Up" msgid "Fullscreen &stretch mode" -msgstr "Tam ekran &germe modu" +msgstr "Tam e&kran germe modu" msgid "&Full screen stretch" msgstr "&Tam ekrana ger" @@ -130,13 +130,13 @@ msgid "&Integer scale" msgstr "Tam &sayı ölçeklemesi" msgid "4:&3 Integer scale" -msgstr "4:&3 Tam sayı ölçeklemesi" +msgstr "Tam sayı ölçeklemesi (4:&3)" msgid "E&GA/(S)VGA settings" msgstr "EGA/&(S)VGA ayarları" msgid "&Inverted VGA monitor" -msgstr "Ters &renk VGA monitör" +msgstr "Ters &renkli VGA monitör" msgid "VGA screen &type" msgstr "VGA ekran &tipi" @@ -148,16 +148,16 @@ msgid "&RGB Grayscale" msgstr "RGB (&gri tonlama)" msgid "&Amber monitor" -msgstr "&Kehribar rengi monitör" +msgstr "&Kehribar renkli monitör" msgid "&Green monitor" -msgstr "&Yeşil renk monitör" +msgstr "&Yeşil renkli monitör" msgid "&White monitor" -msgstr "&Beyaz renk monitör" +msgstr "&Beyaz renkli monitör" msgid "Grayscale &conversion type" -msgstr "&Gri tonlama dönüştürme tipi" +msgstr "&Gri tonlama dönüştürme türü" msgid "BT&601 (NTSC/PAL)" msgstr "BT&601 (NTSC/PAL)" @@ -184,7 +184,7 @@ msgid "&Settings..." msgstr "&Ayarlar..." msgid "&Update status bar icons" -msgstr "Durum &çubuğu ikonlarını güncelle" +msgstr "Durum &çubuğu simgelerini güncelle" msgid "Take s&creenshot\tCtrl+F11" msgstr "&Ekran görüntüsü al\tCtrl+F11" @@ -196,13 +196,13 @@ msgid "Enable &Discord integration" msgstr "&Discord entegrasyonunu etkinleştir" msgid "Sound &gain..." -msgstr "&Ses yükseltici..." +msgstr "&Ses düzeyi artışı..." msgid "Begin trace\tCtrl+T" -msgstr "Begin trace\tCtrl+T" +msgstr "İzlemeyi başlat\tCtrl+T" msgid "End trace\tCtrl+T" -msgstr "End trace\tCtrl+T" +msgstr "İzlemeyi bitir\tCtrl+T" msgid "&Help" msgstr "&Yardım" @@ -211,7 +211,7 @@ msgid "&Documentation..." msgstr "&Dökümanlar..." msgid "&About 86Box..." -msgstr "&86Box Hakkında..." +msgstr "&86Box hakkında..." msgid "&New image..." msgstr "&Yeni imaj oluştur..." @@ -220,7 +220,7 @@ msgid "&Existing image..." msgstr "&İmaj seç..." msgid "Existing image (&Write-protected)..." -msgstr "İmaj &seç (Yazma-korumalı)..." +msgstr "İmaj &seç (Yazma korumalı)..." msgid "&Record" msgstr "&Kaydet" @@ -241,7 +241,7 @@ msgid "&Image..." msgstr "&İmaj..." msgid "E&xport to 86F..." -msgstr "&86F dosyası olarak aktar..." +msgstr "&86F dosyası olarak kaydet..." msgid "&Mute" msgstr "&Sesi kapat" @@ -250,13 +250,13 @@ msgid "E&mpty" msgstr "İmajı &çıkar" msgid "&Reload previous image" -msgstr "&Önceki imajı seç" +msgstr "&Önceki imajı yeniden seç" msgid "&Folder..." msgstr "&Klasör..." msgid "Target &framerate" -msgstr "Hedef &kare oranı" +msgstr "Hedef &kare hızı oranı" msgid "&Sync with video" msgstr "Video ile &senkronize et" @@ -289,25 +289,25 @@ msgid "Preferences" msgstr "Tercihler" msgid "Sound Gain" -msgstr "Ses Artırma" +msgstr "Ses düzeyi artışı" msgid "New Image" -msgstr "Yeni İmaj" +msgstr "Yeni imaj" 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 et" +msgstr "İptal" msgid "Save these settings as &global defaults" -msgstr "Bu ayarları &varsayılan olarak kaydet" +msgstr "Ayarları &varsayılan olarak kaydet" msgid "&Default" msgstr "&Varsayılan" @@ -319,7 +319,7 @@ msgid "Icon set:" msgstr "Simge seti:" msgid "Gain" -msgstr "Artırma" +msgstr "Artış" msgid "File name:" msgstr "Dosya adı:" @@ -352,16 +352,16 @@ msgid "Configure" msgstr "Ayarla" msgid "CPU type:" -msgstr "CPU türü:" +msgstr "İşlemci türü:" msgid "Speed:" msgstr "Hız:" msgid "Frequency:" -msgstr "Sıklık:" +msgstr "Saat hızı:" msgid "FPU:" -msgstr "FPU:" +msgstr "Kayan Nokta Birimi (FPU):" msgid "Wait states:" msgstr "Bekleme süreleri:" @@ -385,19 +385,22 @@ msgid "Enabled (UTC)" msgstr "Etkin (UTC)" msgid "Dynamic Recompiler" -msgstr "Dinamik Derleyici" +msgstr "Dinamik derleyici" msgid "Video:" msgstr "Ekran kartı:" -msgid "Voodoo Graphics" -msgstr "Voodoo Grafikleri" +msgid "Video #2:" +msgstr "Ekran kartı 2:" + +msgid "Voodoo 1 or 2 Graphics" +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 "Mouse:" msgstr "Fare:" @@ -430,16 +433,16 @@ msgid "Sound card #4:" msgstr "Ses kartı 4:" 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" msgid "Use FLOAT32 sound" -msgstr "FLOAT32 ses kullan" +msgstr "FLOAT32 sesi kullan" msgid "FM synth driver" msgstr "FM sentez sürücüsü" @@ -451,7 +454,7 @@ msgid "YMFM (faster)" msgstr "YMFM (daha hızlı)" msgid "Network type:" -msgstr "Ağ tipi:" +msgstr "Ağ türü:" msgid "PCap device:" msgstr "PCap cihazı:" @@ -460,28 +463,28 @@ msgid "Network adapter:" msgstr "Ağ cihazı:" 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" @@ -508,16 +511,16 @@ msgid "Parallel port 4" msgstr "Paralel port 4" msgid "HD Controller:" -msgstr "HD Kontrolcüsü:" +msgstr "Hard disk kontrolcüsü:" msgid "FD Controller:" -msgstr "FD Kontrolcüsü:" +msgstr "Disket sürücü kontrolcüsü:" msgid "Tertiary IDE Controller" -msgstr "Üçlü IDE Kontrolcüsü" +msgstr "Üçlü IDE kontrolcüsü" msgid "Quaternary IDE Controller" -msgstr "Dörtlü IDE Kontrolcüsü" +msgstr "Dörtlü IDE kontrolcüsü" msgid "SCSI" msgstr "SCSI" @@ -544,7 +547,7 @@ msgid "&New..." msgstr "&Yeni..." msgid "&Existing..." -msgstr "&Var olan..." +msgstr "&Var olanı seç..." msgid "&Remove" msgstr "&Kaldır" @@ -565,7 +568,7 @@ msgid "Sectors:" msgstr "Sektörler:" msgid "Heads:" -msgstr "Veri Kafaları:" +msgstr "Veri kafaları:" msgid "Cylinders:" msgstr "Silindirler:" @@ -574,13 +577,13 @@ msgid "Size (MB):" msgstr "Boyut (MB):" msgid "Type:" -msgstr "Tip:" +msgstr "Tür:" msgid "Image Format:" -msgstr "İmaj Düzeni:" +msgstr "İmaj düzeni:" msgid "Block Size:" -msgstr "Blok Boyutu:" +msgstr "Blok boyutu:" msgid "Floppy drives:" msgstr "Disket sürücüleri:" @@ -607,7 +610,7 @@ msgid "ISA RTC:" msgstr "ISA RTC:" msgid "ISA Memory Expansion" -msgstr "ISA Bellek Artırma" +msgstr "ISA bellek artırma" msgid "Card 1:" msgstr "Kart 1:" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Kritik hata" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - DURAKLATILDI" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Pencere moduna geri dönmek için Ctrl+Alt+PgDn tuşlarına basın." @@ -652,13 +655,13 @@ msgid "ZIP images" msgstr "ZIP imajları" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box hiç bir kullanılabilir ROM imajı bulamadı.\n\nLütfen ROM setini indirin ve onu \"Roms\" klasörüne çıkarın." +msgstr "86Box kullanılabilir hiçbir ROM imajı bulamadı.\n\nLütfen ROM setini indirin ve \"Roms\" klasörüne çıkarın." msgid "(empty)" -msgstr "(empty)" +msgstr "(boş)" msgid "All files" -msgstr "All files" +msgstr "Tüm dosyalar" msgid "Turbo" msgstr "Turbo" @@ -679,10 +682,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 mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir makineye geçiş yapılıyor." +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." 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 mevcut olmayan ROM imajı yüzünden mevcut değil. Mevcut olan bir ekran kartına geçiş yapılıyor." +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." + +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." + +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." msgid "Machine" msgstr "Makine" @@ -724,7 +733,7 @@ msgid "Press %1 to release mouse" msgstr "Farenin bırakılması için %1 tuşlarına basın" msgid "Press %1 or middle button to release mouse" -msgstr "Farenin bırakılması için %1 veya farenin orta tuşuna basın" +msgstr "Farenin bırakılması için %1 tuşlarına veya tekerlek tuşuna basın" msgid "Bus" msgstr "Veri yolu" @@ -762,17 +771,26 @@ msgstr "Herhangi bir PCap cihazı bulunamadı" msgid "Invalid PCap device" msgstr "Geçersiz PCap cihazı" -msgid "Standard 2-button joystick(s)" -msgstr "Standart 2-button oyun kolları" +msgid "2-axis, 2-button joystick(s)" +msgstr "2 eksenli, 2 düğmeli oyun kolları" -msgid "Standard 4-button joystick" -msgstr "Standart 4-button oyun kolu" +msgid "2-axis, 4-button joystick" +msgstr "2 eksenli, 4 düğmeli oyun kolu" -msgid "Standard 6-button joystick" -msgstr "Standart 6-button oyun kolu" +msgid "2-axis, 6-button joystick" +msgstr "2 eksenli, 6 düğmeli oyun kolu" -msgid "Standard 8-button joystick" -msgstr "Standart 8-button oyun kolu" +msgid "2-axis, 8-button joystick" +msgstr "2 eksenli, 8 düğmeli oyun kolu" + +msgid "3-axis, 2-button joystick" +msgstr "3 eksenli, 2 düğmeli oyun kollu" + +msgid "3-axis, 4-button joystick" +msgstr "3 eksenli, 4 düğmeli oyun kolu" + +msgid "4-axis, 4-button joystick" +msgstr "4 eksenli, 4 düğmeli oyun kolu" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -781,7 +799,7 @@ msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Kontrol Sistemi" +msgstr "Thrustmaster Flight Control System" msgid "None" msgstr "Hiçbiri" @@ -796,10 +814,10 @@ msgid "Advanced sector images" msgstr "Gelişmiş sektör imajları" msgid "Flux images" -msgstr "Flux images" +msgstr "Flux imajları" msgid "Are you sure you want to hard reset the emulated machine?" -msgstr "Emüle edilen makineyi yeniden başlatmak istediğinizden emin misiniz?" +msgstr "Makineyi yeniden başlamaya zorlamak istediğinizden emin misiniz?" msgid "Are you sure you want to exit 86Box?" msgstr "86Box'tan çıkmak istediğinize emin misiniz?" @@ -807,6 +825,9 @@ msgstr "86Box'tan çıkmak istediğinize emin misiniz?" msgid "Unable to initialize Ghostscript" msgstr "Ghostscript başlatılamadı" +msgid "Unable to initialize GhostPCL" +msgstr "GhostPCL başlatılamadı" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "MO imajları" msgid "Welcome to 86Box!" msgstr "86Box'a hoşgeldiniz!" -msgid "Internal controller" -msgstr "Dahili kontrolcü" +msgid "Internal device" +msgstr "Dahili cihazı" msgid "Exit" msgstr "Çıkış" @@ -829,25 +850,25 @@ 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 makineyi yeniden başlatacak." +msgstr "Bu işlem makineyi zorla yeniden başlatacak." msgid "Save" msgstr "Kaydet" msgid "About 86Box" -msgstr "86Box Hakkında" +msgstr "86Box hakkında" 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\nYapanlar: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, ve diğerleri.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, ve diğerleri.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE'ı gözden geçirin." +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." msgid "Hardware not available" msgstr "Donanım 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ğında bulunduğunuzdan emin olun." +msgstr "%1 kurulu olduğundan ve libpcap uyumlu bir internet ağı kullandığınızdan emin olun." msgid "Invalid configuration" msgstr "Geçersiz konfigürasyon" @@ -855,8 +876,11 @@ msgstr "Geçersiz konfigürasyon" 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." +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çiliyor" +msgstr "Tam ekran moduna geçiş yapılıyor" msgid "Don't show this message again" msgstr "Bu mesajı bir daha gösterme" @@ -865,31 +889,31 @@ msgid "Don't exit" msgstr "Çıkış yapma" msgid "Reset" -msgstr "Yeniden başlat" +msgstr "Evet" msgid "Don't reset" -msgstr "Yeniden başlatma" +msgstr "Hayır" msgid "CD-ROM images" msgstr "CD-ROM imajları" msgid "%1 Device Configuration" -msgstr "%1 Cihaz Konfigürasyonu" +msgstr "%1 cihaz konfigürasyonu" msgid "Monitor in sleep mode" msgstr "Monitör uyku modunda" msgid "OpenGL Shaders" -msgstr "OpenGL Gölgelendiricileri" +msgstr "OpenGL gölgelendiricileri" msgid "OpenGL options" msgstr "OpenGL ayarları" msgid "You are loading an unsupported configuration" -msgstr "Desteklenmeyen bir konfigürasyon yüklüyorsunuz" +msgstr "Desteklenmeyen bir konfigürasyon 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 CPU (işlemci) türü filtrelemesi bu emülasyon için devre dışı bırakıldı.\n\nBu, normalde seçilen makine ile uyumlu olmayan bir CPU seçmenizi mümkün kılmaktadır. Ancak, bundan dolayı seçilen makinenin BIOS'u veya diğer yazılımlar ile uyumsuzluk sorunu yaşayabilirsiniz.\n\nBu filtrelemeyi devre dışı bırakmak emülatör tarafından resmi olarak desteklenmemektedir ve açtığınız bug (hata) raporları geçersiz olarak kapatılabilir." +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." msgid "Continue" msgstr "Devam et" @@ -907,28 +931,28 @@ msgid "Cartridge images" msgstr "Kartuş imajları" msgid "Error initializing renderer" -msgstr "Oluşturucu başlatılırken hata oluştu" +msgstr "İşleyici başlatılırken hata oluştu" msgid "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." -msgstr "OpenGL (3.0 Core) görüntüleyici başlatılamadı. Başka bir görüntüleyici kullanın." +msgstr "OpenGL (3.0 Core) işleyici başlatılamadı. Başka bir görüntüleyici kullanın." msgid "Resume execution" -msgstr "Yürütmeye devam et" +msgstr "Çalıştırmaya devam et" msgid "Pause execution" -msgstr "Yürütmeyi duraklat" +msgstr "Çalıştırmayı duraklat" msgid "Press Ctrl+Alt+Del" -msgstr "Ctrl+Alt+Del" +msgstr "Ctrl+Alt+Del tuşlarına bas" msgid "Press Ctrl+Alt+Esc" -msgstr "Ctrl+Alt+Esc" +msgstr "Ctrl+Alt+Esc tuşlarına bas" msgid "Hard reset" msgstr "Makineyi yeniden başlat" msgid "ACPI shutdown" -msgstr "ACPI kapatma" +msgstr "ACPI kapanma" msgid "Hard disk (%1)" msgstr "Hard disk (%1)" @@ -943,16 +967,16 @@ 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 dosyası oluştur" msgid "Add Existing Hard Disk" -msgstr "Var Olan Hard Disk Dosyası Ekle" +msgstr "Var olan bir hard disk dosyası ekle" msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI disk imajları 4 GB'tan daha büyük olamaz." +msgstr "HDI disk imajları 4 GB boyutundan daha büyük olamaz." msgid "Disk images cannot be larger than 127 GB." -msgstr "Disk imajları 127 GB'tan daha büyük olamaz." +msgstr "Disk imajları 127 GB boyutundan daha büyük olamaz." msgid "Hard disk images" msgstr "Hard disk imajları" @@ -967,7 +991,7 @@ 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." msgid "Disk image file already exists" -msgstr "Disk imaj dosyası zaten var olmakta" +msgstr "Bu disk imaj dosyası zaten mevcuttur" msgid "Please specify a valid file name." msgstr "Lütfen geçerli bir dosya ismi belirleyin." @@ -985,7 +1009,7 @@ 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 diski bölmeyi ve formatlamayı unutmayın." +msgstr "Yeni oluşturulan diskte bölümler oluşturmayı ve formatlamayı 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?" @@ -999,6 +1023,27 @@ msgstr "Üzerine yaz" msgid "Don't overwrite" msgstr "Üzerine yazma" +msgid "Raw image" +msgstr "Ham imaj" + +msgid "HDI image" +msgstr "HDI imajı" + +msgid "HDX image" +msgstr "HDX imajı" + +msgid "Fixed-size VHD" +msgstr "Sabit-boyutlu VHD" + +msgid "Dynamic-size VHD" +msgstr "Dinamik-boyutlu VHD" + +msgid "Differencing VHD" +msgstr "Farklandırılan VHD" + +msgid "(N/A)" +msgstr "(yok)" + msgid "Raw image (.img)" msgstr "Ham imaj (.img)" @@ -1009,13 +1054,13 @@ msgid "HDX image (.hdx)" msgstr "HDX imajı (.hdx)" msgid "Fixed-size VHD (.vhd)" -msgstr "Sabit-boyutlu VHD (.vhd)" +msgstr "Sabit boyutlu VHD (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "Dinamik-boyutlu VHD (.vhd)" +msgstr "Dinamik boyutlu VHD (.vhd)" msgid "Differencing VHD (.vhd)" -msgstr "Differencing VHD (.vhd)" +msgstr "Farklandırılan VHD (.vhd)" msgid "Large blocks (2 MB)" msgstr "Büyük bloklar (2 MB)" @@ -1030,10 +1075,10 @@ 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, farkı alınan imaj oluşturulduktan sonra ana imaj dosyasının düzenlendiği 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ı olmuş olabilir.\n\nZaman damgalarını düzeltmek ister misiniz?" +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?" msgid "Parent and child disk timestamps do not match" -msgstr "Ana ve ek disk zaman damgaları uyuşmuyor" +msgstr "Ana ve ek disklerin zaman damgaları uyuşmuyor" msgid "Could not fix VHD timestamp." msgstr "VHD zaman damgası düzeltilemedi." @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1084,10 +1129,10 @@ msgid "1.44 MB" msgstr "1.44 MB" msgid "DMF (cluster 1024)" -msgstr "DMF (cluster 1024)" +msgstr "DMF (1024 kümeli)" msgid "DMF (cluster 2048)" -msgstr "DMF (cluster 2048)" +msgstr "DMF (2048 kümeli)" msgid "2.88 MB" msgstr "2.88 MB" @@ -1138,7 +1183,7 @@ msgid "2% below perfect RPM" 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ı" @@ -1150,7 +1195,7 @@ msgid "Mouse sensitivity:" msgstr "Fare hassasiyeti:" msgid "Select media images from program working directory" -msgstr "Program çalışma dizininden medya görüntülerini seçme" +msgstr "Medya görüntülerini programın çalışma dizininden seç" msgid "PIT mode:" msgstr "PIT modu:" @@ -1165,10 +1210,922 @@ msgid "Fast" msgstr "Hızlı" msgid "&Auto-pause on focus loss" -msgstr "&Odak kaybında otomatik duraklatma" +msgstr "Pencere &odağı kaybında otomatik olarak duraklat" msgid "WinBox is no longer supported" -msgstr "WinBox artık desteklenmiyor" +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, bakımcı eksikliği nedeniyle 2022 yılında durduruldu. Çabalarımızı 86Box'ı daha da iyi hale getirmeye yönlendirdiğimiz için, WinBox'ı artık bir yönetici olarak desteklememe kararı aldık.\n\nWinBox aracılığıyla daha fazla güncelleme sağlanmayacak ve 86Box'ın daha yeni sürümleriyle kullanmaya devam ederseniz hatalı davranışlarla karşılaşabilirsiniz. WinBox davranışıyla ilgili tüm hata raporları geçersiz olarak kapatılacaktır.\n\nKullanabileceğiniz diğer yöneticilerin bir listesi için 86box.net adresine gidin." +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." + +msgid "Generate" +msgstr "Oluştur" + +msgid "Joystick configuration" +msgstr "Oyun kolu yapılandırması" + +msgid "Device" +msgstr "Cihaz" + +msgid "%1 (X axis)" +msgstr "1 (X ekseni)" + +msgid "%1 (Y axis)" +msgstr "1 (Y ekseni)" + +msgid "MCA devices" +msgstr "MCA cihazları" + +msgid "List of MCA devices:" +msgstr "MCA cihazlarının listesi:" + +msgid "Tablet tool" +msgstr "Tablet aracı" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Qt hakkında" + +msgid "MCA devices..." +msgstr "MCA cihazları..." + +msgid "Show non-primary monitors" +msgstr "Birincil olmayan monitörleri göster" + +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 "Cursor/Puck" +msgstr "İmleç/Puck" + +msgid "Pen" +msgstr "Kalem" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "Ana bilgisayar CD/DVD sürücüsü (%1:)" + +msgid "&Connected" +msgstr "&Bağlı" + +msgid "Clear image history" +msgstr "İmaj geçmişini temizleyin" + +msgid "Create..." +msgstr "Oluştur..." + +msgid "previous image" +msgstr "önceki imaj" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Ana bilgisayar CD/DVD sürücüsü (%1)" + +msgid "Unknown Bus" +msgstr "Bilinmeyen veri yolu" + +msgid "Null Driver" +msgstr "Null sürücü" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "\"%1\": %2 açılırken hata oluştu" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "\"%1\" dosyasında tepe gölgelendirici derlenirken hata oluştu" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "\"%1\" dosyasında parça gölgelendirici derlenirken hata oluştu" + +msgid "Error linking shader program in file \"%1\"" +msgstr "\"%1\" dosyasında gölgelendirici programı bağlanırken hata oluştu" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 işleyici seçenekleri" + +msgid "Render behavior" +msgstr "İşleyiş davranışı" + +msgid "Use target framerate:" +msgstr "Şu hedef kare hızı oranını kullan:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Emüle edilen ekranla senkronize olarak her kareyi hemen işleyin.</p><p><span style=" font-style:italic;">Kullanılan gölgelendiriciler animasyonlu efektler için kare zamanını kullanmıyorsa bu önerilen seçenektir.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Video ile senkronize et" + +msgid "Shaders" +msgstr "Gölgelendiriciler" + +msgid "Remove" +msgstr "Kaldır" + +msgid "No shader selected" +msgstr "Gölgelendirici seçili değil" + +msgid "Browse..." +msgstr "Göz at..." + +msgid "Shader error" +msgstr "Gölgelendirici hatası" + +msgid "Could not load shaders." +msgstr "Gölgelendiriciler yüklenemedi." + +msgid "More information in details." +msgstr "Daha fazla bilgi detaylardadır." + +msgid "Couldn't create OpenGL context." +msgstr "OpenGL bağlamı oluşturulamadı." + +msgid "Couldn't switch to OpenGL context." +msgstr "OpenGL bağlamına geçilemedi." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "OpenGL sürüm 3.0 veya üstü gereklidir. Geçerli sürüm %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL başlatılamadı. Hata %1." + +msgid "Error initializing OpenGL" +msgstr "OpenGL başlatılırken hata oluştu" + +msgid "Falling back to software rendering.\n" +msgstr "Yazılım işleyicisine geri dönülüyor.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Paket açma arabelleği için bellek ayırma başarısız oldu.\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>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 "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." + +msgid "I Moved It" +msgstr "Taşındı" + +msgid "I Copied It" +msgstr "Kopyalandı" + +msgid "86Box Monitor #" +msgstr "86Box monitör " + +msgid "No MCA devices." +msgstr "MCA cihazı yok." + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "Ağ kartı 1" + +msgid "Network Card #2" +msgstr "Ağ kartı 2" + +msgid "Network Card #3" +msgstr "Ağ kartı 3" + +msgid "Network Card #4" +msgstr "Ağ kartı 4" + +msgid "Mode" +msgstr "Mod" + +msgid "Interface" +msgstr "Arayüz" + +msgid "Adapter" +msgstr "Adaptör" + +msgid "VDE Socket" +msgstr "VDE soketi" + +msgid "86Box Unit Tester" +msgstr "86Box birim test cihazı" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x anahtar kartı" + +msgid "Serial port passthrough 1" +msgstr "Seri port geçişi 1" + +msgid "Serial port passthrough 2" +msgstr "Seri port geçişi 2" + +msgid "Serial port passthrough 3" +msgstr "Seri port geçişi 3" + +msgid "Serial port passthrough 4" +msgstr "Seri port geçişi 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "İşleyici seçenekleri..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft veri yolu bağlantılı fare" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft veri yolu bağlantılı fare (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems seri fare" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft seri fare" + +msgid "Logitech Serial Mouse" +msgstr "Logitech seri fare" + +msgid "PS/2 Mouse" +msgstr "PS/2 fare" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (seri)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Standart Hayes uyumlu modem" + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32 emülasyonu" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32 (yeni) emülasyonu" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32L emülasyonu" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LN emülasyonu" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML yankartı" + +msgid "System MIDI" +msgstr "Sistem MIDI'si" + +msgid "MIDI Input Device" +msgstr "MIDI giriş cihazı" + +msgid "BIOS Address" +msgstr "BIOS adresi" + +msgid "Enable BIOS extension ROM Writes" +msgstr "BIOS uzantı ROM'larına yazmayı etkinleştir" + +msgid "Address" +msgstr "Adres" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS sürümü" + +msgid "Translate 26 -> 17" +msgstr "26 -> 17 olarak çevir" + +msgid "Language" +msgstr "Dil" + +msgid "Enable backlight" +msgstr "Arka ışığı etkinleştir" + +msgid "Invert colors" +msgstr "Renkleri ters çevir" + +msgid "BIOS size" +msgstr "BIOS boyutu" + +msgid "Map C0000-C7FFF as UMB" +msgstr "C0000-C7FFF'yi UMB olarak eşleyin" + +msgid "Map C8000-CFFFF as UMB" +msgstr "C8000-CFFFF'yi UMB olarak eşleyin" + +msgid "Map D0000-D7FFF as UMB" +msgstr "D0000-D7FFF'yi UMB olarak eşleyin" + +msgid "Map D8000-DFFFF as UMB" +msgstr "D8000-DFFFF'yi UMB olarak eşleyin" + +msgid "Map E0000-E7FFF as UMB" +msgstr "E0000-E7FFF'yi UMB olarak eşleyin" + +msgid "Map E8000-EFFFF as UMB" +msgstr "E8000-EFFFF'yi UMB olarak eşleyin" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 jumper'ı (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI çıkış cihazı" + +msgid "MIDI Real time" +msgstr "Gerçek zamanlı MIDI" + +msgid "MIDI Thru" +msgstr "MIDI geçişi" + +msgid "MIDI Clockout" +msgstr "MIDI saat çıkışı" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Çıkış ses düzeyi kazancı" + +msgid "Chorus" +msgstr "Koro" + +msgid "Chorus Voices" +msgstr "Koro sesleri" + +msgid "Chorus Level" +msgstr "Koro seviyesi" + +msgid "Chorus Speed" +msgstr "Koro hızı" + +msgid "Chorus Depth" +msgstr "Koro derinliği" + +msgid "Chorus Waveform" +msgstr "Koro dalga biçimi" + +msgid "Reverb" +msgstr "Yankı" + +msgid "Reverb Room Size" +msgstr "Yankı odası boyutu" + +msgid "Reverb Damping" +msgstr "Yankı sönümleme" + +msgid "Reverb Width" +msgstr "Yankı genişliği" + +msgid "Reverb Level" +msgstr "Yankı seviyesi" + +msgid "Interpolation Method" +msgstr "İnterpolasyon yöntemi" + +msgid "Reverb Output Gain" +msgstr "Yankı çıkış ses düzeyi artışı" + +msgid "Reversed stereo" +msgstr "Tersine çevrilmiş stereo" + +msgid "Nice ramp" +msgstr "Güzel rampa" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Düğmeler" + +msgid "Serial Port" +msgstr "Seri port" + +msgid "RTS toggle" +msgstr "RTS geçişi" + +msgid "Revision" +msgstr "Sürüm" + +msgid "Controller" +msgstr "Kontrolcü" + +msgid "Show Crosshair" +msgstr "Nişangahı göster" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC adresi" + +msgid "MAC Address OUI" +msgstr "MAC adresinin OUI'si" + +msgid "Enable BIOS" +msgstr "BIOS'u etkinleştir" + +msgid "Baud Rate" +msgstr "Baud hızı" + +msgid "TCP/IP listening port" +msgstr "TCP/IP dinleme portu" + +msgid "Phonebook File" +msgstr "Telefon rehber dosyası" + +msgid "Telnet emulation" +msgstr "Telnet emülasyonu" + +msgid "RAM Address" +msgstr "RAM adresi" + +msgid "RAM size" +msgstr "RAM boyutu" + +msgid "Initial RAM size" +msgstr "İlk RAM boyutu" + +msgid "Serial Number" +msgstr "Seri numarası" + +msgid "Host ID" +msgstr "Ana bilgisayar kimliği" + +msgid "FDC Address" +msgstr "FDC adresi" + +msgid "MPU-401 Address" +msgstr "MPU-401 adresi" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "MIDI girişi al" + +msgid "Low DMA" +msgstr "Düşük DMA" + +msgid "Enable Game port" +msgstr "Gameport girişini etkinleştir" + +msgid "Surround module" +msgstr "Surround modülü" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "CODEC kurulumunda CODEC kesmesini yükselt (bazı sürücüler tarafından gereklidir)" + +msgid "SB Address" +msgstr "SB adresi" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "OPL'yi etkinleştir" + +msgid "Receive MIDI input (MPU-401)" +msgstr "MIDI girişi al (MPU-401)" + +msgid "SB low DMA" +msgstr "SB düşük DMA" + +msgid "6CH variant (6-channel)" +msgstr "6CH varyantı (6 kanallı)" + +msgid "Enable CMS" +msgstr "CMS'yi Etkinleştir" + +msgid "Mixer" +msgstr "Karıştırıcı" + +msgid "High DMA" +msgstr "Yüksek DMA" + +msgid "Control PC speaker" +msgstr "PC hoparlörünü kontrol et" + +msgid "Memory size" +msgstr "Bellek boyutu" + +msgid "EMU8000 Address" +msgstr "EMU8000 adresi" + +msgid "IDE Controller" +msgstr "IDE Kontrolcüsü" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "GUS türü" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "0x04 \"86Box'tan çık\" komutunu etkinleştir" + +msgid "Display type" +msgstr "Ekran türü" + +msgid "Composite type" +msgstr "Kompozit türü" + +msgid "RGB type" +msgstr "RGB türü" + +msgid "Line doubling type" +msgstr "Hat ikiye katlama türü" + +msgid "Snow emulation" +msgstr "Kar emülasyonu" + +msgid "Monitor type" +msgstr "Monitör türü" + +msgid "Character set" +msgstr "Karakter seti" + +msgid "XGA type" +msgstr "XGA türü" + +msgid "Instance" +msgstr "Örnek" + +msgid "MMIO Address" +msgstr "MMIO adresi" + +msgid "RAMDAC type" +msgstr "RAMDAC türü" + +msgid "Blend" +msgstr "Karışım" + +msgid "Bilinear filtering" +msgstr "Bilineer filtreleme" + +msgid "Dithering" +msgstr "Dithering" + +msgid "Enable NMI for CGA emulation" +msgstr "CGA öykünmesi için NMI'yi etkinleştir" + +msgid "Voodoo type" +msgstr "Voodoo türü" + +msgid "Framebuffer memory size" +msgstr "Çerçeve arabelleği bellek boyutu" + +msgid "Texture memory size" +msgstr "Doku bellek boyutu" + +msgid "Dither subtraction" +msgstr "Dither çıkarma" + +msgid "Screen Filter" +msgstr "Ekran filtresi" + +msgid "Render threads" +msgstr "İşleme için iş parçacığı sayısı" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Başlangıç adresi" + +msgid "Contiguous Size" +msgstr "Bitişik boyut" + +msgid "I/O Width" +msgstr "G/Ç genişliği" + +msgid "Transfer Speed" +msgstr "Transfer hızı" + +msgid "EMS mode" +msgstr "EMS modu" + +msgid "Address for > 2 MB" +msgstr "> 2 MB için adres" + +msgid "Frame Address" +msgstr "Çerçeve adresi" + +msgid "USA" +msgstr "ABD" + +msgid "Danish" +msgstr "Danca" + +msgid "Always at selected speed" +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" +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 "Sine" +msgstr "Sinüs" + +msgid "Triangle" +msgstr "Üçgen" + +msgid "Linear" +msgstr "Doğrusal" + +msgid "4th Order" +msgstr "4. sıra" + +msgid "7th Order" +msgstr "7. sıra" + +msgid "Non-timed (original)" +msgstr "Zamanlayıcı olmadan (orijinal)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2'de jumper yok)" + +msgid "Two" +msgstr "İki" + +msgid "Three" +msgstr "Üç" + +msgid "Wheel" +msgstr "Tekerlek" + +msgid "Five + Wheel" +msgstr "Beş + tekerlek" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 seri / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) seri" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "BIOS'u devre dışı bırak" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (stereo)" + +msgid "Classic" +msgstr "Klasik" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Kompozit" + +msgid "Old" +msgstr "Eski" + +msgid "New" +msgstr "Yeni" + +msgid "Color (generic)" +msgstr "Renk (sıradan)" + +msgid "Green Monochrome" +msgstr "Yeşil monokrom" + +msgid "Amber Monochrome" +msgstr "Kehribar monokrom" + +msgid "Gray Monochrome" +msgstr "Gri monokrom" + +msgid "Color (no brown)" +msgstr "Renk (kahverengi yok)" + +msgid "Color (IBM 5153)" +msgstr "Renkli (IBM 5153)" + +msgid "Simple doubling" +msgstr "Basit ikiye katlama" + +msgid "sRGB interpolation" +msgstr "sRGB interpolasyonu" + +msgid "Linear interpolation" +msgstr "Doğrusal interpolasyon" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Monokrom (5151/MDA) (beyaz)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Monokrom (5151/MDA) (yeşil)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Monokrom (5151/MDA) (kehribar)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Renkli 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Renkli 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Geliştirilmiş renkli - Normal mod (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Geliştirilmiş renkli - Geliştirilmiş mod (5154/ECD)" + +msgid "Green" +msgstr "Yeşil" + +msgid "Amber" +msgstr "Kehribar" + +msgid "Gray" +msgstr "Gri" + +msgid "Color" +msgstr "Renk" + +msgid "U.S. English" +msgstr "ABD İngilizcesi" + +msgid "Scandinavian" +msgstr "İskandinav" + +msgid "Other languages" +msgstr "Diğer diller" + +msgid "Bochs latest" +msgstr "Bochs en son sürümü" + +msgid "Mono Non-Interlaced" +msgstr "Monokrom (geçmeli tarama yok)" + +msgid "Color Interlaced" +msgstr "Renkli (geçmeli tarama var)" + +msgid "Color Non-Interlaced" +msgstr "Renkli (geçmeli tarama yok)" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx Voodoo Grafikleri" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8-bit" + +msgid "16-bit" +msgstr "16-bit" + +msgid "Standard (150ns)" +msgstr "Standart (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Yüksek Hızlı (120ns)" + +msgid "Enabled" +msgstr "Etkin" + +msgid "Standard" +msgstr "Standart" + +msgid "High-Speed" +msgstr "Yüksek Hızlı" + +msgid "Stereo LPT DAC" +msgstr "Stereo LPT DAC" + +msgid "Generic Text Printer" +msgstr "Sıradan metin yazıcı" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Sıradan ESC/P Dot Matrix yazıcı" + +msgid "Generic PostScript Printer" +msgstr "Sıradan PostScript yazıcı" + +msgid "Generic PCL5e Printer" +msgstr "Sıradan 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'ı" + +msgid "Serial Passthrough Device" +msgstr "Seri port geçiş cihazı" + +msgid "Passthrough Mode" +msgstr "Geçişli mod" + +msgid "Host Serial Device" +msgstr "Ana bilgisayar seri cihazı" + +msgid "Name of pipe" +msgstr "Boru adı" + +msgid "Data bits" +msgstr "Veri bitleri" + +msgid "Stop bits" +msgstr "Dur bitleri" + +msgid "Baud Rate of Passthrough" +msgstr "Geçiş Baud hızı" + +msgid "Named Pipe (Server)" +msgstr "Adlandırılmış boru (Sunucu)" + +msgid "Host Serial Passthrough" +msgstr "Ana bilgisayar seri port geçişi" + +msgid "Eject %s" +msgstr "%s diskini çıkar" + +msgid "&Unmute" +msgstr "&Sesi aç" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Ciddi performans düşüklüğüne neden olabilir" + +msgid "RAM Disk (max. speed)" +msgstr "RAM Disk (maks. hız)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A klonu (ISA)" + +msgid "Vendor" +msgstr "Üretici" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Sıradan PC/XT bellek artırma" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Sıradan PC/AT bellek artırma" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 9c76d803e..5ce59be01 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -390,8 +390,11 @@ msgstr "Динамічний рекомпілятор" msgid "Video:" msgstr "Відеокарта:" -msgid "Voodoo Graphics" -msgstr "Прискорювач Voodoo" +msgid "Video #2:" +msgstr "Відеокарта 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Прискорювач Voodoo 1 або 2" msgid "IBM 8514/A Graphics" msgstr "Прискорювач IBM 8514/A" @@ -637,7 +640,7 @@ msgid "Fatal error" msgstr "Непереробна помилка" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - ПРИЗУПИНЕННЯ" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Натисніть Ctrl+Alt+PgDn для повернення у віконний режим." @@ -684,6 +687,12 @@ msgstr "Системна плата \"%hs\" недоступна через ві msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Відеокарта \"%hs\" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Переключення на доступну відеокарту." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Відеокарта 2 \"%hs\" недоступна через відсутність файлу її ПЗУ в каталозі roms/video. Відключення другої відеокарти." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Пристрій \"%hs\" недоступний через відсутність файлу його ПЗУ. Ігнорування пристрою." + msgid "Machine" msgstr "Комп'ютер" @@ -741,9 +750,6 @@ msgstr "H" msgid "S" msgstr "S" -msgid "MiB" -msgstr "МіБ" - msgid "KB" msgstr "КБ" @@ -765,17 +771,26 @@ msgstr "Пристрої PCap не знайдені" msgid "Invalid PCap device" msgstr "Невірний пристрій PCap" -msgid "Standard 2-button joystick(s)" -msgstr "Стандартний 2-кнопковий джойстик" +msgid "2-axis, 2-button joystick(s)" +msgstr "2-осьовий, 2-кнопковий джойстик" -msgid "Standard 4-button joystick" -msgstr "Стандартний 4-кнопковий джойстик" +msgid "2-axis, 4-button joystick" +msgstr "2-осьовий, 4-кнопковий джойстик" -msgid "Standard 6-button joystick" -msgstr "Стандартний 6-кнопковий джойстик" +msgid "2-axis, 6-button joystick" +msgstr "2-осьовий, 6-кнопковий джойстик" -msgid "Standard 8-button joystick" -msgstr "Стандартний 8-кнопковий джойстик" +msgid "2-axis, 8-button joystick" +msgstr "2-осьовий, 8-кнопковий джойстик" + +msgid "3-axis, 2-button joystick" +msgstr "3-осьовий, 2-кнопковий джойстик" + +msgid "3-axis, 4-button joystick" +msgstr "3-осьовий, 4-кнопковий джойстик" + +msgid "4-axis, 4-button joystick" +msgstr "4-осьовий, 4-кнопковий джойстик" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -810,6 +825,9 @@ msgstr "Ви впевнені, що хочете вийти з 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Неможливо ініціалізувати Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Неможливо ініціалізувати GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "Магнітооптичний %i (%ls): %ls" @@ -819,8 +837,8 @@ msgstr "Образи магнітооптичних дисків" msgid "Welcome to 86Box!" msgstr "Ласкаво просимо в 86Box!" -msgid "Internal controller" -msgstr "Вбудований контролер" +msgid "Internal device" +msgstr "Вбудований пристрій" msgid "Exit" msgstr "Вихід" @@ -844,7 +862,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 "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." +msgstr "Емулятор старих комп'ютерів\n\nАвтори: Miran Grča (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nЗ попередніми основними внесками Sarah Walker, leilei, JohnElliott, greatpsycho та інших.\n\nВипускаєтся під ліцензією GNU General Public License версії 2 або більше пізніше. Додадкову інформацію см. у файлі LICENSE." msgid "Hardware not available" msgstr "Обладнання недоступне" @@ -858,6 +876,9 @@ msgstr "Неприпустима конфігурація" 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 в PDF.\n\nВсі документи, відправлені на загальний принтер PostScript, будуть збережені у вигляді файлів 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 Language (.pcl) files." +msgstr "%1 потрібно для автоматичного перетворення файлів PCL в PDF.\n\nВсі документи, відправлені на загальний принтер PCL, будуть збережені у вигляді файлів Printer Command Language (.ps)." + msgid "Entering fullscreen mode" msgstr "Вхід у повноекранний режим" @@ -1002,6 +1023,27 @@ msgstr "Перезаписати" msgid "Don't overwrite" msgstr "Не перезаписувати" +msgid "Raw image" +msgstr "RAW образ" + +msgid "HDI image" +msgstr "Образ HDI" + +msgid "HDX image" +msgstr "Образ HDX" + +msgid "Fixed-size VHD" +msgstr "VHD фіксованого розміру" + +msgid "Dynamic-size VHD" +msgstr "VHD динамічного розміру" + +msgid "Differencing VHD" +msgstr "Диференційований образ VHD" + +msgid "(N/A)" +msgstr "(Ні)" + msgid "Raw image (.img)" msgstr "RAW образ (.img)" @@ -1059,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 кБ" +msgid "160 KB" +msgstr "160 КБ" -msgid "180 kB" -msgstr "180 кБ" +msgid "180 KB" +msgstr "180 КБ" -msgid "320 kB" -msgstr "320 кБ" +msgid "320 KB" +msgstr "320 КБ" -msgid "360 kB" -msgstr "360 кБ" +msgid "360 KB" +msgstr "360 КБ" -msgid "640 kB" -msgstr "640 кБ" +msgid "640 KB" +msgstr "640 КБ" -msgid "720 kB" -msgstr "720 кБ" +msgid "720 KB" +msgstr "720 КБ" msgid "1.2 MB" msgstr "1.2 МБ" @@ -1175,3 +1217,921 @@ msgstr "WinBox більше не підтримується" 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 було припинено у 2022 році через брак супровідників. Оскільки ми спрямовуємо наші зусилля на те, щоб зробити 86Box ще кращим, ми прийняли рішення більше не підтримувати WinBox як менеджер.\n\nБільше ніяких оновлень не буде надаватися через WinBox, і ви можете зіткнутися з некоректною поведінкою, якщо продовжите використовувати його з новими версіями 86Box. Будь-які повідомлення про помилки, пов'язані з поведінкою WinBox, будуть закриті як недійсні.\n\nПерейдіть на 86box.net для отримання списку інших менеджерів, які ви можете використовувати." + +msgid "Generate" +msgstr "Згенерувати" + +msgid "Joystick configuration" +msgstr "Конфігурація джойстика" + +msgid "Device" +msgstr "Пристрій" + +msgid "%1 (X axis)" +msgstr "%1 (вісь X)" + +msgid "%1 (Y axis)" +msgstr "%1 (вісь Y)" + +msgid "MCA devices" +msgstr "Пристрої MCA" + +msgid "List of MCA devices:" +msgstr "Список пристроїв MCA:" + +msgid "Tablet tool" +msgstr "Інструмент для планшета" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "Про Qt" + +msgid "MCA devices..." +msgstr "Пристрої MCA..." + +msgid "Show non-primary monitors" +msgstr "Показати неосновні монітори" + +msgid "Open screenshots folder..." +msgstr "Відкрийте папку скріншотів..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "Застосовувати розстягування у повноекранному режимі у максимізованому стані" + +msgid "Cursor/Puck" +msgstr "Курсор/шайба" + +msgid "Pen" +msgstr "Ручка" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "CD/DVD привід хоста (%1:)" + +msgid "&Connected" +msgstr "&Підключено" + +msgid "Clear image history" +msgstr "Очистити історію образів" + +msgid "Create..." +msgstr "Створити..." + +msgid "previous image" +msgstr "попередній образ" + +msgid "Host CD/DVD Drive (%1)" +msgstr "CD/DVD привід хоста (%1)" + +msgid "Unknown Bus" +msgstr "Невідома шина" + +msgid "Null Driver" +msgstr "Нульовий драйвер" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Помилка відкриття \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Помилка компіляції вершинного шейдера у файлі \"%1\"." + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Помилка компіляції фрагментного шейдера у файлі \"%1\"." + +msgid "Error linking shader program in file \"%1\"" +msgstr "Помилка зв'язування шейдерної програми у файлі \"%1\"." + +msgid "OpenGL 3.0 renderer options" +msgstr "Параметри рендерингу OpenGL 3.0" + +msgid "Render behavior" +msgstr "Поведінка рендерингу" + +msgid "Use target framerate:" +msgstr "Використовувати цільову частоту кадрів:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Відображати кожен кадр миттєво, синхронно з емульованим дисплеєм.</p><p><span style=" font-style:italic;">Це рекомендований варіант, якщо використовувані шейдери не використовують час кадру для анімованих ефектів.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Синхронізація з відео" + +msgid "Shaders" +msgstr "Шейдери" + +msgid "Remove" +msgstr "Видалити" + +msgid "No shader selected" +msgstr "Не вибрано шейдер" + +msgid "Browse..." +msgstr "Переглянути..." + +msgid "Shader error" +msgstr "Помилка шейдеру" + +msgid "Could not load shaders." +msgstr "Не вдалося завантажити шейдери." + +msgid "More information in details." +msgstr "Більше інформації в деталях." + +msgid "Couldn't create OpenGL context." +msgstr "Не вдалося створити контекст OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Не вдалося переключитися на контекст OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "Потрібна версія OpenGL 3.0 або новіша. Поточна версія %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Не вдалося ініціалізувати OpenGL. Помилка %1." + +msgid "Error initializing OpenGL" +msgstr "Помилка ініціалізації OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Повернення до програмного рендерингу.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +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 "This machine might have been moved or copied." +msgstr "Цю машину могли перемістити або скопіювати." + +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 "Щоб забезпечити належну мережеву функціональність, 86Box повинен знати, чи машина була переміщена або скопійована.\n\nЯкщо ви не впевнені, виберіте \"Скопійована\"." + +msgid "I Moved It" +msgstr "Переміщена" + +msgid "I Copied It" +msgstr "Скопійована" + +msgid "86Box Monitor #" +msgstr "Монітор 86Box " + +msgid "No MCA devices." +msgstr "Ніяких пристроїв MCA." + +msgid "MiB" +msgstr "МіБ" + +msgid "Network Card #1" +msgstr "Мережева карта 1" + +msgid "Network Card #2" +msgstr "Мережева карта 2" + +msgid "Network Card #3" +msgstr "Мережева карта 3" + +msgid "Network Card #4" +msgstr "Мережева карта 4" + +msgid "Mode" +msgstr "Режим" + +msgid "Interface" +msgstr "Інтерфейс" + +msgid "Adapter" +msgstr "Адаптер" + +msgid "VDE Socket" +msgstr "VDE сокет" + +msgid "86Box Unit Tester" +msgstr "Тестер блоків 86Box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Ключова картка Novell NetWare 2.x" + +msgid "Serial port passthrough 1" +msgstr "Пропуск послідовного порту 1" + +msgid "Serial port passthrough 2" +msgstr "Пропуск послідовного порту 2" + +msgid "Serial port passthrough 3" +msgstr "Пропуск послідовного порту 3" + +msgid "Serial port passthrough 4" +msgstr "Пропуск послідовного порту 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "Параметри рендерингу..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Шинна миша Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Шинна миша Microsoft (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Послідовна миша Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Послідовна миша Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Послідовна миша Logitech" + +msgid "PS/2 Mouse" +msgstr "Миша PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (послідовна)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Стандартний модем, сумісний зі стандартом Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Емуляція Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Емуляція Roland MT-32 (новий)" + +msgid "Roland CM-32L Emulation" +msgstr "Емуляція Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Емуляція Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Дочірня плата OPL4-ML" + +msgid "System MIDI" +msgstr "MIDI системи" + +msgid "MIDI Input Device" +msgstr "Пристрій введення MIDI" + +msgid "BIOS Address" +msgstr "Адреса BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Увімкнути розширення BIOS Записи в ПЗУ" + +msgid "Address" +msgstr "Адреса" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Ревізія BIOS" + +msgid "Translate 26 -> 17" +msgstr "Перекладіть 26 -> 17" + +msgid "Language" +msgstr "Мова" + +msgid "Enable backlight" +msgstr "Увімкнути підсвічування" + +msgid "Invert colors" +msgstr "Інвертувати кольори" + +msgid "BIOS size" +msgstr "Розмір BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Зіставлення C0000-C7FFF як UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Зіставлення C8000-CFFFF як UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Зіставлення D0000-D7FFF як UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Зіставлення D8000-DFFFF як UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Зіставлення E0000-E7FFF як UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Зіставлення E8000-EFFFF як UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "Джампер JS9 (JIM)" + +msgid "MIDI Output Device" +msgstr "Вихідний пристрій MIDI" + +msgid "MIDI Real time" +msgstr "MIDI в реальному часі" + +msgid "MIDI Thru" +msgstr "Прохід MIDI-вхіду" + +msgid "MIDI Clockout" +msgstr "Вихід MIDI-годинника" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "Вихідний коефіцієнт підсилення" + +msgid "Chorus" +msgstr "Приспів" + +msgid "Chorus Voices" +msgstr "Голоси приспіву" + +msgid "Chorus Level" +msgstr "Рівень приспіву" + +msgid "Chorus Speed" +msgstr "Швидкість приспіву" + +msgid "Chorus Depth" +msgstr "Глибина приспіву" + +msgid "Chorus Waveform" +msgstr "Форма сигналу приспіву" + +msgid "Reverb" +msgstr "Реверберація" + +msgid "Reverb Room Size" +msgstr "Розмір ревербераційної кімнати" + +msgid "Reverb Damping" +msgstr "Демпфування реверберації" + +msgid "Reverb Width" +msgstr "Ширина реверберації" + +msgid "Reverb Level" +msgstr "Рівень реверберації" + +msgid "Interpolation Method" +msgstr "Метод інтерполяції" + +msgid "Reverb Output Gain" +msgstr "Посилення виходу реверберації" + +msgid "Reversed stereo" +msgstr "Реверсивне стерео" + +msgid "Nice ramp" +msgstr "Гарний пандус" + +msgid "Hz" +msgstr "Гц" + +msgid "Buttons" +msgstr "Кнопки" + +msgid "Serial Port" +msgstr "Послідовний порт" + +msgid "RTS toggle" +msgstr "Перемикач RTS" + +msgid "Revision" +msgstr "Ревізія" + +msgid "Controller" +msgstr "Контролер" + +msgid "Show Crosshair" +msgstr "Показати перехрестя" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC-адреса" + +msgid "MAC Address OUI" +msgstr "MAC-адреса OUI" + +msgid "Enable BIOS" +msgstr "Увімкнення BIOS" + +msgid "Baud Rate" +msgstr "Швидкість передачі даних" + +msgid "TCP/IP listening port" +msgstr "Порт прослуховування TCP/IP" + +msgid "Phonebook File" +msgstr "Файл телефонної книги" + +msgid "Telnet emulation" +msgstr "Емуляція Telnet" + +msgid "RAM Address" +msgstr "Адреса оперативної пам'яті" + +msgid "RAM size" +msgstr "Розмір оперативної пам'яті" + +msgid "Initial RAM size" +msgstr "Початковий розмір оперативної пам'яті" + +msgid "Serial Number" +msgstr "Серійний номер" + +msgid "Host ID" +msgstr "Ідентифікатор хоста" + +msgid "FDC Address" +msgstr "Адреса FDC" + +msgid "MPU-401 Address" +msgstr "Адреса MPU-401" + +msgid "MPU-401 IRQ" +msgstr "IRQ MPU-401" + +msgid "Receive MIDI input" +msgstr "Отримання MIDI-входу" + +msgid "Low DMA" +msgstr "Низький рівень DMA" + +msgid "Enable Game port" +msgstr "Увімкнути ігровий порт" + +msgid "Surround module" +msgstr "Модуль об'ємного звучання" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Піднімати переривання CODEC під час встановлення CODEC (потрібно для деяких драйверів)" + +msgid "SB Address" +msgstr "Адреса SB" + +msgid "WSS IRQ" +msgstr "IRQ WSS" + +msgid "WSS DMA" +msgstr "DMA WSS" + +msgid "Enable OPL" +msgstr "Ввімкнути OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Отримання MIDI-входу (MPU-401)" + +msgid "SB low DMA" +msgstr "SB низький DMA" + +msgid "6CH variant (6-channel)" +msgstr "Варіант 6CH (6-канальний)" + +msgid "Enable CMS" +msgstr "Ввімкнути CMS" + +msgid "Mixer" +msgstr "Міксер" + +msgid "High DMA" +msgstr "Високий DMA" + +msgid "Control PC speaker" +msgstr "Керування динаміком ПК" + +msgid "Memory size" +msgstr "Обсяг пам'яті" + +msgid "EMU8000 Address" +msgstr "Адреса EMU8000" + +msgid "IDE Controller" +msgstr "Контролер IDE" + +msgid "Codec" +msgstr "Кодек" + +msgid "GUS type" +msgstr "Тип GUS" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Увімкнути команду 0x04 \"Вихід з 86Box\"." + +msgid "Display type" +msgstr "Тип відображення" + +msgid "Composite type" +msgstr "Композитний тип" + +msgid "RGB type" +msgstr "Тип RGB" + +msgid "Line doubling type" +msgstr "Тип подвоєння лінії" + +msgid "Snow emulation" +msgstr "Емуляція снігу" + +msgid "Monitor type" +msgstr "Тип монітора" + +msgid "Character set" +msgstr "Набір символів" + +msgid "XGA type" +msgstr "Тип XGA" + +msgid "Instance" +msgstr "Примірник" + +msgid "MMIO Address" +msgstr "Адреса MMIO" + +msgid "RAMDAC type" +msgstr "Тип RAMDAC" + +msgid "Blend" +msgstr "Суміш" + +msgid "Bilinear filtering" +msgstr "Білінійна фільтрація" + +msgid "Dithering" +msgstr "Дизеринг" + +msgid "Enable NMI for CGA emulation" +msgstr "Увімкнути NMI для емуляції CGA" + +msgid "Voodoo type" +msgstr "Тип вуду" + +msgid "Framebuffer memory size" +msgstr "Розмір пам'яті фреймбуфера" + +msgid "Texture memory size" +msgstr "Розмір пам'яті текстур" + +msgid "Dither subtraction" +msgstr "Віднімання з похибкою" + +msgid "Screen Filter" +msgstr "Сітчастий фільтр" + +msgid "Render threads" +msgstr "Відрендерити потоки" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Початкова адреса" + +msgid "Contiguous Size" +msgstr "Суміжний розмір" + +msgid "I/O Width" +msgstr "Ширина вводу/виводу" + +msgid "Transfer Speed" +msgstr "Швидкість передачі даних" + +msgid "EMS mode" +msgstr "Режим EMS" + +msgid "Address for > 2 MB" +msgstr "Адреса для > 2 МБ" + +msgid "Frame Address" +msgstr "Адреса кадру" + +msgid "USA" +msgstr "США" + +msgid "Danish" +msgstr "Данська" + +msgid "Always at selected speed" +msgstr "Завжди на обраній швидкості" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "Налаштування BIOS + Гарячі клавіші (вимкнено під час POST)" + +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 "Sine" +msgstr "Синусоїдальна" + +msgid "Triangle" +msgstr "Трикутна" + +msgid "Linear" +msgstr "Лінійний" + +msgid "4th Order" +msgstr "4-го порядку" + +msgid "7th Order" +msgstr "7-го порядку" + +msgid "Non-timed (original)" +msgstr "Без таймера (оригінал)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Гц (без джампера на JMP2)" + +msgid "Two" +msgstr "Два" + +msgid "Three" +msgstr "Три" + +msgid "Wheel" +msgstr "Колесо" + +msgid "Five + Wheel" +msgstr "П'ять + колесо" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 послідовна / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) послідовна" + +msgid "8 KB" +msgstr "8 КБ" + +msgid "32 KB" +msgstr "32 КБ" + +msgid "16 KB" +msgstr "16 КБ" + +msgid "64 KB" +msgstr "64 КБ" + +msgid "Disable BIOS" +msgstr "Вимкнення BIOS" + +msgid "512 KB" +msgstr "512 КБ" + +msgid "2 MB" +msgstr "2 МБ" + +msgid "8 MB" +msgstr "8 МБ" + +msgid "28 MB" +msgstr "28 МБ" + +msgid "1 MB" +msgstr "1 МБ" + +msgid "4 MB" +msgstr "4 МБ" + +msgid "12 MB" +msgstr "12 МБ" + +msgid "16 MB" +msgstr "16 МБ" + +msgid "20 MB" +msgstr "20 МБ" + +msgid "24 MB" +msgstr "24 МБ" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (стерео)" + +msgid "Classic" +msgstr "Класичний" + +msgid "256 KB" +msgstr "256 КБ" + +msgid "Composite" +msgstr "Композитний" + +msgid "Old" +msgstr "Старий" + +msgid "New" +msgstr "Новий" + +msgid "Color (generic)" +msgstr "Кольоровий (загальний)" + +msgid "Green Monochrome" +msgstr "Зелений монохромний" + +msgid "Amber Monochrome" +msgstr "Бурштиновий монохромний" + +msgid "Gray Monochrome" +msgstr "Сірий монохромний" + +msgid "Color (no brown)" +msgstr "Кольоровий (без коричневого)" + +msgid "Color (IBM 5153)" +msgstr "Кольоровий (IBM 5153)" + +msgid "Simple doubling" +msgstr "Просте подвоєння" + +msgid "sRGB interpolation" +msgstr "sRGB інтерполяція" + +msgid "Linear interpolation" +msgstr "Лінійна інтерполяція" + +msgid "128 KB" +msgstr "128 КБ" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Монохромний (5151/MDA) (білий)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Монохромний (5151/MDA) (зелений)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Монохромний (5151/MDA) (бурштиновий)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Кольоровий 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Кольоровий 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Покращений колір - звичайний режим (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Покращений колір - розширений режим (5154/ECD)" + +msgid "Green" +msgstr "Зелений" + +msgid "Amber" +msgstr "Бурштиновий" + +msgid "Gray" +msgstr "Сірий" + +msgid "Color" +msgstr "Кольоровий" + +msgid "U.S. English" +msgstr "Американський англійський" + +msgid "Scandinavian" +msgstr "Скандинавський" + +msgid "Other languages" +msgstr "Інші мови" + +msgid "Bochs latest" +msgstr "Bochs останній" + +msgid "Mono Non-Interlaced" +msgstr "Монохромний неінтерлейсний" + +msgid "Color Interlaced" +msgstr "Кольоровий інтерлейсний" + +msgid "Color Non-Interlaced" +msgstr "Кольоровий неінтерлейсний" + +msgid "3Dfx Voodoo Graphics" +msgstr "Прискорювач 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8-розрядний" + +msgid "16-bit" +msgstr "16-розрядний" + +msgid "Standard (150ns)" +msgstr "Стандартний (150 нс)" + +msgid "High-Speed (120ns)" +msgstr "Високошвидкісний (120нс)" + +msgid "Enabled" +msgstr "Увімкнено" + +msgid "Standard" +msgstr "Стандартний" + +msgid "High-Speed" +msgstr "Високошвидкісний" + +msgid "Stereo LPT DAC" +msgstr "Стерео LPT ЦАП" + +msgid "Generic Text Printer" +msgstr "Загальний текстовий принтер" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Загальний матричний принтер ESC/P" + +msgid "Generic PostScript Printer" +msgstr "Загальний принтер PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Загальний принтер PCL5e" + +msgid "Parallel Line Internet Protocol" +msgstr "Parallel Line Internet Protocol" + +msgid "Protection Dongle for Savage Quest" +msgstr "Ключовий захист для Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Пристрій для пропуску послідовного порту" + +msgid "Passthrough Mode" +msgstr "Наскрізний режим" + +msgid "Host Serial Device" +msgstr "Послідовний пристрій хоста" + +msgid "Name of pipe" +msgstr "Назва пайпа" + +msgid "Data bits" +msgstr "Біти даних" + +msgid "Stop bits" +msgstr "Стоп-біти" + +msgid "Baud Rate of Passthrough" +msgstr "Швидкість передачі даних пропуску" + +msgid "Named Pipe (Server)" +msgstr "Іменований пайп (сервер)" + +msgid "Host Serial Passthrough" +msgstr "Пропуск послідовного порту хоста" + +msgid "Eject %s" +msgstr "Вилучити %s" + +msgid "&Unmute" +msgstr "&Увімкнути звук" + +msgid "Softfloat FPU" +msgstr "FPU Softfloat" + +msgid "High performance impact" +msgstr "Високий вплив на продуктивність" + +msgid "RAM Disk (max. speed)" +msgstr "Диск оперативної пам'яті (макс. швидкість)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "Клон IBM 8514/A (ISA)" + +msgid "Vendor" +msgstr "Виробник" + +msgid "30 Hz (JMP2 = 1)" +msgstr "30 Гц (JMP2 = 1)" + +msgid "60 Hz (JMP2 = 2)" +msgstr "60 Гц (JMP2 = 2)" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Загальне розширення пам'яті PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Загальне розширення пам'яті PC/AT" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index ee6d77849..707c7ae7f 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -13,7 +13,7 @@ msgid "&Keyboard requires capture" msgstr "Bàn phím &hoạt động cần capture chuột" msgid "&Right CTRL is left ALT" -msgstr "Gắn CTRL p&hải vào ALT trái" +msgstr "Gắn ALT trái vào CTRL ph&ải" msgid "&Hard Reset..." msgstr "Buộc khởi độn&g lại" @@ -390,8 +390,11 @@ msgstr "Bộ tái biên dịch động (Dynamic Recompiler)" msgid "Video:" msgstr "Video:" -msgid "Voodoo Graphics" -msgstr "Đồ họa Voodoo" +msgid "Video #2:" +msgstr "Video 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Đồ họa Voodoo 1 hoặc 2" msgid "IBM 8514/A Graphics" msgstr "Đồ họa IBM 8514/A" @@ -684,6 +687,12 @@ msgstr "Mẫu máy \"%hs\" không giả lập được do thiếu file ROM tươ msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "Card đồ họa \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Hãy chọn card đồ họa khác." +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "Card đồ họa 2 \"%hs\" không giả lập được do thiếu file ROM tương ứng trong mục roms/video. Vô hiệu hóa card đồ họa thứ hai." + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "Thiết bị \"%hs\" không giả lập được do thiếu file ROM. Bỏ qua thiết bị." + msgid "Machine" msgstr "Mẫu máy" @@ -718,7 +727,7 @@ msgid "Other peripherals" msgstr "Thiết bị ngoại vi khác" msgid "Click to capture mouse" -msgstr "Bấm để capture ('nhốt') chuột vào" +msgstr "Nhấp vào khung hình để 'nhốt' chuột vào" msgid "Press %1 to release mouse" msgstr "Nhấn %1 để thả chuột" @@ -762,17 +771,26 @@ msgstr "Không tìm thấy thiết bị PCap" msgid "Invalid PCap device" msgstr "Thiết bị PCap không hợp quy" -msgid "Standard 2-button joystick(s)" -msgstr "Cần điều khiển hai nút tiêu chuẩn" +msgid "2-axis, 2-button joystick(s)" +msgstr "Cần điều khiển hai trục, hai nút" -msgid "Standard 4-button joystick" -msgstr "Cần điều khiển bốn nút tiêu chuẩn" +msgid "2-axis, 4-button joystick" +msgstr "Cần điều khiển hai trục, bốn nút" -msgid "Standard 6-button joystick" -msgstr "Cần điều khiển sáu nút tiêu chuẩn" +msgid "2-axis, 6-button joystick" +msgstr "Cần điều khiển hai trục, sáu nút" -msgid "Standard 8-button joystick" -msgstr "Cần điều khiển tám nút tiêu chuẩn" +msgid "2-axis, 8-button joystick" +msgstr "Cần điều khiển hai trục, tám nút" + +msgid "3-axis, 2-button joystick" +msgstr "Cần điều khiển ba trục, hai nút" + +msgid "3-axis, 4-button joystick" +msgstr "Cần điều khiển ba trục, bốn nút" + +msgid "4-axis, 4-button joystick" +msgstr "Cần điều khiển bốn trục, bốn nút" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "Bạn có muốn thoát 86Box?" msgid "Unable to initialize Ghostscript" msgstr "Không thể khởi tạo Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "Không thể khởi tạo GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "MO %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "Ảnh đĩa MO" msgid "Welcome to 86Box!" msgstr "Chào mừng đến 86Box!" -msgid "Internal controller" -msgstr "Vi điều khiển nội bộ" +msgid "Internal device" +msgstr "Thiết bị nội bộ" msgid "Exit" msgstr "Thoát" @@ -855,6 +876,9 @@ msgstr "Tinh chỉnh không hợp lý" 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 "Cần có %1 để tự động chuyển đổi file PostScript qua PDF.\n\nMọi tài liệu được đưa qua máy in generic PostScript sẽ lưu ở dạng 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 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" @@ -999,6 +1023,27 @@ msgstr "Có ghi đè" msgid "Don't overwrite" msgstr "Không ghi đè" +msgid "Raw image" +msgstr "Ảnh đĩa thô" + +msgid "HDI image" +msgstr "Ảnh đĩa HDI" + +msgid "HDX image" +msgstr "Ảnh đĩa HDX" + +msgid "Fixed-size VHD" +msgstr "Ảnh VHD kích thước cố định" + +msgid "Dynamic-size VHD" +msgstr "Ảnh VHD kích thước tăng dần" + +msgid "Differencing VHD" +msgstr "Ảnh VHD đa chủng (differencing)" + +msgid "(N/A)" +msgstr "(Không có)" + msgid "Raw image (.img)" msgstr "Ảnh đĩa thô (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "CD-ROM %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1172,3 +1217,915 @@ msgstr "WinBox không còn được hỗ trợ" 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 "Trình quản lý phiên WinBox đã bị dừng phát triển năm 2022 do thiếu nhân sự duy trì. Vì những quyết định để cho 86Box trở nên tốt hơn, chúng tôi đã không còn hỗ trợ trình quản lý WinBox.\n\n Sẽ không có bản cập nhật mới cho WinBox nữa, và nếu bạn tiếp tục sử dụng với các bản 86Box mới hơn có thể gặp lỗi. Bất kì các bản bug report liên quan đến lỗi của WinBox sẽ bị coi là không hợp lệ và bị đóng.\n\nTruy cập 86Box.net để tìm qua các trình quản lý phiên/manager khác cho phù hợp." + +msgid "Generate" +msgstr "Phát ra" + +msgid "Joystick configuration" +msgstr "Cấu hình cần điều khiển" + +msgid "Device" +msgstr "Thiết bị" + +msgid "%1 (X axis)" +msgstr "%1 (trục x)" + +msgid "%1 (Y axis)" +msgstr "%1 (trục y)" + +msgid "MCA devices" +msgstr "Thiết bị MCA" + +msgid "List of MCA devices:" +msgstr "Danh sách các thiết bị MCA:" + +msgid "Tablet tool" +msgstr "Công cụ máy tính bảng" + +msgid "Qt (OpenGL &ES)" +msgstr "QT (OpenGL &ES)" + +msgid "About Qt" +msgstr "Về qt" + +msgid "MCA devices..." +msgstr "Thiết bị MCA..." + +msgid "Show non-primary monitors" +msgstr "Hiển thị các màn hình phụ" + +msgid "Open screenshots folder..." +msgstr "Mở thư mục ảnh chụp màn hình..." + +msgid "Apply 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 "Pen" +msgstr "Cái bút" + +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" +msgstr "Xóa lịch sử ảnh đĩa" + +msgid "Create..." +msgstr "Tạo nên..." + +msgid "previous image" +msgstr "đĩa trước đó" + +msgid "Host CD/DVD Drive (%1)" +msgstr "Máy chủ CD/DVD Drive (%1)" + +msgid "Unknown Bus" +msgstr "Bus không xác định" + +msgid "Null Driver" +msgstr "Trình điều khiển NULL" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i ( %ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "Mở lỗi \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "Lỗi biên dịch shader đỉnh trong tệp \"%1\"" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "Lỗi biên dịch shader fragment trong tệp \"%1\"" + +msgid "Error linking shader program in file \"%1\"" +msgstr "Lỗi liên kết chương trình shader trong tệp \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "Tùy chọn kết xuất OpenGL 3.0" + +msgid "Render behavior" +msgstr "Hiện ra hành vi" + +msgid "Use target framerate:" +msgstr "Dùng số khung hình mục tiêu:" + +msgid " fps" +msgstr " khung hình / giây" + +msgid "VSync" +msgstr "Vsync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>Kết xuất mỗi khung ngay lập tức, đồng bộ với màn hình mô phỏng.</p><p><span style=" font-style:italic;">Đây là tùy chọn được đề xuất nếu các shader đang sử dụng không sử dụng hình chữ nhật cho các hiệu ứng hoạt hình.</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "Đồng bộ hóa với video" + +msgid "Shaders" +msgstr "Shaders" + +msgid "Remove" +msgstr "Di dời" + +msgid "No shader selected" +msgstr "Không có shader được chọn" + +msgid "Browse..." +msgstr "Duyệt..." + +msgid "Shader error" +msgstr "Lỗi shader" + +msgid "Could not load shaders." +msgstr "Không thể tải shader." + +msgid "More information in details." +msgstr "Thêm thông tin chi tiết." + +msgid "Couldn't create OpenGL context." +msgstr "Không thể tạo bối cảnh OpenGL." + +msgid "Couldn't switch to OpenGL context." +msgstr "Không thể chuyển sang bối cảnh OpenGL." + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "OpenGL phiên bản 3.0 trở lên là bắt buộc. Phiên bản hiện tại là %1. %2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "Khởi tạo OpenGL không thành công. Lỗi %1." + +msgid "Error initializing OpenGL" +msgstr "Lỗi khởi tạo OpenGL" + +msgid "Falling back to software rendering.\n" +msgstr "Rơi trở lại kết xuất phần mềm.\n" + +msgid "Allocating memory for unpack buffer failed.\n" +msgstr "Phân bổ bộ nhớ cho bộ đệm giải nén không thành công.\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>Khi chọn hình ảnh phương tiện (CD-ROM, FLOPPY, 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 "This machine might have been moved or copied." +msgstr "Máy này có thể đã được di chuyển hoặc sao chép." + +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 "Để đảm bảo chức năng kết nối mạng thích hợp, 86box cần biết liệu máy này có được di chuyển hay sao chép không.\n\nNếu bạn không chắc chắn, chọn \"Tôi đã sao chép nó\"." + +msgid "I Moved It" +msgstr "Tôi đã di chuyển nó" + +msgid "I Copied It" +msgstr "Tôi đã sao chép nó" + +msgid "86Box Monitor #" +msgstr "Màn hình 86box #" + +msgid "No MCA devices." +msgstr "Không có thiết bị MCA." + +msgid "MiB" +msgstr "Mib" + +msgid "Network Card #1" +msgstr "Thẻ mạng 1" + +msgid "Network Card #2" +msgstr "Thẻ mạng 2" + +msgid "Network Card #3" +msgstr "Thẻ mạng 3" + +msgid "Network Card #4" +msgstr "Thẻ mạng 4" + +msgid "Mode" +msgstr "Cách thức" + +msgid "Interface" +msgstr "Giao diện" + +msgid "Adapter" +msgstr "Bộ chuyển đổi" + +msgid "VDE Socket" +msgstr "Ổ cắm VDE" + +msgid "86Box Unit Tester" +msgstr "Người kiểm tra đơn vị 86box" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Thẻ khóa Novell Netware 2.x" + +msgid "Serial port passthrough 1" +msgstr "Thông qua cổng serial 1" + +msgid "Serial port passthrough 2" +msgstr "Thông qua cổng serial 2" + +msgid "Serial port passthrough 3" +msgstr "Thông qua cổng serial 3" + +msgid "Serial port passthrough 4" +msgstr "Thông qua cổng serial 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Hệ thống tầm nhìn LBA Enhancer" + +msgid "Renderer options..." +msgstr "Tùy chọn kết xuất ..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Chuột bus Logitech/Microsoft" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Chuột bus Microsoft (INPORT)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Chuột serial Mouse Systems" + +msgid "Microsoft Serial Mouse" +msgstr "Chuột serial Microsoft" + +msgid "Logitech Serial Mouse" +msgstr "Chuột serial Logitech" + +msgid "PS/2 Mouse" +msgstr "Chuột PS/2" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (Serial)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] Modem tuân thủ tiêu chuẩn Hayes" + +msgid "Roland MT-32 Emulation" +msgstr "Mô phỏng Roland MT-32" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Mô phỏng Roland MT-32 (mới)" + +msgid "Roland CM-32L Emulation" +msgstr "Mô phỏng Roland CM-32L" + +msgid "Roland CM-32LN Emulation" +msgstr "Mô phỏng Roland CM-32LN" + +msgid "OPL4-ML Daughterboard" +msgstr "Con gái OPL4-ML" + +msgid "System MIDI" +msgstr "MIDI của hệ thống" + +msgid "MIDI Input Device" +msgstr "Thiết bị nhập MIDI" + +msgid "BIOS Address" +msgstr "Địa chỉ BIOS" + +msgid "Enable BIOS extension ROM Writes" +msgstr "Bật ROM mở rộng BIOS" + +msgid "Address" +msgstr "Địa chỉ" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "Sửa đổi BIOS" + +msgid "Translate 26 -> 17" +msgstr "Dịch 26 -> 17" + +msgid "Language" +msgstr "Ngôn ngữ" + +msgid "Enable backlight" +msgstr "Bật đèn nền" + +msgid "Invert colors" +msgstr "Đảo ngược màu sắc" + +msgid "BIOS size" +msgstr "Kích thước BIOS" + +msgid "Map C0000-C7FFF as UMB" +msgstr "Bản đồ C0000-C7FFF dưới dạng UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "Bản đồ C8000-CFFFF dưới dạng UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "Bản đồ D0000-D7FFF dưới dạng UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "Bản đồ D8000-Dffff dưới dạng UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "Bản đồ E0000-E7FFF dưới dạng UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "Bản đồ e8000-effff dưới dạng umb" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 Jumper (Jim)" + +msgid "MIDI Output Device" +msgstr "Thiết bị đầu ra MIDI" + +msgid "MIDI Real time" +msgstr "MIDI trong thời gian thực" + +msgid "MIDI Thru" +msgstr "Thông qua đầu vào MIDI" + +msgid "MIDI Clockout" +msgstr "MIDI đồng hồ" + +msgid "SoundFont" +msgstr "Soundfont" + +msgid "Output Gain" +msgstr "Đầu ra tăng" + +msgid "Chorus" +msgstr "Điệp khúc" + +msgid "Chorus Voices" +msgstr "Tiếng nói của điệp khúc" + +msgid "Chorus Level" +msgstr "Cấp độ điệp khúc" + +msgid "Chorus Speed" +msgstr "Tốc độ điệp khúc" + +msgid "Chorus Depth" +msgstr "Độ sâu điệp khúc" + +msgid "Chorus Waveform" +msgstr "Dạng sóng điệp khúc" + +msgid "Reverb" +msgstr "Hồi âm" + +msgid "Reverb Room Size" +msgstr "Kích thước phòng hồi âm" + +msgid "Reverb Damping" +msgstr "Giảm chấn hồi âm" + +msgid "Reverb Width" +msgstr "Chiều rộng hồi âm" + +msgid "Reverb Level" +msgstr "Mức độ hồi âm" + +msgid "Interpolation Method" +msgstr "Phương pháp nội suy" + +msgid "Reverb Output Gain" +msgstr "Gợi ý đầu ra hồi âm" + +msgid "Reversed stereo" +msgstr "Đảo ngược âm thanh nổi" + +msgid "Nice ramp" +msgstr "Đoạn đường dốc đẹp" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "Nút" + +msgid "Serial Port" +msgstr "Cổng serial" + +msgid "RTS toggle" +msgstr "RT chuyển đổi" + +msgid "Revision" +msgstr "Ôn tập" + +msgid "Controller" +msgstr "Người điều khiển" + +msgid "Show Crosshair" +msgstr "Hiển thị hình chữ thập" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "Địa chỉ MAC" + +msgid "MAC Address OUI" +msgstr " OUI địa chỉ MAC" + +msgid "Enable BIOS" +msgstr "Bật BIOS" + +msgid "Baud Rate" +msgstr "Tốc độ baud" + +msgid "TCP/IP listening port" +msgstr "Cổng nghe TCP/IP" + +msgid "Phonebook File" +msgstr "Tệp danh bạ" + +msgid "Telnet emulation" +msgstr "Mô phỏng telnet" + +msgid "RAM Address" +msgstr "Địa chỉ RAM" + +msgid "RAM size" +msgstr "Kích thước ram" + +msgid "Initial RAM size" +msgstr "Kích thước ram ban đầu" + +msgid "Serial Number" +msgstr "Số seri" + +msgid "Host ID" +msgstr "ID máy chủ" + +msgid "FDC Address" +msgstr "Địa chỉ FDC" + +msgid "MPU-401 Address" +msgstr "Địa chỉ MPU-401" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "Nhận nhập MIDI" + +msgid "Low DMA" +msgstr "DMA thấp" + +msgid "Enable Game port" +msgstr "Bật cổng trò chơi" + +msgid "Surround module" +msgstr "Mô đun vòm" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "Tăng ngắt CODEC trên thiết lập CODEC (cần bởi một số trình điều khiển)" + +msgid "SB Address" +msgstr "Địa chỉ SB" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "Bật OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "Nhận nhập MIDI (MPU-401)" + +msgid "SB low DMA" +msgstr "SB DMA thấp" + +msgid "6CH variant (6-channel)" +msgstr "Biến thể 6CH (6 kênh)" + +msgid "Enable CMS" +msgstr "Bật CMS" + +msgid "Mixer" +msgstr "Máy trộn" + +msgid "High DMA" +msgstr "DMA cao" + +msgid "Control PC speaker" +msgstr "Kiểm soát loa PC" + +msgid "Memory size" +msgstr "Kích thước bộ nhớ" + +msgid "EMU8000 Address" +msgstr "Địa chỉ EMU8000" + +msgid "IDE Controller" +msgstr "Bộ điều khiển IDE" + +msgid "Codec" +msgstr "Codec" + +msgid "GUS type" +msgstr "Loại Gus" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "Bật lệnh 0x04 \" Thoát 86box \"" + +msgid "Display type" +msgstr "Loại hiển thị" + +msgid "Composite type" +msgstr "Loại tổng hợp" + +msgid "RGB type" +msgstr "Loại RGB" + +msgid "Line doubling type" +msgstr "Dòng nhân đôi" + +msgid "Snow emulation" +msgstr "Đun tuyết" + +msgid "Monitor type" +msgstr "Loại giám sát" + +msgid "Character set" +msgstr "Bộ ký tự" + +msgid "XGA type" +msgstr "Loại XGA" + +msgid "Instance" +msgstr "Ví dụ" + +msgid "MMIO Address" +msgstr "Địa chỉ MMIO" + +msgid "RAMDAC type" +msgstr "Loại Ramdac" + +msgid "Blend" +msgstr "Trộn" + +msgid "Bilinear filtering" +msgstr "Lọc song tuyến" + +msgid "Dithering" +msgstr "Ngân tán" + +msgid "Enable NMI for CGA emulation" +msgstr "Bật NMI cho mô phỏng CGA" + +msgid "Voodoo type" +msgstr "Loại voodoo" + +msgid "Framebuffer memory size" +msgstr "Kích thước bộ nhớ FRAMEBUFFER" + +msgid "Texture memory size" +msgstr "Kích thước bộ nhớ kết cấu" + +msgid "Dither subtraction" +msgstr "Phân biệt trừ" + +msgid "Screen Filter" +msgstr "Bộ lọc màn hình" + +msgid "Render threads" +msgstr "Kết xuất chủ đề" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "Địa chỉ bắt đầu" + +msgid "Contiguous Size" +msgstr "Kích thước tiếp giáp" + +msgid "I/O Width" +msgstr "Chiều rộng I/O" + +msgid "Transfer Speed" +msgstr "Tốc độ chuyển" + +msgid "EMS mode" +msgstr "Chế độ EMS" + +msgid "Address for > 2 MB" +msgstr "Địa chỉ cho> 2 MB" + +msgid "Frame Address" +msgstr "Địa chỉ khung" + +msgid "USA" +msgstr "Hoa Kỳ" + +msgid "Danish" +msgstr "Đan Mạch" + +msgid "Always at selected speed" +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 bài đăng)" + +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 "Sine" +msgstr "Sin" + +msgid "Triangle" +msgstr "Tam giác" + +msgid "Linear" +msgstr "Tuyến tính" + +msgid "4th Order" +msgstr "Thứ tự thứ 4" + +msgid "7th Order" +msgstr "Thứ tự thứ 7" + +msgid "Non-timed (original)" +msgstr "Không đúng lúc (bản gốc)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 không dân cư)" + +msgid "Two" +msgstr "Hai" + +msgid "Three" +msgstr "Ba" + +msgid "Wheel" +msgstr "Bánh xe" + +msgid "Five + Wheel" +msgstr "Năm + bánh xe" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 Serial / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) Serial" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "Vô hiệu hóa BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "Sigmatel Stac9721T (âm thanh nổi)" + +msgid "Classic" +msgstr "Cổ điển" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "Tổng hợp" + +msgid "Old" +msgstr "Cũ" + +msgid "New" +msgstr "Mới" + +msgid "Color (generic)" +msgstr "Màu (chung)" + +msgid "Green Monochrome" +msgstr "Đơn sắc màu xanh lá cây" + +msgid "Amber Monochrome" +msgstr "Đơn sắc màu hổ phách" + +msgid "Gray Monochrome" +msgstr "Đơn sắc màu xám" + +msgid "Color (no brown)" +msgstr "Màu (không có màu nâu)" + +msgid "Color (IBM 5153)" +msgstr "Màu sắc (IBM 5153)" + +msgid "Simple doubling" +msgstr "Nhân đôi đơn giản" + +msgid "sRGB interpolation" +msgstr "Nội suy SRGB" + +msgid "Linear interpolation" +msgstr "Nội suy tuyến tính" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "Đơn sắc (5151/MDA) (Trắng)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "Đơn sắc (5151/MDA) (màu xanh lá cây)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "Đơn sắc (5151/MDA) (Amber)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "Màu 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "Màu 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "Màu sắc nâng cao - Chế độ bình thường (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "Màu sắc nâng cao - Chế độ nâng cao (5154/ECD)" + +msgid "Green" +msgstr "Màu xanh lá cây" + +msgid "Amber" +msgstr "Màu hổ phách" + +msgid "Gray" +msgstr "Màu xám" + +msgid "Color" +msgstr "Màu sắc" + +msgid "U.S. English" +msgstr "Tiếng Anh Hoa Kỳ" + +msgid "Scandinavian" +msgstr "Scandinavia" + +msgid "Other languages" +msgstr "Các ngôn ngữ khác" + +msgid "Bochs latest" +msgstr "Bochs mới nhất" + +msgid "Mono Non-Interlaced" +msgstr "Đơn sắc không được xen kẽ" + +msgid "Color Interlaced" +msgstr "Màu sắc xen kẽ" + +msgid "Color Non-Interlaced" +msgstr "Màu sắc không được xen kẽ" + +msgid "3Dfx Voodoo Graphics" +msgstr "Đồ họa 3Dfx Voodoo" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8 bit" + +msgid "16-bit" +msgstr "16 bit" + +msgid "Standard (150ns)" +msgstr "Tiêu chuẩn (150ns)" + +msgid "High-Speed (120ns)" +msgstr "Tốc độ cao (120ns)" + +msgid "Enabled" +msgstr "Đã bật" + +msgid "Standard" +msgstr "Tiêu chuẩn" + +msgid "High-Speed" +msgstr "Tốc độ cao" + +msgid "Stereo LPT DAC" +msgstr "STEREO LPT DAC" + +msgid "Generic Text Printer" +msgstr "Máy in generic văn bản" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "Máy in generic ESC/P ma trận chấm" + +msgid "Generic PostScript Printer" +msgstr "Máy in generic PostScript" + +msgid "Generic PCL5e Printer" +msgstr "Máy in generic PCL5E" + +msgid "Parallel Line Internet Protocol" +msgstr "Parallel Line Internet Protocol" + +msgid "Protection Dongle for Savage Quest" +msgstr "Bảo vệ dongle cho Savage Quest" + +msgid "Serial Passthrough Device" +msgstr "Thiết bị thông qua cổng serial" + +msgid "Passthrough Mode" +msgstr "Chế độ thông qua" + +msgid "Host Serial Device" +msgstr "Thiết bị serial máy chủ" + +msgid "Name of pipe" +msgstr "Tên của đường ống" + +msgid "Data bits" +msgstr "Bit dữ liệu" + +msgid "Stop bits" +msgstr "Dừng bit" + +msgid "Baud Rate of Passthrough" +msgstr "Tốc độ baud của qua đường" + +msgid "Named Pipe (Server)" +msgstr "Đường ống được đặt tên (máy chủ)" + +msgid "Host Serial Passthrough" +msgstr "Thông qua cổng serial của máy chủ" + +msgid "Eject %s" +msgstr "Đẩy đĩa ra %s" + +msgid "&Unmute" +msgstr "&Không quay được" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "Tác động cao đến hiệu suất" + +msgid "RAM Disk (max. speed)" +msgstr "Đĩa RAM (Tối đa. Tốc độ)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A dòng vô tính (ISA)" + +msgid "Vendor" +msgstr "Nhà sản xuất" + +msgid "Generic PC/XT Memory Expansion" +msgstr "Chung mở rộng bộ nhớ qua PC/XT" + +msgid "Generic PC/AT Memory Expansion" +msgstr "Chung mở rộng bộ nhớ qua PC/AT" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index c8bd8f7bd..81451b2b3 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -390,14 +390,17 @@ msgstr "动态重编译器" msgid "Video:" msgstr "显卡:" -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" +msgid "Video #2:" +msgstr "显卡 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 或 2 图形" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" +msgstr "IBM 8514/A 图形" msgid "XGA Graphics" -msgstr "XGA Graphics" +msgstr "XGA 图形" msgid "Mouse:" msgstr "鼠标:" @@ -684,6 +687,12 @@ msgstr "由于 roms/machines 文件夹中缺少合适的 ROM,机型 \"%hs\" msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "由于 roms/video 文件夹中缺少合适的 ROM,显卡 \"%hs\" 不可用。将切换到其他可用显卡。" +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "由于 roms/video 文件夹中缺少合适的 ROM,显卡 2 \"%hs\" 不可用。禁用第二块显卡。" + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "由于缺少合适的 ROM,设备 \"%hs\" 不可用。忽略设备。" + msgid "Machine" msgstr "机型" @@ -762,17 +771,26 @@ msgstr "未找到 PCap 设备" msgid "Invalid PCap device" msgstr "无效 PCap 设备" -msgid "Standard 2-button joystick(s)" -msgstr "标准 2 键操纵杆" +msgid "2-axis, 2-button joystick(s)" +msgstr "2 轴, 2 键操纵杆" -msgid "Standard 4-button joystick" -msgstr "标准 4 键操纵杆" +msgid "2-axis, 4-button joystick" +msgstr "2 轴, 4 键操纵杆" -msgid "Standard 6-button joystick" -msgstr "标准 6 键操纵杆" +msgid "2-axis, 6-button joystick" +msgstr "2 轴, 6 键操纵杆" -msgid "Standard 8-button joystick" -msgstr "标准 8 键操纵杆" +msgid "2-axis, 8-button joystick" +msgstr "2 轴, 8 键操纵杆" + +msgid "3-axis, 2-button joystick" +msgstr "3 轴, 2 键操纵杆" + +msgid "3-axis, 4-button joystick" +msgstr "3 轴, 4 键操纵杆" + +msgid "4-axis, 4-button joystick" +msgstr "4 轴, 4 键操纵杆" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "确定要退出 86Box 吗?" msgid "Unable to initialize Ghostscript" msgstr "无法初始化 Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "无法初始化 GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "磁光盘 %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "磁光盘映像" msgid "Welcome to 86Box!" msgstr "欢迎使用 86Box!" -msgid "Internal controller" -msgstr "内部控制器" +msgid "Internal device" +msgstr "内部设备" msgid "Exit" msgstr "退出" @@ -841,7 +862,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 "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" +msgstr "一个旧式计算机模拟器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\n感谢 Sarah Walker、leilei、JohnElliott、greatpsycho 和其他人的核心贡献。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" msgid "Hardware not available" msgstr "硬件不可用" @@ -855,6 +876,9 @@ msgstr "无效配置" 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 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 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 Language (.pcl) files." +msgstr "%1 是将 PCL 文件转换为 PDF 所需要的库。\n\n使用通用 PCL 打印机打印的文档将被保存为 Printer Command Language (.pcl) 文件。" + msgid "Entering fullscreen mode" msgstr "正在进入全屏模式" @@ -999,6 +1023,27 @@ msgstr "覆盖" msgid "Don't overwrite" msgstr "不覆盖" +msgid "Raw image" +msgstr "原始映像" + +msgid "HDI image" +msgstr "HDI 映像" + +msgid "HDX image" +msgstr "HDX 映像" + +msgid "Fixed-size VHD" +msgstr "固定大小 VHD" + +msgid "Dynamic-size VHD" +msgstr "动态大小 VHD" + +msgid "Differencing VHD" +msgstr "差分 VHD" + +msgid "(N/A)" +msgstr "(不适用)" + msgid "Raw image (.img)" msgstr "原始映像 (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "光盘 %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1147,7 +1192,7 @@ msgid "The network configuration will be switched to the null driver" msgstr "网络配置将切换为空驱动程序" msgid "Mouse sensitivity:" -msgstr "鼠标敏感度:" +msgstr "鼠标灵敏度:" msgid "Select media images from program working directory" msgstr "从程序工作目录中选择介质映像" @@ -1172,3 +1217,915 @@ msgstr "WinBox 不再受支持" 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 管理器的开发工作于 2022 年停止。由于我们正努力将 86Box 做得更好,因此决定不再支持 WinBox 作为管理器。\n\nWinBox将不再提供更新,如果你继续在86Box的新版本中使用WinBox,可能会遇到不正确的行为。任何与 WinBox 行为相关的错误报告都将被视为无效而关闭。\n\n请访问 86box.net,查看你可以使用的其他管理器列表。" + +msgid "Generate" +msgstr "生成" + +msgid "Joystick configuration" +msgstr "操纵杆配置" + +msgid "Device" +msgstr "设备" + +msgid "%1 (X axis)" +msgstr "%1(X 轴)" + +msgid "%1 (Y axis)" +msgstr "%1(Y 轴)" + +msgid "MCA devices" +msgstr "MCA 设备" + +msgid "List of MCA devices:" +msgstr "MCA 设备清单:" + +msgid "Tablet tool" +msgstr "平板工具" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt(OpenGL &ES)" + +msgid "About Qt" +msgstr "关于 Qt" + +msgid "MCA devices..." +msgstr "MCA 设备..." + +msgid "Show non-primary monitors" +msgstr "显示非主要显示器" + +msgid "Open screenshots folder..." +msgstr "打开屏幕截图文件夹..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "最大化时应用全屏拉伸模式" + +msgid "Cursor/Puck" +msgstr "光标/冰球" + +msgid "Pen" +msgstr "笔" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "主机 CD/DVD 驱动器 (%1:)" + +msgid "&Connected" +msgstr "&Connected" + +msgid "Clear image history" +msgstr "清除映像历史记录" + +msgid "Create..." +msgstr "创建..." + +msgid "previous image" +msgstr "上一张" + +msgid "Host CD/DVD Drive (%1)" +msgstr "主机 CD/DVD 驱动器 (%1)" + +msgid "Unknown Bus" +msgstr "未知总线" + +msgid "Null Driver" +msgstr "空驱动程序" + +msgid "NIC %02i (%ls) %ls" +msgstr "NIC %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "打开 \"%1\": %2 时出错" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "文件 \"%1\" 中的顶点着色器编译出错" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "文件 \"%1\" 中的片段着色器编译出错" + +msgid "Error linking shader program in file \"%1\"" +msgstr "文件 \"%1\" 中的着色器程序链接出错" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 渲染器选项" + +msgid "Render behavior" +msgstr "渲染行为" + +msgid "Use target framerate:" +msgstr "使用目标帧率:" + +msgid " fps" +msgstr " fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>与模拟显示同步,即时渲染每一帧。</p><p><span style=" font-style:italic;">如果使用的着色器不使用帧时间来产生动画效果,则建议使用此选项。</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "与视频同步" + +msgid "Shaders" +msgstr "着色器" + +msgid "Remove" +msgstr "移除" + +msgid "No shader selected" +msgstr "未选择着色器" + +msgid "Browse..." +msgstr "浏览..." + +msgid "Shader error" +msgstr "着色器错误" + +msgid "Could not load shaders." +msgstr "无法加载着色器。" + +msgid "More information in details." +msgstr "更多详细信息。" + +msgid "Couldn't create OpenGL context." +msgstr "无法创建 OpenGL 上下文。" + +msgid "Couldn't switch to OpenGL context." +msgstr "无法切换到 OpenGL 上下文。" + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "需要 OpenGL 3.0 或更高版本。当前版本为 %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL 初始化失败。错误 %1." + +msgid "Error initializing OpenGL" +msgstr "初始化 OpenGL 时出错" + +msgid "Falling back to software rendering.\n" +msgstr "回到软件渲染。" + +msgid "Allocating memory for unpack buffer failed.\n" +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 "This machine might have been moved or copied." +msgstr "这台机器可能被移动或复制过。" + +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 "为了确保网络功能正常,86Box需要知道这台机器是否被移动或复制。\n\n如果您不确定,请选择\"我已复制这台机器\"。" + +msgid "I Moved It" +msgstr "我已移动这台机器" + +msgid "I Copied It" +msgstr "我已复制这台机器" + +msgid "86Box Monitor #" +msgstr "86Box 监测器 " + +msgid "No MCA devices." +msgstr "无 MCA 设备。" + +msgid "MiB" +msgstr "兆字节" + +msgid "Network Card #1" +msgstr "网卡 1" + +msgid "Network Card #2" +msgstr "网卡 2" + +msgid "Network Card #3" +msgstr "网卡 3" + +msgid "Network Card #4" +msgstr "网卡 4" + +msgid "Mode" +msgstr "模式" + +msgid "Interface" +msgstr "界面" + +msgid "Adapter" +msgstr "适配器" + +msgid "VDE Socket" +msgstr "VDE 套接字" + +msgid "86Box Unit Tester" +msgstr "86Box 装置测试仪" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x 密钥卡" + +msgid "Serial port passthrough 1" +msgstr "串行端口直通 1" + +msgid "Serial port passthrough 2" +msgstr "串行端口直通 2" + +msgid "Serial port passthrough 3" +msgstr "串行端口直通 3" + +msgid "Serial port passthrough 4" +msgstr "串行端口直通 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA 增强器" + +msgid "Renderer options..." +msgstr "渲染器选项..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft 总线鼠标" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft 总线鼠标(InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems 串行鼠标" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft 串行鼠标" + +msgid "Logitech Serial Mouse" +msgstr "Logitech 串行鼠标" + +msgid "PS/2 Mouse" +msgstr "PS/2 鼠标" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (串行)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] 标准 Hayes 兼容调制解调器" + +msgid "Roland MT-32 Emulation" +msgstr "Roland MT-32 仿真" + +msgid "Roland MT-32 (New) Emulation" +msgstr "Roland MT-32(新)仿真" + +msgid "Roland CM-32L Emulation" +msgstr "Roland CM-32L 仿真" + +msgid "Roland CM-32LN Emulation" +msgstr "Roland CM-32LN 仿真" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML 子板" + +msgid "System MIDI" +msgstr "系统 MIDI" + +msgid "MIDI Input Device" +msgstr "MIDI 输入设备" + +msgid "BIOS Address" +msgstr "BIOS 地址" + +msgid "Enable BIOS extension ROM Writes" +msgstr "启用 BIOS 扩展 ROM 写入功能" + +msgid "Address" +msgstr "地址" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS 修订版" + +msgid "Translate 26 -> 17" +msgstr "翻译 26 -> 17" + +msgid "Language" +msgstr "语言" + +msgid "Enable backlight" +msgstr "启用背光" + +msgid "Invert colors" +msgstr "反转颜色" + +msgid "BIOS size" +msgstr "BIOS 大小" + +msgid "Map C0000-C7FFF as UMB" +msgstr "将 C0000-C7FFF 映射为 UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "将 C8000-CFFFF 映射为 UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "将 D0000-D7FFF 映射为 UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "将 D8000-DFFFF 映射为 UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "将 E0000-E7FFF 映射为 UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "将 E8000-EFFFF 映射为 UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 跳线 (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI 输出设备" + +msgid "MIDI Real time" +msgstr "实时 MIDI" + +msgid "MIDI Thru" +msgstr "MIDI 输入直通" + +msgid "MIDI Clockout" +msgstr "MIDI 时钟输出" + +msgid "SoundFont" +msgstr "声音字体" + +msgid "Output Gain" +msgstr "输出增益" + +msgid "Chorus" +msgstr "合唱" + +msgid "Chorus Voices" +msgstr "合唱声部" + +msgid "Chorus Level" +msgstr "合唱音量" + +msgid "Chorus Speed" +msgstr "合唱速度" + +msgid "Chorus Depth" +msgstr "合唱深度" + +msgid "Chorus Waveform" +msgstr "合唱波形" + +msgid "Reverb" +msgstr "混响" + +msgid "Reverb Room Size" +msgstr "混响室的大小" + +msgid "Reverb Damping" +msgstr "混响阻尼" + +msgid "Reverb Width" +msgstr "混响宽度" + +msgid "Reverb Level" +msgstr "混响电平" + +msgid "Interpolation Method" +msgstr "插值法" + +msgid "Reverb Output Gain" +msgstr "混响输出的增益" + +msgid "Reversed stereo" +msgstr "反转立体声" + +msgid "Nice ramp" +msgstr "漂亮的斜坡" + +msgid "Hz" +msgstr "Hz" + +msgid "Buttons" +msgstr "按钮" + +msgid "Serial Port" +msgstr "串行端口" + +msgid "RTS toggle" +msgstr "RTS 切换" + +msgid "Revision" +msgstr "修订" + +msgid "Controller" +msgstr "控制器" + +msgid "Show Crosshair" +msgstr "显示十字准线" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC 地址" + +msgid "MAC Address OUI" +msgstr "MAC 地址的 OUI" + +msgid "Enable BIOS" +msgstr "启用 BIOS" + +msgid "Baud Rate" +msgstr "波特率" + +msgid "TCP/IP listening port" +msgstr "TCP/IP 监听端口" + +msgid "Phonebook File" +msgstr "电话簿文件" + +msgid "Telnet emulation" +msgstr "Telnet 仿真" + +msgid "RAM Address" +msgstr "内存地址" + +msgid "RAM size" +msgstr "内存大小" + +msgid "Initial RAM size" +msgstr "初始 RAM 大小" + +msgid "Serial Number" +msgstr "序列号" + +msgid "Host ID" +msgstr "主机 ID" + +msgid "FDC Address" +msgstr "FDC 地址" + +msgid "MPU-401 Address" +msgstr "MPU-401 地址" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "接收 MIDI 输入" + +msgid "Low DMA" +msgstr "低 DMA" + +msgid "Enable Game port" +msgstr "启用游戏端口" + +msgid "Surround module" +msgstr "环绕声模块" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "在 CODEC 设置时引发 CODEC 中断(某些驱动程序需要)。" + +msgid "SB Address" +msgstr "SB 地址" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "启用 OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "接收 MIDI 输入(MPU-401)" + +msgid "SB low DMA" +msgstr "SB 低 DMA" + +msgid "6CH variant (6-channel)" +msgstr "6 通道变体(6 通道)" + +msgid "Enable CMS" +msgstr "启用 CMS" + +msgid "Mixer" +msgstr "混合器" + +msgid "High DMA" +msgstr "高 DMA" + +msgid "Control PC speaker" +msgstr "控制电脑扬声器" + +msgid "Memory size" +msgstr "内存大小" + +msgid "EMU8000 Address" +msgstr "EMU8000 地址" + +msgid "IDE Controller" +msgstr "IDE 控制器" + +msgid "Codec" +msgstr "编解码器" + +msgid "GUS type" +msgstr "GUS 类型" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "启用命令 0x04 \"退出 86Box\"" + +msgid "Display type" +msgstr "显示类型" + +msgid "Composite type" +msgstr "复合视频类型" + +msgid "RGB type" +msgstr "RGB 类型" + +msgid "Line doubling type" +msgstr "线路倍增类型" + +msgid "Snow emulation" +msgstr "雪花模拟" + +msgid "Monitor type" +msgstr "显示器类型" + +msgid "Character set" +msgstr "字符集" + +msgid "XGA type" +msgstr "XGA 类型" + +msgid "Instance" +msgstr "实例" + +msgid "MMIO Address" +msgstr "MMIO 地址" + +msgid "RAMDAC type" +msgstr "RAMDAC 类型" + +msgid "Blend" +msgstr "混合" + +msgid "Bilinear filtering" +msgstr "双线性滤波" + +msgid "Dithering" +msgstr "抖动" + +msgid "Enable NMI for CGA emulation" +msgstr "为 CGA 仿真启用 NMI" + +msgid "Voodoo type" +msgstr "巫毒类型" + +msgid "Framebuffer memory size" +msgstr "帧缓冲区内存大小" + +msgid "Texture memory size" +msgstr "纹理内存大小" + +msgid "Dither subtraction" +msgstr "抖动减法" + +msgid "Screen Filter" +msgstr "滤镜" + +msgid "Render threads" +msgstr "渲染线程" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "起始地址" + +msgid "Contiguous Size" +msgstr "连续大小" + +msgid "I/O Width" +msgstr "输入/输出宽度" + +msgid "Transfer Speed" +msgstr "传输速度" + +msgid "EMS mode" +msgstr "EMS (扩展内存)模式" + +msgid "Address for > 2 MB" +msgstr "地址 > 2 MB" + +msgid "Frame Address" +msgstr "帧地址" + +msgid "USA" +msgstr "美国" + +msgid "Danish" +msgstr "丹麦语" + +msgid "Always at selected speed" +msgstr "始终保持选定速度" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "BIOS 设置 + 热键 (开机自检期间关闭)" + +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 "Sine" +msgstr "正弦" + +msgid "Triangle" +msgstr "三角" + +msgid "Linear" +msgstr "线性" + +msgid "4th Order" +msgstr "四阶" + +msgid "7th Order" +msgstr "七阶" + +msgid "Non-timed (original)" +msgstr "没有计时器 (原版)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 上无跳线)" + +msgid "Two" +msgstr "两键" + +msgid "Three" +msgstr "三键" + +msgid "Wheel" +msgstr "滚轮" + +msgid "Five + Wheel" +msgstr "五键+滚轮" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 串行 / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R)串行" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "禁用 BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (立体声)" + +msgid "Classic" +msgstr "经典" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "复合视频" + +msgid "Old" +msgstr "旧" + +msgid "New" +msgstr "新" + +msgid "Color (generic)" +msgstr "彩色(通用)" + +msgid "Green Monochrome" +msgstr "单色绿色" + +msgid "Amber Monochrome" +msgstr "琥珀单色" + +msgid "Gray Monochrome" +msgstr "灰色单色" + +msgid "Color (no brown)" +msgstr "彩色(无棕色)" + +msgid "Color (IBM 5153)" +msgstr "彩色(IBM 5153)" + +msgid "Simple doubling" +msgstr "简单加倍" + +msgid "sRGB interpolation" +msgstr "sRGB 插值" + +msgid "Linear interpolation" +msgstr "线性插值" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "单色(5151/MDA)(白色)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "单色(5151/MDA)(绿色)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "单色 (5151/MDA)(琥珀色)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "彩色 40x25(5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "彩色 80x25(5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "增强色彩 - 正常模式 (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "增强色彩 - 增强模式 (5154/ECD)" + +msgid "Green" +msgstr "绿色" + +msgid "Amber" +msgstr "琥珀色" + +msgid "Gray" +msgstr "灰色" + +msgid "Color" +msgstr "彩色" + +msgid "U.S. English" +msgstr "美国英语" + +msgid "Scandinavian" +msgstr "斯堪的纳维亚语系" + +msgid "Other languages" +msgstr "其他语言" + +msgid "Bochs latest" +msgstr "Bochs 最新版本" + +msgid "Mono Non-Interlaced" +msgstr "单色非隔行扫描" + +msgid "Color Interlaced" +msgstr "彩色隔行扫描" + +msgid "Color Non-Interlaced" +msgstr "彩色非隔行扫描" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx Voodoo 图形" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst(2 个 TMU)" + +msgid "8-bit" +msgstr "8 位" + +msgid "16-bit" +msgstr "16 位" + +msgid "Standard (150ns)" +msgstr "标准 (150ns)" + +msgid "High-Speed (120ns)" +msgstr "高速 (120ns)" + +msgid "Enabled" +msgstr "已启用" + +msgid "Standard" +msgstr "标准" + +msgid "High-Speed" +msgstr "高速" + +msgid "Stereo LPT DAC" +msgstr "立体声 LPT DAC" + +msgid "Generic Text Printer" +msgstr "通用文本打印机" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "通用 ESC/P 点阵打印机" + +msgid "Generic PostScript Printer" +msgstr "通用 PostScript 打印机" + +msgid "Generic PCL5e Printer" +msgstr "通用 PCL5e 打印机" + +msgid "Parallel Line Internet Protocol" +msgstr "Parallel Line Internet Protocol" + +msgid "Protection Dongle for Savage Quest" +msgstr "Savage Quest保护加密狗" + +msgid "Serial Passthrough Device" +msgstr "串行端口直通设备" + +msgid "Passthrough Mode" +msgstr "直通模式" + +msgid "Host Serial Device" +msgstr "主机串行设备" + +msgid "Name of pipe" +msgstr "管道名称" + +msgid "Data bits" +msgstr "数据位" + +msgid "Stop bits" +msgstr "停止位" + +msgid "Baud Rate of Passthrough" +msgstr "直通波特率" + +msgid "Named Pipe (Server)" +msgstr "命名管道(服务器)" + +msgid "Host Serial Passthrough" +msgstr "主机串行端口直通" + +msgid "Eject %s" +msgstr "弹出 %s" + +msgid "&Unmute" +msgstr "解除静音(&U)" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "重大性能影响" + +msgid "RAM Disk (max. speed)" +msgstr "RAM 磁盘 (最大速度)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A 克隆 (ISA)" + +msgid "Vendor" +msgstr "制造商" + +msgid "Generic PC/XT Memory Expansion" +msgstr "通用 PC/XT 内存扩展" + +msgid "Generic PC/AT Memory Expansion" +msgstr "通用 PC/AT 内存扩展" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 3de6bf4c4..9bf8edfc6 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -256,7 +256,7 @@ msgid "&Folder..." msgstr "資料夾(&F)..." msgid "Target &framerate" -msgstr "目標幀率(&F)" +msgstr "目標影格速率(&F)" msgid "&Sync with video" msgstr "與視訊同步(&S)" @@ -390,8 +390,11 @@ msgstr "動態重編譯器" msgid "Video:" msgstr "顯示卡:" -msgid "Voodoo Graphics" -msgstr "Voodoo Graphics" +msgid "Video #2:" +msgstr "顯示卡 2:" + +msgid "Voodoo 1 or 2 Graphics" +msgstr "Voodoo 1 或 2 圖形" msgid "IBM 8514/A Graphics" msgstr "IBM 8514/A Graphics" @@ -684,6 +687,12 @@ msgstr "由於 roms/machines 資料夾中缺少合適的 ROM,機型 \"%hs\" msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card." msgstr "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 \"%hs\" 不可用。將切換到其他可用顯示卡。" +msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." +msgstr "由於 roms/video 資料夾中缺少合適的 ROM,顯示卡 2 \"%hs\" 不可用。禁用第二块显卡。" + +msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." +msgstr "由於缺少合適的 ROM,裝置 \"%hs\" 不可用。忽略设备。" + msgid "Machine" msgstr "機型" @@ -762,17 +771,26 @@ msgstr "未找到 PCap 裝置" msgid "Invalid PCap device" msgstr "無效 PCap 裝置" -msgid "Standard 2-button joystick(s)" -msgstr "標準 2 鍵搖桿" +msgid "2-axis, 2-button joystick(s)" +msgstr "2 軸, 2 鍵搖桿" -msgid "Standard 4-button joystick" -msgstr "標準 4 鍵搖桿" +msgid "2-axis, 4-button joystick" +msgstr "2 軸, 4 鍵搖桿" -msgid "Standard 6-button joystick" -msgstr "標準 6 鍵搖桿" +msgid "2-axis, 6-button joystick" +msgstr "2 軸, 6 鍵搖桿" -msgid "Standard 8-button joystick" -msgstr "標準 8 鍵搖桿" +msgid "2-axis, 8-button joystick" +msgstr "2 軸, 8 鍵搖桿" + +msgid "3-axis, 2-button joystick" +msgstr "3 軸, 2 鍵搖桿" + +msgid "3-axis, 4-button joystick" +msgstr "3 軸, 4 鍵搖桿" + +msgid "4-axis, 4-button joystick" +msgstr "4 軸, 4 鍵搖桿" msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" @@ -807,6 +825,9 @@ msgstr "確定要退出 86Box 嗎?" msgid "Unable to initialize Ghostscript" msgstr "無法初始化 Ghostscript" +msgid "Unable to initialize GhostPCL" +msgstr "無法初始化 GhostPCL" + msgid "MO %i (%ls): %ls" msgstr "磁光碟 %i (%ls): %ls" @@ -816,8 +837,8 @@ msgstr "磁光碟映像" msgid "Welcome to 86Box!" msgstr "歡迎使用 86Box!" -msgid "Internal controller" -msgstr "內部控制器" +msgid "Internal device" +msgstr "內部裝置" msgid "Exit" msgstr "退出" @@ -841,7 +862,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 "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" +msgstr "一個舊式電腦模擬器\n\n作者: Miran Grča (OBattler)、RichardG867、Jasmine Iwanek、TC1995、coldbrewed、Teemu Korhonen (Manaatti)、Joakim L. Gilje、Adrien Moulin (elyosh)、Daniel Balsom (gloriouscow)、Cacodemon345、Fred N. van Kempen (waltje)、Tiseno100、reenigne 等人。\n\n之前的核心貢獻來自 Sarah Walker、leilei、JohnElliott、greatpsycho 等人。\n\n本軟體依據 GNU 通用公共授權第二版或更新版本發布。詳情見 LICENSE 檔案。" msgid "Hardware not available" msgstr "硬體不可用" @@ -855,6 +876,9 @@ msgstr "無效設定" 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 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PostScript 印表機列印的文件將被儲存為 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 Language (.pcl) files." +msgstr "%1 是將 PCL 檔案轉換為 PDF 所需要的庫。\n\n使用通用 PCL 印表機列印的文件將被儲存為 Printer Command Language (.pcl) 檔案。" + msgid "Entering fullscreen mode" msgstr "正在進入全螢幕模式" @@ -999,6 +1023,27 @@ msgstr "覆蓋" msgid "Don't overwrite" msgstr "不覆蓋" +msgid "Raw image" +msgstr "原始映像" + +msgid "HDI image" +msgstr "HDI 映像" + +msgid "HDX image" +msgstr "HDX 映像" + +msgid "Fixed-size VHD" +msgstr "固定大小 VHD" + +msgid "Dynamic-size VHD" +msgstr "動態大小 VHD" + +msgid "Differencing VHD" +msgstr "差分 VHD" + +msgid "(N/A)" +msgstr "(不適用)" + msgid "Raw image (.img)" msgstr "原始映像 (.img)" @@ -1056,23 +1101,23 @@ msgstr "ATAPI" msgid "CD-ROM %i (%s): %s" msgstr "光碟 %i (%s): %s" -msgid "160 kB" -msgstr "160 kB" +msgid "160 KB" +msgstr "160 KB" -msgid "180 kB" -msgstr "180 kB" +msgid "180 KB" +msgstr "180 KB" -msgid "320 kB" -msgstr "320 kB" +msgid "320 KB" +msgstr "320 KB" -msgid "360 kB" -msgstr "360 kB" +msgid "360 KB" +msgstr "360 KB" -msgid "640 kB" -msgstr "640 kB" +msgid "640 KB" +msgstr "640 KB" -msgid "720 kB" -msgstr "720 kB" +msgid "720 KB" +msgstr "720 KB" msgid "1.2 MB" msgstr "1.2 MB" @@ -1153,7 +1198,7 @@ msgid "Select media images from program working directory" msgstr "從程式工作目錄中選擇介質映像" msgid "PIT mode:" -msgstr "PIT模式:" +msgstr "PIT 模式:" msgid "Auto" msgstr "自動" @@ -1172,3 +1217,915 @@ msgstr "WinBox is no longer supported" 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 behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." + +msgid "Generate" +msgstr "產生" + +msgid "Joystick configuration" +msgstr "搖桿設定" + +msgid "Device" +msgstr "裝置" + +msgid "%1 (X axis)" +msgstr "%1 (X 軸)" + +msgid "%1 (Y axis)" +msgstr "%1 (Y 軸)" + +msgid "MCA devices" +msgstr "MCA 裝置" + +msgid "List of MCA devices:" +msgstr "MCA 裝置清單:" + +msgid "Tablet tool" +msgstr "平板工具" + +msgid "Qt (OpenGL &ES)" +msgstr "Qt (OpenGL &ES)" + +msgid "About Qt" +msgstr "關於 Qt" + +msgid "MCA devices..." +msgstr "MCA 裝置..." + +msgid "Show non-primary monitors" +msgstr "顯示非主要顯示器" + +msgid "Open screenshots folder..." +msgstr "開啟螢幕截圖資料夾..." + +msgid "Apply fullscreen stretch mode when maximized" +msgstr "最大化時套用全螢幕拉伸模式" + +msgid "Cursor/Puck" +msgstr "游標/球棒" + +msgid "Pen" +msgstr "筆" + +msgid "Host CD/DVD Drive (%1:)" +msgstr "主機 CD/DVD 光碟機 (%1:)" + +msgid "&Connected" +msgstr "已連線" + +msgid "Clear image history" +msgstr "清除映像歷史記錄" + +msgid "Create..." +msgstr "建立..." + +msgid "previous image" +msgstr "上一個映像" + +msgid "Host CD/DVD Drive (%1)" +msgstr "主機 CD/DVD 光碟機 (%1)" + +msgid "Unknown Bus" +msgstr "未知匯流排" + +msgid "Null Driver" +msgstr "空驅動程式" + +msgid "NIC %02i (%ls) %ls" +msgstr "網路卡 %02i (%ls) %ls" + +msgid "Error opening \"%1\": %2" +msgstr "錯誤開啟 \"%1\": %2" + +msgid "Error compiling vertex shader in file \"%1\"" +msgstr "編譯檔案 \"%1\" 中的頂點著色器時發生錯誤" + +msgid "Error compiling fragment shader in file \"%1\"" +msgstr "編譯檔案 \"%1\" 中的片段著色器出錯" + +msgid "Error linking shader program in file \"%1\"" +msgstr "在檔案中連結shader程式出錯 \"%1\"" + +msgid "OpenGL 3.0 renderer options" +msgstr "OpenGL 3.0 渲染器選項" + +msgid "Render behavior" +msgstr "渲染行為" + +msgid "Use target framerate:" +msgstr "使用目標影格速率:" + +msgid " fps" +msgstr "fps" + +msgid "VSync" +msgstr "VSync" + +msgid "<html><head/><body><p>Render each frame immediately, in sync with the emulated display.</p><p><span style=" font-style:italic;">This is the recommended option if the shaders in use don't utilize frametime for animated effects.</span></p></body></html>" +msgstr "<html><head/><body><p>立即渲染每個畫面,與模擬顯示同步。</p><p><span style=" font-style:italic;">如果使用中的著色器不利用影格時間製作動畫效果,建議使用此選項。</span></p></body></html>" + +msgid "Synchronize with video" +msgstr "與視訊同步" + +msgid "Shaders" +msgstr "著色器" + +msgid "Remove" +msgstr "移除" + +msgid "No shader selected" +msgstr "未選擇著色器" + +msgid "Browse..." +msgstr "瀏覽..." + +msgid "Shader error" +msgstr "著色器錯誤" + +msgid "Could not load shaders." +msgstr "無法載入著色器。" + +msgid "More information in details." +msgstr "更多詳細資訊。" + +msgid "Couldn't create OpenGL context." +msgstr "無法建立 OpenGL 上下文。" + +msgid "Couldn't switch to OpenGL context." +msgstr "無法切換至 OpenGL 上下文。" + +msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" +msgstr "需要 OpenGL 版本 3.0 或更高。目前版本為 %1.%2" + +msgid "OpenGL initialization failed. Error %1." +msgstr "OpenGL 初始化失敗。錯誤 %1." + +msgid "Error initializing OpenGL" +msgstr "初始化 OpenGL 出錯" + +msgid "Falling back to software rendering.\n" +msgstr "回退到軟體渲染。" + +msgid "Allocating memory for unpack buffer failed.\n" +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 "This machine might have been moved or copied." +msgstr "這台機器可能已被移動或複製。" + +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 "為了確保正常的網路功能,86Box 需要知道這台機器是否被移動或複製。\n\n如果您不確定,請選擇「我已複製這台機器」。" + +msgid "I Moved It" +msgstr "我已移動這台機器" + +msgid "I Copied It" +msgstr "我已複製這台機器" + +msgid "86Box Monitor #" +msgstr "86Box Monitor " + +msgid "No MCA devices." +msgstr "沒有 MCA 裝置。" + +msgid "MiB" +msgstr "MiB" + +msgid "Network Card #1" +msgstr "網路卡 1" + +msgid "Network Card #2" +msgstr "網路卡 2" + +msgid "Network Card #3" +msgstr "網路卡 3" + +msgid "Network Card #4" +msgstr "網路卡 4" + +msgid "Mode" +msgstr "模式" + +msgid "Interface" +msgstr "介面" + +msgid "Adapter" +msgstr "配接器" + +msgid "VDE Socket" +msgstr "VDE 插座" + +msgid "86Box Unit Tester" +msgstr "86Box 單元測試器" + +msgid "Novell NetWare 2.x Key Card" +msgstr "Novell NetWare 2.x 密鑰卡" + +msgid "Serial port passthrough 1" +msgstr "序列埠的直通 1" + +msgid "Serial port passthrough 2" +msgstr "序列埠的直通 2" + +msgid "Serial port passthrough 3" +msgstr "序列埠的直通 3" + +msgid "Serial port passthrough 4" +msgstr "序列埠的直通 4" + +msgid "Vision Systems LBA Enhancer" +msgstr "Vision Systems LBA Enhancer" + +msgid "Renderer options..." +msgstr "渲染器選項..." + +msgid "Logitech/Microsoft Bus Mouse" +msgstr "Logitech/Microsoft 匯流排滑鼠" + +msgid "Microsoft Bus Mouse (InPort)" +msgstr "Microsoft 匯流排滑鼠 (InPort)" + +msgid "Mouse Systems Serial Mouse" +msgstr "Mouse Systems 序列滑鼠" + +msgid "Microsoft Serial Mouse" +msgstr "Microsoft 序列滑鼠" + +msgid "Logitech Serial Mouse" +msgstr "Logitech 序列滑鼠" + +msgid "PS/2 Mouse" +msgstr "PS/2 滑鼠" + +msgid "3M MicroTouch (Serial)" +msgstr "3M MicroTouch (序列)" + +msgid "[COM] Standard Hayes-compliant Modem" +msgstr "[COM] 標準 Hayes 相容的數據機" + +msgid "Roland MT-32 Emulation" +msgstr "羅蘭 MT-32 模擬" + +msgid "Roland MT-32 (New) Emulation" +msgstr "羅蘭 MT-32(新)模擬" + +msgid "Roland CM-32L Emulation" +msgstr "羅蘭 CM-32L 模擬" + +msgid "Roland CM-32LN Emulation" +msgstr "羅蘭 CM-32LN 模擬" + +msgid "OPL4-ML Daughterboard" +msgstr "OPL4-ML 子板" + +msgid "System MIDI" +msgstr "系統的 MIDI" + +msgid "MIDI Input Device" +msgstr "MIDI 輸入裝置" + +msgid "BIOS Address" +msgstr "BIOS 位址" + +msgid "Enable BIOS extension ROM Writes" +msgstr "啟用 BIOS 擴充 ROM 寫入" + +msgid "Address" +msgstr "位址" + +msgid "IRQ" +msgstr "IRQ" + +msgid "BIOS Revision" +msgstr "BIOS 版本" + +msgid "Translate 26 -> 17" +msgstr "轉換 26 -> 17" + +msgid "Language" +msgstr "語言" + +msgid "Enable backlight" +msgstr "啟用背光" + +msgid "Invert colors" +msgstr "反轉顏色" + +msgid "BIOS size" +msgstr "BIOS 大小" + +msgid "Map C0000-C7FFF as UMB" +msgstr "映射 C0000-C7FFF 為 UMB" + +msgid "Map C8000-CFFFF as UMB" +msgstr "映射 C8000-CFFFF 為 UMB" + +msgid "Map D0000-D7FFF as UMB" +msgstr "映射 D0000-D7FFF 為 UMB" + +msgid "Map D8000-DFFFF as UMB" +msgstr "映射 D8000-DFFFF 為 UMB" + +msgid "Map E0000-E7FFF as UMB" +msgstr "映射 E0000-E7FFF 為 UMB" + +msgid "Map E8000-EFFFF as UMB" +msgstr "映射 E8000-EFFFF 為 UMB" + +msgid "JS9 Jumper (JIM)" +msgstr "JS9 跳線 (JIM)" + +msgid "MIDI Output Device" +msgstr "MIDI 輸出裝置" + +msgid "MIDI Real time" +msgstr "實時 MIDI" + +msgid "MIDI Thru" +msgstr "MIDI 輸入直通" + +msgid "MIDI Clockout" +msgstr "MIDI 時鐘輸出" + +msgid "SoundFont" +msgstr "SoundFont" + +msgid "Output Gain" +msgstr "輸出增益" + +msgid "Chorus" +msgstr "合唱" + +msgid "Chorus Voices" +msgstr "合唱聲部" + +msgid "Chorus Level" +msgstr "合唱音量" + +msgid "Chorus Speed" +msgstr "合唱速度" + +msgid "Chorus Depth" +msgstr "合唱深度" + +msgid "Chorus Waveform" +msgstr "合唱波形" + +msgid "Reverb" +msgstr "混響" + +msgid "Reverb Room Size" +msgstr "混響室的大小" + +msgid "Reverb Damping" +msgstr "混響阻尼" + +msgid "Reverb Width" +msgstr "混響寬度" + +msgid "Reverb Level" +msgstr "混響電平" + +msgid "Interpolation Method" +msgstr "插值方法" + +msgid "Reverb Output Gain" +msgstr "迴響輸出增益" + +msgid "Reversed stereo" +msgstr "反向立體聲" + +msgid "Nice ramp" +msgstr "漂亮的斜坡" + +msgid "Hz" +msgstr "赫茲" + +msgid "Buttons" +msgstr "按鈕" + +msgid "Serial Port" +msgstr "串列埠" + +msgid "RTS toggle" +msgstr "RTS 切換" + +msgid "Revision" +msgstr "修訂" + +msgid "Controller" +msgstr "控制器" + +msgid "Show Crosshair" +msgstr "顯示十字線" + +msgid "DMA" +msgstr "DMA" + +msgid "MAC Address" +msgstr "MAC 位址" + +msgid "MAC Address OUI" +msgstr "MAC 位址的 OUI" + +msgid "Enable BIOS" +msgstr "啟用 BIOS" + +msgid "Baud Rate" +msgstr "鮑率" + +msgid "TCP/IP listening port" +msgstr "TCP/IP 監聽埠" + +msgid "Phonebook File" +msgstr "電話簿檔案" + +msgid "Telnet emulation" +msgstr "Telnet 模擬" + +msgid "RAM Address" +msgstr "RAM 位址" + +msgid "RAM size" +msgstr "RAM 大小" + +msgid "Initial RAM size" +msgstr "初始 RAM 大小" + +msgid "Serial Number" +msgstr "序列號" + +msgid "Host ID" +msgstr "主機 ID" + +msgid "FDC Address" +msgstr "FDC 位址" + +msgid "MPU-401 Address" +msgstr "MPU-401 位址" + +msgid "MPU-401 IRQ" +msgstr "MPU-401 IRQ" + +msgid "Receive MIDI input" +msgstr "接收 MIDI 輸入" + +msgid "Low DMA" +msgstr "低 DMA" + +msgid "Enable Game port" +msgstr "啟用遊戲埠" + +msgid "Surround module" +msgstr "環繞聲模組" + +msgid "CODEC" +msgstr "CODEC" + +msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" +msgstr "在 CODEC 設定時啟動 CODEC 中斷 (某些驅動程式需要)" + +msgid "SB Address" +msgstr "SB 位址" + +msgid "WSS IRQ" +msgstr "WSS IRQ" + +msgid "WSS DMA" +msgstr "WSS DMA" + +msgid "Enable OPL" +msgstr "啟用 OPL" + +msgid "Receive MIDI input (MPU-401)" +msgstr "接收 MIDI 輸入 (MPU-401)" + +msgid "SB low DMA" +msgstr "SB 低 DMA" + +msgid "6CH variant (6-channel)" +msgstr "6CH 變數 (6 通道)" + +msgid "Enable CMS" +msgstr "啟用 CMS" + +msgid "Mixer" +msgstr "混音器" + +msgid "High DMA" +msgstr "高 DMA" + +msgid "Control PC speaker" +msgstr "控制電腦喇叭" + +msgid "Memory size" +msgstr "記憶體大小" + +msgid "EMU8000 Address" +msgstr "EMU8000 位址" + +msgid "IDE Controller" +msgstr "IDE 控制器" + +msgid "Codec" +msgstr "編解碼器" + +msgid "GUS type" +msgstr "GUS 類型" + +msgid "Enable 0x04 \"Exit 86Box\" command" +msgstr "啟用 0x04 \"退出 86Box\" 指令" + +msgid "Display type" +msgstr "顯示類型" + +msgid "Composite type" +msgstr "複合視訊類型" + +msgid "RGB type" +msgstr "RGB 類型" + +msgid "Line doubling type" +msgstr "行倍增類型" + +msgid "Snow emulation" +msgstr "雪花模擬" + +msgid "Monitor type" +msgstr "顯示器類型" + +msgid "Character set" +msgstr "字元集" + +msgid "XGA type" +msgstr "XGA 類型" + +msgid "Instance" +msgstr "實例" + +msgid "MMIO Address" +msgstr "MMIO 位址" + +msgid "RAMDAC type" +msgstr "RAMDAC 類型" + +msgid "Blend" +msgstr "混合" + +msgid "Bilinear filtering" +msgstr "雙線性濾波" + +msgid "Dithering" +msgstr "抖動" + +msgid "Enable NMI for CGA emulation" +msgstr "啟用 CGA 模擬的 NMI" + +msgid "Voodoo type" +msgstr "Voodoo 類型" + +msgid "Framebuffer memory size" +msgstr "影格緩衝記憶體大小" + +msgid "Texture memory size" +msgstr "材質記憶體大小" + +msgid "Dither subtraction" +msgstr "抖動減法" + +msgid "Screen Filter" +msgstr "濾鏡" + +msgid "Render threads" +msgstr "渲染執行緒" + +msgid "SLI" +msgstr "SLI" + +msgid "Start Address" +msgstr "起始位址" + +msgid "Contiguous Size" +msgstr "連續大小" + +msgid "I/O Width" +msgstr "I/O 寬度" + +msgid "Transfer Speed" +msgstr "傳輸速度" + +msgid "EMS mode" +msgstr "EMS 模式" + +msgid "Address for > 2 MB" +msgstr "> 2 MB 的位址" + +msgid "Frame Address" +msgstr "影格位址" + +msgid "USA" +msgstr "美國" + +msgid "Danish" +msgstr "丹麥語" + +msgid "Always at selected speed" +msgstr "永遠以所選速度運作" + +msgid "BIOS setting + Hotkeys (off during POST)" +msgstr "BIOS 設定 + 熱鍵 (POST 期間關閉)" + +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 "Sine" +msgstr "正弦" + +msgid "Triangle" +msgstr "三角" + +msgid "Linear" +msgstr "線性" + +msgid "4th Order" +msgstr "四階" + +msgid "7th Order" +msgstr "七階" + +msgid "Non-timed (original)" +msgstr "非定時 (原始)" + +msgid "45 Hz (JMP2 not populated)" +msgstr "45 Hz (JMP2 未填充)" + +msgid "Two" +msgstr "二鍵" + +msgid "Three" +msgstr "三鍵" + +msgid "Wheel" +msgstr "滾輪" + +msgid "Five + Wheel" +msgstr "五鍵 + 滾輪" + +msgid "A3 - SMT2 Serial / SMT3(R)V" +msgstr "A3 - SMT2 序列 / SMT3(R)V" + +msgid "Q1 - SMT3(R) Serial" +msgstr "Q1 - SMT3(R) 序列" + +msgid "8 KB" +msgstr "8 KB" + +msgid "32 KB" +msgstr "32 KB" + +msgid "16 KB" +msgstr "16 KB" + +msgid "64 KB" +msgstr "64 KB" + +msgid "Disable BIOS" +msgstr "停用 BIOS" + +msgid "512 KB" +msgstr "512 KB" + +msgid "2 MB" +msgstr "2 MB" + +msgid "8 MB" +msgstr "8 MB" + +msgid "28 MB" +msgstr "28 MB" + +msgid "1 MB" +msgstr "1 MB" + +msgid "4 MB" +msgstr "4 MB" + +msgid "12 MB" +msgstr "12 MB" + +msgid "16 MB" +msgstr "16 MB" + +msgid "20 MB" +msgstr "20 MB" + +msgid "24 MB" +msgstr "24 MB" + +msgid "SigmaTel STAC9721T (stereo)" +msgstr "SigmaTel STAC9721T (立體聲)" + +msgid "Classic" +msgstr "經典" + +msgid "256 KB" +msgstr "256 KB" + +msgid "Composite" +msgstr "複合視訊" + +msgid "Old" +msgstr "舊" + +msgid "New" +msgstr "新" + +msgid "Color (generic)" +msgstr "彩色(通用)" + +msgid "Green Monochrome" +msgstr "綠色單色" + +msgid "Amber Monochrome" +msgstr "琥珀單色" + +msgid "Gray Monochrome" +msgstr "灰色單色" + +msgid "Color (no brown)" +msgstr "彩色(無棕色)" + +msgid "Color (IBM 5153)" +msgstr "彩色(IBM 5153)" + +msgid "Simple doubling" +msgstr "簡單加倍" + +msgid "sRGB interpolation" +msgstr "sRGB 插值" + +msgid "Linear interpolation" +msgstr "線性插補" + +msgid "128 KB" +msgstr "128 KB" + +msgid "Monochrome (5151/MDA) (white)" +msgstr "單色 (5151/MDA)(白色)" + +msgid "Monochrome (5151/MDA) (green)" +msgstr "單色 (5151/MDA)(綠色)" + +msgid "Monochrome (5151/MDA) (amber)" +msgstr "單色 (5151/MDA)(琥珀色)" + +msgid "Color 40x25 (5153/CGA)" +msgstr "彩色 40x25 (5153/CGA)" + +msgid "Color 80x25 (5153/CGA)" +msgstr "彩色 80x25 (5153/CGA)" + +msgid "Enhanced Color - Normal Mode (5154/ECD)" +msgstr "增強彩色 - 一般模式 (5154/ECD)" + +msgid "Enhanced Color - Enhanced Mode (5154/ECD)" +msgstr "增強彩色 - 增強模式 (5154/ECD)" + +msgid "Green" +msgstr "綠色" + +msgid "Amber" +msgstr "琥珀色" + +msgid "Gray" +msgstr "灰色" + +msgid "Color" +msgstr "顏色" + +msgid "U.S. English" +msgstr "美國英語" + +msgid "Scandinavian" +msgstr "斯堪的納維亞語" + +msgid "Other languages" +msgstr "其他語言" + +msgid "Bochs latest" +msgstr "Bochs 最新" + +msgid "Mono Non-Interlaced" +msgstr "單色非隔行掃描" + +msgid "Color Interlaced" +msgstr "彩色隔行扫描" + +msgid "Color Non-Interlaced" +msgstr "彩色非隔行掃描" + +msgid "3Dfx Voodoo Graphics" +msgstr "3Dfx Voodoo 圖形" + +msgid "Obsidian SB50 + Amethyst (2 TMUs)" +msgstr "Obsidian SB50 + Amethyst (2 TMU)" + +msgid "8-bit" +msgstr "8 位元" + +msgid "16-bit" +msgstr "16 位元" + +msgid "Standard (150ns)" +msgstr "標準 (150ns)" + +msgid "High-Speed (120ns)" +msgstr "高速 (120ns)" + +msgid "Enabled" +msgstr "啟用" + +msgid "Standard" +msgstr "標準" + +msgid "High-Speed" +msgstr "高速" + +msgid "Stereo LPT DAC" +msgstr "立體聲 LPT DAC" + +msgid "Generic Text Printer" +msgstr "通用文字印表機" + +msgid "Generic ESC/P Dot-Matrix Printer" +msgstr "通用 ESC/P 點矩陣" + +msgid "Generic PostScript Printer" +msgstr "通用 PostScript 印表機" + +msgid "Generic PCL5e Printer" +msgstr "通用 PCL5e 印表機" + +msgid "Parallel Line Internet Protocol" +msgstr "Parallel Line Internet Protocol" + +msgid "Protection Dongle for Savage Quest" +msgstr "用於 Savage Quest 的保護加密狗" + +msgid "Serial Passthrough Device" +msgstr "序列埠的直通裝置" + +msgid "Passthrough Mode" +msgstr "直通模式" + +msgid "Host Serial Device" +msgstr "主機串列裝置" + +msgid "Name of pipe" +msgstr "管道名稱" + +msgid "Data bits" +msgstr "資料位元" + +msgid "Stop bits" +msgstr "停止位元" + +msgid "Baud Rate of Passthrough" +msgstr "直通的鮑率" + +msgid "Named Pipe (Server)" +msgstr "已命名管道 (伺服器)" + +msgid "Host Serial Passthrough" +msgstr "主機序列埠的直通" + +msgid "Eject %s" +msgstr "退出 %s" + +msgid "&Unmute" +msgstr "解除靜音 (&U)" + +msgid "Softfloat FPU" +msgstr "Softfloat FPU" + +msgid "High performance impact" +msgstr "對效能影響大" + +msgid "RAM Disk (max. speed)" +msgstr "RAM 磁碟 (最大速度)" + +msgid "IBM 8514/A clone (ISA)" +msgstr "IBM 8514/A 克隆 (ISA)" + +msgid "Vendor" +msgstr "製造商" + +msgid "Generic PC/XT Memory Expansion" +msgstr "通用 PC/XT 記憶體擴充" + +msgid "Generic PC/AT Memory Expansion" +msgstr "通用 PC/AT 記憶體擴充" diff --git a/src/qt/qdarkstyle/dark/darkstyle.qrc b/src/qt/qdarkstyle/dark/darkstyle.qrc new file mode 100644 index 000000000..ce0d85be6 --- /dev/null +++ b/src/qt/qdarkstyle/dark/darkstyle.qrc @@ -0,0 +1,216 @@ + + + + rc/arrow_down.png + rc/arrow_down@2x.png + rc/arrow_down_disabled.png + rc/arrow_down_disabled@2x.png + rc/arrow_down_focus.png + rc/arrow_down_focus@2x.png + rc/arrow_down_pressed.png + rc/arrow_down_pressed@2x.png + rc/arrow_left.png + rc/arrow_left@2x.png + rc/arrow_left_disabled.png + rc/arrow_left_disabled@2x.png + rc/arrow_left_focus.png + rc/arrow_left_focus@2x.png + rc/arrow_left_pressed.png + rc/arrow_left_pressed@2x.png + rc/arrow_right.png + rc/arrow_right@2x.png + rc/arrow_right_disabled.png + rc/arrow_right_disabled@2x.png + rc/arrow_right_focus.png + rc/arrow_right_focus@2x.png + rc/arrow_right_pressed.png + rc/arrow_right_pressed@2x.png + rc/arrow_up.png + rc/arrow_up@2x.png + rc/arrow_up_disabled.png + rc/arrow_up_disabled@2x.png + rc/arrow_up_focus.png + rc/arrow_up_focus@2x.png + rc/arrow_up_pressed.png + rc/arrow_up_pressed@2x.png + rc/base_icon.png + rc/base_icon@2x.png + rc/base_icon_disabled.png + rc/base_icon_disabled@2x.png + rc/base_icon_focus.png + rc/base_icon_focus@2x.png + rc/base_icon_pressed.png + rc/base_icon_pressed@2x.png + rc/branch_closed.png + rc/branch_closed@2x.png + rc/branch_closed_disabled.png + rc/branch_closed_disabled@2x.png + rc/branch_closed_focus.png + rc/branch_closed_focus@2x.png + rc/branch_closed_pressed.png + rc/branch_closed_pressed@2x.png + rc/branch_end.png + rc/branch_end@2x.png + rc/branch_end_disabled.png + rc/branch_end_disabled@2x.png + rc/branch_end_focus.png + rc/branch_end_focus@2x.png + rc/branch_end_pressed.png + rc/branch_end_pressed@2x.png + rc/branch_line.png + rc/branch_line@2x.png + rc/branch_line_disabled.png + rc/branch_line_disabled@2x.png + rc/branch_line_focus.png + rc/branch_line_focus@2x.png + rc/branch_line_pressed.png + rc/branch_line_pressed@2x.png + rc/branch_more.png + rc/branch_more@2x.png + rc/branch_more_disabled.png + rc/branch_more_disabled@2x.png + rc/branch_more_focus.png + rc/branch_more_focus@2x.png + rc/branch_more_pressed.png + rc/branch_more_pressed@2x.png + rc/branch_open.png + rc/branch_open@2x.png + rc/branch_open_disabled.png + rc/branch_open_disabled@2x.png + rc/branch_open_focus.png + rc/branch_open_focus@2x.png + rc/branch_open_pressed.png + rc/branch_open_pressed@2x.png + rc/checkbox_checked.png + rc/checkbox_checked@2x.png + rc/checkbox_checked_disabled.png + rc/checkbox_checked_disabled@2x.png + rc/checkbox_checked_focus.png + rc/checkbox_checked_focus@2x.png + rc/checkbox_checked_pressed.png + rc/checkbox_checked_pressed@2x.png + rc/checkbox_indeterminate.png + rc/checkbox_indeterminate@2x.png + rc/checkbox_indeterminate_disabled.png + rc/checkbox_indeterminate_disabled@2x.png + rc/checkbox_indeterminate_focus.png + rc/checkbox_indeterminate_focus@2x.png + rc/checkbox_indeterminate_pressed.png + rc/checkbox_indeterminate_pressed@2x.png + rc/checkbox_unchecked.png + rc/checkbox_unchecked@2x.png + rc/checkbox_unchecked_disabled.png + rc/checkbox_unchecked_disabled@2x.png + rc/checkbox_unchecked_focus.png + rc/checkbox_unchecked_focus@2x.png + rc/checkbox_unchecked_pressed.png + rc/checkbox_unchecked_pressed@2x.png + rc/line_horizontal.png + rc/line_horizontal@2x.png + rc/line_horizontal_disabled.png + rc/line_horizontal_disabled@2x.png + rc/line_horizontal_focus.png + rc/line_horizontal_focus@2x.png + rc/line_horizontal_pressed.png + rc/line_horizontal_pressed@2x.png + rc/line_vertical.png + rc/line_vertical@2x.png + rc/line_vertical_disabled.png + rc/line_vertical_disabled@2x.png + rc/line_vertical_focus.png + rc/line_vertical_focus@2x.png + rc/line_vertical_pressed.png + rc/line_vertical_pressed@2x.png + rc/radio_checked.png + rc/radio_checked@2x.png + rc/radio_checked_disabled.png + rc/radio_checked_disabled@2x.png + rc/radio_checked_focus.png + rc/radio_checked_focus@2x.png + rc/radio_checked_pressed.png + rc/radio_checked_pressed@2x.png + rc/radio_unchecked.png + rc/radio_unchecked@2x.png + rc/radio_unchecked_disabled.png + rc/radio_unchecked_disabled@2x.png + rc/radio_unchecked_focus.png + rc/radio_unchecked_focus@2x.png + rc/radio_unchecked_pressed.png + rc/radio_unchecked_pressed@2x.png + rc/toolbar_move_horizontal.png + rc/toolbar_move_horizontal@2x.png + rc/toolbar_move_horizontal_disabled.png + rc/toolbar_move_horizontal_disabled@2x.png + rc/toolbar_move_horizontal_focus.png + rc/toolbar_move_horizontal_focus@2x.png + rc/toolbar_move_horizontal_pressed.png + rc/toolbar_move_horizontal_pressed@2x.png + rc/toolbar_move_vertical.png + rc/toolbar_move_vertical@2x.png + rc/toolbar_move_vertical_disabled.png + rc/toolbar_move_vertical_disabled@2x.png + rc/toolbar_move_vertical_focus.png + rc/toolbar_move_vertical_focus@2x.png + rc/toolbar_move_vertical_pressed.png + rc/toolbar_move_vertical_pressed@2x.png + rc/toolbar_separator_horizontal.png + rc/toolbar_separator_horizontal@2x.png + rc/toolbar_separator_horizontal_disabled.png + rc/toolbar_separator_horizontal_disabled@2x.png + rc/toolbar_separator_horizontal_focus.png + rc/toolbar_separator_horizontal_focus@2x.png + rc/toolbar_separator_horizontal_pressed.png + rc/toolbar_separator_horizontal_pressed@2x.png + rc/toolbar_separator_vertical.png + rc/toolbar_separator_vertical@2x.png + rc/toolbar_separator_vertical_disabled.png + rc/toolbar_separator_vertical_disabled@2x.png + rc/toolbar_separator_vertical_focus.png + rc/toolbar_separator_vertical_focus@2x.png + rc/toolbar_separator_vertical_pressed.png + rc/toolbar_separator_vertical_pressed@2x.png + rc/transparent.png + rc/transparent@2x.png + rc/transparent_disabled.png + rc/transparent_disabled@2x.png + rc/transparent_focus.png + rc/transparent_focus@2x.png + rc/transparent_pressed.png + rc/transparent_pressed@2x.png + rc/window_close.png + rc/window_close@2x.png + rc/window_close_disabled.png + rc/window_close_disabled@2x.png + rc/window_close_focus.png + rc/window_close_focus@2x.png + rc/window_close_pressed.png + rc/window_close_pressed@2x.png + rc/window_grip.png + rc/window_grip@2x.png + rc/window_grip_disabled.png + rc/window_grip_disabled@2x.png + rc/window_grip_focus.png + rc/window_grip_focus@2x.png + rc/window_grip_pressed.png + rc/window_grip_pressed@2x.png + rc/window_minimize.png + rc/window_minimize@2x.png + rc/window_minimize_disabled.png + rc/window_minimize_disabled@2x.png + rc/window_minimize_focus.png + rc/window_minimize_focus@2x.png + rc/window_minimize_pressed.png + rc/window_minimize_pressed@2x.png + rc/window_undock.png + rc/window_undock@2x.png + rc/window_undock_disabled.png + rc/window_undock_disabled@2x.png + rc/window_undock_focus.png + rc/window_undock_focus@2x.png + rc/window_undock_pressed.png + rc/window_undock_pressed@2x.png + + + darkstyle.qss + + diff --git a/src/qt/qdarkstyle/dark/darkstyle.qss b/src/qt/qdarkstyle/dark/darkstyle.qss new file mode 100644 index 000000000..6e1ec4b06 --- /dev/null +++ b/src/qt/qdarkstyle/dark/darkstyle.qss @@ -0,0 +1,2214 @@ +/* --------------------------------------------------------------------------- + + WARNING! File created programmatically. All changes made in this file will be lost! + + Created by the qtsass compiler v0.4.0 + + The definitions are in the "qdarkstyle.qss._styles.scss" module + +--------------------------------------------------------------------------- */ +/* Light Style - QDarkStyleSheet ------------------------------------------ */ +/* + +See Qt documentation: + + - https://doc.qt.io/qt-5/stylesheet.html + - https://doc.qt.io/qt-5/stylesheet-reference.html + - https://doc.qt.io/qt-5/stylesheet-examples.html + +--------------------------------------------------------------------------- */ +/* Reset elements ------------------------------------------------------------ + +Resetting everything helps to unify styles across different operating systems + +--------------------------------------------------------------------------- */ + +/* Changed to be fully grayscale. */ + +* { + padding: 0px; + margin: 0px; + border: 0px; + border-style: none; + border-image: none; + outline: 0; +} + +/* specific reset for elements inside QToolBar */ +QToolBar * { + margin: 0px; + padding: 0px; +} + +/* QWidget ---------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QWidget { + background-color: #272727; + border: 0px solid #525252; + padding: 0px; + color: #E3E3E3; + selection-background-color: #616161; + selection-color: #E3E3E3; +} + +QWidget:disabled { + background-color: #272727; + color: #8B8B8B; + selection-background-color: #444444; + selection-color: #8B8B8B; +} + +QWidget::item:selected { + background-color: #616161; +} + +QWidget::item:hover:!selected { + background-color: #666666; +} + +/* QMainWindow ------------------------------------------------------------ + +This adjusts the splitter in the dock widget, not qsplitter +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmainwindow + +--------------------------------------------------------------------------- */ +QMainWindow::separator { + background-color: #525252; + border: 0px solid #272727; + spacing: 0px; + padding: 2px; +} + +QMainWindow::separator:hover { + background-color: #767676; + border: 0px solid #666666; +} + +QMainWindow::separator:horizontal { + width: 5px; + margin-top: 2px; + margin-bottom: 2px; + image: url(":/qss_icons/dark/rc/toolbar_separator_vertical.png"); +} + +QMainWindow::separator:vertical { + height: 5px; + margin-left: 2px; + margin-right: 2px; + image: url(":/qss_icons/dark/rc/toolbar_separator_horizontal.png"); +} + +/* QToolTip --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtooltip + +--------------------------------------------------------------------------- */ +QToolTip { + background-color: #616161; + color: #E3E3E3; + /* If you remove the border property, background stops working on Windows */ + border: none; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Remove opacity, fix #174 - may need to use RGBA */ +} + +/* QStatusBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qstatusbar + +--------------------------------------------------------------------------- */ +QStatusBar { + border: 1px solid #272727; + /* Fixes Spyder #9120, #9121 */ + background: #272727; + /* Fixes #205, white vertical borders separating items */ +} + +QStatusBar::item { + border: none; +} + +QStatusBar QToolTip { + background-color: #666666; + border: 1px solid #272727; + color: #272727; + /* Remove padding, for fix combo box tooltip */ + padding: 0px; + /* Reducing transparency to read better */ + opacity: 230; +} + +QStatusBar QLabel { + /* Fixes Spyder #9120, #9121 */ + background: transparent; + padding: 0px; +} + +/* QCheckBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcheckbox + +--------------------------------------------------------------------------- */ +QCheckBox { + background-color: #272727; + color: #E3E3E3; + spacing: 4px; + outline: none; + padding-top: 4px; + padding-bottom: 4px; +} + +QCheckBox:focus { + border: none; +} + +QCheckBox QWidget:disabled { + background-color: #272727; + color: #8B8B8B; +} + +QCheckBox::indicator { + margin-left: 2px; + height: 14px; + width: 14px; +} + +QCheckBox::indicator:unchecked { + image: url(":/qss_icons/dark/rc/checkbox_unchecked.png"); +} + +QCheckBox::indicator:unchecked:hover, QCheckBox::indicator:unchecked:focus, QCheckBox::indicator:unchecked:pressed { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_unchecked_focus.png"); +} + +QCheckBox::indicator:unchecked:disabled { + image: url(":/qss_icons/dark/rc/checkbox_unchecked_disabled.png"); +} + +QCheckBox::indicator:checked { + image: url(":/qss_icons/dark/rc/checkbox_checked.png"); +} + +QCheckBox::indicator:checked:hover, QCheckBox::indicator:checked:focus, QCheckBox::indicator:checked:pressed { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_checked_focus.png"); +} + +QCheckBox::indicator:checked:disabled { + image: url(":/qss_icons/dark/rc/checkbox_checked_disabled.png"); +} + +QCheckBox::indicator:indeterminate { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate.png"); +} + +QCheckBox::indicator:indeterminate:disabled { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate_disabled.png"); +} + +QCheckBox::indicator:indeterminate:focus, QCheckBox::indicator:indeterminate:hover, QCheckBox::indicator:indeterminate:pressed { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate_focus.png"); +} + +/* QGroupBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qgroupbox + +--------------------------------------------------------------------------- */ +QGroupBox { + font-weight: bold; + border: 1px solid #525252; + border-radius: 4px; + padding: 2px; + margin-top: 6px; + margin-bottom: 4px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 4px; + padding-left: 2px; + padding-right: 4px; + padding-top: -4px; +} + +QGroupBox::indicator { + margin-left: 2px; + margin-top: 2px; + padding: 0; + height: 14px; + width: 14px; +} + +QGroupBox::indicator:unchecked { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_unchecked.png"); +} + +QGroupBox::indicator:unchecked:hover, QGroupBox::indicator:unchecked:focus, QGroupBox::indicator:unchecked:pressed { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_unchecked_focus.png"); +} + +QGroupBox::indicator:unchecked:disabled { + image: url(":/qss_icons/dark/rc/checkbox_unchecked_disabled.png"); +} + +QGroupBox::indicator:checked { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_checked.png"); +} + +QGroupBox::indicator:checked:hover, QGroupBox::indicator:checked:focus, QGroupBox::indicator:checked:pressed { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_checked_focus.png"); +} + +QGroupBox::indicator:checked:disabled { + image: url(":/qss_icons/dark/rc/checkbox_checked_disabled.png"); +} + +/* QRadioButton ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qradiobutton + +--------------------------------------------------------------------------- */ +QRadioButton { + background-color: #272727; + color: #E3E3E3; + spacing: 4px; + padding-top: 4px; + padding-bottom: 4px; + border: none; + outline: none; +} + +QRadioButton:focus { + border: none; +} + +QRadioButton:disabled { + background-color: #272727; + color: #8B8B8B; + border: none; + outline: none; +} + +QRadioButton QWidget { + background-color: #272727; + color: #E3E3E3; + spacing: 0px; + padding: 0px; + outline: none; + border: none; +} + +QRadioButton::indicator { + border: none; + outline: none; + margin-left: 2px; + height: 14px; + width: 14px; +} + +QRadioButton::indicator:unchecked { + image: url(":/qss_icons/dark/rc/radio_unchecked.png"); +} + +QRadioButton::indicator:unchecked:hover, QRadioButton::indicator:unchecked:focus, QRadioButton::indicator:unchecked:pressed { + border: none; + outline: none; + image: url(":/qss_icons/dark/rc/radio_unchecked_focus.png"); +} + +QRadioButton::indicator:unchecked:disabled { + image: url(":/qss_icons/dark/rc/radio_unchecked_disabled.png"); +} + +QRadioButton::indicator:checked { + border: none; + outline: none; + image: url(":/qss_icons/dark/rc/radio_checked.png"); +} + +QRadioButton::indicator:checked:hover, QRadioButton::indicator:checked:focus, QRadioButton::indicator:checked:pressed { + border: none; + outline: none; + image: url(":/qss_icons/dark/rc/radio_checked_focus.png"); +} + +QRadioButton::indicator:checked:disabled { + outline: none; + image: url(":/qss_icons/dark/rc/radio_checked_disabled.png"); +} + +/* QMenuBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenubar + +--------------------------------------------------------------------------- */ +QMenuBar { + background-color: #272727; + padding: 2px; + border: 1px solid #525252; + color: #E3E3E3; + selection-background-color: #666666; +} + +QMenuBar:focus { + border: 1px solid #616161; +} + +QMenuBar::item { + background: transparent; + padding-left: 7px; + padding-right: 7px; +} + +QMenuBar::item:selected { + padding: 4px; + background: transparent; + border: 0px solid #525252; + background-color: #383838; +} + +QMenuBar::item:pressed { + padding: 4px; + border: 0px solid #525252; + background-color: #383838; + color: #E3E3E3; +} + +/* QMenu ------------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu + +--------------------------------------------------------------------------- */ +QMenu { + border: 0px solid #525252; + color: #E3E3E3; + margin: 0px; + background-color: #2C2C2C; + selection-background-color: #666666; +} + +QMenu::separator { + height: 1px; + background-color: #767676; + color: #E3E3E3; +} + +QMenu::item { + background-color: #2C2C2C; + padding: 4px 24px 4px 28px; + /* Reserve space for selection border */ + border: 1px transparent #525252; +} + +QMenu::item:selected { + color: #E3E3E3; + background-color: #353535; +} + +QMenu::item:pressed { + background-color: #353535; +} + +QMenu::icon { + padding-left: 10px; + width: 14px; + height: 14px; +} + +QMenu::indicator { + padding-left: 8px; + width: 12px; + height: 12px; + /* non-exclusive indicator = check box style indicator (see QActionGroup::setExclusive) */ + /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ +} + +QMenu::indicator:non-exclusive:unchecked { + image: url(":/qss_icons/dark/rc/checkbox_unchecked.png"); +} + +QMenu::indicator:non-exclusive:unchecked:hover, QMenu::indicator:non-exclusive:unchecked:focus, QMenu::indicator:non-exclusive:unchecked:pressed { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_unchecked_focus.png"); +} + +QMenu::indicator:non-exclusive:unchecked:disabled { + image: url(":/qss_icons/dark/rc/checkbox_unchecked_disabled.png"); +} + +QMenu::indicator:non-exclusive:checked { + image: url(":/qss_icons/dark/rc/checkbox_checked.png"); +} + +QMenu::indicator:non-exclusive:checked:hover, QMenu::indicator:non-exclusive:checked:focus, QMenu::indicator:non-exclusive:checked:pressed { + border: none; + image: url(":/qss_icons/dark/rc/checkbox_checked_focus.png"); +} + +QMenu::indicator:non-exclusive:checked:disabled { + image: url(":/qss_icons/dark/rc/checkbox_checked_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:disabled { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate_disabled.png"); +} + +QMenu::indicator:non-exclusive:indeterminate:focus, QMenu::indicator:non-exclusive:indeterminate:hover, QMenu::indicator:non-exclusive:indeterminate:pressed { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate_focus.png"); +} + +QMenu::indicator:exclusive:unchecked { + image: url(":/qss_icons/dark/rc/radio_unchecked.png"); +} + +QMenu::indicator:exclusive:unchecked:hover, QMenu::indicator:exclusive:unchecked:focus, QMenu::indicator:exclusive:unchecked:pressed { + border: none; + outline: none; + image: url(":/qss_icons/dark/rc/radio_unchecked_focus.png"); +} + +QMenu::indicator:exclusive:unchecked:disabled { + image: url(":/qss_icons/dark/rc/radio_unchecked_disabled.png"); +} + +QMenu::indicator:exclusive:checked { + border: none; + outline: none; + image: url(":/qss_icons/dark/rc/radio_checked.png"); +} + +QMenu::indicator:exclusive:checked:hover, QMenu::indicator:exclusive:checked:focus, QMenu::indicator:exclusive:checked:pressed { + border: none; + outline: none; + image: url(":/qss_icons/dark/rc/radio_checked_focus.png"); +} + +QMenu::indicator:exclusive:checked:disabled { + outline: none; + image: url(":/qss_icons/dark/rc/radio_checked_disabled.png"); +} + +QMenu::right-arrow { + margin: 5px; + padding-left: 12px; + image: url(":/qss_icons/dark/rc/arrow_right.png"); + height: 12px; + width: 12px; +} + +/* QAbstractItemView ------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QAbstractItemView { + alternate-background-color: #272727; + color: #E3E3E3; + border: 1px solid #525252; + border-radius: 4px; +} + +QAbstractItemView QLineEdit { + padding: 2px; +} + +/* QAbstractScrollArea ---------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QAbstractScrollArea { + background-color: #272727; + border: 1px solid #525252; + border-radius: 4px; + /* fix #159 */ + padding: 2px; + /* remove min-height to fix #244 */ + color: #E3E3E3; +} + +QAbstractScrollArea:disabled { + color: #8B8B8B; +} + +/* QScrollArea ------------------------------------------------------------ + +--------------------------------------------------------------------------- */ +QScrollArea QWidget QWidget:disabled { + background-color: #272727; +} + +/* QScrollBar ------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qscrollbar + +--------------------------------------------------------------------------- */ +QScrollBar:horizontal { + height: 16px; + margin: 2px 16px 2px 16px; + border: 1px solid #525252; + border-radius: 4px; + background-color: #272727; +} + +QScrollBar:vertical { + background-color: #272727; + width: 16px; + margin: 16px 2px 16px 2px; + border: 1px solid #525252; + border-radius: 4px; +} + +QScrollBar::handle:horizontal { + background-color: #767676; + border: 1px solid #525252; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:hover { + background-color: #616161; + border: #616161; + border-radius: 4px; + min-width: 8px; +} + +QScrollBar::handle:horizontal:focus { + border: 1px solid #666666; +} + +QScrollBar::handle:vertical { + background-color: #767676; + border: 1px solid #525252; + min-height: 8px; + border-radius: 4px; +} + +QScrollBar::handle:vertical:hover { + background-color: #616161; + border: #616161; + border-radius: 4px; + min-height: 8px; +} + +QScrollBar::handle:vertical:focus { + border: 1px solid #666666; +} + +QScrollBar::add-line:horizontal { + margin: 0px 0px 0px 0px; + border-image: url(":/qss_icons/dark/rc/arrow_right_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:horizontal:hover, QScrollBar::add-line:horizontal:on { + border-image: url(":/qss_icons/dark/rc/arrow_right.png"); + height: 12px; + width: 12px; + subcontrol-position: right; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/qss_icons/dark/rc/arrow_down_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on { + border-image: url(":/qss_icons/dark/rc/arrow_down.png"); + height: 12px; + width: 12px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal { + margin: 0px 3px 0px 3px; + border-image: url(":/qss_icons/dark/rc/arrow_left_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on { + border-image: url(":/qss_icons/dark/rc/arrow_left.png"); + height: 12px; + width: 12px; + subcontrol-position: left; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical { + margin: 3px 0px 3px 0px; + border-image: url(":/qss_icons/dark/rc/arrow_up_disabled.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::sub-line:vertical:hover, QScrollBar::sub-line:vertical:on { + border-image: url(":/qss_icons/dark/rc/arrow_up.png"); + height: 12px; + width: 12px; + subcontrol-position: top; + subcontrol-origin: margin; +} + +QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal { + background: none; +} + +QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { + background: none; +} + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { + background: none; +} + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { + background: none; +} + +/* QTextEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-specific-widgets + +--------------------------------------------------------------------------- */ +QTextEdit { + background-color: #272727; + color: #E3E3E3; + border-radius: 4px; + border: 1px solid #525252; +} + +QTextEdit:focus { + border: 1px solid #666666; +} + +QTextEdit:selected { + background: #616161; + color: #525252; +} + +/* QPlainTextEdit --------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QPlainTextEdit { + background-color: #272727; + color: #E3E3E3; + border-radius: 4px; + border: 1px solid #525252; +} + +QPlainTextEdit:focus { + border: 1px solid #666666; +} + +QPlainTextEdit:selected { + background: #616161; + color: #525252; +} + +/* QSizeGrip -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsizegrip + +--------------------------------------------------------------------------- */ +QSizeGrip { + background: transparent; + width: 12px; + height: 12px; + image: url(":/qss_icons/dark/rc/window_grip.png"); +} + +/* QToolBar --------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbar + +--------------------------------------------------------------------------- */ +QToolBar { + background-color: #272727; + border-bottom: 1px solid #272727; + padding: 1px; + font-weight: bold; +} + +QToolBar:disabled { + /* Fixes #272 */ + background-color: #272727; +} + +QToolBar::handle:horizontal { + width: 16px; + image: url(":/qss_icons/dark/rc/toolbar_move_horizontal.png"); +} + +QToolBar::handle:vertical { + height: 16px; + image: url(":/qss_icons/dark/rc/toolbar_move_vertical.png"); +} + +QToolBar::separator:horizontal { + width: 16px; + image: url(":/qss_icons/dark/rc/toolbar_separator_horizontal.png"); +} + +QToolBar::separator:vertical { + height: 16px; + image: url(":/qss_icons/dark/rc/toolbar_separator_vertical.png"); +} + +QToolButton#qt_toolbar_ext_button { + background: #272727; + border: 0px; + color: #E3E3E3; + image: url(":/qss_icons/dark/rc/arrow_right.png"); +} + +/* QAbstractSpinBox ------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractSpinBox { + background-color: #272727; + border: 1px solid #525252; + color: #E3E3E3; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + border-radius: 4px; + /* min-width: 5px; removed to fix 109 */ +} + +QAbstractSpinBox:up-button { + background-color: transparent #272727; + subcontrol-origin: border; + subcontrol-position: top right; + border-left: 1px solid #525252; + border-bottom: 1px solid #525252; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-bottom: -1px; +} + +QAbstractSpinBox::up-arrow, QAbstractSpinBox::up-arrow:disabled, QAbstractSpinBox::up-arrow:off { + image: url(":/qss_icons/dark/rc/arrow_up_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::up-arrow:hover { + image: url(":/qss_icons/dark/rc/arrow_up.png"); +} + +QAbstractSpinBox:down-button { + background-color: transparent #272727; + subcontrol-origin: border; + subcontrol-position: bottom right; + border-left: 1px solid #525252; + border-top: 1px solid #525252; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + margin: 1px; + width: 12px; + margin-top: -1px; +} + +QAbstractSpinBox::down-arrow, QAbstractSpinBox::down-arrow:disabled, QAbstractSpinBox::down-arrow:off { + image: url(":/qss_icons/dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QAbstractSpinBox::down-arrow:hover { + image: url(":/qss_icons/dark/rc/arrow_down.png"); +} + +QAbstractSpinBox:hover { + border: 1px solid #616161; + color: #E3E3E3; +} + +QAbstractSpinBox:focus { + border: 1px solid #666666; +} + +QAbstractSpinBox:selected { + background: #616161; + color: #525252; +} + +/* ------------------------------------------------------------------------ */ +/* DISPLAYS --------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QLabel ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe + +--------------------------------------------------------------------------- */ +QLabel { + background-color: #272727; + border: 0px solid #525252; + padding: 2px; + margin: 0px; + color: #E3E3E3; +} + +QLabel:disabled { + background-color: #272727; + border: 0px solid #525252; + color: #8B8B8B; +} + +/* QTextBrowser ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea + +--------------------------------------------------------------------------- */ +QTextBrowser { + background-color: #272727; + border: 1px solid #525252; + color: #E3E3E3; + border-radius: 4px; +} + +QTextBrowser:disabled { + background-color: #272727; + border: 1px solid #525252; + color: #8B8B8B; + border-radius: 4px; +} + +QTextBrowser:hover, QTextBrowser:!hover, QTextBrowser:selected, QTextBrowser:pressed { + border: 1px solid #525252; +} + +/* QGraphicsView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QGraphicsView { + background-color: #272727; + border: 1px solid #525252; + color: #E3E3E3; + border-radius: 4px; +} + +QGraphicsView:disabled { + background-color: #272727; + border: 1px solid #525252; + color: #8B8B8B; + border-radius: 4px; +} + +QGraphicsView:hover, QGraphicsView:!hover, QGraphicsView:selected, QGraphicsView:pressed { + border: 1px solid #525252; +} + +/* QCalendarWidget -------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCalendarWidget { + border: 1px solid #525252; + border-radius: 4px; +} + +QCalendarWidget:disabled { + background-color: #272727; + color: #8B8B8B; +} + +/* QLCDNumber ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QLCDNumber { + background-color: #272727; + color: #E3E3E3; +} + +QLCDNumber:disabled { + background-color: #272727; + color: #8B8B8B; +} + +/* QProgressBar ----------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qprogressbar + +--------------------------------------------------------------------------- */ +QProgressBar { + background-color: #272727; + border: 1px solid #525252; + color: #E3E3E3; + border-radius: 4px; + text-align: center; +} + +QProgressBar:disabled { + background-color: #272727; + border: 1px solid #525252; + color: #8B8B8B; + border-radius: 4px; + text-align: center; +} + +QProgressBar::chunk { + background-color: #616161; + color: #272727; + border-radius: 4px; +} + +QProgressBar::chunk:disabled { + background-color: #444444; + color: #8B8B8B; + border-radius: 4px; +} + +/* ------------------------------------------------------------------------ */ +/* BUTTONS ---------------------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QPushButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qpushbutton + +--------------------------------------------------------------------------- */ +QPushButton { + background-color: #333333; + color: #E3E3E3; + border-radius: 4px; + padding: 4px; + outline: none; + border: 1px solid white; +} + +QPushButton:disabled { + background-color: #333333; + color: #8B8B8B; + border-radius: 4px; + padding: 4px; + border: 1px solid #9B9B9B; +} + +QPushButton:checked { + background-color: #666666; + border-radius: 4px; + padding: 4px; + outline: none; +} + +QPushButton:checked:disabled { + background-color: #525252; + color: #8B8B8B; + border-radius: 4px; + padding: 4px; + outline: none; +} + +QPushButton:checked:selected { + background: #454545; +} + +QPushButton:hover { + background-color: #454545; + color: #E3E3E3; + border: 1px solid #9B9B9B; +} + +QPushButton:pressed { + background-color: #666666; + border: 1px solid #9B9B9B; +} + +QPushButton:selected { + background: #333333; + color: #E3E3E3; +} + +QPushButton::menu-indicator { + subcontrol-origin: padding; + subcontrol-position: bottom right; + bottom: 4px; +} + +QDialogButtonBox QPushButton { + /* Issue #194 #248 - Special case of QPushButton inside dialogs, for better UI */ + min-width: 80px; +} + +/* QToolButton ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton + +--------------------------------------------------------------------------- */ +QToolButton { + background-color: #272727; + color: #E3E3E3; + border-radius: 4px; + padding: 2px; + outline: none; + border: none; + /* The subcontrols below are used only in the DelayedPopup mode */ + /* The subcontrols below are used only in the MenuButtonPopup mode */ + /* The subcontrol below is used only in the InstantPopup or DelayedPopup mode */ +} + +QToolButton:disabled { + background-color: #272727; + color: #8B8B8B; + border-radius: 4px; + padding: 2px; +} + +QToolButton:checked { + background-color: #767676; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:disabled { + background-color: #767676; + color: #8B8B8B; + border-radius: 4px; + padding: 2px; + outline: none; +} + +QToolButton:checked:hover { + background-color: #666666; + color: #E3E3E3; +} + +QToolButton:checked:pressed { + background-color: #767676; +} + +QToolButton:checked:selected { + background: #767676; + color: #E3E3E3; +} + +QToolButton:hover { + background-color: #666666; + color: #E3E3E3; +} + +QToolButton:pressed { + background-color: #767676; +} + +QToolButton:selected { + background: #767676; + color: #E3E3E3; +} + +QToolButton[popupMode="0"] { + /* Only for DelayedPopup */ + padding-right: 2px; +} + +QToolButton[popupMode="1"] { + /* Only for MenuButtonPopup */ + padding-right: 20px; +} + +QToolButton[popupMode="1"]::menu-button { + border: none; +} + +QToolButton[popupMode="1"]::menu-button:hover { + border: none; + border-left: 1px solid #525252; + border-radius: 0; +} + +QToolButton[popupMode="2"] { + /* Only for InstantPopup */ + padding-right: 2px; +} + +QToolButton::menu-button { + padding: 2px; + border-radius: 4px; + width: 12px; + border: none; + outline: none; +} + +QToolButton::menu-button:hover { + border: 1px solid #616161; +} + +QToolButton::menu-button:checked:hover { + border: 1px solid #616161; +} + +QToolButton::menu-indicator { + image: url(":/qss_icons/dark/rc/arrow_down.png"); + height: 8px; + width: 8px; + top: 0; + /* Exclude a shift for better image */ + left: -2px; + /* Shift it a bit */ +} + +QToolButton::menu-arrow { + image: url(":/qss_icons/dark/rc/arrow_down.png"); + height: 8px; + width: 8px; +} + +QToolButton::menu-arrow:hover { + image: url(":/qss_icons/dark/rc/arrow_down_focus.png"); +} + +/* QCommandLinkButton ----------------------------------------------------- + +--------------------------------------------------------------------------- */ +QCommandLinkButton { + background-color: transparent; + border: 1px solid #525252; + color: #E3E3E3; + border-radius: 4px; + padding: 0px; + margin: 0px; +} + +QCommandLinkButton:disabled { + background-color: transparent; + color: #8B8B8B; +} + +/* ------------------------------------------------------------------------ */ +/* INPUTS - NO FIELDS ----------------------------------------------------- */ +/* ------------------------------------------------------------------------ */ +/* QComboBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qcombobox + +--------------------------------------------------------------------------- */ +QComboBox { + border: 1px solid #525252; + border-radius: 4px; + selection-background-color: #616161; + padding-left: 4px; + padding-right: 4px; + /* padding-right = 36; 4 + 16*2 See scrollbar size */ + /* changed to 4px to fix #239 */ + /* Fixes #103, #111 */ + min-height: 1.5em; + /* padding-top: 2px; removed to fix #132 */ + /* padding-bottom: 2px; removed to fix #132 */ + /* min-width: 75px; removed to fix #109 */ + /* Needed to remove indicator - fix #132 */ +} + +QComboBox QAbstractItemView { + border: 1px solid #525252; + border-radius: 0; + background-color: #272727; + selection-background-color: #616161; +} + +QComboBox QAbstractItemView:hover { + background-color: #272727; + color: #E3E3E3; +} + +QComboBox QAbstractItemView:selected { + background: #616161; + color: #525252; +} + +QComboBox QAbstractItemView:alternate { + background: #272727; +} + +QComboBox:disabled { + background-color: #272727; + color: #8B8B8B; +} + +QComboBox:hover { + border: 1px solid #616161; + background-color: #454545; +} + +QComboBox:focus { + border: 1px solid #666666; +} + +QComboBox:on { + selection-background-color: #616161; + background-color: #666666; +} + +QComboBox::indicator { + border: none; + border-radius: 0; + background-color: transparent; + selection-background-color: transparent; + color: transparent; + selection-color: transparent; + /* Needed to remove indicator - fix #132 */ +} + +QComboBox::indicator:alternate { + background: #272727; +} + +QComboBox::item { + /* Remove to fix #282, #285 and MR #288*/ + /*&:checked { + font-weight: bold; + } + + &:selected { + border: 0px solid transparent; + } + */ +} + +QComboBox::item:alternate { + background: #272727; +} + +QComboBox::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #525252; +} + +QComboBox::down-arrow { + image: url(":/qss_icons/dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QComboBox::down-arrow:on, QComboBox::down-arrow:hover, QComboBox::down-arrow:focus { + image: url(":/qss_icons/dark/rc/arrow_down.png"); +} + +/* QSlider ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qslider + +--------------------------------------------------------------------------- */ +QSlider:disabled { + background: #272727; +} + +QSlider:focus { + border: none; +} + +QSlider::groove:horizontal { + background: #525252; + border: 1px solid #525252; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::groove:vertical { + background: #525252; + border: 1px solid #525252; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical { + background: #616161; + border: 1px solid #525252; + width: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::add-page:vertical :disabled { + background: #444444; +} + +QSlider::sub-page:horizontal { + background: #616161; + border: 1px solid #525252; + height: 4px; + margin: 0px; + border-radius: 4px; +} + +QSlider::sub-page:horizontal:disabled { + background: #444444; +} + +QSlider::handle:horizontal { + background: #A9A9A9; + border: 1px solid #525252; + width: 8px; + height: 8px; + margin: -8px 0px; + border-radius: 4px; +} + +QSlider::handle:horizontal:hover { + background: #616161; + border: 1px solid #616161; +} + +QSlider::handle:horizontal:focus { + border: 1px solid #666666; +} + +QSlider::handle:vertical { + background: #A9A9A9; + border: 1px solid #525252; + width: 8px; + height: 8px; + margin: 0 -8px; + border-radius: 4px; +} + +QSlider::handle:vertical:hover { + background: #616161; + border: 1px solid #616161; +} + +QSlider::handle:vertical:focus { + border: 1px solid #666666; +} + +/* QLineEdit -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlineedit + +--------------------------------------------------------------------------- */ +QLineEdit { + background-color: #272727; + padding-top: 2px; + /* This QLineEdit fix 103, 111 */ + padding-bottom: 2px; + /* This QLineEdit fix 103, 111 */ + padding-left: 4px; + padding-right: 4px; + border-style: solid; + border: 1px solid #525252; + border-radius: 4px; + color: #E3E3E3; +} + +QLineEdit:disabled { + background-color: #272727; + color: #8B8B8B; +} + +QLineEdit:hover { + border: 1px solid #616161; + color: #E3E3E3; +} + +QLineEdit:focus { + border: 1px solid #666666; +} + +QLineEdit:selected { + background-color: #616161; + color: #525252; +} + +/* QTabWiget -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabWidget { + padding: 2px; + selection-background-color: #525252; +} + +QTabWidget QWidget { + /* Fixes #189 */ + border-radius: 4px; +} + +QTabWidget::pane { + border: 1px solid #525252; + border-radius: 4px; + margin: 0px; + /* Fixes double border inside pane with pyqt5 */ + padding: 0px; +} + +QTabWidget::pane:selected { + background-color: #525252; + border: 1px solid #616161; +} + +/* QTabBar ---------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar + +--------------------------------------------------------------------------- */ +QTabBar, QDockWidget QTabBar { + qproperty-drawBase: 0; + border-radius: 4px; + margin: 0px; + padding: 2px; + border: 0; + /* left: 5px; move to the right by 5px - removed for fix */ +} + +QTabBar::close-button, QDockWidget QTabBar::close-button { + border: 0; + margin: 0; + padding: 4px; + image: url(":/qss_icons/dark/rc/window_close.png"); +} + +QTabBar::close-button:hover, QDockWidget QTabBar::close-button:hover { + image: url(":/qss_icons/dark/rc/window_close_focus.png"); +} + +QTabBar::close-button:pressed, QDockWidget QTabBar::close-button:pressed { + image: url(":/qss_icons/dark/rc/window_close_pressed.png"); +} + +QTabBar::tab, QDockWidget QTabBar::tab { + /* !selected and disabled ----------------------------------------- */ + /* selected ------------------------------------------------------- */ +} + +QTabBar::tab:top:selected:disabled, QDockWidget QTabBar::tab:top:selected:disabled { + border-bottom: 3px solid #444444; + color: #8B8B8B; + background-color: #525252; +} + +QTabBar::tab:bottom:selected:disabled, QDockWidget QTabBar::tab:bottom:selected:disabled { + border-top: 3px solid #444444; + color: #8B8B8B; + background-color: #525252; +} + +QTabBar::tab:left:selected:disabled, QDockWidget QTabBar::tab:left:selected:disabled { + border-right: 3px solid #444444; + color: #8B8B8B; + background-color: #525252; +} + +QTabBar::tab:right:selected:disabled, QDockWidget QTabBar::tab:right:selected:disabled { + border-left: 3px solid #444444; + color: #8B8B8B; + background-color: #525252; +} + +QTabBar::tab:top:!selected:disabled, QDockWidget QTabBar::tab:top:!selected:disabled { + border-bottom: 3px solid #272727; + color: #8B8B8B; + background-color: #272727; +} + +QTabBar::tab:bottom:!selected:disabled, QDockWidget QTabBar::tab:bottom:!selected:disabled { + border-top: 3px solid #272727; + color: #8B8B8B; + background-color: #272727; +} + +QTabBar::tab:left:!selected:disabled, QDockWidget QTabBar::tab:left:!selected:disabled { + border-right: 3px solid #272727; + color: #8B8B8B; + background-color: #272727; +} + +QTabBar::tab:right:!selected:disabled, QDockWidget QTabBar::tab:right:!selected:disabled { + border-left: 3px solid #272727; + color: #8B8B8B; + background-color: #272727; +} + +QTabBar::tab:top:!selected, QDockWidget QTabBar::tab:top:!selected { + border-bottom: 2px solid #272727; + margin-top: 2px; +} + +QTabBar::tab:bottom:!selected, QDockWidget QTabBar::tab:bottom:!selected { + border-top: 2px solid #272727; + margin-bottom: 2px; +} + +QTabBar::tab:left:!selected, QDockWidget QTabBar::tab:left:!selected { + border-left: 2px solid #272727; + margin-right: 2px; +} + +QTabBar::tab:right:!selected, QDockWidget QTabBar::tab:right:!selected { + border-right: 2px solid #272727; + margin-left: 2px; +} + +QTabBar::tab:top, QDockWidget QTabBar::tab:top { + background-color: #525252; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + min-width: 5px; + border-bottom: 3px solid #525252; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:selected, QDockWidget QTabBar::tab:top:selected { + background-color: #666666; + border-bottom: 3px solid #898989; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QTabBar::tab:top:!selected:hover, QDockWidget QTabBar::tab:top:!selected:hover { + border: 1px solid #666666; + border-bottom: 3px solid #666666; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:bottom, QDockWidget QTabBar::tab:bottom { + border-top: 3px solid #525252; + background-color: #525252; + margin-left: 2px; + padding-left: 4px; + padding-right: 4px; + padding-top: 2px; + padding-bottom: 2px; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + min-width: 5px; +} + +QTabBar::tab:bottom:selected, QDockWidget QTabBar::tab:bottom:selected { + background-color: #666666; + border-top: 3px solid #898989; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +QTabBar::tab:bottom:!selected:hover, QDockWidget QTabBar::tab:bottom:!selected:hover { + border: 1px solid #666666; + border-top: 3px solid #666666; + /* Fixes spyder-ide/spyder#9766 and #243 */ + padding-left: 3px; + padding-right: 3px; +} + +QTabBar::tab:left, QDockWidget QTabBar::tab:left { + background-color: #525252; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:left:selected, QDockWidget QTabBar::tab:left:selected { + background-color: #666666; + border-right: 3px solid #898989; +} + +QTabBar::tab:left:!selected:hover, QDockWidget QTabBar::tab:left:!selected:hover { + border: 1px solid #666666; + border-right: 3px solid #666666; + /* Fixes different behavior #271 */ + margin-right: 0px; + padding-right: -1px; +} + +QTabBar::tab:right, QDockWidget QTabBar::tab:right { + background-color: #525252; + margin-top: 2px; + padding-left: 2px; + padding-right: 2px; + padding-top: 4px; + padding-bottom: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + min-height: 5px; +} + +QTabBar::tab:right:selected, QDockWidget QTabBar::tab:right:selected { + background-color: #666666; + border-left: 3px solid #898989; +} + +QTabBar::tab:right:!selected:hover, QDockWidget QTabBar::tab:right:!selected:hover { + border: 1px solid #666666; + border-left: 3px solid #666666; + /* Fixes different behavior #271 */ + margin-left: 0px; + padding-left: 0px; +} + +QTabBar QToolButton, QDockWidget QTabBar QToolButton { + /* Fixes #136 */ + background-color: #525252; + height: 12px; + width: 12px; +} + +QTabBar QToolButton:pressed, QDockWidget QTabBar QToolButton:pressed { + background-color: #525252; +} + +QTabBar QToolButton:pressed:hover, QDockWidget QTabBar QToolButton:pressed:hover { + border: 1px solid #616161; +} + +QTabBar QToolButton::left-arrow:enabled, QDockWidget QTabBar QToolButton::left-arrow:enabled { + image: url(":/qss_icons/dark/rc/arrow_left.png"); +} + +QTabBar QToolButton::left-arrow:disabled, QDockWidget QTabBar QToolButton::left-arrow:disabled { + image: url(":/qss_icons/dark/rc/arrow_left_disabled.png"); +} + +QTabBar QToolButton::right-arrow:enabled, QDockWidget QTabBar QToolButton::right-arrow:enabled { + image: url(":/qss_icons/dark/rc/arrow_right.png"); +} + +QTabBar QToolButton::right-arrow:disabled, QDockWidget QTabBar QToolButton::right-arrow:disabled { + image: url(":/qss_icons/dark/rc/arrow_right_disabled.png"); +} + +/* QDockWiget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QDockWidget { + outline: 1px solid #525252; + background-color: #272727; + border: 1px solid #525252; + border-radius: 4px; + titlebar-close-icon: url(":/qss_icons/dark/rc/transparent.png"); + titlebar-normal-icon: url(":/qss_icons/dark/rc/transparent.png"); +} + +QDockWidget::title { + /* Better size for title bar */ + padding: 3px; + spacing: 4px; + border: none; + background-color: #525252; +} + +QDockWidget::close-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/qss_icons/dark/rc/window_close.png"); +} + +QDockWidget::close-button:hover { + image: url(":/qss_icons/dark/rc/window_close_focus.png"); +} + +QDockWidget::close-button:pressed { + image: url(":/qss_icons/dark/rc/window_close_pressed.png"); +} + +QDockWidget::float-button { + icon-size: 12px; + border: none; + background: transparent; + background-image: transparent; + border: 0; + margin: 0; + padding: 0; + image: url(":/qss_icons/dark/rc/window_undock.png"); +} + +QDockWidget::float-button:hover { + image: url(":/qss_icons/dark/rc/window_undock_focus.png"); +} + +QDockWidget::float-button:pressed { + image: url(":/qss_icons/dark/rc/window_undock_pressed.png"); +} + +/* QTreeView QListView QTableView ----------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtreeview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qlistview +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtableview + +--------------------------------------------------------------------------- */ +QTreeView:branch:selected, QTreeView:branch:hover { + background: url(":/qss_icons/dark/rc/transparent.png"); +} + +QTreeView:branch:has-siblings:!adjoins-item { + border-image: url(":/qss_icons/dark/rc/branch_line.png") 0; +} + +QTreeView:branch:has-siblings:adjoins-item { + border-image: url(":/qss_icons/dark/rc/branch_more.png") 0; +} + +QTreeView:branch:!has-children:!has-siblings:adjoins-item { + border-image: url(":/qss_icons/dark/rc/branch_end.png") 0; +} + +QTreeView:branch:has-children:!has-siblings:closed, QTreeView:branch:closed:has-children:has-siblings { + border-image: none; + image: url(":/qss_icons/dark/rc/branch_closed.png"); +} + +QTreeView:branch:open:has-children:!has-siblings, QTreeView:branch:open:has-children:has-siblings { + border-image: none; + image: url(":/qss_icons/dark/rc/branch_open.png"); +} + +QTreeView:branch:has-children:!has-siblings:closed:hover, QTreeView:branch:closed:has-children:has-siblings:hover { + image: url(":/qss_icons/dark/rc/branch_closed_focus.png"); +} + +QTreeView:branch:open:has-children:!has-siblings:hover, QTreeView:branch:open:has-children:has-siblings:hover { + image: url(":/qss_icons/dark/rc/branch_open_focus.png"); +} + +QTreeView::indicator:checked, +QListView::indicator:checked, +QTableView::indicator:checked, +QColumnView::indicator:checked { + image: url(":/qss_icons/dark/rc/checkbox_checked.png"); +} + +QTreeView::indicator:checked:hover, QTreeView::indicator:checked:focus, QTreeView::indicator:checked:pressed, +QListView::indicator:checked:hover, +QListView::indicator:checked:focus, +QListView::indicator:checked:pressed, +QTableView::indicator:checked:hover, +QTableView::indicator:checked:focus, +QTableView::indicator:checked:pressed, +QColumnView::indicator:checked:hover, +QColumnView::indicator:checked:focus, +QColumnView::indicator:checked:pressed { + image: url(":/qss_icons/dark/rc/checkbox_checked_focus.png"); +} + +QTreeView::indicator:unchecked, +QListView::indicator:unchecked, +QTableView::indicator:unchecked, +QColumnView::indicator:unchecked { + image: url(":/qss_icons/dark/rc/checkbox_unchecked.png"); +} + +QTreeView::indicator:unchecked:hover, QTreeView::indicator:unchecked:focus, QTreeView::indicator:unchecked:pressed, +QListView::indicator:unchecked:hover, +QListView::indicator:unchecked:focus, +QListView::indicator:unchecked:pressed, +QTableView::indicator:unchecked:hover, +QTableView::indicator:unchecked:focus, +QTableView::indicator:unchecked:pressed, +QColumnView::indicator:unchecked:hover, +QColumnView::indicator:unchecked:focus, +QColumnView::indicator:unchecked:pressed { + image: url(":/qss_icons/dark/rc/checkbox_unchecked_focus.png"); +} + +QTreeView::indicator:indeterminate, +QListView::indicator:indeterminate, +QTableView::indicator:indeterminate, +QColumnView::indicator:indeterminate { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate.png"); +} + +QTreeView::indicator:indeterminate:hover, QTreeView::indicator:indeterminate:focus, QTreeView::indicator:indeterminate:pressed, +QListView::indicator:indeterminate:hover, +QListView::indicator:indeterminate:focus, +QListView::indicator:indeterminate:pressed, +QTableView::indicator:indeterminate:hover, +QTableView::indicator:indeterminate:focus, +QTableView::indicator:indeterminate:pressed, +QColumnView::indicator:indeterminate:hover, +QColumnView::indicator:indeterminate:focus, +QColumnView::indicator:indeterminate:pressed { + image: url(":/qss_icons/dark/rc/checkbox_indeterminate_focus.png"); +} + +QTreeView, +QListView, +QTableView, +QColumnView { + background-color: #272727; + border: 1px solid #525252; + color: #E3E3E3; + gridline-color: #525252; + border-radius: 4px; +} + +QTreeView:disabled, +QListView:disabled, +QTableView:disabled, +QColumnView:disabled { + background-color: #272727; + color: #8B8B8B; +} + +QTreeView:selected, +QListView:selected, +QTableView:selected, +QColumnView:selected { + background-color: #616161; + color: #525252; +} + +QTreeView:focus, +QListView:focus, +QTableView:focus, +QColumnView:focus { + border: 1px solid #666666; +} + +QTreeView::item:pressed, +QListView::item:pressed, +QTableView::item:pressed, +QColumnView::item:pressed { + background-color: #616161; +} + +QTreeView::item:selected:active, +QListView::item:selected:active, +QTableView::item:selected:active, +QColumnView::item:selected:active { + background-color: #616161; +} + +QTreeView::item:selected:!active, +QListView::item:selected:!active, +QTableView::item:selected:!active, +QColumnView::item:selected:!active { + color: #E3E3E3; + background-color: #414141; +} + +QTreeView::item:!selected:hover, +QListView::item:!selected:hover, +QTableView::item:!selected:hover, +QColumnView::item:!selected:hover { + outline: 0; + color: #E3E3E3; + background-color: #414141; +} + +QTableCornerButton::section { + background-color: #272727; + border: 1px transparent #525252; + border-radius: 0px; +} + +/* QHeaderView ------------------------------------------------------------ + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qheaderview + +--------------------------------------------------------------------------- */ +QHeaderView { + background-color: #525252; + border: 0px transparent #525252; + padding: 0; + margin: 0; + border-radius: 0; +} + +QHeaderView:disabled { + background-color: #525252; + border: 1px transparent #525252; +} + +QHeaderView::section { + background-color: #525252; + color: #E3E3E3; + border-radius: 0; + text-align: left; + font-size: 13px; +} + +QHeaderView::section::horizontal { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-left: 1px solid #272727; +} + +QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one { + border-left: 1px solid #525252; +} + +QHeaderView::section::horizontal:disabled { + color: #8B8B8B; +} + +QHeaderView::section::vertical { + padding-top: 0; + padding-bottom: 0; + padding-left: 4px; + padding-right: 4px; + border-top: 1px solid #272727; +} + +QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one { + border-top: 1px solid #525252; +} + +QHeaderView::section::vertical:disabled { + color: #8B8B8B; +} + +QHeaderView::down-arrow { + /* Those settings (border/width/height/background-color) solve bug */ + /* transparent arrow background and size */ + background-color: #525252; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/qss_icons/dark/rc/arrow_down.png"); +} + +QHeaderView::up-arrow { + background-color: #525252; + border: none; + height: 12px; + width: 12px; + padding-left: 2px; + padding-right: 2px; + image: url(":/qss_icons/dark/rc/arrow_up.png"); +} + +/* QToolBox -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbox + +--------------------------------------------------------------------------- */ +QToolBox { + padding: 0px; + border: 0px; + border: 1px solid #525252; +} + +QToolBox:selected { + padding: 0px; + border: 2px solid #616161; +} + +QToolBox::tab { + background-color: #272727; + border: 1px solid #525252; + color: #E3E3E3; + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} + +QToolBox::tab:disabled { + color: #8B8B8B; +} + +QToolBox::tab:selected { + background-color: #767676; + border-bottom: 2px solid #616161; +} + +QToolBox::tab:selected:disabled { + background-color: #525252; + border-bottom: 2px solid #444444; +} + +QToolBox::tab:!selected { + background-color: #525252; + border-bottom: 2px solid #525252; +} + +QToolBox::tab:!selected:disabled { + background-color: #272727; +} + +QToolBox::tab:hover { + border-color: #666666; + border-bottom: 2px solid #666666; +} + +QToolBox QScrollArea { + padding: 0px; + border: 0px; + background-color: #272727; +} + +/* QFrame ----------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qframe +https://doc.qt.io/qt-5/qframe.html#-prop +https://doc.qt.io/qt-5/qframe.html#details +https://stackoverflow.com/questions/14581498/qt-stylesheet-for-hline-vline-color + +--------------------------------------------------------------------------- */ +/* (dot) .QFrame fix #141, #126, #123 */ +.QFrame { + border-radius: 4px; + border: 1px solid #525252; + /* No frame */ + /* HLine */ + /* HLine */ +} + +.QFrame[frameShape="0"] { + border-radius: 4px; + border: 1px transparent #525252; +} + +.QFrame[frameShape="4"] { + max-height: 2px; + border: none; + background-color: #525252; +} + +.QFrame[frameShape="5"] { + max-width: 2px; + border: none; + background-color: #525252; +} + +/* QSplitter -------------------------------------------------------------- + +https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qsplitter + +--------------------------------------------------------------------------- */ +QSplitter { + background-color: #525252; + spacing: 0px; + padding: 0px; + margin: 0px; +} + +QSplitter::handle { + background-color: #525252; + border: 0px solid #272727; + spacing: 0px; + padding: 1px; + margin: 0px; +} + +QSplitter::handle:hover { + background-color: #A9A9A9; +} + +QSplitter::handle:horizontal { + width: 5px; + image: url(":/qss_icons/dark/rc/line_vertical.png"); +} + +QSplitter::handle:vertical { + height: 5px; + image: url(":/qss_icons/dark/rc/line_horizontal.png"); +} + +/* QDateEdit, QDateTimeEdit ----------------------------------------------- + +--------------------------------------------------------------------------- */ +QDateEdit, QDateTimeEdit { + selection-background-color: #616161; + border-style: solid; + border: 1px solid #525252; + border-radius: 4px; + /* This fixes 103, 111 */ + padding-top: 2px; + /* This fixes 103, 111 */ + padding-bottom: 2px; + padding-left: 4px; + padding-right: 4px; + min-width: 10px; +} + +QDateEdit:on, QDateTimeEdit:on { + selection-background-color: #616161; +} + +QDateEdit::drop-down, QDateTimeEdit::drop-down { + subcontrol-origin: padding; + subcontrol-position: top right; + width: 12px; + border-left: 1px solid #525252; +} + +QDateEdit::down-arrow, QDateTimeEdit::down-arrow { + image: url(":/qss_icons/dark/rc/arrow_down_disabled.png"); + height: 8px; + width: 8px; +} + +QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, QDateEdit::down-arrow:focus, QDateTimeEdit::down-arrow:on, QDateTimeEdit::down-arrow:hover, QDateTimeEdit::down-arrow:focus { + image: url(":/qss_icons/dark/rc/arrow_down.png"); +} + +QDateEdit QAbstractItemView, QDateTimeEdit QAbstractItemView { + background-color: #272727; + border-radius: 4px; + border: 1px solid #525252; + selection-background-color: #616161; +} + +/* QAbstractView ---------------------------------------------------------- + +--------------------------------------------------------------------------- */ +QAbstractView:hover { + border: 1px solid #616161; + color: #E3E3E3; +} + +QAbstractView:selected { + background: #616161; + color: #525252; +} + +/* PlotWidget ------------------------------------------------------------- + +--------------------------------------------------------------------------- */ +PlotWidget { + /* Fix cut labels in plots #134 */ + padding: 0px; +} diff --git a/src/qt/qdarkstyle/dark/rc/.keep b/src/qt/qdarkstyle/dark/rc/.keep new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/src/qt/qdarkstyle/dark/rc/.keep @@ -0,0 +1 @@ + diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down.png b/src/qt/qdarkstyle/dark/rc/arrow_down.png new file mode 100644 index 000000000..412b76e6f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_down@2x.png new file mode 100644 index 000000000..74d0099ec Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down_disabled.png b/src/qt/qdarkstyle/dark/rc/arrow_down_disabled.png new file mode 100644 index 000000000..972df9cd1 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_down_disabled@2x.png new file mode 100644 index 000000000..b0fb4ad11 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down_focus.png b/src/qt/qdarkstyle/dark/rc/arrow_down_focus.png new file mode 100644 index 000000000..22df2c525 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down_focus@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_down_focus@2x.png new file mode 100644 index 000000000..06b80be4b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down_pressed.png b/src/qt/qdarkstyle/dark/rc/arrow_down_pressed.png new file mode 100644 index 000000000..50f41cc6f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_down_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_down_pressed@2x.png new file mode 100644 index 000000000..ef20f2cb0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_down_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left.png b/src/qt/qdarkstyle/dark/rc/arrow_left.png new file mode 100644 index 000000000..b7aeac5f8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_left@2x.png new file mode 100644 index 000000000..fef91a8c8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left_disabled.png b/src/qt/qdarkstyle/dark/rc/arrow_left_disabled.png new file mode 100644 index 000000000..79b1f0565 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_left_disabled@2x.png new file mode 100644 index 000000000..144fdb5f8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left_focus.png b/src/qt/qdarkstyle/dark/rc/arrow_left_focus.png new file mode 100644 index 000000000..ef0284994 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left_focus@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_left_focus@2x.png new file mode 100644 index 000000000..ca821dcac Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left_pressed.png b/src/qt/qdarkstyle/dark/rc/arrow_left_pressed.png new file mode 100644 index 000000000..c723d3bff Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_left_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_left_pressed@2x.png new file mode 100644 index 000000000..f0bcb5229 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_left_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right.png b/src/qt/qdarkstyle/dark/rc/arrow_right.png new file mode 100644 index 000000000..78d67f2db Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_right@2x.png new file mode 100644 index 000000000..ce0a8faeb Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right_disabled.png b/src/qt/qdarkstyle/dark/rc/arrow_right_disabled.png new file mode 100644 index 000000000..88da1f980 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_right_disabled@2x.png new file mode 100644 index 000000000..5351587e3 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right_focus.png b/src/qt/qdarkstyle/dark/rc/arrow_right_focus.png new file mode 100644 index 000000000..92271a8ed Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right_focus@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_right_focus@2x.png new file mode 100644 index 000000000..d6c31bdda Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right_pressed.png b/src/qt/qdarkstyle/dark/rc/arrow_right_pressed.png new file mode 100644 index 000000000..22902cf4f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_right_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_right_pressed@2x.png new file mode 100644 index 000000000..f6181eb64 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_right_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up.png b/src/qt/qdarkstyle/dark/rc/arrow_up.png new file mode 100644 index 000000000..50321f29b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_up@2x.png new file mode 100644 index 000000000..8c73c3be3 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up_disabled.png b/src/qt/qdarkstyle/dark/rc/arrow_up_disabled.png new file mode 100644 index 000000000..48054a8ae Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_up_disabled@2x.png new file mode 100644 index 000000000..e99960594 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up_focus.png b/src/qt/qdarkstyle/dark/rc/arrow_up_focus.png new file mode 100644 index 000000000..567ec8bdf Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up_focus@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_up_focus@2x.png new file mode 100644 index 000000000..f6998104b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up_pressed.png b/src/qt/qdarkstyle/dark/rc/arrow_up_pressed.png new file mode 100644 index 000000000..223320106 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/arrow_up_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/arrow_up_pressed@2x.png new file mode 100644 index 000000000..9954cf519 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/arrow_up_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon.png b/src/qt/qdarkstyle/dark/rc/base_icon.png new file mode 100644 index 000000000..bb00857a4 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon@2x.png b/src/qt/qdarkstyle/dark/rc/base_icon@2x.png new file mode 100644 index 000000000..bc4ab78a2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon_disabled.png b/src/qt/qdarkstyle/dark/rc/base_icon_disabled.png new file mode 100644 index 000000000..bb00857a4 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/base_icon_disabled@2x.png new file mode 100644 index 000000000..bc4ab78a2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon_focus.png b/src/qt/qdarkstyle/dark/rc/base_icon_focus.png new file mode 100644 index 000000000..bb00857a4 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon_focus@2x.png b/src/qt/qdarkstyle/dark/rc/base_icon_focus@2x.png new file mode 100644 index 000000000..bc4ab78a2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon_pressed.png b/src/qt/qdarkstyle/dark/rc/base_icon_pressed.png new file mode 100644 index 000000000..bb00857a4 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/base_icon_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/base_icon_pressed@2x.png new file mode 100644 index 000000000..bc4ab78a2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/base_icon_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed.png b/src/qt/qdarkstyle/dark/rc/branch_closed.png new file mode 100644 index 000000000..4c152b795 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed@2x.png b/src/qt/qdarkstyle/dark/rc/branch_closed@2x.png new file mode 100644 index 000000000..a641a550b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed_disabled.png b/src/qt/qdarkstyle/dark/rc/branch_closed_disabled.png new file mode 100644 index 000000000..165fae29b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/branch_closed_disabled@2x.png new file mode 100644 index 000000000..421e8e094 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed_focus.png b/src/qt/qdarkstyle/dark/rc/branch_closed_focus.png new file mode 100644 index 000000000..ccc249a59 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed_focus@2x.png b/src/qt/qdarkstyle/dark/rc/branch_closed_focus@2x.png new file mode 100644 index 000000000..88dd0a62b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed_pressed.png b/src/qt/qdarkstyle/dark/rc/branch_closed_pressed.png new file mode 100644 index 000000000..2aae68a0a Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_closed_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/branch_closed_pressed@2x.png new file mode 100644 index 000000000..3849a7ff0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_closed_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end.png b/src/qt/qdarkstyle/dark/rc/branch_end.png new file mode 100644 index 000000000..f92994650 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end@2x.png b/src/qt/qdarkstyle/dark/rc/branch_end@2x.png new file mode 100644 index 000000000..582832220 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end_disabled.png b/src/qt/qdarkstyle/dark/rc/branch_end_disabled.png new file mode 100644 index 000000000..bb4344c78 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/branch_end_disabled@2x.png new file mode 100644 index 000000000..8feb46d46 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end_focus.png b/src/qt/qdarkstyle/dark/rc/branch_end_focus.png new file mode 100644 index 000000000..ff713cf5f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end_focus@2x.png b/src/qt/qdarkstyle/dark/rc/branch_end_focus@2x.png new file mode 100644 index 000000000..0bd0e4ba3 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end_pressed.png b/src/qt/qdarkstyle/dark/rc/branch_end_pressed.png new file mode 100644 index 000000000..2020162f2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_end_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/branch_end_pressed@2x.png new file mode 100644 index 000000000..2a5c4fabf Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_end_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line.png b/src/qt/qdarkstyle/dark/rc/branch_line.png new file mode 100644 index 000000000..2e8c72ab6 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line@2x.png b/src/qt/qdarkstyle/dark/rc/branch_line@2x.png new file mode 100644 index 000000000..c8f07af31 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line_disabled.png b/src/qt/qdarkstyle/dark/rc/branch_line_disabled.png new file mode 100644 index 000000000..9c8c47b3d Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/branch_line_disabled@2x.png new file mode 100644 index 000000000..9b868f2a5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line_focus.png b/src/qt/qdarkstyle/dark/rc/branch_line_focus.png new file mode 100644 index 000000000..c2ab3e19e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line_focus@2x.png b/src/qt/qdarkstyle/dark/rc/branch_line_focus@2x.png new file mode 100644 index 000000000..512ee13a2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line_pressed.png b/src/qt/qdarkstyle/dark/rc/branch_line_pressed.png new file mode 100644 index 000000000..3ca15c5d0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_line_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/branch_line_pressed@2x.png new file mode 100644 index 000000000..368553102 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_line_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more.png b/src/qt/qdarkstyle/dark/rc/branch_more.png new file mode 100644 index 000000000..976354bc4 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more@2x.png b/src/qt/qdarkstyle/dark/rc/branch_more@2x.png new file mode 100644 index 000000000..9c1ab07d0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more_disabled.png b/src/qt/qdarkstyle/dark/rc/branch_more_disabled.png new file mode 100644 index 000000000..29d99a63e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/branch_more_disabled@2x.png new file mode 100644 index 000000000..aba830362 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more_focus.png b/src/qt/qdarkstyle/dark/rc/branch_more_focus.png new file mode 100644 index 000000000..20a6f27b8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more_focus@2x.png b/src/qt/qdarkstyle/dark/rc/branch_more_focus@2x.png new file mode 100644 index 000000000..6f42eea84 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more_pressed.png b/src/qt/qdarkstyle/dark/rc/branch_more_pressed.png new file mode 100644 index 000000000..4f4d9fb91 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_more_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/branch_more_pressed@2x.png new file mode 100644 index 000000000..5f18f8341 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_more_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open.png b/src/qt/qdarkstyle/dark/rc/branch_open.png new file mode 100644 index 000000000..fdf0f8b43 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open@2x.png b/src/qt/qdarkstyle/dark/rc/branch_open@2x.png new file mode 100644 index 000000000..703cd6af3 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open_disabled.png b/src/qt/qdarkstyle/dark/rc/branch_open_disabled.png new file mode 100644 index 000000000..8328e84d7 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/branch_open_disabled@2x.png new file mode 100644 index 000000000..d8d0faecb Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open_focus.png b/src/qt/qdarkstyle/dark/rc/branch_open_focus.png new file mode 100644 index 000000000..711ce0979 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open_focus@2x.png b/src/qt/qdarkstyle/dark/rc/branch_open_focus@2x.png new file mode 100644 index 000000000..b38e17a33 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open_pressed.png b/src/qt/qdarkstyle/dark/rc/branch_open_pressed.png new file mode 100644 index 000000000..441c27344 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/branch_open_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/branch_open_pressed@2x.png new file mode 100644 index 000000000..0e43e8b73 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/branch_open_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked.png new file mode 100644 index 000000000..3687e56c0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked@2x.png new file mode 100644 index 000000000..e7a6b1afe Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked_disabled.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked_disabled.png new file mode 100644 index 000000000..e3cb2f127 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png new file mode 100644 index 000000000..0c8c28a24 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked_focus.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked_focus.png new file mode 100644 index 000000000..58982ce87 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png new file mode 100644 index 000000000..ba33ba4fb Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked_pressed.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked_pressed.png new file mode 100644 index 000000000..f104bb240 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png new file mode 100644 index 000000000..bb972d68f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_checked_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate.png new file mode 100644 index 000000000..8159551de Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png new file mode 100644 index 000000000..75864b46d Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png new file mode 100644 index 000000000..181625a00 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png new file mode 100644 index 000000000..0d32c78f3 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png new file mode 100644 index 000000000..d7b19f61a Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png new file mode 100644 index 000000000..d6403ca42 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png new file mode 100644 index 000000000..37f46ca3d Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png new file mode 100644 index 000000000..aa7493edc Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_indeterminate_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked.png new file mode 100644 index 000000000..e363ed620 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked@2x.png new file mode 100644 index 000000000..520f5e2a2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png new file mode 100644 index 000000000..066185ee7 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png new file mode 100644 index 000000000..9c80ad75a Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_focus.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_focus.png new file mode 100644 index 000000000..366b868de Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png new file mode 100644 index 000000000..4ab217356 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png new file mode 100644 index 000000000..d9a0bf71c Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png new file mode 100644 index 000000000..9e2b0515e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/checkbox_unchecked_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal.png b/src/qt/qdarkstyle/dark/rc/line_horizontal.png new file mode 100644 index 000000000..4f88ddf7b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal@2x.png b/src/qt/qdarkstyle/dark/rc/line_horizontal@2x.png new file mode 100644 index 000000000..63be00c16 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal_disabled.png b/src/qt/qdarkstyle/dark/rc/line_horizontal_disabled.png new file mode 100644 index 000000000..941f14a38 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png new file mode 100644 index 000000000..972fa0800 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal_focus.png b/src/qt/qdarkstyle/dark/rc/line_horizontal_focus.png new file mode 100644 index 000000000..221fd4607 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal_focus@2x.png b/src/qt/qdarkstyle/dark/rc/line_horizontal_focus@2x.png new file mode 100644 index 000000000..7e6505cae Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal_pressed.png b/src/qt/qdarkstyle/dark/rc/line_horizontal_pressed.png new file mode 100644 index 000000000..9f9113323 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png new file mode 100644 index 000000000..465680c3b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_horizontal_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical.png b/src/qt/qdarkstyle/dark/rc/line_vertical.png new file mode 100644 index 000000000..6ee62c156 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical@2x.png b/src/qt/qdarkstyle/dark/rc/line_vertical@2x.png new file mode 100644 index 000000000..d65e74c62 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical_disabled.png b/src/qt/qdarkstyle/dark/rc/line_vertical_disabled.png new file mode 100644 index 000000000..c7c4c8959 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/line_vertical_disabled@2x.png new file mode 100644 index 000000000..b052de522 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical_focus.png b/src/qt/qdarkstyle/dark/rc/line_vertical_focus.png new file mode 100644 index 000000000..36baa0936 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical_focus@2x.png b/src/qt/qdarkstyle/dark/rc/line_vertical_focus@2x.png new file mode 100644 index 000000000..24a2b771c Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical_pressed.png b/src/qt/qdarkstyle/dark/rc/line_vertical_pressed.png new file mode 100644 index 000000000..60e357446 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/line_vertical_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/line_vertical_pressed@2x.png new file mode 100644 index 000000000..c9494051c Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/line_vertical_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked.png b/src/qt/qdarkstyle/dark/rc/radio_checked.png new file mode 100644 index 000000000..acb890155 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked@2x.png b/src/qt/qdarkstyle/dark/rc/radio_checked@2x.png new file mode 100644 index 000000000..e19047621 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked_disabled.png b/src/qt/qdarkstyle/dark/rc/radio_checked_disabled.png new file mode 100644 index 000000000..49df43922 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/radio_checked_disabled@2x.png new file mode 100644 index 000000000..a9ffd40ce Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked_focus.png b/src/qt/qdarkstyle/dark/rc/radio_checked_focus.png new file mode 100644 index 000000000..4bd472e16 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked_focus@2x.png b/src/qt/qdarkstyle/dark/rc/radio_checked_focus@2x.png new file mode 100644 index 000000000..aed5e0c94 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked_pressed.png b/src/qt/qdarkstyle/dark/rc/radio_checked_pressed.png new file mode 100644 index 000000000..ebb323b8c Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_checked_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/radio_checked_pressed@2x.png new file mode 100644 index 000000000..ffe0fd851 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_checked_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked.png new file mode 100644 index 000000000..9ffddc4a0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked@2x.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked@2x.png new file mode 100644 index 000000000..2160a32ed Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked_disabled.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked_disabled.png new file mode 100644 index 000000000..7ddff642d Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png new file mode 100644 index 000000000..4de5d0d2d Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked_focus.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked_focus.png new file mode 100644 index 000000000..e62b996b1 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png new file mode 100644 index 000000000..eaf7bc26b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked_pressed.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked_pressed.png new file mode 100644 index 000000000..8aaa343e8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png new file mode 100644 index 000000000..ba4f83b91 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/radio_unchecked_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal.png new file mode 100644 index 000000000..fa449d6ee Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png new file mode 100644 index 000000000..682575ee2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png new file mode 100644 index 000000000..568b0fbe1 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png new file mode 100644 index 000000000..4d15f1478 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png new file mode 100644 index 000000000..cdb96bfb9 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png new file mode 100644 index 000000000..23e06a015 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png new file mode 100644 index 000000000..9ce6f8d89 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png new file mode 100644 index 000000000..4d8e53e8e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_horizontal_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical.png new file mode 100644 index 000000000..bbc8abb1f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png new file mode 100644 index 000000000..136ebae2c Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png new file mode 100644 index 000000000..37453ac25 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png new file mode 100644 index 000000000..cca8f6d96 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png new file mode 100644 index 000000000..b54877181 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png new file mode 100644 index 000000000..d4dd49dec Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png new file mode 100644 index 000000000..768ebaf4c Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png new file mode 100644 index 000000000..2f170ffd8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_move_vertical_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal.png new file mode 100644 index 000000000..01e350132 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png new file mode 100644 index 000000000..68d768e5e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png new file mode 100644 index 000000000..f8796f9e6 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png new file mode 100644 index 000000000..1d9f20421 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png new file mode 100644 index 000000000..b592e61c1 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png new file mode 100644 index 000000000..a593a7e76 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png new file mode 100644 index 000000000..a806257e0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png new file mode 100644 index 000000000..e1e8e3c14 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_horizontal_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical.png new file mode 100644 index 000000000..2a14f5cbd Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png new file mode 100644 index 000000000..35371feea Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png new file mode 100644 index 000000000..48b2657f5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png new file mode 100644 index 000000000..a2173c5ee Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png new file mode 100644 index 000000000..e31c694b0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png new file mode 100644 index 000000000..ce743cc86 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png new file mode 100644 index 000000000..4ee7aaaab Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png new file mode 100644 index 000000000..d8bf93bf6 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/toolbar_separator_vertical_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent.png b/src/qt/qdarkstyle/dark/rc/transparent.png new file mode 100644 index 000000000..67753617f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent@2x.png b/src/qt/qdarkstyle/dark/rc/transparent@2x.png new file mode 100644 index 000000000..4012944b5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent_disabled.png b/src/qt/qdarkstyle/dark/rc/transparent_disabled.png new file mode 100644 index 000000000..67753617f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/transparent_disabled@2x.png new file mode 100644 index 000000000..4012944b5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent_focus.png b/src/qt/qdarkstyle/dark/rc/transparent_focus.png new file mode 100644 index 000000000..67753617f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent_focus@2x.png b/src/qt/qdarkstyle/dark/rc/transparent_focus@2x.png new file mode 100644 index 000000000..4012944b5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent_pressed.png b/src/qt/qdarkstyle/dark/rc/transparent_pressed.png new file mode 100644 index 000000000..67753617f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/transparent_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/transparent_pressed@2x.png new file mode 100644 index 000000000..4012944b5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/transparent_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close.png b/src/qt/qdarkstyle/dark/rc/window_close.png new file mode 100644 index 000000000..0b67d3bcc Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close@2x.png b/src/qt/qdarkstyle/dark/rc/window_close@2x.png new file mode 100644 index 000000000..bb8ac7da5 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close_disabled.png b/src/qt/qdarkstyle/dark/rc/window_close_disabled.png new file mode 100644 index 000000000..46de804b8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/window_close_disabled@2x.png new file mode 100644 index 000000000..8e4cd15d8 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close_focus.png b/src/qt/qdarkstyle/dark/rc/window_close_focus.png new file mode 100644 index 000000000..bb7d8c511 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close_focus@2x.png b/src/qt/qdarkstyle/dark/rc/window_close_focus@2x.png new file mode 100644 index 000000000..692ce24f2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close_pressed.png b/src/qt/qdarkstyle/dark/rc/window_close_pressed.png new file mode 100644 index 000000000..53ae7f38e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_close_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/window_close_pressed@2x.png new file mode 100644 index 000000000..e02b12292 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_close_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip.png b/src/qt/qdarkstyle/dark/rc/window_grip.png new file mode 100644 index 000000000..db9ccb877 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip@2x.png b/src/qt/qdarkstyle/dark/rc/window_grip@2x.png new file mode 100644 index 000000000..30b0639f4 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip_disabled.png b/src/qt/qdarkstyle/dark/rc/window_grip_disabled.png new file mode 100644 index 000000000..97c0e0f90 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/window_grip_disabled@2x.png new file mode 100644 index 000000000..7a3d8de6d Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip_focus.png b/src/qt/qdarkstyle/dark/rc/window_grip_focus.png new file mode 100644 index 000000000..99b27c9ce Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip_focus@2x.png b/src/qt/qdarkstyle/dark/rc/window_grip_focus@2x.png new file mode 100644 index 000000000..833cb90a9 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip_pressed.png b/src/qt/qdarkstyle/dark/rc/window_grip_pressed.png new file mode 100644 index 000000000..afea9749e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_grip_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/window_grip_pressed@2x.png new file mode 100644 index 000000000..c1c1a0e4b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_grip_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize.png b/src/qt/qdarkstyle/dark/rc/window_minimize.png new file mode 100644 index 000000000..d8c54ebf2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize@2x.png b/src/qt/qdarkstyle/dark/rc/window_minimize@2x.png new file mode 100644 index 000000000..5421a3690 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize_disabled.png b/src/qt/qdarkstyle/dark/rc/window_minimize_disabled.png new file mode 100644 index 000000000..cc51ed0ee Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/window_minimize_disabled@2x.png new file mode 100644 index 000000000..c1676469f Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize_focus.png b/src/qt/qdarkstyle/dark/rc/window_minimize_focus.png new file mode 100644 index 000000000..1dcd083c0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize_focus@2x.png b/src/qt/qdarkstyle/dark/rc/window_minimize_focus@2x.png new file mode 100644 index 000000000..2a4c868e0 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize_pressed.png b/src/qt/qdarkstyle/dark/rc/window_minimize_pressed.png new file mode 100644 index 000000000..0bb532126 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_minimize_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/window_minimize_pressed@2x.png new file mode 100644 index 000000000..5a515c806 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_minimize_pressed@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock.png b/src/qt/qdarkstyle/dark/rc/window_undock.png new file mode 100644 index 000000000..d1f454259 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock@2x.png b/src/qt/qdarkstyle/dark/rc/window_undock@2x.png new file mode 100644 index 000000000..f0efa3429 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock_disabled.png b/src/qt/qdarkstyle/dark/rc/window_undock_disabled.png new file mode 100644 index 000000000..6a609492b Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock_disabled.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock_disabled@2x.png b/src/qt/qdarkstyle/dark/rc/window_undock_disabled@2x.png new file mode 100644 index 000000000..c2e1b8fa7 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock_disabled@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock_focus.png b/src/qt/qdarkstyle/dark/rc/window_undock_focus.png new file mode 100644 index 000000000..d6eebbdc2 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock_focus.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock_focus@2x.png b/src/qt/qdarkstyle/dark/rc/window_undock_focus@2x.png new file mode 100644 index 000000000..1aef06053 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock_focus@2x.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock_pressed.png b/src/qt/qdarkstyle/dark/rc/window_undock_pressed.png new file mode 100644 index 000000000..8b6beb19e Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock_pressed.png differ diff --git a/src/qt/qdarkstyle/dark/rc/window_undock_pressed@2x.png b/src/qt/qdarkstyle/dark/rc/window_undock_pressed@2x.png new file mode 100644 index 000000000..677ded425 Binary files /dev/null and b/src/qt/qdarkstyle/dark/rc/window_undock_pressed@2x.png differ diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 21f9a7e80..e2d6759ad 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -124,7 +124,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) return; while (config->type != -1) { - const int config_type = config->type & CONFIG_TYPE_MASK; + const int config_type = config->type & CONFIG_TYPE_MASK; /* Ignore options of the wrong class. */ if (!!(config->type & CONFIG_DEP) != is_dep) @@ -168,7 +168,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) auto *cbox = new QCheckBox(); cbox->setObjectName(config->name); cbox->setChecked(value > 0); - this->ui->formLayout->addRow(config->description, cbox); + this->ui->formLayout->addRow(tr(config->description), cbox); break; } #ifdef USE_RTMIDI @@ -187,7 +187,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) if (i == value) currentIndex = i; } - this->ui->formLayout->addRow(config->description, cbox); + this->ui->formLayout->addRow(tr(config->description), cbox); cbox->setCurrentIndex(currentIndex); break; } @@ -206,7 +206,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) if (i == value) currentIndex = i; } - this->ui->formLayout->addRow(config->description, cbox); + this->ui->formLayout->addRow(tr(config->description), cbox); cbox->setCurrentIndex(currentIndex); break; } @@ -224,12 +224,12 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { - int row = Models::AddEntry(model, sel->description, sel->value); + int row = Models::AddEntry(model, tr(sel->description), sel->value); if (sel->value == value) currentIndex = row; } - this->ui->formLayout->addRow(config->description, cbox); + this->ui->formLayout->addRow(tr(config->description), cbox); cbox->setCurrentIndex(currentIndex); break; } @@ -248,13 +248,13 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) for (int d = 0; d < bios->files_no; d++) p += !!rom_present(const_cast(bios->files[d])); if (p == bios->files_no) { - const int row = Models::AddEntry(model, bios->name, q); + const int row = Models::AddEntry(model, tr(bios->name), q); if (!strcmp(selected.toUtf8().constData(), bios->internal_name)) currentIndex = row; } q++; } - this->ui->formLayout->addRow(config->description, cbox); + this->ui->formLayout->addRow(tr(config->description), cbox); cbox->setCurrentIndex(currentIndex); break; } @@ -267,7 +267,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) if (config->spinner.step > 0) spinBox->setSingleStep(config->spinner.step); spinBox->setValue(value); - this->ui->formLayout->addRow(config->description, spinBox); + this->ui->formLayout->addRow(tr(config->description), spinBox); break; } case CONFIG_FNAME: @@ -277,7 +277,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) fileField->setFileName(selected); fileField->setFilter(QString(config->file_filter).left(static_cast(strcspn(config->file_filter, "|")))); - this->ui->formLayout->addRow(config->description, fileField); + this->ui->formLayout->addRow(tr(config->description), fileField); break; } case CONFIG_STRING: @@ -286,7 +286,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) lineEdit->setObjectName(config->name); lineEdit->setCursor(Qt::IBeamCursor); lineEdit->setText(selected); - this->ui->formLayout->addRow(config->description, lineEdit); + this->ui->formLayout->addRow(tr(config->description), lineEdit); break; } case CONFIG_SERPORT: @@ -305,7 +305,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) currentIndex = row; } - this->ui->formLayout->addRow(config->description, cbox); + this->ui->formLayout->addRow(tr(config->description), cbox); cbox->setCurrentIndex(currentIndex); break; } @@ -337,7 +337,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) }); hboxLayout->addWidget(lineEdit); hboxLayout->addWidget(generateButton); - this->ui->formLayout->addRow(config->description, hboxLayout); + this->ui->formLayout->addRow(tr(config->description), hboxLayout); break; } } @@ -349,15 +349,15 @@ void DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) { DeviceConfig dc(settings); - dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); + dc.setWindowTitle(tr("%1 Device Configuration").arg(tr(device->name))); device_context_t device_context; device_set_context(&device_context, device, instance); - const auto device_label = new QLabel(device->name); + const auto device_label = new QLabel(tr(device->name)); device_label->setAlignment(Qt::AlignCenter); dc.ui->formLayout->addRow(device_label); - const auto line = new QFrame; + const auto line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); dc.ui->formLayout->addRow(line); @@ -457,12 +457,12 @@ DeviceConfig::DeviceName(const _device_ *device, const char *internalName, const if (QStringLiteral("none") == internalName) return tr("None"); else if (QStringLiteral("internal") == internalName) - return tr("Internal controller"); + return tr("Internal device"); else if (device == nullptr) return ""; else { char temp[512]; device_get_name(device, bus, temp); - return tr(temp, nullptr, 512); + return tr((const char *) temp); } } diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index df10a6d38..2acaaeacc 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -20,6 +20,9 @@ #include "ui_qt_harddiskdialog.h" extern "C" { +#ifdef __unix__ +#include +#endif #include <86box/86box.h> #include <86box/hdd.h> #include "../disk/minivhd/minivhd.h" @@ -227,7 +230,11 @@ static HarddiskDialog *callbackPtr = nullptr; static MVHDGeom create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt) { - MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; + MVHDGeom _86box_geometry = { + .cyl = cyl, + .heads = heads, + .spt = spt + }; MVHDGeom vhd_geometry; adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); @@ -253,7 +260,11 @@ create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, static MVHDGeom create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) { - MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; + MVHDGeom _86box_geometry = { + .cyl = cyl, + .heads = heads, + .spt = spt + }; MVHDGeom vhd_geometry; adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); int vhd_error = 0; @@ -447,6 +458,7 @@ HarddiskDialog::onCreateNewFile() } // formats 0, 1 and 2 +#ifndef __unix__ connect(this, &HarddiskDialog::fileProgress, this, [this](int value) { ui->progressBar->setValue(value); QApplication::processEvents(); }); ui->progressBar->setVisible(true); [size, &file, this] { @@ -469,6 +481,13 @@ HarddiskDialog::onCreateNewFile() } emit fileProgress(100); }(); +#else + int ret = ftruncate(file.handle(), (size_t) size); + + if (ret) { + QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); + } +#endif QMessageBox::information(this, tr("Disk image created"), tr("Remember to partition and format the newly-created drive.")); setResult(QDialog::Accepted); diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index 8489dfd22..62a9302d1 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -41,7 +41,7 @@ JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget Models::AddEntry(model, plat_joystick_state[c].name, c + 1); } - ui->comboBoxDevice->setCurrentIndex(joystick_state[joystick_nr].plat_joystick_nr); + ui->comboBoxDevice->setCurrentIndex(joystick_state[0][joystick_nr].plat_joystick_nr); layout()->setSizeConstraint(QLayout::SetFixedSize); } @@ -119,7 +119,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) } int nr_axes = plat_joystick_state[joystick].nr_axes; - int mapping = joystick_state[joystick_nr].axis_mapping[c]; + int mapping = joystick_state[0][joystick_nr].axis_mapping[c]; if (mapping & POV_X) cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2); else if (mapping & POV_Y) @@ -147,7 +147,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, plat_joystick_state[joystick].button[d].name, 0); } - cbox->setCurrentIndex(joystick_state[joystick_nr].button_mapping[c]); + cbox->setCurrentIndex(joystick_state[0][joystick_nr].button_mapping[c]); ui->ct->addWidget(label, row, 0); ui->ct->addWidget(cbox, row, 1); @@ -179,7 +179,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); } - int mapping = joystick_state[joystick_nr].pov_mapping[c / 2][c & 1]; + int mapping = joystick_state[0][joystick_nr].pov_mapping[c / 2][c & 1]; int nr_povs = plat_joystick_state[joystick].nr_povs; if (mapping & POV_X) cbox->setCurrentIndex((mapping & 3) * 2); diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 64f3b0e43..d1335873c 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -61,6 +61,8 @@ extern uint64_t tsc; extern MainWindow *main_window; +static bool sbar_initialized = false; + namespace { struct PixmapSetActive { QPixmap normal; @@ -367,12 +369,12 @@ MachineStatus::iterateNIC(const std::function &cb) } static int -hdd_count(int bus) +hdd_count(const int bus_type) { int c = 0; for (uint8_t i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus == bus) { + if (hdd[i].bus_type == bus_type) { c++; } } @@ -380,6 +382,31 @@ hdd_count(int bus) return c; } +void +MachineStatus::refreshEmptyIcons() +{ + /* Check if icons are initialized. */ + if (!sbar_initialized) + return; + + for (size_t i = 0; i < FDD_NUM; ++i) + d->fdd[i].setEmpty(machine_status.fdd[i].empty); + 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++) + d->mo[i].setEmpty(machine_status.mo[i].empty); + + d->cassette.setEmpty(machine_status.cassette.empty); + + for (size_t i = 0; i < NET_CARD_MAX; i++) + d->net[i].setEmpty(machine_status.net[i].empty); + + for (int i = 0; i < 2; ++i) + d->cartridge[i].setEmpty(machine_status.cartridge[i].empty); +} + void MachineStatus::refreshIcons() { @@ -387,48 +414,32 @@ MachineStatus::refreshIcons() if (!update_icons) return; - for (size_t i = 0; i < FDD_NUM; ++i) { + for (size_t i = 0; i < FDD_NUM; ++i) d->fdd[i].setActive(machine_status.fdd[i].active); - d->fdd[i].setEmpty(machine_status.fdd[i].empty); - } for (size_t i = 0; i < CDROM_NUM; ++i) { d->cdrom[i].setActive(machine_status.cdrom[i].active); if (machine_status.cdrom[i].active) ui_sb_update_icon(SB_CDROM | i, 0); - - d->cdrom[i].setEmpty(machine_status.cdrom[i].empty); } for (size_t i = 0; i < ZIP_NUM; i++) { d->zip[i].setActive(machine_status.zip[i].active); if (machine_status.zip[i].active) ui_sb_update_icon(SB_ZIP | i, 0); - - d->zip[i].setEmpty(machine_status.zip[i].empty); } for (size_t i = 0; i < MO_NUM; i++) { d->mo[i].setActive(machine_status.mo[i].active); if (machine_status.mo[i].active) ui_sb_update_icon(SB_MO | i, 0); - - d->mo[i].setEmpty(machine_status.mo[i].empty); } - d->cassette.setEmpty(machine_status.cassette.empty); - for (size_t i = 0; i < HDD_BUS_USB; i++) { d->hdds[i].setActive(machine_status.hdd[i].active); if (machine_status.hdd[i].active) ui_sb_update_icon(SB_HDD | i, 0); } - for (size_t i = 0; i < NET_CARD_MAX; i++) { + for (size_t i = 0; i < NET_CARD_MAX; i++) d->net[i].setActive(machine_status.net[i].active); - d->net[i].setEmpty(machine_status.net[i].empty); - } - - for (int i = 0; i < 2; ++i) { - d->cartridge[i].setEmpty(machine_status.cartridge[i].empty); - } } void @@ -664,6 +675,10 @@ MachineStatus::refresh(QStatusBar *sbar) sbar->addWidget(d->sound.get()); d->text = std::make_unique(); sbar->addWidget(d->text.get()); + + sbar_initialized = true; + + refreshEmptyIcons(); } void @@ -719,4 +734,6 @@ MachineStatus::updateTip(int tag) case SB_TEXT: break; } + + refreshEmptyIcons(); } diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index cf706180d..fc0e33e91 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -75,6 +75,7 @@ public slots: void refresh(QStatusBar *sbar); void message(const QString &msg); void updateTip(int tag); + void refreshEmptyIcons(); void refreshIcons(); private: diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c39007864..72b0eef53 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -31,6 +31,8 @@ #include #include #include +#include +#include #ifdef QT_STATIC /* Static builds need plugin imports */ @@ -42,13 +44,6 @@ Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) # endif #endif -#ifdef Q_OS_WINDOWS -# include "qt_winrawinputfilter.hpp" -# include "qt_winmanagerfilter.hpp" -# include <86box/win.h> -# include -#endif - extern "C" { #include <86box/86box.h> #include <86box/config.h> @@ -62,6 +57,15 @@ extern "C" { #include <86box/version.h> } +#ifdef Q_OS_WINDOWS +# include "qt_rendererstack.hpp" +# include "qt_winrawinputfilter.hpp" +# include "qt_winmanagerfilter.hpp" +# include <86box/win.h> +# include +# include +#endif + #include #include #include @@ -81,6 +85,7 @@ extern QElapsedTimer elapsed_timer; extern MainWindow *main_window; extern "C" { +#include <86box/keyboard.h> #include <86box/timer.h> #include <86box/nvr.h> extern int qt_nvr_save(void); @@ -88,6 +93,177 @@ extern int qt_nvr_save(void); void qt_set_sequence_auto_mnemonic(bool b); +#ifdef Q_OS_WINDOWS +static void +keyboard_getkeymap() +{ + const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + const LPCSTR valueName = "Scancode Map"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; + + /* First, prepare the default scan code map list which is 1:1. + * Remappings will be inserted directly into it. + * 512 bytes so this takes less memory, bit 9 set means E0 + * prefix. + */ + for (j = 0; j < 512; j++) + scancode_map[j] = j; + + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + bufSize = 32768; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { + bufEx2 = (UINT32 *) buf; + scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) { + bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount * 2; j += 2) { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + scancode_unmapped = bufEx[j + 1]; + scancode_mapped = bufEx[j]; + + scancode_unmapped = convert_scan_code(scancode_unmapped); + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Ignore source scan codes with prefixes other than E1 + that are not E1 1D. */ + if (scancode_unmapped != 0xFFFF) + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +void +win_keyboard_handle(uint32_t scancode, int up, int e0, int e1) +{ + /* If it's not a scan code that starts with 0xE1 */ + if (e1) { + if (scancode == 0x1D) { + scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would + otherwise be E0 00 but that is invalid + anyway). + Also, take a potential mapping into + account. */ + } else + scancode = 0xFFFF; + if (scancode != 0xFFFF) + keyboard_input(!up, scancode); + } else { + if (e0) + scancode |= 0x100; + + /* Translate the scan code to 9-bit */ + scancode = convert_scan_code(scancode); + + /* Remap it according to the list from the Registry */ + if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { + // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); + scancode = scancode_map[scancode]; + } + + /* If it's not 0xFFFF, send it to the emulated + keyboard. + We use scan code 0xFFFF to mean a mapping that + has a prefix other than E0 and that is not E1 1D, + which is, for our purposes, invalid. */ + + /* Translate right CTRL to left ALT if the user has so + chosen. */ + if ((scancode == 0x11d) && rctrl_is_lalt) + scancode = 0x038; + + /* Normal scan code pass through, pass it through as is if + it's not an invalid scan code. */ + if (scancode != 0xFFFF) + keyboard_input(!up, scancode); + + main_window->checkFullscreenHotkey(); + } +} + +static LRESULT CALLBACK +emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; + /* Checks if CTRL was pressed. */ + BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); + BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId())); + BOOL ret = TRUE; + + static int last = 0; + + if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { + const auto &secondaryRenderer = main_window->renderers[monitor_index]; + is_over_window = is_over_window || ((secondaryRenderer != nullptr) && + (GetForegroundWindow() == ((HWND) secondaryRenderer->winId()))); + } + + if ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window) + return CallNextHookEx(NULL, nCode, wParam, lParam); + else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + ret = TRUE; + else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + ret = TRUE; + else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + ret = TRUE; + else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + ret = TRUE; + else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + ret = TRUE; + else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && + !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + ret = TRUE; + else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) + ret = TRUE; + else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) + ret = TRUE; + else + ret = CallNextHookEx(NULL, nCode, wParam, lParam); + + if (lpKdhs->scanCode == 0x00000045) { + if ((lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000090)) { + /* NumLock. */ + lpKdhs->flags &= ~LLKHF_EXTENDED; + } else if (!(lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000013)) { + /* Pause - send E1 1D. */ + win_keyboard_handle(0xe1, 0, 0, 0); + win_keyboard_handle(0x1d, LLKHF_UP, 0, 0); + } + } else if (!last && (lpKdhs->scanCode == 0x00000036)) + /* Non-fake right shift. */ + lpKdhs->flags &= ~LLKHF_EXTENDED; + + if (lpKdhs->scanCode == 0x00000236) + last = 1; + else if (last && (lpKdhs->scanCode == 0x00000036)) + last = 0; + + win_keyboard_handle(lpKdhs->scanCode, lpKdhs->flags & LLKHF_UP, lpKdhs->flags & LLKHF_EXTENDED, 0); + + return ret; +} +#endif + +#ifdef Q_OS_WINDOWS +static HHOOK llhook = NULL; +#endif + void main_thread_fn() { @@ -138,9 +314,18 @@ main_thread_fn() } } else { /* Just so we dont overload the host OS. */ + + /* Trigger a hard reset if one is pending. */ + if (hard_reset_pending) { + hard_reset_pending = 0; + pc_reset_hard_close(); + pc_reset_hard_init(); + } + if (dopause) ack_pause(); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + + plat_delay_ms(1); } } @@ -148,7 +333,7 @@ main_thread_fn() for (uint8_t i = 1; i < GFXCARD_MAX; i ++) { if (gfxcard[i]) { ui_deinit_monitor(i); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); + plat_delay_ms(500); } } QTimer::singleShot(0, QApplication::instance(), []() { QApplication::processEvents(); QApplication::instance()->quit(); }); @@ -156,6 +341,10 @@ main_thread_fn() static std::thread *main_thread; +#ifdef Q_OS_WINDOWS +extern bool windows_is_light_theme(); +#endif + int main(int argc, char *argv[]) { @@ -167,9 +356,27 @@ main(int argc, char *argv[]) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif + QApplication app(argc, argv); QLocale::setDefault(QLocale::C); +#ifdef Q_OS_WINDOWS + Q_INIT_RESOURCE(darkstyle); + QApplication::setAttribute(Qt::AA_NativeWindows); + + if (!windows_is_light_theme()) { + QFile f(":qdarkstyle/dark/darkstyle.qss"); + + if (!f.exists()) { + printf("Unable to set stylesheet, file not found\n"); + } else { + f.open(QFile::ReadOnly | QFile::Text); + QTextStream ts(&f); + qApp->setStyleSheet(ts.readAll()); + } + } +#endif + qt_set_sequence_auto_mnemonic(false); Q_INIT_RESOURCE(qt_resources); Q_INIT_RESOURCE(qt_translations); @@ -184,6 +391,13 @@ main(int argc, char *argv[]) #endif elapsed_timer.start(); + for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++) + scancode_map[i] = i; + +#ifdef Q_OS_WINDOWS + keyboard_getkeymap(); +#endif + if (!pc_init(argc, argv)) { return 0; } @@ -331,6 +545,21 @@ main(int argc, char *argv[]) }); } + /* Force raw input if a debugger is present. */ + if (IsDebuggerPresent()) { + pclog("WARNING: Debugged detected, forcing raw input\n"); + hook_enabled = 0; + } + + if (hook_enabled) { + /* Yes, low-level hooks *DO* work with raw input, at least global ones. */ + llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); + atexit([] () -> void { + if (llhook) + UnhookWindowsHookEx(llhook); + }); + } + /* Setup raw input */ auto rawInputFilter = WindowsRawInputFilter::Register(main_window); if (rawInputFilter) { @@ -383,15 +612,16 @@ main(int argc, char *argv[]) /* Initialize the rendering window, or fullscreen. */ QTimer::singleShot(0, &app, [] { pc_reset_hard_init(); - main_thread = new std::thread(main_thread_fn); /* Set the PAUSE mode depending on the renderer. */ #ifdef USE_VNC - if (vnc_enabled && vid_api != 5) + if (vid_api == 5) plat_pause(1); else #endif plat_pause(0); + + main_thread = new std::thread(main_thread_fn); }); const auto ret = app.exec(); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 32720c48b..3ee58f23b 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -946,10 +946,9 @@ MainWindow::on_actionSettings_triggered() default: break; case QDialog::Accepted: - pc_reset_hard_close(); settings.save(); config_changed = 2; - pc_reset_hard_init(); + pc_reset_hard(); break; case QDialog::Rejected: break; @@ -1726,7 +1725,8 @@ MainWindow::on_actionAbout_86Box_triggered() 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("About 86Box"); - msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); + 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)); @@ -1905,6 +1905,13 @@ MainWindow::updateUiPauseState() ui->actionPause->setToolTip(tooltip_text); } +void +MainWindow::updateStatusEmptyIcons() +{ + if (status != nullptr) + status->refreshEmptyIcons(); +} + void MainWindow::on_actionPreferences_triggered() { diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 175ef5b7e..25e33d77c 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -63,6 +63,7 @@ public slots: void togglePause(); void initRendererMonitorSlot(int monitor_index); void destroyRendererMonitorSlot(int monitor_index); + void updateStatusEmptyIcons(); void updateUiPauseState(); private slots: void on_actionFullscreen_triggered(); @@ -176,6 +177,7 @@ private: friend class ProgSettings; friend class RendererCommon; friend class RendererStack; // For UI variable access by non-primary renderer windows. + friend class WindowsRawInputFilter; // Needed to reload renderers on style sheet changes. }; #endif // QT_MAINWINDOW_HPP diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 672ccfa8d..d548c0779 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -24,8 +24,15 @@ extern "C" { #include <86box/timer.h> -#include <86box/cdrom.h> +#include <86box/device.h> +#include <86box/cassette.h> +#include <86box/cartridge.h> #include <86box/fdd.h> +#include <86box/cdrom.h> +#include <86box/scsi_device.h> +#include <86box/zip.h> +#include <86box/mo.h> +#include <86box/path.h> } namespace ui { @@ -100,7 +107,14 @@ MediaHistoryManager::getImageForSlot(int index, int slot, ui::MediaType type) int MediaHistoryManager::maxDevicesSupported(ui::MediaType type) { - return type == ui::MediaType::Cassette ? 1 : 4; + switch (type) { + default: + return 4; + case ui::MediaType::Cassette: + return 1; + case ui::MediaType::Cartridge: + return 2; + } } void @@ -163,14 +177,26 @@ MediaHistoryManager::initialDeduplication() for (int device_index = 0; device_index < maxDevicesSupported(device_type); device_index++) { device_index_list_t device_history = getHistoryListForDeviceIndex(device_index, device_type); switch (device_type) { - case ui::MediaType::Optical: - current_image = cdrom[device_index].image_path; + default: + continue; + break; + case ui::MediaType::Cassette: + current_image = cassette_fname; + break; + case ui::MediaType::Cartridge: + current_image = cart_fns[device_index]; break; case ui::MediaType::Floppy: current_image = floppyfns[device_index]; break; - default: - continue; + case ui::MediaType::Optical: + current_image = cdrom[device_index].image_path; + break; + case ui::MediaType::Zip: + current_image = zip_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)); @@ -190,12 +216,20 @@ char ** MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index) { switch (type) { - case ui::MediaType::Optical: - return &cdrom[index].image_history[0]; - case ui::MediaType::Floppy: - return &fdd_image_history[index][0]; default: return nullptr; + case ui::MediaType::Cassette: + return &cassette_image_history[0]; + case ui::MediaType::Cartridge: + return &cart_image_history[index][0]; + case ui::MediaType::Floppy: + 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::Mo: + return &mo_drives[index].image_history[0]; } } @@ -275,9 +309,6 @@ MediaHistoryManager::pathAdjustSingle(QString checked_path) if (file_info.filePath().isEmpty() || current_usr_path.isEmpty() || file_info.isRelative()) { return checked_path; } - if (file_info.filePath().startsWith(current_usr_path)) { - checked_path = file_info.filePath().remove(current_usr_path); - } return checked_path; } @@ -304,10 +335,28 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) if (file_info.filePath().isEmpty()) { continue; } - // For this check, explicitly prepend `usr_path` to relative paths to account for $CWD platform variances - QFileInfo absolute_path = file_info.isRelative() ? QFileInfo(getUsrPath().append(file_info.filePath())) : file_info; - if ((file_info.filePath().left(8) != "ioctl://") && !absolute_path.exists()) { - qWarning("Image file %s does not exist - removing from history", qPrintable(file_info.filePath())); + + 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()); + } 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); + else + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), checked_path.toUtf8().constData()); + } + path_normalize(temp); + + QString qstr = QString::fromUtf8(temp); + QFileInfo new_fi(qstr); + + if ((new_fi.filePath().left(8) != "ioctl://") && !new_fi.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 4eae46f9c..29ada8e2a 100644 --- a/src/qt/qt_mediahistorymanager.hpp +++ b/src/qt/qt_mediahistorymanager.hpp @@ -47,7 +47,8 @@ enum class MediaType { Optical, Zip, Mo, - Cassette + Cassette, + Cartridge }; // This macro allows us to do a reverse lookup of the enum with `QMetaEnum` Q_ENUM_NS(MediaType) @@ -61,6 +62,10 @@ typedef QHash master_list_t; static const MediaType AllSupportedMediaHistoryTypes[] = { MediaType::Optical, MediaType::Floppy, + MediaType::Zip, + MediaType::Mo, + MediaType::Cassette, + MediaType::Cartridge }; class MediaHistoryManager { diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index c80d9d17f..fdea16c2a 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -91,6 +91,11 @@ MediaMenu::refresh(QMenu *parentMenu) cassetteMenu->addAction(tr("&Existing image..."), [this]() { cassetteSelectImage(false); }); cassetteMenu->addAction(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(QString::asprintf(tr("Image %i").toUtf8().constData(), 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); cassettePlayPos = cassetteMenu->children().count(); @@ -111,6 +116,11 @@ MediaMenu::refresh(QMenu *parentMenu) auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); menu->addSeparator(); + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + cartridgeImageHistoryPos[slot] = menu->children().count(); + menu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { cartridgeMenuSelect(i, slot); })->setCheckable(false); + } + menu->addSeparator(); cartridgeEjectPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { cartridgeEject(i); }); cartridgeMenus[i] = menu; @@ -179,10 +189,13 @@ MediaMenu::refresh(QMenu *parentMenu) menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); menu->addAction(tr("Existing image (&Write-protected)..."), [this, i]() { zipSelectImage(i, true); }); menu->addSeparator(); + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + zipImageHistoryPos[slot] = menu->children().count(); + menu->addAction(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { zipReload(i, slot); })->setCheckable(false); + } + menu->addSeparator(); zipEjectPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { zipEject(i); }); - zipReloadPos = menu->children().count(); - menu->addAction(tr("&Reload previous image"), [this, i]() { zipReload(i); }); zipMenus[i] = menu; zipUpdateMenu(i); }); @@ -195,10 +208,13 @@ MediaMenu::refresh(QMenu *parentMenu) menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); menu->addAction(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(QString::asprintf(tr("Image %i").toUtf8().constData(), slot), [this, i, slot]() { moReload(i, slot); })->setCheckable(false); + } + menu->addSeparator(); moEjectPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { moEject(i); }); - moReloadPos = menu->children().count(); - menu->addAction(tr("&Reload previous image"), [this, i]() { moReload(i); }); moMenus[i] = menu; moUpdateMenu(i); }); @@ -243,9 +259,19 @@ MediaMenu::cassetteSelectImage(bool wp) cassetteMount(filename, wp); } +void +MediaMenu::cassetteMenuSelect(int slot) +{ + QString filename = mhm.getImageForSlot(0, slot, ui::MediaType::Cassette); + cassetteMount(filename.toUtf8().constData(), 0); + cassetteUpdateMenu(); + ui_sb_update_tip(SB_CASSETTE); +} + void MediaMenu::cassetteMount(const QString &filename, bool wp) { + auto previous_image = QFileInfo(cassette_fname); pc_cas_set_fname(cassette, nullptr); memset(cassette_fname, 0, sizeof(cassette_fname)); cassette_ui_writeprot = wp ? 1 : 0; @@ -257,6 +283,7 @@ MediaMenu::cassetteMount(const QString &filename, bool wp) } ui_sb_update_icon_state(SB_CASSETTE, filename.isEmpty() ? 1 : 0); + mhm.addImageToHistory(0, ui::MediaType::Cassette, previous_image.filePath(), filename); cassetteUpdateMenu(); ui_sb_update_tip(SB_CASSETTE); config_save(); @@ -265,6 +292,7 @@ MediaMenu::cassetteMount(const QString &filename, bool wp) void MediaMenu::cassetteEject() { + mhm.addImageToHistory(0, ui::MediaType::Cassette, cassette_fname, QString()); pc_cas_set_fname(cassette, nullptr); memset(cassette_fname, 0, sizeof(cassette_fname)); ui_sb_update_icon_state(SB_CASSETTE, 1); @@ -297,16 +325,22 @@ MediaMenu::cassetteUpdateMenu() cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); + + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + updateImageHistory(0, slot, ui::MediaType::Cassette); + } } void MediaMenu::cartridgeMount(int i, const QString &filename) { + auto previous_image = QFileInfo(cart_fns[i]); cart_close(i); QByteArray filenameBytes = filename.toUtf8(); cart_load(i, filenameBytes.data()); ui_sb_update_icon_state(SB_CARTRIDGE | i, filename.isEmpty() ? 1 : 0); + mhm.addImageToHistory(i, ui::MediaType::Cartridge, previous_image.filePath(), filename); cartridgeUpdateMenu(i); ui_sb_update_tip(SB_CARTRIDGE | i); config_save(); @@ -327,9 +361,19 @@ MediaMenu::cartridgeSelectImage(int i) cartridgeMount(i, filename); } +void +MediaMenu::cartridgeMenuSelect(int index, int slot) +{ + QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Cartridge); + cartridgeMount(index, filename.toUtf8().constData()); + cartridgeUpdateMenu(index); + ui_sb_update_tip(SB_CARTRIDGE | index); +} + void MediaMenu::cartridgeEject(int i) { + mhm.addImageToHistory(i, ui::MediaType::Cartridge, cart_fns[i], QString()); cart_close(i); ui_sb_update_icon_state(SB_CARTRIDGE | i, 1); cartridgeUpdateMenu(i); @@ -347,6 +391,10 @@ MediaMenu::cartridgeUpdateMenu(int i) ejectMenu->setEnabled(!name.isEmpty()); // menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("Cartridge %i: %ls").toUtf8().constData(), i + 1, name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); + + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + updateImageHistory(i, slot, ui::MediaType::Cartridge); + } } void @@ -476,13 +524,11 @@ MediaMenu::cdromMute(int i) void MediaMenu::cdromMount(int i, const QString &filename) { - QByteArray fn = filename.toUtf8().data(); + QByteArray fn = filename.toUtf8().data(); + int was_empty = cdrom_is_empty(i); - strcpy(cdrom[i].prev_image_path, cdrom[i].image_path); - if (cdrom[i].ops && cdrom[i].ops->exit) - cdrom[i].ops->exit(&(cdrom[i])); + cdrom_exit(i); - cdrom[i].ops = nullptr; memset(cdrom[i].image_path, 0, sizeof(cdrom[i].image_path)); #ifdef Q_OS_WINDOWS if ((fn.data() != nullptr) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '/')) @@ -491,14 +537,17 @@ MediaMenu::cdromMount(int i, const QString &filename) if ((fn.data() != NULL) && (strlen(fn.data()) >= 1) && (fn.data()[strlen(fn.data()) - 1] == '\\')) fn.data()[strlen(fn.data()) - 1] = '/'; #endif - if ((fn.data() != nullptr) && fn.contains("ioctl://")) - cdrom_ioctl_open(&(cdrom[i]), fn.data()); - else - cdrom_image_open(&(cdrom[i]), fn.data()); + cdrom_load(&(cdrom[i]), fn.data(), 1); + /* Signal media change to the emulated machine. */ - if (cdrom[i].insert) + if (cdrom[i].insert) { cdrom[i].insert(cdrom[i].priv); + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + cdrom[i].insert(cdrom[i].priv); + } + if (strlen(cdrom[i].image_path) > 0) ui_sb_update_icon_state(SB_CDROM | i, 0); else @@ -580,6 +629,36 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) QString menu_item_name; switch (type) { + default: + menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); + return; + case ui::MediaType::Cassette: + if (!MachineStatus::hasCassette()) + return; + menu = cassetteMenu; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[cassetteImageHistoryPos[slot]]); + fi.setFile(fn); + menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); + break; + case ui::MediaType::Cartridge: + if (!machine_has_cartridge(machine)) + return; + menu = cartridgeMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[cartridgeImageHistoryPos[slot]]); + fi.setFile(fn); + menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); + break; + case ui::MediaType::Floppy: + if (!floppyMenus.contains(index)) + return; + menu = floppyMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); + fi.setFile(fn); + menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); + break; case ui::MediaType::Optical: if (!cdromMenus.contains(index)) return; @@ -600,18 +679,24 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) } imageHistoryUpdatePos->setIcon(menu_icon); break; - case ui::MediaType::Floppy: - if (!floppyMenus.contains(index)) + case ui::MediaType::Zip: + if (!zipMenus.contains(index)) return; - menu = floppyMenus[index]; + menu = zipMenus[index]; children = menu->children(); - imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); + imageHistoryUpdatePos = dynamic_cast(children[zipImageHistoryPos[slot]]); fi.setFile(fn); menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); break; - default: + case ui::MediaType::Mo: + if (!moMenus.contains(index)) + return; + menu = moMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[moImageHistoryPos[slot]]); + fi.setFile(fn); menu_item_name = fi.fileName().isEmpty() ? tr("previous image").toUtf8().constData() : fi.fileName().toUtf8().constData(); - return; + break; } imageHistoryUpdatePos->setText(QString::asprintf(tr("%s").toUtf8().constData(), menu_item_name.toUtf8().constData())); @@ -718,15 +803,23 @@ MediaMenu::zipSelectImage(int i, bool wp) void MediaMenu::zipMount(int i, const QString &filename, bool wp) { - const auto dev = static_cast(zip_drives[i].priv); + const auto dev = static_cast(zip_drives[i].priv); + int was_empty = zip_is_empty(i); zip_disk_close(dev); zip_drives[i].read_only = wp; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); - zip_load(dev, filenameBytes.data()); + zip_load(dev, filenameBytes.data(), 1); + + /* Signal media change to the emulated machine. */ zip_insert(dev); + + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + zip_insert(dev); } + mhm.addImageToHistory(i, ui::MediaType::Zip, zip_drives[i].prev_image_path, zip_drives[i].image_path); ui_sb_update_icon_state(SB_ZIP | i, filename.isEmpty() ? 1 : 0); zipUpdateMenu(i); @@ -740,6 +833,7 @@ MediaMenu::zipEject(int i) { const auto dev = static_cast(zip_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) { @@ -754,7 +848,7 @@ MediaMenu::zipEject(int i) } void -MediaMenu::zipReload(int i) +MediaMenu::zipReloadPrev(int i) { const auto dev = static_cast(zip_drives[i].priv); @@ -771,6 +865,15 @@ MediaMenu::zipReload(int i) config_save(); } +void +MediaMenu::zipReload(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); +} + void MediaMenu::zipUpdateMenu(int i) { @@ -782,9 +885,7 @@ MediaMenu::zipUpdateMenu(int i) auto childs = menu->children(); auto *ejectMenu = dynamic_cast(childs[zipEjectPos]); - auto *reloadMenu = dynamic_cast(childs[zipReloadPos]); ejectMenu->setEnabled(!name.isEmpty()); - reloadMenu->setEnabled(!prev_name.isEmpty()); QString busName = tr("Unknown Bus"); switch (zip_drives[i].bus_type) { @@ -800,6 +901,9 @@ MediaMenu::zipUpdateMenu(int i) // menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("ZIP %03i %i (%s): %ls").toUtf8().constData(), (zip_drives[i].is_250 > 0) ? 250 : 100, i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); + + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) + updateImageHistory(i, slot, ui::MediaType::Zip); } void @@ -835,15 +939,23 @@ MediaMenu::moSelectImage(int i, bool wp) void MediaMenu::moMount(int i, const QString &filename, bool wp) { - const auto dev = static_cast(mo_drives[i].priv); + const auto dev = static_cast(mo_drives[i].priv); + int was_empty = mo_is_empty(i); mo_disk_close(dev); mo_drives[i].read_only = wp; if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); - mo_load(dev, filenameBytes.data()); + mo_load(dev, filenameBytes.data(), 1); + + /* Signal media change to the emulated machine. */ mo_insert(dev); + + /* The drive was previously empty, transition directly to UNIT ATTENTION. */ + if (was_empty) + mo_insert(dev); } + mhm.addImageToHistory(i, ui::MediaType::Mo, mo_drives[i].prev_image_path, mo_drives[i].image_path); ui_sb_update_icon_state(SB_MO | i, filename.isEmpty() ? 1 : 0); moUpdateMenu(i); @@ -857,6 +969,7 @@ MediaMenu::moEject(int i) { const auto dev = static_cast(mo_drives[i].priv); + mhm.addImageToHistory(i, ui::MediaType::Mo, mo_drives[i].image_path, QString()); mo_disk_close(dev); mo_drives[i].image_path[0] = 0; if (mo_drives[i].bus_type) { @@ -871,7 +984,7 @@ MediaMenu::moEject(int i) } void -MediaMenu::moReload(int i) +MediaMenu::moReloadPrev(int i) { mo_t *dev = (mo_t *) mo_drives[i].priv; @@ -888,6 +1001,15 @@ MediaMenu::moReload(int i) config_save(); } +void +MediaMenu::moReload(int index, int slot) +{ + const QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Mo); + moMount(index, filename, false); + moUpdateMenu(index); + ui_sb_update_tip(SB_MO | index); +} + void MediaMenu::moUpdateMenu(int i) { @@ -899,9 +1021,7 @@ MediaMenu::moUpdateMenu(int i) auto childs = menu->children(); auto *ejectMenu = dynamic_cast(childs[moEjectPos]); - auto *reloadMenu = dynamic_cast(childs[moReloadPos]); ejectMenu->setEnabled(!name.isEmpty()); - reloadMenu->setEnabled(!prev_name.isEmpty()); QString busName = tr("Unknown Bus"); switch (mo_drives[i].bus_type) { @@ -916,6 +1036,9 @@ MediaMenu::moUpdateMenu(int i) } menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); + + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) + updateImageHistory(i, slot, ui::MediaType::Mo); } void @@ -1043,7 +1166,7 @@ zip_mount(uint8_t id, char *fn, uint8_t wp) void zip_reload(uint8_t id) { - MediaMenu::ptr->zipReload(id); + MediaMenu::ptr->zipReloadPrev(id); } void @@ -1061,6 +1184,6 @@ mo_mount(uint8_t id, char *fn, uint8_t wp) void mo_reload(uint8_t id) { - MediaMenu::ptr->moReload(id); + MediaMenu::ptr->moReloadPrev(id); } } diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 725ce92b3..b069c67d9 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -24,12 +24,14 @@ public: void cassetteNewImage(); void cassetteSelectImage(bool wp); void cassetteMount(const QString &filename, bool wp); + void cassetteMenuSelect(int slot); void cassetteEject(); void cassetteUpdateMenu(); void cartridgeSelectImage(int i); void cartridgeMount(int i, const QString &filename); void cartridgeEject(int i); + void cartridgeMenuSelect(int index, int slot); void cartridgeUpdateMenu(int i); void floppyNewImage(int i); @@ -53,14 +55,16 @@ public: void zipSelectImage(int i, bool wp); void zipMount(int i, const QString &filename, bool wp); void zipEject(int i); - void zipReload(int i); + void zipReloadPrev(int i); + void zipReload(int index, int slot); void zipUpdateMenu(int i); void moNewImage(int i); void moSelectImage(int i, bool wp); void moMount(int i, const QString &filename, bool wp); void moEject(int i); - void moReload(int i); + void moReloadPrev(int i); + void moReload(int index, int slot); void moUpdateMenu(int i); void nicConnect(int i); @@ -94,24 +98,25 @@ private: int cassetteRewindPos; int cassetteFastFwdPos; int cassetteEjectPos; + int cassetteImageHistoryPos[MAX_PREV_IMAGES]; int cartridgeEjectPos; + int cartridgeImageHistoryPos[MAX_PREV_IMAGES]; int floppyExportPos; int floppyEjectPos; + int floppyImageHistoryPos[MAX_PREV_IMAGES]; int cdromMutePos; - int cdromReloadPos; int cdromImagePos; int cdromDirPos; int cdromImageHistoryPos[MAX_PREV_IMAGES]; - int floppyImageHistoryPos[MAX_PREV_IMAGES]; int zipEjectPos; - int zipReloadPos; + int zipImageHistoryPos[MAX_PREV_IMAGES]; int moEjectPos; - int moReloadPos; + int moImageHistoryPos[MAX_PREV_IMAGES]; int netDisconnPos; diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index e24ad9aa1..48be09777 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -96,12 +96,12 @@ static const QStringList rpmModes = { }; static const QStringList floppyTypes = { - "160 kB", - "180 kB", - "320 kB", - "360 kB", - "640 kB", - "720 kB", + "160 KB", + "180 KB", + "320 KB", + "360 KB", + "640 KB", + "720 KB", "1.2 MB", "1.25 MB", "1.44 MB", diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index a200e38ec..dd6c34efc 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -54,6 +54,10 @@ # include #endif +#ifdef Q_OS_OPENBSD +# include +#endif + #if 0 static QByteArray buf; #endif @@ -152,6 +156,7 @@ strnicmp(const char *s1, const char *s2, size_t n) void do_start(void) { + // } void @@ -227,7 +232,12 @@ plat_getcwd(char *bufp, int max) { #ifdef __APPLE__ /* Working directory for .app bundles is undefined. */ +#ifdef USE_EXE_PATH strncpy(bufp, exe_path, max); +#else + CharPointer(bufp, max) = QDir::homePath().toUtf8(); + path_append_filename(bufp, bufp, "Library/86Box"); +#endif #else CharPointer(bufp, max) = QDir::currentPath().toUtf8(); #endif @@ -356,6 +366,8 @@ plat_mmap(size_t size, uint8_t executable) #elif defined Q_OS_UNIX # if defined Q_OS_DARWIN && defined MAP_JIT void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); +# elif defined(PROT_MPROTECT) + void *ret = mmap(0, size, PROT_MPROTECT(PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0)), MAP_ANON | MAP_PRIVATE, -1, 0); # else void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); # endif @@ -449,6 +461,7 @@ QMap> ProgSettings::lcid_langcode = { { 0x0410, { "it-IT", "Italian (Italy)" } }, { 0x0411, { "ja-JP", "Japanese (Japan)" } }, { 0x0412, { "ko-KR", "Korean (Korea)" } }, + { 0x0413, { "nl-NL", "Dutch (Netherlands)" } }, { 0x0415, { "pl-PL", "Polish (Poland)" } }, { 0x0416, { "pt-BR", "Portuguese (Brazil)" } }, { 0x0816, { "pt-PT", "Portuguese (Portugal)" } }, @@ -545,7 +558,7 @@ endblit() std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } -} +} /*extern "C" */ #ifdef Q_OS_WINDOWS size_t @@ -583,6 +596,8 @@ 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" @@ -592,12 +607,10 @@ c16stombs(char dst[], const uint16_t src[], int len) # define LIB_NAME_GPCL "gpcl6dll32.dll" # endif # define LIB_NAME_PCAP "Npcap" -# define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else # define LIB_NAME_GS "libgs" # define LIB_NAME_GPCL "libgpcl6" # define LIB_NAME_PCAP "libpcap" -# define MOUSE_CAPTURE_KEYSEQ "Ctrl+End" #endif QMap ProgSettings::translatedstrings; @@ -620,7 +633,8 @@ ProgSettings::reloadStrings() translatedstrings[STRING_GHOSTPCL_ERROR_DESC] = QCoreApplication::translate("", "%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.").arg(LIB_NAME_GPCL).toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_MACHINE] = QCoreApplication::translate("", "Machine \"%hs\" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO] = QCoreApplication::translate("", "Video card \"%hs\" is not available due to missing ROMs in the roms/video directory. Switching to an available video card.").toStdWString(); - translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_VIDEO2] = QCoreApplication::translate("", "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.").toStdWString(); + translatedstrings[STRING_HW_NOT_AVAILABLE_DEVICE] = QCoreApplication::translate("", "Device \"%hs\" is not available due to missing ROMs. Ignoring the device.").toStdWString(); translatedstrings[STRING_HW_NOT_AVAILABLE_TITLE] = QCoreApplication::translate("", "Hardware not available").toStdWString(); translatedstrings[STRING_MONITOR_SLEEP] = QCoreApplication::translate("", "Monitor in sleep mode").toStdWString(); translatedstrings[STRING_NET_ERROR] = QCoreApplication::translate("", "Failed to initialize network driver").toStdWString(); @@ -795,12 +809,18 @@ plat_set_thread_name(void *thread, const char *name) if (thread) /* Apple pthread can only set self's name */ return; char truncated[64]; +# elif defined(Q_OS_NETBSD) + char truncated[64]; # else char truncated[16]; # endif strncpy(truncated, name, sizeof(truncated) - 1); -# ifdef Q_OS_DARWIN +# if defined(Q_OS_DARWIN) pthread_setname_np(truncated); +# elif defined(Q_OS_NETBSD) + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated, "%s"); +# elif defined(Q_OS_OPENBSD) + pthread_set_name_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); # else pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); # endif diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 4e53b2818..9e1f8c168 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -195,7 +195,9 @@ ProgSettings::loadTranslators(QObject *parent) qDebug() << "Translations loaded.\n"; QCoreApplication::installTranslator(translator); if (!qtTranslator->load(QLatin1String("qtbase_") + localetofilename.replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) - qtTranslator->load(QLatin1String("qt_") + localetofilename.replace('-', '_'), QApplication::applicationDirPath() + "/./translations/"); + if (!qtTranslator->load(QLatin1String("qtbase_") + localetofilename.left(localetofilename.indexOf('-')), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + if (!qtTranslator->load(QLatin1String("qt_") + localetofilename.replace('-', '_'), QApplication::applicationDirPath() + "/./translations/")) + qtTranslator->load(QLatin1String("qt_") + localetofilename.replace('-', '_'), QLatin1String(":/")); if (QApplication::installTranslator(qtTranslator)) { qDebug() << "Qt translations loaded." << "\n"; @@ -207,7 +209,10 @@ ProgSettings::loadTranslators(QObject *parent) translator->load(QLatin1String("86box_") + lcid_langcode[lang_id].first, QLatin1String(":/")); QCoreApplication::installTranslator(translator); if (!qtTranslator->load(QLatin1String("qtbase_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) - qtTranslator->load(QLatin1String("qt_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QApplication::applicationDirPath() + "/./translations/"); + if (!qtTranslator->load(QLatin1String("qtbase_") + QString(lcid_langcode[lang_id].first).left(QString(lcid_langcode[lang_id].first).indexOf('-')), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + if(!qtTranslator->load(QLatin1String("qt_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QApplication::applicationDirPath() + "/./translations/")) + qtTranslator->load(QLatin1String("qt_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QLatin1String(":/")); + QCoreApplication::installTranslator(qtTranslator); } } diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui index 16fb439be..ac4327341 100644 --- a/src/qt/qt_progsettings.ui +++ b/src/qt/qt_progsettings.ui @@ -88,7 +88,7 @@ - + 10 diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index d594b94f0..a8bd47a79 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -200,7 +200,15 @@ RendererStack::mousePressEvent(QMouseEvent *event) void RendererStack::wheelEvent(QWheelEvent *event) { - mouse_set_z(event->pixelDelta().y()); + if (!mouse_capture) { + event->ignore(); + return; + } + + double numSteps = (double) event->angleDelta().y() / 120.0; + + mouse_set_z((int) numSteps); + event->accept(); } void diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index f6be74cf2..75f8d376b 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -24,6 +24,7 @@ extern "C" { #include <86box/device.h> #include <86box/machine.h> #include <86box/video.h> +#include <86box/vid_8514a_device.h> #include <86box/vid_xga_device.h> #include <86box/vid_ps55da2.h> } @@ -54,6 +55,7 @@ SettingsDisplay::save() // TODO for (uint8_t i = 1; i < GFXCARD_MAX; i ++) gfxcard[i] = ui->comboBoxVideoSecondary->currentData().toInt(); + voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; ibm8514_standalone_enabled = ui->checkBox8514->isChecked() ? 1 : 0; xga_standalone_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; @@ -129,6 +131,16 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast(Settings::settings)); } +void +SettingsDisplay::on_pushButtonConfigure8514_clicked() +{ + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + DeviceConfig::ConfigureDevice(&ibm8514_mca_device, 0, qobject_cast(Settings::settings)); + } else { + DeviceConfig::ConfigureDevice(&gen8514_isa_device, 0, qobject_cast(Settings::settings)); + } +} + void SettingsDisplay::on_pushButtonConfigureXga_clicked() { @@ -175,6 +187,8 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) ui->checkBox8514->setEnabled(machineSupports8514); ui->checkBox8514->setChecked(ibm8514_standalone_enabled && machineSupports8514); + ui->pushButtonConfigure8514->setEnabled(ui->checkBox8514->isEnabled() && ui->checkBox8514->isChecked()); + ui->checkBoxXga->setEnabled(machineSupportsXga); ui->checkBoxXga->setChecked(xga_standalone_enabled && machineSupportsXga); @@ -251,6 +265,12 @@ SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked); } +void +SettingsDisplay::on_checkBox8514_stateChanged(int state) +{ + ui->pushButtonConfigure8514->setEnabled(state == Qt::Checked); +} + void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index f2edb0c8a..854fce658 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -29,10 +29,12 @@ private slots: 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_pushButtonConfigureVoodoo_clicked(); + void on_pushButtonConfigure8514_clicked(); void on_pushButtonConfigureXga_clicked(); void on_pushButtonConfigureDa2_clicked(); void on_pushButtonConfigure_clicked(); diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index 8be84a17f..a8799204c 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -106,6 +106,13 @@ + + + + Configure + + + diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 190dbc2e1..cc58d3cde 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -90,6 +90,14 @@ setCDROMSpeed(QAbstractItemModel *model, const QModelIndex &idx, uint8_t speed) model->setData(i, speed, Qt::UserRole); } +static QString +CDROMName(int type) +{ + char temp[512]; + cdrom_get_name(type, temp); + return QObject::tr((const char *) temp); +} + static void setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type) { @@ -97,7 +105,7 @@ setCDROMType(QAbstractItemModel *model, const QModelIndex &idx, int type) if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == CDROM_BUS_DISABLED) model->setData(i, QCoreApplication::translate("", "None")); else if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() != CDROM_BUS_MITSUMI) - model->setData(i, QObject::tr(cdrom_getname(type))); + model->setData(i, CDROMName(type)); model->setData(i, type, Qt::UserRole); } @@ -156,8 +164,12 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) auto idx = model->index(i, 0); int type = cdrom_get_type(i); setCDROMBus(model, idx, cdrom[i].bus_type, cdrom[i].res); - setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed); setCDROMType(model, idx.siblingAtColumn(2), type); + int speed = cdrom_get_speed(type); + if (speed == -1) + setCDROMSpeed(model, idx.siblingAtColumn(1), cdrom[i].speed); + else + setCDROMSpeed(model, idx.siblingAtColumn(1), speed); 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) @@ -186,7 +198,7 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) && ((cdrom_drive_types[j].bus_type == bus_type) || (cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) { - QString name = tr(cdrom_getname(j)); + QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if ((cdrom[cdromIdx].bus_type == bus_type) && (cdrom[cdromIdx].type == j)) selectedTypeRow = eligibleRows; @@ -220,7 +232,7 @@ SettingsFloppyCDROM::save() for (int i = 0; i < CDROM_NUM; i++) { cdrom[i].priv = NULL; cdrom[i].ops = NULL; - cdrom[i].image = NULL; + cdrom[i].local = NULL; cdrom[i].insert = NULL; cdrom[i].close = NULL; cdrom[i].get_volume = NULL; @@ -246,7 +258,6 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) { uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); int type = current.siblingAtColumn(2).data(Qt::UserRole).toInt(); ui->comboBoxBus->setCurrentIndex(-1); @@ -260,7 +271,14 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) if (!match.isEmpty()) ui->comboBoxChannel->setCurrentIndex(match.first().row()); + int speed = cdrom_get_speed(type); + if (speed == -1) { + speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + ui->comboBoxSpeed->setEnabled(true); + } else + ui->comboBoxSpeed->setEnabled(false); ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); + ui->comboBoxCDROMType->setCurrentIndex(type); enableCurrentlySelectedChannel(); } @@ -351,7 +369,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) if (((bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) && ((cdrom_drive_types[j].bus_type == bus_type) || (cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH))) { - QString name = tr(cdrom_getname(j)); + QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if ((cdrom[cdromIdx].bus_type == bus_type) && (cdrom[cdromIdx].type == j)) selectedTypeRow = eligibleRows; @@ -401,9 +419,22 @@ SettingsFloppyCDROM::on_comboBoxChannel_activated(int) void SettingsFloppyCDROM::on_comboBoxCDROMType_activated(int) { + int type = ui->comboBoxCDROMType->currentData().toUInt(); + setCDROMType(ui->tableViewCDROM->model(), ui->tableViewCDROM->selectionModel()->currentIndex(), - ui->comboBoxCDROMType->currentData().toUInt()); + type); ui->tableViewCDROM->resizeColumnsToContents(); ui->tableViewCDROM->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + + int speed = cdrom_get_speed(type); + if (speed == -1) { + speed = ui->comboBoxSpeed->currentData().toUInt(); + ui->comboBoxSpeed->setEnabled(true); + } else + ui->comboBoxSpeed->setEnabled(false); + ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); + + auto idx = ui->tableViewCDROM->selectionModel()->currentIndex(); + setCDROMSpeed(ui->tableViewCDROM->model(), idx.siblingAtColumn(1), speed); } diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index 3f02ffe54..e679dafa5 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -55,7 +55,7 @@ normalize_hd_list() memset(ihdd, 0x00, HDD_NUM * sizeof(hard_disk_t)); for (uint8_t i = 0; i < HDD_NUM; i++) { - if (temp_hdd[i].bus != HDD_BUS_DISABLED) { + if (temp_hdd[i].bus_type != HDD_BUS_DISABLED) { memcpy(&(ihdd[j]), &(temp_hdd[i]), sizeof(hard_disk_t)); j++; } @@ -79,14 +79,14 @@ addRow(QAbstractItemModel *model, hard_disk_t *hd) int row = model->rowCount(); model->insertRow(row); - QString busName = Harddrives::BusChannelName(hd->bus, hd->channel); + QString busName = Harddrives::BusChannelName(hd->bus_type, hd->channel); model->setData(model->index(row, ColumnBus), busName); model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon("/hard_disk.ico"), Qt::DecorationRole); - model->setData(model->index(row, ColumnBus), hd->bus, DataBus); - model->setData(model->index(row, ColumnBus), hd->bus, DataBusPrevious); + model->setData(model->index(row, ColumnBus), hd->bus_type, DataBus); + model->setData(model->index(row, ColumnBus), hd->bus_type, DataBusPrevious); model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannel); model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannelPrevious); - Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus, hd->channel); + Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus_type, hd->channel); QString fileName = hd->fn; if (fileName.startsWith(userPath, Qt::CaseInsensitive)) { model->setData(model->index(row, ColumnFilename), fileName.mid(userPath.size())); @@ -99,7 +99,7 @@ addRow(QAbstractItemModel *model, hard_disk_t *hd) model->setData(model->index(row, ColumnHeads), hd->hpc); model->setData(model->index(row, ColumnSectors), hd->spt); model->setData(model->index(row, ColumnSize), (hd->tracks * hd->hpc * hd->spt) >> 11); - model->setData(model->index(row, ColumnSpeed), hdd_preset_getname(hd->speed_preset)); + model->setData(model->index(row, ColumnSpeed), QObject::tr(hdd_preset_getname(hd->speed_preset))); model->setData(model->index(row, ColumnSpeed), hd->speed_preset, Qt::UserRole); } @@ -120,7 +120,7 @@ SettingsHarddisks::SettingsHarddisks(QWidget *parent) ui->tableView->setModel(model); for (int i = 0; i < HDD_NUM; i++) { - if (hdd[i].bus > 0) { + if (hdd[i].bus_type > 0) { addRow(model, &hdd[i]); } } @@ -153,7 +153,7 @@ SettingsHarddisks::save() int rows = model->rowCount(); for (int i = 0; i < rows; ++i) { auto idx = model->index(i, ColumnBus); - hdd[i].bus = idx.data(DataBus).toUInt(); + hdd[i].bus_type = idx.data(DataBus).toUInt(); hdd[i].channel = idx.data(DataBusChannel).toUInt(); hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt(); hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt(); @@ -267,7 +267,7 @@ SettingsHarddisks::on_comboBoxSpeed_currentIndexChanged(int index) auto *model = ui->tableView->model(); auto col = idx.siblingAtColumn(ColumnSpeed); model->setData(col, ui->comboBoxSpeed->currentData(Qt::UserRole), Qt::UserRole); - model->setData(col, hdd_preset_getname(ui->comboBoxSpeed->currentData(Qt::UserRole).toUInt())); + model->setData(col, QObject::tr(hdd_preset_getname(ui->comboBoxSpeed->currentData(Qt::UserRole).toUInt()))); } } @@ -313,11 +313,11 @@ addDriveFromDialog(Ui::SettingsHarddisks *ui, const HarddiskDialog &dlg) hard_disk_t hd; memset(&hd, 0, sizeof(hd)); - hd.bus = dlg.bus(); - hd.channel = dlg.channel(); - hd.tracks = dlg.cylinders(); - hd.hpc = dlg.heads(); - hd.spt = dlg.sectors(); + hd.bus_type = dlg.bus(); + hd.channel = dlg.channel(); + hd.tracks = dlg.cylinders(); + hd.hpc = dlg.heads(); + hd.spt = dlg.sectors(); strncpy(hd.fn, fn.data(), sizeof(hd.fn) - 1); hd.speed_preset = dlg.speed(); diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 05e44c2c0..d7c61e8d2 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -136,7 +136,7 @@ static int get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) { int axis_sel = jc.selectedAxis(axis); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; + int nr_axes = plat_joystick_state[joystick_state[0][joystick_nr].plat_joystick_nr - 1].nr_axes; if (axis_sel < nr_axes) { return axis_sel; @@ -153,7 +153,7 @@ static int get_pov(JoystickConfiguration &jc, int pov, int joystick_nr) { int pov_sel = jc.selectedPov(pov); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; + int nr_povs = plat_joystick_state[joystick_state[0][joystick_nr].plat_joystick_nr - 1].nr_povs * 2; if (pov_sel < nr_povs) { if (pov_sel & 1) @@ -176,17 +176,19 @@ updateJoystickConfig(int type, int joystick_nr, QWidget *parent) break; } - joystick_state[joystick_nr].plat_joystick_nr = jc.selectedDevice(); - if (joystick_state[joystick_nr].plat_joystick_nr) { - for (int c = 0; c < joystick_get_axis_count(type); c++) { - joystick_state[joystick_nr].axis_mapping[c] = get_axis(jc, c, joystick_nr); + joystick_state[0][joystick_nr].plat_joystick_nr = jc.selectedDevice(); + if (joystick_state[0][joystick_nr].plat_joystick_nr) { + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(type); axis_nr++) { + joystick_state[0][joystick_nr].axis_mapping[axis_nr] = get_axis(jc, axis_nr, joystick_nr); } - for (int c = 0; c < joystick_get_button_count(type); c++) { - joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c); + + for (int button_nr = 0; button_nr < joystick_get_button_count(type); button_nr++) { + joystick_state[0][joystick_nr].button_mapping[button_nr] = jc.selectedButton(button_nr); } - for (int c = 0; c < joystick_get_pov_count(type) * 2; c += 2) { - joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c + 1, joystick_nr); + + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(type) * 2; pov_nr += 2) { + joystick_state[0][joystick_nr].pov_mapping[pov_nr][0] = get_pov(jc, pov_nr, joystick_nr); + joystick_state[0][joystick_nr].pov_mapping[pov_nr][1] = get_pov(jc, pov_nr + 1, joystick_nr); } } } diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index 01d7d3f9f..9679c9e21 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -160,6 +160,7 @@ SettingsPorts::on_pushButtonSerialPassThru4_clicked() DeviceConfig::ConfigureDevice(&serial_passthrough_device, 4, qobject_cast(Settings::settings)); } +#if 0 void SettingsPorts::on_pushButtonSerialPassThru5_clicked() { @@ -177,6 +178,7 @@ SettingsPorts::on_pushButtonSerialPassThru7_clicked() { DeviceConfig::ConfigureDevice(&serial_passthrough_device, 7, qobject_cast(Settings::settings)); } +#endif void SettingsPorts::on_checkBoxSerialPassThru1_clicked(bool checked) @@ -220,4 +222,4 @@ SettingsPorts::on_checkBoxSerialPassThru7_clicked(bool checked) { ui->pushButtonSerialPassThru7->setEnabled(checked); } -#endif \ No newline at end of file +#endif diff --git a/src/qt/qt_settingsports.hpp b/src/qt/qt_settingsports.hpp index 1ecb051af..fb9cdb343 100644 --- a/src/qt/qt_settingsports.hpp +++ b/src/qt/qt_settingsports.hpp @@ -19,45 +19,23 @@ public: #if 0 private slots: void on_checkBoxSerialPassThru7_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru6_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru5_clicked(bool checked); #endif - -private slots: void on_checkBoxSerialPassThru4_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru3_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru2_clicked(bool checked); - -private slots: void on_checkBoxSerialPassThru1_clicked(bool checked); private slots: +#if 0 void on_pushButtonSerialPassThru7_clicked(); - -private slots: void on_pushButtonSerialPassThru6_clicked(); - -private slots: void on_pushButtonSerialPassThru5_clicked(); - -private slots: +#endif void on_pushButtonSerialPassThru4_clicked(); - -private slots: void on_pushButtonSerialPassThru3_clicked(); - -private slots: void on_pushButtonSerialPassThru2_clicked(); - -private slots: void on_pushButtonSerialPassThru1_clicked(); private slots: diff --git a/src/qt/qt_styleoverride.cpp b/src/qt/qt_styleoverride.cpp index 7ec5a341c..60a7162a5 100644 --- a/src/qt/qt_styleoverride.cpp +++ b/src/qt/qt_styleoverride.cpp @@ -19,6 +19,13 @@ #include #include +#ifdef Q_OS_WINDOWS +#include +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif +#endif + int StyleOverride::styleHint( StyleHint hint, @@ -48,6 +55,11 @@ StyleOverride::polish(QWidget *widget) widget->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, true); } widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false); +#ifdef Q_OS_WINDOWS + extern bool windows_is_light_theme(); + BOOL DarkMode = !windows_is_light_theme(); + DwmSetWindowAttribute((HWND)widget->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&DarkMode, sizeof(DarkMode)); +#endif } if (qobject_cast(widget)) { diff --git a/src/qt/qt_translations.qrc b/src/qt/qt_translations.qrc.in similarity index 93% rename from src/qt/qt_translations.qrc rename to src/qt/qt_translations.qrc.in index 9f75fd6d6..655323563 100644 --- a/src/qt/qt_translations.qrc +++ b/src/qt/qt_translations.qrc.in @@ -13,6 +13,7 @@ 86box_it-IT.qm 86box_ja-JP.qm 86box_ko-KR.qm + 86box_nl-NL.qm 86box_pl-PL.qm 86box_pt-BR.qm 86box_pt-PT.qm @@ -24,5 +25,6 @@ 86box_vi-VN.qm 86box_zh-CN.qm 86box_zh-TW.qm +@QT_TRANSLATIONS_LIST@ diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index fc111e5b4..b9253663b 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -56,10 +56,22 @@ extern "C" { #include <86box/network.h> #include <86box/machine_status.h> +#ifdef Q_OS_WINDOWS +# include <86box/win.h> +#endif + void plat_delay_ms(uint32_t count) { +#ifdef Q_OS_WINDOWS + // On Win32 the accuracy of Sleep() depends on the timer resolution, which can be set by calling timeBeginPeriod + // https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod + timeBeginPeriod(1); + Sleep(count); + timeEndPeriod(1); +#else QThread::msleep(count); +#endif } wchar_t * @@ -256,6 +268,9 @@ ui_sb_update_icon_state(int tag, int state) case SB_TEXT: break; } + + if (main_window != nullptr) + main_window->updateStatusEmptyIcons(); } void diff --git a/src/qt/qt_vulkanrenderer.cpp b/src/qt/qt_vulkanrenderer.cpp index 9227cdcb3..13728b82e 100644 --- a/src/qt/qt_vulkanrenderer.cpp +++ b/src/qt/qt_vulkanrenderer.cpp @@ -30,10 +30,11 @@ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ +#include "qt_vulkanrenderer.hpp" #include #include -#include "qt_vulkanrenderer.hpp" + #if QT_CONFIG(vulkan) # include @@ -676,7 +677,7 @@ VulkanRenderer2::initResources() v_texcoord = texcoord; gl_Position = ubuf.mvp * position; } -#endif +#endif /* 0 */ VkShaderModule vertShaderModule = createShader(QStringLiteral(":/texture_vert.spv")); #if 0 #version 440 @@ -691,7 +692,7 @@ VulkanRenderer2::initResources() { fragColor = texture(tex, v_texcoord); } -#endif +#endif /* 0 */ VkShaderModule fragShaderModule = createShader(QStringLiteral(":/texture_frag.spv")); // Graphics pipeline @@ -1009,4 +1010,4 @@ VulkanRenderer2::startNextFrame() m_window->frameReady(); m_window->requestUpdate(); // render continuously, throttled by the presentation rate } -#endif +#endif /* QT_CONFIG(vulkan) */ diff --git a/src/qt/qt_vulkanrenderer.hpp b/src/qt/qt_vulkanrenderer.hpp index d4580d848..2c131e5d7 100644 --- a/src/qt/qt_vulkanrenderer.hpp +++ b/src/qt/qt_vulkanrenderer.hpp @@ -31,6 +31,8 @@ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ****************************************************************************/ +#ifndef VULKANRENDERER_HPP +#define VULKANRENDERER_HPP #include #include @@ -90,4 +92,6 @@ private: QMatrix4x4 m_proj; }; -#endif +#endif // QT_CONFIG(vulkan) + +#endif // VULKANRENDERER_HPP diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index 60ad5be96..ab46b5961 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -1,3 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2022 Cacodemon345 +** Copyright (C) 2017 The Qt Company Ltd. +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +****************************************************************************/ #include "qt_vulkanwindowrenderer.hpp" #include @@ -697,7 +729,7 @@ public: # if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 case VK_ERROR_INCOMPATIBLE_VERSION_KHR: return "VK_ERROR_INCOMPATIBLE_VERSION_KHR"; -# endif +# endif /* VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 */ case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; case VK_ERROR_NOT_PERMITTED_EXT: @@ -788,7 +820,7 @@ public: m_devFuncs->vkDeviceWaitIdle(m_window->device()); } }; -# endif +# endif /* 0*/ VulkanWindowRenderer::VulkanWindowRenderer(QWidget *parent) : QVulkanWindow(parent->windowHandle()) @@ -851,4 +883,4 @@ VulkanWindowRenderer::getBuffers() { return std::vector { std::make_tuple((uint8_t *) renderer->mappedPtr, &this->buf_usage[0]) }; } -#endif +#endif /* QT_CONFIG(vulkan) */ diff --git a/src/qt/qt_vulkanwindowrenderer.hpp b/src/qt/qt_vulkanwindowrenderer.hpp index 828d091e6..de9f46b6f 100644 --- a/src/qt/qt_vulkanwindowrenderer.hpp +++ b/src/qt/qt_vulkanwindowrenderer.hpp @@ -35,6 +35,6 @@ private: VulkanRenderer2 *renderer; }; -#endif +#endif // QT_CONFIG(vulkan) #endif // VULKANWINDOWRENDERER_HPP diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 66d8ad8e5..13e0ec9a7 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -34,38 +34,87 @@ #include "qt_winrawinputfilter.hpp" #include +#include +#include +#include +#include #include #include +#include +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif #include <86box/keyboard.h> #include <86box/mouse.h> #include <86box/plat.h> #include <86box/86box.h> +#include <86box/cdrom.h> +#include <86box/video.h> +#include +#include + +extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); #include #include #include "qt_rendererstack.hpp" +#include "ui_qt_mainwindow.h" + +bool windows_is_light_theme() { + // based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application + + // The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian + auto buffer = std::vector(4); + auto cbData = static_cast(buffer.size() * sizeof(char)); + auto res = RegGetValueW( + HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", + L"AppsUseLightTheme", + RRF_RT_REG_DWORD, // expected value type + nullptr, + buffer.data(), + &cbData); + + if (res != ERROR_SUCCESS) { + return 1; + } + + // convert bytes written to our buffer to an int, assuming little-endian + auto i = int(buffer[3] << 24 | + buffer[2] << 16 | + buffer[1] << 8 | + buffer[0]); + + return i == 1; +} extern "C" void win_joystick_handle(PRAWINPUT); std::unique_ptr WindowsRawInputFilter::Register(MainWindow *window) { RAWINPUTDEVICE rid[2] = { - {.usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_NOHOTKEYS, - .hwndTarget = nullptr}, - { .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = 0, - .hwndTarget = nullptr} + { + .usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_NOHOTKEYS, + .hwndTarget = nullptr + }, + { + .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = 0, + .hwndTarget = nullptr + } }; - if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) - return std::unique_ptr(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); std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); @@ -80,27 +129,83 @@ WindowsRawInputFilter::WindowsRawInputFilter(MainWindow *window) connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; }); connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; }); } - - for (size_t i = 0; i < sizeof(scancode_map) / sizeof(scancode_map[0]); i++) - scancode_map[i] = i; - - keyboard_getkeymap(); } WindowsRawInputFilter::~WindowsRawInputFilter() { RAWINPUTDEVICE rid[2] = { - {.usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL}, - { .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL} + { + .usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL + }, + { + .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL + } }; - RegisterRawInputDevices(rid, 2, sizeof(rid[0])); + if (hook_enabled) + RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])); + else + RegisterRawInputDevices(rid, 2, sizeof(rid[0])); +} + +static void +notify_drives(ULONG unitmask, int empty) +{ + char p[1024] = { 0 }; + + for (int i = 0; i < 26; ++i) { + if (unitmask & 0x1) { + cdrom_t *dev = NULL; + + sprintf(p, "ioctl://\\\\.\\%c:", 'A' + i); + + for (int i = 0; i < CDROM_NUM; i++) + if (!stricmp(cdrom[i].image_path, p)) { + dev = &(cdrom[i]); + if (empty) + cdrom_set_empty(dev); + else + cdrom_update_status(dev); + // pclog("CD-ROM %i : Drive notified of media %s\n", + // dev->id, empty ? "removal" : "change"); + } + } + + unitmask = unitmask >> 1; + } +} + +static void +device_change(WPARAM wParam, LPARAM lParam) +{ + PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam; + + switch(wParam) { + case DBT_DEVICEARRIVAL: + case DBT_DEVICEREMOVECOMPLETE: + /* Check whether a CD or DVD was inserted into a drive. */ + if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME) { + PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME) lpdb; + + if (lpdbv->dbcv_flags & DBTF_MEDIA) + notify_drives(lpdbv->dbcv_unitmask, + (wParam == DBT_DEVICEREMOVECOMPLETE)); + } + break; + + default: + /* + Process other WM_DEVICECHANGE notifications for other + devices or reasons. + */ + break; + } } bool @@ -109,28 +214,82 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess if (eventType == "windows_generic_MSG") { MSG *msg = static_cast(message); - if (msg->message == WM_INPUT) { - - if (window->isActiveWindow() && menus_open == 0) - handle_input((HRAWINPUT) msg->lParam); - else - { - for (auto &w : window->renderers) { - if (w && w->isActiveWindow()) { - handle_input((HRAWINPUT) msg->lParam); - break; + if (msg != nullptr) switch(msg->message) { + case WM_INPUT: + if (window->isActiveWindow() && (menus_open == 0)) + handle_input((HRAWINPUT) msg->lParam); + else { + for (auto &w : window->renderers) { + if (w && w->isActiveWindow()) { + handle_input((HRAWINPUT) msg->lParam); + break; + } } } - } - - return true; - } - - /* Stop processing of Alt-F4 */ - if (msg->message == WM_SYSKEYDOWN) { - if (msg->wParam == 0x73) { return true; - } + case WM_SETTINGCHANGE: + if ((((void *) msg->lParam) != nullptr) && + (wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0)) { + + if (!windows_is_light_theme()) { + QFile f(":qdarkstyle/dark/darkstyle.qss"); + + if (!f.exists()) + printf("Unable to set stylesheet, file not found\n"); + else { + f.open(QFile::ReadOnly | QFile::Text); + QTextStream ts(&f); + 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); + } + }); + } else { + qApp->setStyleSheet(""); + QTimer::singleShot(1000, [this] () { + BOOL DarkMode = FALSE; + DwmSetWindowAttribute((HWND) window->winId(), + DWMWA_USE_IMMERSIVE_DARK_MODE, + (LPCVOID) &DarkMode, + sizeof(DarkMode)); + }); + } + + QTimer::singleShot(1000, [this] () { + 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); + } + }); + } + break; + case WM_SYSKEYDOWN: + /* Stop processing of Alt-F4 */ + if (msg->wParam == 0x73) + return true; + break; + case WM_DEVICECHANGE: + if (msg->hwnd == (HWND) window->winId()) + device_change(msg->wParam, msg->lParam); + break; } } @@ -158,10 +317,8 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input) mouse_handle(raw); break; case RIM_TYPEHID: - { - win_joystick_handle(raw); - break; - } + win_joystick_handle(raw); + break; } } } @@ -171,125 +328,10 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input) void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { - USHORT scancode; - RAWKEYBOARD rawKB = raw->data.keyboard; - scancode = rawKB.MakeCode; - /* If it's not a scan code that starts with 0xE1 */ - if ((rawKB.Flags & RI_KEY_E1)) { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } else { - if (rawKB.Flags & RI_KEY_E0) - scancode |= 0x100; - - /* Translate the scan code to 9-bit */ - scancode = convert_scan_code(scancode); - - /* Remap it according to the list from the Registry */ - if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { - pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); - scancode = scancode_map[scancode]; - } - - /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - - /* Translate right CTRL to left ALT if the user has so - chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; - - /* Normal scan code pass through, pass it through as is if - it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - - window->checkFullscreenHotkey(); - } -} - -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -UINT16 -WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) -{ - if ((scan_code & 0xff00) == 0xe000) - scan_code = (scan_code & 0xff) | 0x0100; - - if (scan_code == 0xE11D) - scan_code = 0x0100; - /* E0 00 is sent by some USB keyboards for their special keys, as it is an - invalid scan code (it has no untranslated set 2 equivalent), we mark it - appropriately so it does not get passed through. */ - else if ((scan_code > 0x01FF) || (scan_code == 0x0100)) - scan_code = 0xFFFF; - - return scan_code; -} - -void -WindowsRawInputFilter::keyboard_getkeymap() -{ - const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - const LPCSTR valueName = "Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - UINT32 *bufEx2; - int scMapCount; - UINT16 *bufEx; - int scancode_unmapped; - int scancode_mapped; - - /* First, prepare the default scan code map list which is 1:1. - * Remappings will be inserted directly into it. - * 512 bytes so this takes less memory, bit 9 set means E0 - * prefix. - */ - for (j = 0; j < 512; j++) - scancode_map[j] = j; - - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - bufSize = 32768; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { - if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { - bufEx2 = (UINT32 *) buf; - scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) { - bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount * 2; j += 2) { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - scancode_unmapped = bufEx[j + 1]; - scancode_mapped = bufEx[j]; - - scancode_unmapped = convert_scan_code(scancode_unmapped); - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Ignore source scan codes with prefixes other than E1 - that are not E1 1D. */ - if (scancode_unmapped != 0xFFFF) - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } + win_keyboard_handle(rawKB.MakeCode, (rawKB.Flags & RI_KEY_BREAK), + (rawKB.Flags & RI_KEY_E0), (rawKB.Flags & RI_KEY_E1)); } void diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index f687164ca..411f7841c 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -61,7 +61,6 @@ public: private: MainWindow *window; - uint16_t scancode_map[768]; int buttons = 0; int dx = 0; int dy = 0; @@ -73,8 +72,6 @@ private: void handle_input(HRAWINPUT input); void keyboard_handle(PRAWINPUT raw); void mouse_handle(PRAWINPUT raw); - static UINT16 convert_scan_code(UINT16 scan_code); - void keyboard_getkeymap(); }; #endif diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index d56612872..83a2a67b1 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -8,13 +8,13 @@ * * SDL2 joystick interface. * - * - * * Authors: Sarah Walker, - * Joakim L. Gilje + * Joakim L. Gilje, + * Jasmine Iwanek, jriwanek@gmail.com> * - * Copyright 2017-2021 Sarah Walker - * Copyright 2021 Joakim L. Gilje + * Copyright 2017-2021 Sarah Walker. + * Copyright 2021 Joakim L. Gilje. + * Copyright 2021-2025 Jasmine Iwanek. */ #include @@ -33,8 +33,8 @@ #include <86box/gameport.h> #include <86box/plat_unused.h> -int joysticks_present; -joystick_t joystick_state[MAX_JOYSTICKS]; +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]; @@ -54,28 +54,26 @@ joystick_init(void) joysticks_present = SDL_NumJoysticks(); memset(sdl_joy, 0, sizeof(sdl_joy)); - for (int c = 0; c < joysticks_present; c++) { - sdl_joy[c] = SDL_JoystickOpen(c); + for (int js = 0; js < joysticks_present; js++) { + sdl_joy[js] = SDL_JoystickOpen(js); - if (sdl_joy[c]) { - int d; + if (sdl_joy[js]) { + strncpy(plat_joystick_state[js].name, SDL_JoystickNameForIndex(js), 64); + plat_joystick_state[js].nr_axes = MIN(SDL_JoystickNumAxes(sdl_joy[js]), MAX_JOY_AXES); + plat_joystick_state[js].nr_buttons = MIN(SDL_JoystickNumButtons(sdl_joy[js]), MAX_JOY_BUTTONS); + plat_joystick_state[js].nr_povs = MIN(SDL_JoystickNumHats(sdl_joy[js]), MAX_JOY_POVS); - strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = MIN(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES); - plat_joystick_state[c].nr_buttons = MIN(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS); - plat_joystick_state[c].nr_povs = MIN(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS); - - for (d = 0; d < plat_joystick_state[c].nr_axes; d++) { - snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d); - plat_joystick_state[c].axis[d].id = d; + for (int axis_nr = 0; axis_nr < plat_joystick_state[js].nr_axes; axis_nr++) { + snprintf(plat_joystick_state[js].axis[axis_nr].name, sizeof(plat_joystick_state[js].axis[axis_nr].name), "Axis %i", axis_nr); + plat_joystick_state[js].axis[axis_nr].id = axis_nr; } - for (d = 0; d < plat_joystick_state[c].nr_buttons; d++) { - snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d); - plat_joystick_state[c].button[d].id = d; + for (int button_nr = 0; button_nr < plat_joystick_state[js].nr_buttons; button_nr++) { + snprintf(plat_joystick_state[js].button[button_nr].name, sizeof(plat_joystick_state[js].button[button_nr].name), "Button %i", button_nr); + plat_joystick_state[js].button[button_nr].id = button_nr; } - for (d = 0; d < plat_joystick_state[c].nr_povs; d++) { - snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d); - plat_joystick_state[c].pov[d].id = d; + for (int pov_nr = 0; pov_nr < plat_joystick_state[js].nr_povs; pov_nr++) { + snprintf(plat_joystick_state[js].pov[pov_nr].name, sizeof(plat_joystick_state[js].pov[pov_nr].name), "POV %i", pov_nr); + plat_joystick_state[js].pov[pov_nr].id = pov_nr; } } } @@ -84,16 +82,14 @@ joystick_init(void) void joystick_close(void) { - int c; - - for (c = 0; c < joysticks_present; c++) { - if (sdl_joy[c]) - SDL_JoystickClose(sdl_joy[c]); + for (int js = 0; js < joysticks_present; js++) { + if (sdl_joy[js]) + SDL_JoystickClose(sdl_joy[js]); } } static int -joystick_get_axis(int joystick_nr, int mapping) +joystick_get_axis(int gameport, int joystick_nr, int mapping) { if (mapping & POV_X) { switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { @@ -132,57 +128,60 @@ joystick_get_axis(int joystick_nr, int mapping) void joystick_process(void) { - int c; - int d; - if (!joystick_type) return; SDL_JoystickUpdate(); - for (c = 0; c < joysticks_present; c++) { - int b; + for (int js = 0; js < joysticks_present; js++) { + for (int axis_nr = 0; axis_nr < plat_joystick_state[js].nr_axes; axis_nr++) + plat_joystick_state[js].a[axis_nr] = SDL_JoystickGetAxis(sdl_joy[js], axis_nr); - for (b = 0; b < plat_joystick_state[c].nr_axes; b++) - plat_joystick_state[c].a[b] = SDL_JoystickGetAxis(sdl_joy[c], b); + for (int button_nr = 0; button_nr < plat_joystick_state[js].nr_buttons; button_nr++) + plat_joystick_state[js].b[button_nr] = SDL_JoystickGetButton(sdl_joy[js], button_nr); - for (b = 0; b < plat_joystick_state[c].nr_buttons; b++) - plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); + for (int pov_nr = 0; pov_nr < plat_joystick_state[js].nr_povs; pov_nr++) + plat_joystick_state[js].p[pov_nr] = SDL_JoystickGetHat(sdl_joy[js], pov_nr); - for (b = 0; b < plat_joystick_state[c].nr_povs; b++) - plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); - // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); +#if 0 + pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", js, + joystick_state[0][js].x, + joystick_state[0][js].y, + joystick_state[0][js].b[0], + joystick_state[0][js].b[1], + joysticks_present); +#endif } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { + if (joystick_state[0][js].plat_joystick_nr) { + int joystick_nr = joystick_state[0][js].plat_joystick_nr - 1; - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x, y; - double angle, magnitude; + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) + joystick_state[0][js].axis[axis_nr] = joystick_get_axis(0, joystick_nr, joystick_state[0][js].axis_mapping[axis_nr]); - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) + joystick_state[0][js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[0][js].button_mapping[button_nr]]; - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { + int x = joystick_get_axis(0, joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][0]); + int y = joystick_get_axis(0, joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][1]); + double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); + double magnitude = sqrt((double) x * (double) x + (double) y * (double) y); if (magnitude < 16384) - joystick_state[c].pov[d] = -1; + joystick_state[0][js].pov[pov_nr] = -1; else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; + joystick_state[0][js].pov[pov_nr] = ((int) angle + 90 + 360) % 360; } } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) + joystick_state[0][js].axis[axis_nr] = 0; + + for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) + joystick_state[0][js].button[button_nr] = 0; + + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) + joystick_state[0][js].pov[pov_nr] = -1; } } } diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index ff422bcd2..621cf0b76 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -19,393 +19,791 @@ #define UNICODE #define BITMAP WINDOWS_BITMAP #include -#include #undef BITMAP #include -#include #include "ntddcdrm.h" #include "ntddscsi.h" +#ifdef ENABLE_IOCTL_LOG #include +#endif #include #include #include #include +#include #include -#define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/scsi_device.h> #include <86box/cdrom.h> -#include <86box/plat_unused.h> -#include <86box/plat_cdrom.h> +#include <86box/log.h> +#include <86box/plat_cdrom_ioctl.h> +#include <86box/scsi_device.h> -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) +typedef struct ioctl_t { + cdrom_t *dev; + void *log; + int is_dvd; + int has_audio; + int32_t tracks_num; + uint8_t cur_toc[65536]; + CDROM_READ_TOC_EX cur_read_toc_ex; + int blocks_num; + uint8_t cur_rti[65536]; + HANDLE handle; + WCHAR path[256]; +} ioctl_t; -static int toc_valid = 0; -static CDROM_TOC cur_toc = { 0 }; -static HANDLE handle = NULL; -static WCHAR ioctl_path[256] = { 0 }; -static WCHAR old_ioctl_path[256] = { 0 }; +static int ioctl_read_dvd_structure(const void *local, uint8_t layer, uint8_t format, + uint8_t *buffer, uint32_t *info); -#ifdef ENABLE_WIN_CDROM_IOCTL_LOG -int win_cdrom_ioctl_do_log = ENABLE_WIN_CDROM_IOCTL_LOG; +#ifdef ENABLE_IOCTL_LOG +int ioctl_do_log = ENABLE_IOCTL_LOG; void -win_cdrom_ioctl_log(const char *fmt, ...) +ioctl_log(void *priv, const char *fmt, ...) { - va_list ap; - - if (win_cdrom_ioctl_do_log) { + if (ioctl_do_log) { + va_list ap; va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define win_cdrom_ioctl_log(fmt, ...) +# define ioctl_log(priv, fmt, ...) #endif -static int -plat_cdrom_open(void) +/* Internal functions. */ +static void +ioctl_close_handle(const ioctl_t *ioctl) { - plat_cdrom_close(); - - handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); - - return (handle != INVALID_HANDLE_VALUE); + if (ioctl->handle != NULL) + CloseHandle(ioctl->handle); } static int -plat_cdrom_load(void) +ioctl_open_handle(ioctl_t *ioctl) { - plat_cdrom_close(); + ioctl_log(ioctl->log, "ioctl->path = \"%ls\"\n", ioctl->path); + ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); - handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); - if (handle != INVALID_HANDLE_VALUE) { - long size; - DeviceIoControl(handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); - return 1; + ioctl_log(ioctl->log, "handle=%p, error=%x\n", + ioctl->handle, (unsigned int) GetLastError()); + + return (ioctl->handle != INVALID_HANDLE_VALUE); +} + +static int +ioctl_read_normal_toc(ioctl_t *ioctl, uint8_t *toc_buf) +{ + long size = 0; + PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL; + + ioctl->tracks_num = 0; + memset(toc_buf, 0x00, 65536); + + cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536); + + ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_TOC; + ioctl_log(ioctl->log, "cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format); + ioctl->cur_read_toc_ex.Msf = 1; + ioctl->cur_read_toc_ex.SessionTrack = 1; + + ioctl_open_handle(ioctl); + const int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, + &ioctl->cur_read_toc_ex, 65535, + cur_full_toc, 65535, + (LPDWORD) &size, NULL); + ioctl_close_handle(ioctl); + ioctl_log(ioctl->log, "temp = %i\n", temp); + + if (temp != 0) { + const int length = ((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) + 2; + memcpy(toc_buf, cur_full_toc, length); + ioctl->tracks_num = (length - 4) / 8; } - return 0; + + free(cur_full_toc); + +#ifdef ENABLE_IOCTL_LOG + PCDROM_TOC toc = (PCDROM_TOC) toc_buf; + + ioctl_log(ioctl->log, "%i tracks: %02X %02X %02X %02X\n", + ioctl->tracks_num, toc_buf[0], toc_buf[1], toc_buf[2], toc_buf[3]); + + for (int i = 0; i < ioctl->tracks_num; i++) { + const uint8_t *t = (const uint8_t *) &toc->TrackData[i]; + ioctl_log(ioctl->log, "Track %03i: %02X %02X %02X %02X %02X %02X %02X %02X\n", + i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]); + } +#endif + + return temp; } static void -plat_cdrom_read_toc(void) +ioctl_read_raw_toc(ioctl_t *ioctl) { - long size = 0; + PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL; + long size = 0; + raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti; + uint8_t *buffer = (uint8_t *) calloc (1, 2052); - if (!toc_valid) { - toc_valid = 1; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &cur_toc, sizeof(cur_toc), (LPDWORD)&size, NULL); - plat_cdrom_close(); + ioctl->is_dvd = (ioctl_read_dvd_structure(ioctl, 0, 0, buffer, NULL) > 0); + free(buffer); + + ioctl->has_audio = 0; + ioctl->blocks_num = 0; + memset(ioctl->cur_rti, 0x00, 65536); + + cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536); + + ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC; + ioctl_log(ioctl->log, "cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format); + ioctl->cur_read_toc_ex.Msf = 1; + ioctl->cur_read_toc_ex.SessionTrack = 1; + + ioctl_open_handle(ioctl); + const int status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, + &ioctl->cur_read_toc_ex, 65535, + cur_full_toc, 65535, + (LPDWORD) &size, NULL); + ioctl_close_handle(ioctl); + ioctl_log(ioctl->log, "status = %i\n", status); + + if ((status == 0) && (ioctl->tracks_num >= 1)) { + /* + This is needed because in some circumstances (eg. a DVD .MDS + mounted in Daemon Tools), reading the raw TOC fails but + reading the cooked TOC does not, so we have to construct the + raw TOC from the cooked TOC. + */ + const CDROM_TOC *toc = (const CDROM_TOC *) ioctl->cur_toc; + const TRACK_DATA *ct = &(toc->TrackData[ioctl->tracks_num - 1]); + + rti[0].adr_ctl = ((ct->Adr & 0xf) << 4) | (ct->Control & 0xf); + rti[0].point = 0xa0; + rti[0].pm = toc->FirstTrack; + + rti[1].adr_ctl = rti[0].adr_ctl; + rti[1].point = 0xa1; + rti[1].pm = toc->LastTrack; + + rti[2].adr_ctl = rti[0].adr_ctl; + rti[2].point = 0xa2; + rti[2].pm = ct->Address[1]; + rti[2].ps = ct->Address[2]; + rti[2].pf = ct->Address[3]; + + ioctl->blocks_num = 3; + + for (int i = 0; i < (ioctl->tracks_num - 1); i++) { + raw_track_info_t *crt = &(rti[ioctl->blocks_num]); + + ct = &(toc->TrackData[i]); + + crt->adr_ctl = ((ct->Adr & 0xf) << 4) | (ct->Control & 0xf); + crt->point = ct->TrackNumber; + crt->pm = ct->Address[1]; + crt->ps = ct->Address[2]; + crt->pf = ct->Address[3]; + + ioctl->blocks_num++; + } + } else if (status != 0) { + ioctl->blocks_num = (((cur_full_toc->Length[0] << 8) | + cur_full_toc->Length[1]) - 2) / 11; + memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11); } -} -int -plat_cdrom_is_track_audio(uint32_t sector) -{ - int control = 0; - uint32_t track_addr = 0; - uint32_t next_track_addr = 0; + if (ioctl->blocks_num) for (int i = 0; i < ioctl->tracks_num; i++) { + const raw_track_info_t *crt = &(rti[i]); - plat_cdrom_read_toc(); - - for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; - next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; - win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", - cur_toc.FirstTrack, cur_toc.LastTrack, - cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, track_addr, sector); - if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector < next_track_addr)) { - control = cur_toc.TrackData[c].Control; + if ((crt->point >= 1) && (crt->point <= 99) && !(crt->adr_ctl & 0x04)) { + ioctl->has_audio = 1; break; } } - const int ret = !(control & 0x04); +#ifdef ENABLE_IOCTL_LOG + uint8_t *u = (uint8_t *) cur_full_toc; - win_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + ioctl_log(ioctl->log, "%i blocks: %02X %02X %02X %02X\n", + ioctl->blocks_num, u[0], u[1], u[2], u[3]); + + for (int i = 0; i < ioctl->blocks_num; i++) { + uint8_t *t = (uint8_t *) &rti[i]; + ioctl_log(ioctl->log, "Block %03i: %02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X\n", + i, t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], + t[9], t[10]); + } +#endif + + free(cur_full_toc); +} + +static void +ioctl_read_toc(ioctl_t *ioctl) +{ + (void) ioctl_read_normal_toc(ioctl, ioctl->cur_toc); + ioctl_read_raw_toc(ioctl); +} + +static int +ioctl_get_track(const ioctl_t *ioctl, const uint32_t sector) { + raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti; + int track = -1; + + for (int i = (ioctl->blocks_num - 1); i >= 0; i--) { + const raw_track_info_t *ct = &(rti[i]); + const uint32_t start = (ct->pm * 60 * 75) + (ct->ps * 75) + ct->pf - 150; + + ioctl_log(ioctl->log, "ioctl_get_track(): ct: %02X, %08X\n", + ct->point, start); + + if ((ct->point >= 1) && (ct->point <= 99) && (sector >= start)) { + track = i; + ioctl_log(ioctl->log, "ioctl_get_track(): found track: %i\n", i); + break; + } + } + + return track; +} + +static int +ioctl_is_track_audio(const ioctl_t *ioctl, const uint32_t pos) +{ + const raw_track_info_t *rti = (const raw_track_info_t *) ioctl->cur_rti; + int ret = 0; + + if (ioctl->has_audio && !ioctl->is_dvd) { + const int track = ioctl_get_track(ioctl, pos); + const int control = rti[track].adr_ctl; + + ret = !(control & 0x04); + + ioctl_log(ioctl->log, "ioctl_is_track_audio(%08X, %02X): %i\n", pos, track, ret); + } return ret; } -int -plat_cdrom_is_track_pre(uint32_t sector) +/* Shared functions. */ +static int +ioctl_get_track_info(const void *local, const uint32_t track, + int end, track_info_t *ti) { - int control = 0; - uint32_t track_addr = 0; - uint32_t next_track_addr = 0; + const ioctl_t * ioctl = (const ioctl_t *) local; + const CDROM_TOC *toc = (const CDROM_TOC *) ioctl->cur_toc; + int ret = 1; - plat_cdrom_read_toc(); + if ((track < 1) || (track == 0xaa) || (track > (toc->LastTrack + 1))) { + ioctl_log(ioctl->log, "ioctl_get_track_info(%02i)\n", track); + ret = 0; + } else { + const TRACK_DATA * td = &toc->TrackData[track - 1]; - for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; - next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; - win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", - cur_toc.FirstTrack, cur_toc.LastTrack, - cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, track_addr, sector); - if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector < next_track_addr)) { - control = cur_toc.TrackData[c].Control; - break; + ti->m = td->Address[1]; + ti->s = td->Address[2]; + ti->f = td->Address[3]; + + ti->number = td->TrackNumber; + ti->attr = td->Control; + ti->attr |= ((td->Adr << 4) & 0xf0); + + ioctl_log(ioctl->log, "ioctl_get_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", + track, ti->m, ti->s, ti->f, ti->number, ti->attr); + } + + return ret; +} + +static void +ioctl_get_raw_track_info(const void *local, int *num, uint8_t *rti) +{ + const ioctl_t *ioctl = (const ioctl_t *) local; + + *num = ioctl->blocks_num; + memcpy(rti, ioctl->cur_rti, ioctl->blocks_num * 11); +} + +static int +ioctl_is_track_pre(const void *local, const uint32_t sector) +{ + const ioctl_t *ioctl = (const ioctl_t *) local; + const raw_track_info_t *rti = (const raw_track_info_t *) ioctl->cur_rti; + int ret = 0; + + if (ioctl->has_audio && !ioctl->is_dvd) { + const int track = ioctl_get_track(ioctl, sector); + const int control = rti[track].adr_ctl; + + ret = control & 0x01; + + ioctl_log(ioctl->log, "ioctl_is_track_pre(%08X, %02X): %i\n", sector, track, ret); + } + + return ret; +} + +static int +ioctl_read_sector(const void *local, uint8_t *buffer, uint32_t const sector) +{ + typedef struct SCSI_PASS_THROUGH_DIRECT_BUF { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR SenseBuf[64]; + } SCSI_PASS_THROUGH_DIRECT_BUF; + + const ioctl_t * ioctl = (const ioctl_t *) local; + const raw_track_info_t * rti = (raw_track_info_t *) ioctl->cur_rti; + unsigned long int unused = 0; + const int sc_offs = (sector == 0xffffffff) ? 0 : 2352; + int len = (sector == 0xffffffff) ? 16 : 2368; + int m = 0; + int s = 0; + int f = 0; + uint32_t lba = sector; + int ret; + SCSI_PASS_THROUGH_DIRECT_BUF req; + + ioctl_open_handle((ioctl_t *) ioctl); + + if (ioctl->is_dvd) { + int track; + + req.spt.DataTransferLength = 0; + ret = 0; + + if (lba == 0xffffffff) { + lba = ioctl->dev->seek_pos; + track = ioctl_get_track(ioctl, lba); + + if (track != -1) { + req.spt.DataTransferLength = len; + ret = 1; } + } else { + len = COOKED_SECTOR_SIZE; + track = ioctl_get_track(ioctl, lba); + + if (track != -1) { + DWORD newPos = SetFilePointer(ioctl->handle, (long) lba * COOKED_SECTOR_SIZE, + 0, FILE_BEGIN); + + if (newPos != 0xffffffff) + ret = ReadFile(ioctl->handle, &(buffer[16]), + COOKED_SECTOR_SIZE, (LPDWORD) &req.spt.DataTransferLength, + NULL); + } + } + + if (ret && (req.spt.DataTransferLength >= len) && (track != -1)) { + const raw_track_info_t *ct = &(rti[track]); + const uint32_t start = (ct->pm * 60 * 75) + (ct->ps * 75) + ct->pf; + + m = s = f = 0; + + /* Construct sector header and sub-header. */ + if (sector != 0xffffffff) { + /* Sync bytes. */ + buffer[0] = 0x00; + memset(&(buffer[1]), 0xff, 10); + buffer[11] = 0x00; + + /* Sector header. */ + FRAMES_TO_MSF(lba + 150, &m, &s, &f); + buffer[12] = bin2bcd(m); + buffer[13] = bin2bcd(s); + buffer[14] = bin2bcd(f); + + /* Mode 1 data. */ + buffer[15] = 0x01; + } + + /* Construct Q. */ + buffer[sc_offs + 0] = (ct->adr_ctl >> 4) | ((ct->adr_ctl & 0xf) << 4); + buffer[sc_offs + 1] = bin2bcd(ct->point); + buffer[sc_offs + 2] = 1; + FRAMES_TO_MSF((int32_t) (lba + 150 - start), &m, &s, &f); + buffer[sc_offs + 3] = bin2bcd(m); + buffer[sc_offs + 4] = bin2bcd(s); + buffer[sc_offs + 5] = bin2bcd(f); + FRAMES_TO_MSF(lba + 150, &m, &s, &f); + buffer[sc_offs + 7] = bin2bcd(m); + buffer[sc_offs + 8] = bin2bcd(s); + buffer[sc_offs + 9] = bin2bcd(f); + } + } else { + memset(&req, 0x00, sizeof(SCSI_PASS_THROUGH_DIRECT_BUF)); + req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + req.spt.PathId = 0; + req.spt.TargetId = 1; + req.spt.Lun = 0; + req.spt.CdbLength = 12; + req.spt.DataIn = SCSI_IOCTL_DATA_IN; + req.spt.SenseInfoLength = sizeof(req.SenseBuf); + req.spt.DataTransferLength = len; + req.spt.TimeOutValue = 6; + req.spt.DataBuffer = buffer; + req.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_BUF, SenseBuf); + + /* Fill in the CDB. */ + req.spt.Cdb[0] = 0xbe; /* READ CD */ + req.spt.Cdb[1] = 0x00; + req.spt.Cdb[2] = (sector >> 24) & 0xff; + req.spt.Cdb[3] = (sector >> 16) & 0xff; + req.spt.Cdb[4] = (sector >> 8) & 0xff; + req.spt.Cdb[5] = sector & 0xff; /* Starting Logical Block Address. */ + req.spt.Cdb[6] = 0x00; + req.spt.Cdb[7] = 0x00; + req.spt.Cdb[8] = 0x01; /* Transfer Length. */ + /* If sector is FFFFFFFF, only return the subchannel. */ + req.spt.Cdb[9] = (sector == 0xffffffff) ? 0x00 : 0xf8; + req.spt.Cdb[10] = 0x02; + req.spt.Cdb[11] = 0x00; + DWORD length = sizeof(SCSI_PASS_THROUGH_DIRECT_BUF); + +#ifdef ENABLE_IOCTL_LOG + uint8_t *cdb = (uint8_t *) req.spt.Cdb; + ioctl_log(ioctl->log, "Host CDB: %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X\n", + ioctl->dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], + cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]); +#endif + + ret = DeviceIoControl(ioctl->handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, + &req, length, + &req, length, &unused, NULL); } - const int ret = (control & 0x01); + ioctl_log(ioctl->log, "ioctl_read_sector: ret = %d, req.spt.DataTransferLength = %lu\n", + ret, req.spt.DataTransferLength); + ioctl_log(ioctl->log, "Sense: %08X, %08X\n", req.spt.SenseInfoLength, req.spt.SenseInfoOffset); + if (req.spt.SenseInfoLength >= 16) { + uint8_t *cdb = (uint8_t *) req.SenseBuf; + if ((cdb[2] == 0x03) && (cdb[12] == 0x11)) + /* Treat this as an error to corectly indicate CIRC error to the guest. */ + ret = 0; + ioctl_log(ioctl->log, "Host sense: %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]); + ioctl_log(ioctl->log, " %02X %02X %02X %02X %02X %02X %02X %02X\n", + cdb[8], cdb[9], cdb[10], cdb[11], cdb[12], cdb[13], cdb[14], cdb[15]); + } - win_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + ret = (!!ret > 0) ? (req.spt.DataTransferLength >= len) : -1; + ioctl_log(ioctl->log, "iocl_read_sector: final ret = %i\n", ret); + + /* Construct raw subchannel data from Q only. */ + if ((ret > 0) && (req.spt.DataTransferLength >= len)) + for (int i = 11; i >= 0; i--) + for (int j = 7; j >= 0; j--) + buffer[2352 + (i * 8) + j] = ((buffer[sc_offs + i] >> (7 - j)) & 0x01) << 6; + + ioctl_close_handle((ioctl_t *) ioctl); return ret; } -uint32_t -plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +static uint8_t +ioctl_get_track_type(const void *local, const uint32_t sector) { - uint32_t track_addr = 0; - uint32_t next_track_addr = 0; + ioctl_t * ioctl = (ioctl_t *) local; + int track = ioctl_get_track(ioctl, sector); + raw_track_info_t * rti = (raw_track_info_t *) ioctl->cur_rti; + const raw_track_info_t *trk = &(rti[track]); + uint8_t ret = 0x00; - plat_cdrom_read_toc(); + if (ioctl_is_track_audio(ioctl, sector)) + ret = CD_TRACK_AUDIO; + else if (track != -1) for (int i = 0; i < ioctl->blocks_num; i++) { + const raw_track_info_t *ct = &(rti[i]); + const raw_track_info_t *nt = &(rti[i + 1]); - for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; - next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; - win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, a: %02X, A: %08X, S: %08X\n", - cur_toc.FirstTrack, cur_toc.LastTrack, - cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, cur_toc.TrackData[c].Adr, - track_addr, sector); - if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector < next_track_addr)) { - *track = cur_toc.TrackData[c].TrackNumber; - *attr = cur_toc.TrackData[c].Control; - *attr |= ((cur_toc.TrackData[c].Adr << 4) & 0xf0); - break; + if (ct->point == 0xa0) { + uint8_t first = ct->pm; + uint8_t last = nt->pm; + + if ((trk->point >= first) && (trk->point <= last)) { + ret = ct->ps; + break; + } } } - win_cdrom_ioctl_log("plat_cdrom_get_track_start(%08X): %i\n", sector, track_addr); - - return track_addr; + return ret; } -uint32_t -plat_cdrom_get_last_block(void) +static uint32_t +ioctl_get_last_block(const void *local) { - uint32_t lb = 0; - uint32_t address = 0; + const ioctl_t *ioctl = (const ioctl_t *) local; + const CDROM_TOC *toc = (const CDROM_TOC *) ioctl->cur_toc; + uint32_t lb = 0; - plat_cdrom_read_toc(); + for (int c = 0; c <= toc->LastTrack; c++) { + const TRACK_DATA *td = &toc->TrackData[c]; + const uint32_t address = MSFtoLBA(td->Address[1], td->Address[2], + td->Address[3]) - 150; - for (int c = 0; c <= cur_toc.LastTrack; c++) { - address = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; if (address > lb) lb = address; } - win_cdrom_ioctl_log("LBCapacity=%d\n", lb); + + ioctl_log(ioctl->log, "LBCapacity=%d\n", lb); + return lb; } -int -plat_cdrom_ext_medium_changed(void) +static int +ioctl_read_dvd_structure(const void *local, const uint8_t layer, const uint8_t format, + uint8_t *buffer, uint32_t *info) { - long size; - CDROM_TOC toc; - int ret = 0; + typedef struct SCSI_PASS_THROUGH_DIRECT_BUF { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR SenseBuf[64]; + } SCSI_PASS_THROUGH_DIRECT_BUF; - plat_cdrom_open(); - int temp = DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, - NULL, 0, &toc, sizeof(toc), - (LPDWORD)&size, NULL); - plat_cdrom_close(); + const ioctl_t * ioctl = (const ioctl_t *) local; + unsigned long int unused = 0; + const int len = 2052; + SCSI_PASS_THROUGH_DIRECT_BUF req; - if (!temp) - /* There has been some kind of error - not a medium change, but a not ready - condition. */ - ret = -1; - else if (!toc_valid || (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0)) { - /* Changed to a different host drive - we already detect such medium changes. */ - toc_valid = 1; - cur_toc = toc; - if (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0) - memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); - } else if ((toc.TrackData[toc.LastTrack].Address[1] != - cur_toc.TrackData[cur_toc.LastTrack].Address[1]) || - (toc.TrackData[toc.LastTrack].Address[2] != - cur_toc.TrackData[cur_toc.LastTrack].Address[2]) || - (toc.TrackData[toc.LastTrack].Address[3] != - cur_toc.TrackData[cur_toc.LastTrack].Address[3])) - /* The TOC has changed. */ - ret = 1; + ioctl_open_handle((ioctl_t *) ioctl); - win_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); + memset(&req, 0x00, sizeof(SCSI_PASS_THROUGH_DIRECT_BUF)); + req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + req.spt.PathId = 0; + req.spt.TargetId = 1; + req.spt.Lun = 0; + req.spt.CdbLength = 12; + req.spt.DataIn = SCSI_IOCTL_DATA_IN; + req.spt.SenseInfoLength = sizeof(req.SenseBuf); + req.spt.DataTransferLength = len; + req.spt.TimeOutValue = 6; + req.spt.DataBuffer = buffer; + req.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_BUF, SenseBuf); + + /* Fill in the CDB. */ + req.spt.Cdb[0] = 0xad; + req.spt.Cdb[1] = 0x00; + req.spt.Cdb[2] = 0x00; + req.spt.Cdb[3] = 0x00; + req.spt.Cdb[4] = 0x00; + req.spt.Cdb[5] = 0x00; + req.spt.Cdb[6] = layer; /* Layer Number */ + req.spt.Cdb[7] = format; /* Format */ + req.spt.Cdb[8] = 0x08; /* Allocation Length */ + req.spt.Cdb[9] = 0x04; + req.spt.Cdb[10] = 0x00; /* AGID */ + req.spt.Cdb[11] = 0x00; + + DWORD length = sizeof(SCSI_PASS_THROUGH_DIRECT_BUF); + +#ifdef ENABLE_IOCTL_LOG + uint8_t *cdb = (uint8_t *) req.spt.Cdb; + ioctl_log(ioctl->log, "Host 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]); +#endif + + int ret = DeviceIoControl(ioctl->handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, + &req, length, + &req, length, + &unused, NULL); + + ioctl_log(ioctl->log, "ioctl_read_dvd_structure(): ret = %d, " + "req.spt.DataTransferLength = %lu\n", + ret, req.spt.DataTransferLength); + ioctl_log(ioctl->log, "Sense: %08X, %08X\n", req.spt.SenseInfoLength, + req.spt.SenseInfoOffset); + + if (req.spt.SenseInfoLength >= 16) { + uint8_t *sb = (uint8_t *) req.SenseBuf; + /* Return sense to the host as is. */ + ret = -((sb[2] << 16) | (sb[12] << 8) | sb[13]); + if (info != NULL) + *info = *(uint32_t *) &(sb[3]); + ioctl_log(ioctl->log, "Host sense: %02X %02X %02X %02X %02X %02X %02X %02X\n", + sb[0], sb[1], sb[ 2], sb[ 3], sb[ 4], sb[ 5], sb[ 6], sb[ 7]); + ioctl_log(ioctl->log, " %02X %02X %02X %02X %02X %02X %02X %02X\n", + sb[8], sb[9], sb[10], sb[11], sb[12], sb[13], sb[14], sb[15]); + } else + ret = ret ? (req.spt.DataTransferLength >= len) : 0; + + ioctl_close_handle((ioctl_t *) ioctl); return ret; } -void -plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +static int +ioctl_is_dvd(const void *local) { - plat_cdrom_read_toc(); + const ioctl_t *ioctl = (const ioctl_t *) local; - *st_track = 1; - *end = cur_toc.LastTrack; - lead_out->min = cur_toc.TrackData[cur_toc.LastTrack].Address[1]; - lead_out->sec = cur_toc.TrackData[cur_toc.LastTrack].Address[2]; - lead_out->fr = cur_toc.TrackData[cur_toc.LastTrack].Address[3]; - - win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", - *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); + return ioctl->is_dvd; } -/* This replaces both Info and EndInfo, they are specified by a variable. */ -int -plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) +static int +ioctl_has_audio(const void *local) { - plat_cdrom_read_toc(); + const ioctl_t *ioctl = (const ioctl_t *) local; - if ((track < 1) || (track == 0xaa) || (track > (cur_toc.LastTrack + 1))) { - win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); - return 0; - } - - start->min = cur_toc.TrackData[track - 1].Address[1]; - start->sec = cur_toc.TrackData[track - 1].Address[2]; - start->fr = cur_toc.TrackData[track - 1].Address[3]; - - *track_num = cur_toc.TrackData[track - 1].TrackNumber; - *attr = cur_toc.TrackData[track - 1].Control; - *attr |= ((cur_toc.TrackData[track - 1].Adr << 4) & 0xf0); - - win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", - track, start->min, start->sec, start->fr, *track_num, *attr); - - return 1; + return ioctl->has_audio; } -/* TODO: See if track start is adjusted by 150 or not. */ -int -plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +static int +ioctl_is_empty(const void *local) { - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - long size = 0; + typedef struct SCSI_PASS_THROUGH_DIRECT_BUF { + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR SenseBuf[64]; + } SCSI_PASS_THROUGH_DIRECT_BUF; - insub.Format = IOCTL_CDROM_CURRENT_POSITION; + const ioctl_t * ioctl = (const ioctl_t *) local; + unsigned long int unused = 0; + SCSI_PASS_THROUGH_DIRECT_BUF req; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); - plat_cdrom_close(); + ioctl_open_handle((ioctl_t *) ioctl); - if (sub.CurrentPosition.TrackNumber < 1) - return 0; + memset(&req, 0x00, sizeof(SCSI_PASS_THROUGH_DIRECT_BUF)); + req.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT); + req.spt.PathId = 0; + req.spt.TargetId = 1; + req.spt.Lun = 0; + req.spt.CdbLength = 12; + req.spt.DataIn = SCSI_IOCTL_DATA_IN; + req.spt.SenseInfoLength = sizeof(req.SenseBuf); + req.spt.DataTransferLength = 0; + req.spt.TimeOutValue = 6; + req.spt.DataBuffer = NULL; + req.spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_BUF, SenseBuf); - *track = sub.CurrentPosition.TrackNumber; - *attr = sub.CurrentPosition.Control; - *attr |= ((sub.CurrentPosition.ADR << 4) & 0xf0); - *index = sub.CurrentPosition.IndexNumber; + /* Fill in the CDB. */ + req.spt.Cdb[0] = 0x00; + req.spt.Cdb[1] = 0x00; + req.spt.Cdb[2] = 0x00; + req.spt.Cdb[3] = 0x00; + req.spt.Cdb[4] = 0x00; + req.spt.Cdb[5] = 0x00; + req.spt.Cdb[6] = 0x00; + req.spt.Cdb[7] = 0x00; + req.spt.Cdb[8] = 0x00; + req.spt.Cdb[9] = 0x00; + req.spt.Cdb[10] = 0x00; + req.spt.Cdb[11] = 0x00; - rel_pos->min = sub.CurrentPosition.TrackRelativeAddress[1]; - rel_pos->sec = sub.CurrentPosition.TrackRelativeAddress[2]; - rel_pos->fr = sub.CurrentPosition.TrackRelativeAddress[3]; - abs_pos->min = sub.CurrentPosition.AbsoluteAddress[1]; - abs_pos->sec = sub.CurrentPosition.AbsoluteAddress[2]; - abs_pos->fr = sub.CurrentPosition.AbsoluteAddress[3]; + DWORD length = sizeof(SCSI_PASS_THROUGH_DIRECT_BUF); - win_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); +#ifdef ENABLE_IOCTL_LOG + uint8_t *cdb = (uint8_t *) req.spt.Cdb; + ioctl_log(ioctl->log, "Host 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]); +#endif - return 1; + int ret = DeviceIoControl(ioctl->handle, IOCTL_SCSI_PASS_THROUGH_DIRECT, + &req, length, + &req, length, + &unused, NULL); + + ioctl_log(ioctl->log, "ioctl_read_dvd_structure(): ret = %d, " + "req.spt.DataTransferLength = %lu\n", + ret, req.spt.DataTransferLength); + ioctl_log(ioctl->log, "Sense: %08X, %08X\n", req.spt.SenseInfoLength, + req.spt.SenseInfoOffset); + + if (req.spt.SenseInfoLength >= 16) { + uint8_t *sb = (uint8_t *) req.SenseBuf; + /* Return sense to the host as is. */ + ret = ((sb[2] == SENSE_NOT_READY) && (sb[12] == ASC_MEDIUM_NOT_PRESENT)); + ioctl_log(ioctl->log, "Host sense: %02X %02X %02X %02X %02X %02X %02X %02X\n", + sb[0], sb[1], sb[ 2], sb[ 3], sb[ 4], sb[ 5], sb[ 6], sb[ 7]); + ioctl_log(ioctl->log, " %02X %02X %02X %02X %02X %02X %02X %02X\n", + sb[8], sb[9], sb[10], sb[11], sb[12], sb[13], sb[14], sb[15]); + } else + ret = 0; + + ioctl_close_handle((ioctl_t *) ioctl); + + return ret; } -int -plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +static void +ioctl_close(void *local) { - long size; - DISK_GEOMETRY dgCDROM; + ioctl_t *ioctl = (ioctl_t *) local; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL); - plat_cdrom_close(); + ioctl_close_handle(ioctl); + ioctl->handle = NULL; - win_cdrom_ioctl_log("BytesPerSector=%d\n", dgCDROM.BytesPerSector); - return dgCDROM.BytesPerSector; + ioctl_log(ioctl->log, "Log closed\n"); + + log_close(ioctl->log); + ioctl->log = NULL; } -int -plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +static void +ioctl_load(const void *local) { - BOOL status; - long size = 0; - int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + const ioctl_t *ioctl = (const ioctl_t *) local; - plat_cdrom_open(); + if (ioctl_open_handle((ioctl_t *) ioctl)) { + long size; + DeviceIoControl(ioctl->handle, IOCTL_STORAGE_LOAD_MEDIA, + NULL, 0, NULL, 0, + (LPDWORD) &size, NULL); + ioctl_close_handle((ioctl_t *) ioctl); - if (raw) { - win_cdrom_ioctl_log("Raw\n"); - /* Raw */ - RAW_READ_INFO in; - in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), - buffer, buflen, (LPDWORD)&size, NULL); - } else { - win_cdrom_ioctl_log("Cooked\n"); - /* Cooked */ - int success = 0; - DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); - if (newPos != 0xFFFFFFFF) - success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); - status = (success != 0); - } - plat_cdrom_close(); - win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); - - return (size == buflen) && (status > 0); -} - -void -plat_cdrom_eject(void) -{ - long size; - - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); - - plat_cdrom_close(); -} - -void -plat_cdrom_close(void) -{ - if (handle != NULL) { - CloseHandle(handle); - handle = NULL; + ioctl_read_toc((ioctl_t *) ioctl); } } -int -plat_cdrom_set_drive(const char *drv) +static const cdrom_ops_t ioctl_ops = { + ioctl_get_track_info, + ioctl_get_raw_track_info, + ioctl_is_track_pre, + ioctl_read_sector, + ioctl_get_track_type, + ioctl_get_last_block, + ioctl_read_dvd_structure, + ioctl_is_dvd, + ioctl_has_audio, + ioctl_is_empty, + ioctl_close, + ioctl_load +}; + +/* Public functions. */ +void * +ioctl_open(cdrom_t *dev, const char *drv) { - plat_cdrom_close(); + ioctl_t *ioctl = (ioctl_t *) calloc(1, sizeof(ioctl_t)); - memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); - memset(ioctl_path, 0x00, sizeof(ioctl_path)); + if (ioctl != NULL) { + char n[1024] = { 0 }; - wsprintf(ioctl_path, L"%S", drv); - win_cdrom_ioctl_log("Path is %S\n", ioctl_path); + sprintf(n, "CD-ROM %i IOCtl", dev->id + 1); + ioctl->log = log_open(n); - toc_valid = 0; + memset(ioctl->path, 0x00, sizeof(ioctl->path)); - plat_cdrom_load(); - return 1; + wsprintf(ioctl->path, L"%S", &(drv[8])); + ioctl_log(ioctl->log, "Path is %S\n", ioctl->path); + + ioctl->dev = dev; + + dev->ops = &ioctl_ops; + + ioctl_load(ioctl); + } + + return ioctl; } diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index bb05c3f5c..5173d4f05 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -8,15 +8,13 @@ * * RawInput joystick interface. * - * - * * Authors: Miran Grca, * GH Cao, - * Jasmine Iwanek, + * Jasmine Iwanek, * * Copyright 2016-2018 Miran Grca. * Copyright 2020 GH Cao. - * Copyright 2021-2023 Jasmine Iwanek. + * Copyright 2021-2025 Jasmine Iwanek. */ #include #include @@ -98,9 +96,9 @@ typedef struct { } pov[MAX_JOY_POVS]; } raw_joystick_t; -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; int joysticks_present = 0; +joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; @@ -412,21 +410,21 @@ win_joystick_handle(PRAWINPUT raw) /* Read buttons */ USAGE usage_list[128] = { 0 }; ULONG usage_length = plat_joystick_state[j].nr_buttons; - memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); + memset(plat_joystick_state[j].b, 0, MAX_JOY_BUTTONS * sizeof(int)); r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); if (r == HIDP_STATUS_SUCCESS) { for (int i = 0; i < usage_length; i++) { - int button = raw_joystick_state[j].usage_button[usage_list[i]]; + int button = raw_joystick_state[j].usage_button[usage_list[i]]; plat_joystick_state[j].b[button] = 128; } } /* Read axes */ - for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { - const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + for (int axis_nr = 0; axis_nr < plat_joystick_state[j].nr_axes; axis_nr++) { + const struct raw_axis_t *axis = &raw_joystick_state[j].axis[axis_nr]; ULONG uvalue = 0; LONG value = 0; LONG center = (axis->max - axis->min + 1) / 2; @@ -453,15 +451,15 @@ win_joystick_handle(PRAWINPUT raw) value = value * 32768 / center; } - plat_joystick_state[j].a[a] = value; + plat_joystick_state[j].a[axis_nr] = value; #if 0 - joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); + joystick_log("%s %-06d ", plat_joystick_state[0][j].axis[axis_nr].name, plat_joystick_state[j].a[axis_nr]); #endif } /* read povs */ - for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { - const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + for (int pov_nr = 0; pov_nr < plat_joystick_state[j].nr_povs; pov_nr++) { + const struct raw_pov_t *pov = &raw_joystick_state[j].pov[pov_nr]; ULONG uvalue = 0; LONG value = -1; @@ -474,10 +472,10 @@ win_joystick_handle(PRAWINPUT raw) value %= 36000; } - plat_joystick_state[j].p[p] = value; + plat_joystick_state[j].p[pov_nr] = value; #if 0 - joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); + joystick_log("%s %-3d ", plat_joystick_state[0][j].pov[pov_nr].name, plat_joystick_state[j].p[pov_nr]); #endif } #if 0 @@ -508,44 +506,39 @@ joystick_get_axis(int joystick_nr, int mapping) void joystick_process(void) { - int d; - if (joystick_type == JS_TYPE_NONE) return; - for (int c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + for (int js = 0; js < joystick_get_max_joysticks(joystick_type); js++) { + if (joystick_state[0][js].plat_joystick_nr) { + int joystick_nr = joystick_state[0][js].plat_joystick_nr - 1; - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) + joystick_state[0][js].axis[axis_nr] = joystick_get_axis(joystick_nr, joystick_state[0][js].axis_mapping[axis_nr]); - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x; - int y; - double angle; - double magnitude; + for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) + joystick_state[0][js].button[button_nr] = plat_joystick_state[joystick_nr].b[joystick_state[0][js].button_mapping[button_nr]]; - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double) x * (double) x + (double) y * (double) y); + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) { + int x = joystick_get_axis(joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][0]); + int y = joystick_get_axis(joystick_nr, joystick_state[0][js].pov_mapping[pov_nr][1]); + double angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); + double magnitude = sqrt((double) x * (double) x + (double) y * (double) y); if (magnitude < 16384) - joystick_state[c].pov[d] = -1; + joystick_state[0][js].pov[pov_nr] = -1; else - joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; + joystick_state[0][js].pov[pov_nr] = ((int) angle + 90 + 360) % 360; } } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type); axis_nr++) + joystick_state[0][js].axis[axis_nr] = 0; + + for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type); button_nr++) + joystick_state[0][js].button[button_nr] = 0; + + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type); pov_nr++) + joystick_state[0][js].pov[pov_nr] = -1; } } } diff --git a/src/qt/win_opendir.c b/src/qt/win_opendir.c index 051ed20bb..46c7eb21e 100644 --- a/src/qt/win_opendir.c +++ b/src/qt/win_opendir.c @@ -40,21 +40,19 @@ opendir(const char *name) DIR *p; /* Create a new control structure. */ - p = (DIR *) malloc(sizeof(DIR)); + p = (DIR *) calloc(1, sizeof(DIR)); if (p == NULL) return (NULL); - memset(p, 0x00, sizeof(DIR)); p->flags = (DIR_F_LOWER | DIR_F_SANE); p->offset = 0; p->sts = 0; /* Create a work area. */ - p->dta = (char *) malloc(sizeof(FINDATA)); + p->dta = (char *) calloc(1, sizeof(FINDATA)); if (p->dta == NULL) { free(p); return (NULL); } - memset(p->dta, 0x00, sizeof(struct _finddata_t)); /* Add search filespec. */ strcpy(p->dir, name); diff --git a/src/qt/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c index 2b77bd219..c1802ce73 100644 --- a/src/qt/win_serial_passthrough.c +++ b/src/qt/win_serial_passthrough.c @@ -88,7 +88,7 @@ plat_serpt_set_params(void *priv) const serial_passthrough_t *dev = (serial_passthrough_t *) priv; if (dev->mode == SERPT_MODE_HOSTSER) { - DCB serialattr = {}; + DCB serialattr = { 0 }; GetCommState((HANDLE) dev->master_fd, &serialattr); #define BAUDRATE_RANGE(baud_rate, min, max) \ if (baud_rate >= min && baud_rate < max) { \ diff --git a/src/qt/win_thread.c b/src/qt/win_thread.c new file mode 100644 index 000000000..9a4f046b3 --- /dev/null +++ b/src/qt/win_thread.c @@ -0,0 +1,179 @@ +/* + * 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. + * + * Implement threads and mutexes for the Win32 platform. + * + * + * + * Authors: Sarah Walker, + * Fred N. van Kempen, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2017-2018 Fred N. van Kempen. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/plat.h> +#include <86box/thread.h> + +typedef struct { + HANDLE handle; +} win_event_t; + +/* For compatibility with thread.h, but Win32 does not allow named threads. */ +thread_t * +thread_create_named(void (*func)(void *param), void *param, UNUSED(const char *name)) +{ + uintptr_t bt = _beginthread(func, 0, param); + return ((thread_t *) bt); +} + +int +thread_test_mutex(thread_t *arg) +{ + if (arg == NULL) + return (0); + + return (WaitForSingleObject(arg, 0) == WAIT_OBJECT_0) ? 1 : 0; +} + +int +thread_wait(thread_t *arg) +{ + if (arg == NULL) + return (0); + + if (WaitForSingleObject(arg, INFINITE)) + return (1); + + return (0); +} + +event_t * +thread_create_event(void) +{ + win_event_t *ev = malloc(sizeof(win_event_t)); + + ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + + return ((event_t *) ev); +} + +void +thread_set_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *) arg; + + if (arg == NULL) + return; + + SetEvent(ev->handle); +} + +void +thread_reset_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *) arg; + + if (arg == NULL) + return; + + ResetEvent(ev->handle); +} + +int +thread_wait_event(event_t *arg, int timeout) +{ + win_event_t *ev = (win_event_t *) arg; + + if (arg == NULL) + return (0); + + if (ev->handle == NULL) + return (0); + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(ev->handle, timeout)) + return (1); + + return (0); +} + +void +thread_destroy_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *) arg; + + if (arg == NULL) + return; + + CloseHandle(ev->handle); + + free(ev); +} + +mutex_t * +thread_create_mutex(void) +{ + mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); + + InitializeCriticalSection(mutex); + + return mutex; +} + +int +thread_wait_mutex(mutex_t *mutex) +{ + if (mutex == NULL) + return (0); + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; + + EnterCriticalSection(critsec); + + return 1; +} + +int +thread_release_mutex(mutex_t *mutex) +{ + if (mutex == NULL) + return (0); + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; + + LeaveCriticalSection(critsec); + + return 1; +} + +void +thread_close_mutex(mutex_t *mutex) +{ + if (mutex == NULL) + return; + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION) mutex; + + DeleteCriticalSection(critsec); + + free(critsec); +} diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index 1be6ec826..4d79ce66d 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -132,7 +132,7 @@ xinput2_proc() XGenericEventCookie *cookie = (XGenericEventCookie *) &ev.xcookie; XNextEvent(disp, (XEvent *) &ev); - if (XGetEventData(disp, cookie) && (cookie->type == GenericEvent) && (cookie->extension == xi2opcode)) { + if (XGetEventData(disp, cookie) && (cookie->type == GenericEvent) && (cookie->extension == xi2opcode) && mouse_capture) { const XIRawEvent *rawev = (const XIRawEvent *) cookie->data; double coords[2] = { 0.0 }; @@ -214,8 +214,6 @@ common_motion: } prev_time = rawev->time; - if (!mouse_capture) - break; XWindowAttributes winattrib {}; if (XGetWindowAttributes(disp, main_window->winId(), &winattrib)) { auto globalPoint = main_window->mapToGlobal(QPoint(main_window->width() / 2, main_window->height() / 2)); diff --git a/src/scsi/CMakeLists.txt b/src/scsi/CMakeLists.txt index 01e20b929..c710f758d 100644 --- a/src/scsi/CMakeLists.txt +++ b/src/scsi/CMakeLists.txt @@ -9,10 +9,24 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(scsi OBJECT scsi.c scsi_device.c scsi_cdrom.c scsi_disk.c - scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c scsi_ncr53c400.c - scsi_t128.c scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) +add_library(scsi OBJECT + scsi.c + scsi_device.c + scsi_cdrom.c + scsi_disk.c + scsi_x54x.c + scsi_aha154x.c + scsi_buslogic.c + scsi_ncr5380.c + scsi_ncr53c400.c + scsi_t128.c + scsi_ncr53c8xx.c + scsi_pcscsi.c + scsi_spock.c +) diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 7d9f1ba24..7c887e28b 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -678,6 +678,7 @@ aha_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) aha_eeprom_save(dev); dev->rom_addr = config->mem[0].base; + aha_log("Base = %08X, Size = %08X\n", config->mem[0].base, config->mem[0].size); if (dev->rom_addr) { mem_mapping_enable(&dev->bios.mapping); aha_log("SCSI BIOS set to: %08X-%08X\n", dev->rom_addr, dev->rom_addr + config->mem[0].size - 1); @@ -869,13 +870,12 @@ aha_setmcode(x54x_t *dev) } aha1542cp_pnp_rom = (uint8_t *) malloc(dev->pnp_len + 7); fseek(fp, dev->pnp_offset, SEEK_SET); - (void) !fread(aha1542cp_pnp_rom, dev->pnp_len, 1, fp); + (void) !fread(aha1542cp_pnp_rom, 4, 1, fp); memset(&(aha1542cp_pnp_rom[4]), 0x00, 5); fseek(fp, dev->pnp_offset + 4, SEEK_SET); (void) !fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, fp); - /* Even the real AHA-1542CP microcode seem to be flipping bit - 4 to not erroneously indicate there is a range length. */ - aha1542cp_pnp_rom[0x87] |= 0x04; + /* Patch determined from Dizzy's AHA-1542CP PNP ROM dump. */ + aha1542cp_pnp_rom[0x26] = 0x03; /* Insert the terminator and the checksum byte that will later be filled in by the isapnp code. */ aha1542cp_pnp_rom[dev->pnp_len + 5] = 0x79; @@ -925,8 +925,7 @@ aha_setnvr(x54x_t *dev) return; /* Allocate and initialize the EEPROM. */ - dev->nvr = (uint8_t *) malloc(NVR_SIZE); - memset(dev->nvr, 0x00, NVR_SIZE); + dev->nvr = (uint8_t *) calloc(1, NVR_SIZE); fp = nvr_fopen(dev->nvr_path, "rb"); if (fp) { @@ -1159,14 +1158,14 @@ aha_init(const device_t *info) // clang-format off static const device_config_t aha_154xb_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x334, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1176,16 +1175,17 @@ static const device_config_t aha_154xb_config[] = { { .description = "0x134", .value = 0x134 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 11, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1194,31 +1194,33 @@ static const device_config_t aha_154xb_config[] = { { .description = "IRQ 15", .value = 15 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1229,16 +1231,17 @@ static const device_config_t aha_154xb_config[] = { { .description = "7", .value = 7 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1246,20 +1249,21 @@ static const device_config_t aha_154xb_config[] = { { .description = "DC00H", .value = 0xdc000 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t aha_154x_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x334, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1269,16 +1273,17 @@ static const device_config_t aha_154x_config[] = { { .description = "0x134", .value = 0x134 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 11, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1287,52 +1292,55 @@ static const device_config_t aha_154x_config[] = { { .description = "IRQ 15", .value = 15 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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_154xcf_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x334, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1342,16 +1350,17 @@ static const device_config_t aha_154xcf_config[] = { { .description = "0x134", .value = 0x134 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 11, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1360,31 +1369,33 @@ static const device_config_t aha_154xcf_config[] = { { .description = "IRQ 15", .value = 15 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "CC00H", .value = 0xcc000 }, @@ -1394,44 +1405,64 @@ static const device_config_t aha_154xcf_config[] = { { .description = "DC00H", .value = 0xdc000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "fdc_addr", - .description = "FDC address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "fdc_addr", + .description = "FDC Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "None", .value = 0 }, { .description = "0x3f0", .value = FDC_PRIMARY_ADDR }, { .description = "0x370", .value = FDC_SECONDARY_ADDR }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t aha_154xcp_config[] = { { - .name = "bios_rev", - .description = "BIOS Revision", - .type = CONFIG_BIOS, + .name = "bios_rev", + .description = "BIOS Revision", + .type = CONFIG_BIOS, .default_string = "v1_02_en", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .bios = { - { .name = "Version 1.02 (English)", .internal_name = "v1_02_en", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp102.bin", - "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12", "" } }, - { .name = "Version 1.02 (German)", .internal_name = "v1_02_de", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/buff_1-0_bios.bin", - "roms/scsi/adaptec/buff_1-0_mcode.bin", "" } }, - { .name = "Version 1.03 (English)", .internal_name = "v1_03_en", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 32768, .files = { "roms/scsi/adaptec/aha1542cp103.bin", - "roms/scsi/adaptec/908301-00_g_mcode_144c.u12.bin", "" } }, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "Version 1.02 (English)", + .internal_name = "v1_02_en", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 32768, + .files = { "roms/scsi/adaptec/aha1542cp102.bin", "roms/scsi/adaptec/908301-00_f_mcode_17c9.u12", "" } + }, + { + .name = "Version 1.02 (German)", + .internal_name = "v1_02_de", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 32768, + .files = { "roms/scsi/adaptec/buff_1-0_bios.bin", "roms/scsi/adaptec/buff_1-0_mcode.bin", "" } + }, + { + .name = "Version 1.03 (English)", + .internal_name = "v1_03_en", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 32768, + .files = { "roms/scsi/adaptec/aha1542cp103.bin", "roms/scsi/adaptec/908301-00_g_mcode_144c.u12.bin", "" } + }, { .files_no = 0 } }, }, @@ -1442,12 +1473,12 @@ static const device_config_t aha_154xcp_config[] = { const device_t aha154xa_device = { .name = "Adaptec AHA-154xA", .internal_name = "aha154xa", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = AHA_154xA, .init = aha_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = aha_154xb_config @@ -1456,12 +1487,12 @@ const device_t aha154xa_device = { const device_t aha154xb_device = { .name = "Adaptec AHA-154xB", .internal_name = "aha154xb", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = AHA_154xB, .init = aha_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = aha_154xb_config @@ -1470,12 +1501,12 @@ const device_t aha154xb_device = { const device_t aha154xc_device = { .name = "Adaptec AHA-154xC", .internal_name = "aha154xc", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = AHA_154xC, .init = aha_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = aha_154x_config @@ -1484,12 +1515,12 @@ const device_t aha154xc_device = { const device_t aha154xcf_device = { .name = "Adaptec AHA-154xCF", .internal_name = "aha154xcf", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = AHA_154xCF, .init = aha_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = aha_154xcf_config @@ -1498,12 +1529,12 @@ const device_t aha154xcf_device = { const device_t aha154xcp_device = { .name = "Adaptec AHA-154xCP", .internal_name = "aha154xcp", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = AHA_154xCP, .init = aha_init, .close = aha1542cp_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = aha_154xcp_config @@ -1517,7 +1548,7 @@ const device_t aha1640_device = { .init = aha_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index ac3b464a8..9fe34380b 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1546,8 +1546,7 @@ buslogic_init(const device_t *info) dev = x54x_init(info); dev->bus = scsi_get_bus(); - dev->ven_data = malloc(sizeof(buslogic_data_t)); - memset(dev->ven_data, 0x00, sizeof(buslogic_data_t)); + dev->ven_data = calloc(1, sizeof(buslogic_data_t)); bl = (buslogic_data_t *) dev->ven_data; @@ -1781,14 +1780,14 @@ buslogic_init(const device_t *info) // clang-format off static const device_config_t BT_ISA_Config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x334, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x334, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "0x330", .value = 0x330 }, { .description = "0x334", .value = 0x334 }, { .description = "0x230", .value = 0x230 }, @@ -1797,16 +1796,17 @@ static const device_config_t BT_ISA_Config[] = { { .description = "0x134", .value = 0x134 }, { .description = "", .value = 0 } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 11, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -1815,48 +1815,55 @@ static const device_config_t BT_ISA_Config[] = { { .description = "IRQ 15", .value = 15 }, { .description = "", 0 } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", .value = 0 } }, + .bios = { { 0 } } }, { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "", .value = 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t BT958D_Config[] = { { - .name = "bios", - .description = "Enable BIOS", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 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 } }; @@ -1865,12 +1872,12 @@ static const device_config_t BT958D_Config[] = { const device_t buslogic_542b_device = { .name = "BusLogic BT-542B ISA", .internal_name = "bt542b", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CHIP_BUSLOGIC_ISA_542B_1991_12_14, .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT_ISA_Config @@ -1879,12 +1886,12 @@ const device_t buslogic_542b_device = { const device_t buslogic_545s_device = { .name = "BusLogic BT-545S ISA", .internal_name = "bt545s", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CHIP_BUSLOGIC_ISA_545S_1992_10_05, .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT_ISA_Config @@ -1893,12 +1900,12 @@ const device_t buslogic_545s_device = { const device_t buslogic_542bh_device = { .name = "BusLogic BT-542BH ISA", .internal_name = "bt542bh", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CHIP_BUSLOGIC_ISA_542BH_1993_05_23, .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT_ISA_Config @@ -1907,12 +1914,12 @@ const device_t buslogic_542bh_device = { const device_t buslogic_545c_device = { .name = "BusLogic BT-545C ISA", .internal_name = "bt545c", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CHIP_BUSLOGIC_ISA_545C_1994_12_01, .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT_ISA_Config @@ -1926,7 +1933,7 @@ const device_t buslogic_640a_device = { .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1940,7 +1947,7 @@ const device_t buslogic_445s_device = { .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT_ISA_Config @@ -1954,7 +1961,7 @@ const device_t buslogic_445c_device = { .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT_ISA_Config @@ -1968,7 +1975,7 @@ const device_t buslogic_958d_pci_device = { .init = buslogic_init, .close = x54x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = BT958D_Config diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index be9809e08..04c6532df 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -9,46 +9,41 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * - * * Authors: Miran Grca, * - * Copyright 2016-2020 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ -#include #include #include +#ifdef ENABLE_SCSI_CDROM_LOG +#include +#endif #include #include #include #include -#include -#define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/config.h> #include <86box/timer.h> +#include <86box/cdrom.h> #include <86box/device.h> -#include <86box/scsi.h> -#include <86box/scsi_device.h> +#include <86box/log.h> #include <86box/machine.h> #include <86box/nvr.h> -#include <86box/hdc.h> -#include <86box/hdc_ide.h> -#include <86box/sound.h> #include <86box/plat.h> -#include <86box/ui.h> -#include <86box/cdrom.h> +#include <86box/scsi.h> +#include <86box/scsi_device.h> +#include <86box/hdc_ide.h> #include <86box/scsi_cdrom.h> -#include <86box/version.h> +#include <86box/ui.h> #define IDE_ATAPI_IS_EARLY id->sc->pad0 #pragma pack(push, 1) typedef struct gesn_cdb_t { - uint8_t opcode; - uint8_t polled; - uint8_t reserved2[2]; - uint8_t class; + uint8_t opcode; + uint8_t polled; + uint8_t reserved2[2]; + uint8_t class; uint8_t reserved3[2]; uint16_t len; uint8_t control; @@ -61,411 +56,192 @@ typedef struct gesn_event_header_t { } gesn_event_header_t; #pragma pack(pop) -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ +// clang-format off +/* + Table of all SCSI commands and their flags, needed for the new disc change / + not ready handler. + */ uint8_t scsi_cdrom_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, /* 0x02 */ - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, /* 0x04-0x07 */ - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, 0, /* 0x09-0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, /* 0x0C */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0x0D */ - 0, 0, 0, 0, /* 0x0E-0x11 */ - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, /* 0x14 */ - IMPLEMENTED, /* 0x15 */ - 0, 0, 0, 0, /* 0x16-0x19 */ - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, 0, /* 0x1C-0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, /* 0x1F-0x21*/ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0x22*/ - 0, 0, /* 0x23-0x24 */ - IMPLEMENTED | CHECK_READY, /* 0x25 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0x26 */ - 0, /* 0x27 */ - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, 0, /* 0x29-0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, 0, /* 0x2C-0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ - 0, 0, /* 0x40-0x41 */ - IMPLEMENTED | CHECK_READY, /* 0x42 */ - IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - IMPLEMENTED | CHECK_READY, /* 0x44 */ - IMPLEMENTED | CHECK_READY, /* 0x45 */ - IMPLEMENTED | ALLOW_UA, /* 0x46 */ - IMPLEMENTED | CHECK_READY, /* 0x47 */ - IMPLEMENTED | CHECK_READY, /* 0x48 */ - IMPLEMENTED | CHECK_READY, /* 0x49 */ - IMPLEMENTED | ALLOW_UA, /* 0x4A */ - IMPLEMENTED | CHECK_READY, /* 0x4B */ - 0, 0, /* 0x4C-0x4D */ - IMPLEMENTED | CHECK_READY, /* 0x4E */ - 0, 0, /* 0x4F-0x50 */ - IMPLEMENTED | CHECK_READY, /* 0x51 */ - IMPLEMENTED | CHECK_READY, /* 0x52 */ - 0, 0, /* 0x53-0x54 */ - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, /* 0x56-0x59 */ - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, /* 0x5B-0x5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ - 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ - IMPLEMENTED | CHECK_READY, /* 0xA5 */ - 0, 0, /* 0xA6-0xA7 */ - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - IMPLEMENTED | CHECK_READY, /* 0xA9 */ - 0, 0, 0, /* 0xAA-0xAC */ - IMPLEMENTED | CHECK_READY, /* 0xAD */ - 0, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, /* 0xB0-0xB3 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ - 0, 0, 0, /* 0xB5-0xB7 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ - IMPLEMENTED | CHECK_READY, /* 0xB9 */ - IMPLEMENTED | CHECK_READY, /* 0xBA */ - IMPLEMENTED, /* 0xBB */ - IMPLEMENTED | CHECK_READY, /* 0xBC */ - IMPLEMENTED, /* 0xBD */ - IMPLEMENTED | CHECK_READY, /* 0xBE */ - IMPLEMENTED | CHECK_READY, /* 0xBF */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC3 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC5 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC8 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC9 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCA */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCB */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD7 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xD8 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xD9 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xDA */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xDB */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xDC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xDD */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xDE */ - 0, /* 0xDF */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE0 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE1 */ - 0, /* 0xE2 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE3 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE4 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE5 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE6 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE7 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE8 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xE9 */ - 0, /* 0xEA */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xEB */ - 0, /* 0xEC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xED */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xEE */ - 0, /* 0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ + [0x00] = IMPLEMENTED | CHECK_READY, + [0x01] = IMPLEMENTED | ALLOW_UA | SCSI_ONLY, + [0x03] = IMPLEMENTED | ALLOW_UA, + [0x08] = IMPLEMENTED | CHECK_READY, + [0x0b] = IMPLEMENTED | CHECK_READY, + [0x0d] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x12] = IMPLEMENTED | ALLOW_UA, + [0x13] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x15] = IMPLEMENTED, + [0x1a] = IMPLEMENTED, + [0x1b] = IMPLEMENTED | CHECK_READY, + [0x1e] = IMPLEMENTED | CHECK_READY, + [0x22] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x25] = IMPLEMENTED | CHECK_READY, + [0x26] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x28] = IMPLEMENTED | CHECK_READY, + [0x2b] = IMPLEMENTED | CHECK_READY, + [0x2f] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x42] = IMPLEMENTED | CHECK_READY, + /* + Read TOC/PMA/ATIP - can get through UNIT_ATTENTION, per VIDE-CDD.SYS. + + NOTE: The ATAPI reference says otherwise, but I think this is a question of + interpreting things right - the UNIT ATTENTION condition we have here + is a tradition from not ready to ready, by definition the drive + eventually becomes ready, make the condition go away. + */ + [0x43 ... 0x45] = IMPLEMENTED | CHECK_READY, + [0x46] IMPLEMENTED | ALLOW_UA, + [0x47 ... 0x49] = IMPLEMENTED | CHECK_READY, + [0x4a] = IMPLEMENTED | ALLOW_UA, + [0x4b] = IMPLEMENTED | CHECK_READY, + [0x4e] = IMPLEMENTED | CHECK_READY, + [0x51 ... 0x52] = IMPLEMENTED | CHECK_READY, + [0x55] = IMPLEMENTED, + [0x5a] = IMPLEMENTED, + [0xa5] = IMPLEMENTED | CHECK_READY, + [0xa8 ... 0xa9] = IMPLEMENTED | CHECK_READY, + [0xad] = IMPLEMENTED, + [0xaf] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xb4] = IMPLEMENTED | CHECK_READY | ATAPI_ONLY, + [0xb8] = IMPLEMENTED | CHECK_READY | ATAPI_ONLY, + [0xb9 ... 0xba] = IMPLEMENTED | CHECK_READY, + [0xbb] = IMPLEMENTED, + [0xbc] = IMPLEMENTED | CHECK_READY, + [0xbd] = IMPLEMENTED, + [0xbe ... 0xbf] = IMPLEMENTED | CHECK_READY, + [0xc0 ... 0xcd] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xd8 ... 0xde] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xe0 ... 0xe1] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xe3 ... 0xe9] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xeb] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xed ... 0xee] = IMPLEMENTED | CHECK_READY | SCSI_ONLY }; -static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_UNIT_ATN_PAGE | GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_FORMAT_DEVICE_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); -static uint64_t scsi_cdrom_mode_sense_page_flags_sony = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE_SONY | GPMODEP_CDROM_AUDIO_PAGE_SONY | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); -static uint64_t scsi_cdrom_drive_status_page_flags = ((1ULL << 0x01ULL) | (1ULL << 0x02ULL) | (1ULL << 0x0fULL) | GPMODEP_ALL_PAGES); +static uint64_t scsi_cdrom_ms_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_CDROM_PAGE | + GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | + GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); +static uint64_t scsi_cdrom_ms_page_flags_scsi = (GPMODEP_UNIT_ATN_PAGE | GPMODEP_R_W_ERROR_PAGE | + GPMODEP_DISCONNECT_PAGE | GPMODEP_FORMAT_DEVICE_PAGE | + GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | + (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | + GPMODEP_ALL_PAGES); +static uint64_t scsi_cdrom_ms_page_flags_sony_scsi = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | + GPMODEP_CDROM_PAGE_SONY | GPMODEP_CDROM_AUDIO_PAGE_SONY | + (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | + GPMODEP_ALL_PAGES); + +static uint64_t scsi_cdrom_drive_status_page_flags = ((1ULL << 0x01ULL) | (1ULL << 0x02ULL) | + (1ULL << 0x0fULL) | GPMODEP_ALL_PAGES); static const mode_sense_pages_t scsi_cdrom_drive_status_pages = { - {{ 0, 0 }, - { 0x01, 0, 2, 0x0f, 0xbf }, /*Drive Status Data Format*/ - { 0x02, 0, 1, 0 }, /*Audio Play Status Format*/ - { 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }} + { [0x01] = { 0x01, 0x00, 0x02, 0x0f, 0xbf }, /* Drive Status Data Format */ + [0x02] = { 0x02, 0x00, 0x01, 0x00 } } /* Audio Play Status Format */ }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = { - {{ 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 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 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0xE, 4, 0, 0, 0, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0x0F, 0x14, 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 }} +static const mode_sense_pages_t scsi_cdrom_ms_pages_default = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00 }, + [0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0x00, 0x01, 0x00, 0x3c, 0x00, 0x4b }, + [0x0e] = { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b, + 0x01, 0xff, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x0f] = { 0x0f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0x07, 0x00, 0x7f, 0x01, 0x0d, 0x03, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x02, 0xc2, + 0x00, 0x00, 0x00, 0x00 } } }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { - {{ GPMODE_UNIT_ATN_PAGE, 6, 0, 0, 0, 0, 0, 0 }, /*Guess-work*/ - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0xE, 5, 4, 0, 128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0x0F, 0x14, 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 }} +static const mode_sense_pages_t scsi_cdrom_ms_pages_default_scsi = { + { [0x00] = { GPMODE_UNIT_ATN_PAGE, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* Guesswork */ + [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x03] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0x00, 0x01, 0x00, 0x3c, 0x00, 0x4b }, + [0x0e] = { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0x0e, 0x05, 0x04, 0x00, 0x80, 0x00, 0x4b, + 0x01, 0xff, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x0f] = { 0x0f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0x07, 0x00, 0x7f, 0x01, 0x0d, 0x03, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x02, 0xc2, + 0x00, 0x00, 0x00, 0x00 } } }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_sony_scsi = { - {{ 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0e, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE_SONY, 2, 0, 5 }, - { GPMODE_CDROM_AUDIO_PAGE_SONY | 0x80, 0xE, 5, 0, 0, 0, 0, 0, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0xE, 5, 4, 0, 128, 0, 75, 1, 255, 2, 255, 0, 0, 0, 0 }, - { 0x0F, 0x14, 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 }} +static const mode_sense_pages_t scsi_cdrom_ms_pages_default_sony_scsi = { + { { 0, 0 }, + [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x08] = { GPMODE_CDROM_PAGE_SONY, 0x02, 0x00, 0x05 }, + [0x09] = { GPMODE_CDROM_AUDIO_PAGE_SONY | 0x80, 0x0e, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0x00, 0x01, 0x00, 0x3c, 0x00, 0x4b }, + [0x0e] = { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0x0e, 0x05, 0x04, 0x00, 0x80, 0x00, 0x4b, + 0x01, 0xff, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x0f] = { 0x0f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0x07, 0x00, 0x7f, 0x01, 0x0d, 0x03, + 0x02, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x02, 0xc2, + 0x00, 0x00, 0x00, 0x00 } } }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = { - {{ GPMODE_UNIT_ATN_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, /*Guess-work*/ - { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, - { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0x0F, 0x14, 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} +static const mode_sense_pages_t scsi_cdrom_ms_pages_changeable = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0e] = { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0f] = { 0x0f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 } } }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable_sony = { - {{ 0, 0 }, - { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, - { GPMODE_DISCONNECT_PAGE, 0x0E, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE_SONY, 2, 0xFF, 0xFF }, - { GPMODE_CDROM_AUDIO_PAGE_SONY | 0x80, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CDROM_PAGE, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0xE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, - { 0x0F, 0x14, 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 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { 0, 0 }, - { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }} +static const mode_sense_pages_t scsi_cdrom_ms_pages_changeable_scsi = { + { [0x00] = { GPMODE_UNIT_ATN_PAGE, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, /* Guesswork */ + [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x03] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0e] = { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0f] = { 0x0f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 } } }; +static const mode_sense_pages_t scsi_cdrom_ms_pages_changeable_sony_scsi = { + { [0x01] = { GPMODE_R_W_ERROR_PAGE, 0x06, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x02] = { GPMODE_DISCONNECT_PAGE, 0x0e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }, + [0x08] = { GPMODE_CDROM_PAGE_SONY, 0x02, 0xff, 0xff }, + [0x09] = { GPMODE_CDROM_AUDIO_PAGE_SONY | 0x80, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0d] = { GPMODE_CDROM_PAGE, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0e] = { GPMODE_CDROM_AUDIO_PAGE | 0x80, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + [0x0f] = { 0x0f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x2a] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } } +}; +// clang-format on + static gesn_cdb_t *gesn_cdb; static gesn_event_header_t *gesn_event_header; @@ -480,22 +256,21 @@ static void scsi_cdrom_init(scsi_cdrom_t *dev); int scsi_cdrom_do_log = ENABLE_SCSI_CDROM_LOG; static void -scsi_cdrom_log(const char *format, ...) +scsi_cdrom_log(void *priv, const char *format, ...) { - va_list ap; - if (scsi_cdrom_do_log) { + va_list ap; va_start(ap, format); - pclog_ex(format, ap); + log_out(priv, format, ap); va_end(ap); } } #else -# define scsi_cdrom_log(format, ...) +# define scsi_cdrom_log(priv, format, ...) #endif static void -scsi_cdrom_set_callback(scsi_cdrom_t *dev) +scsi_cdrom_set_callback(const scsi_cdrom_t *dev) { if (dev && dev->drv && (dev->drv->bus_type != CDROM_BUS_SCSI)) ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); @@ -504,47 +279,51 @@ scsi_cdrom_set_callback(scsi_cdrom_t *dev) static void scsi_cdrom_init(scsi_cdrom_t *dev) { - if (!dev) - return; + if (dev != NULL) { + /* Do a reset (which will also rezero it). */ + scsi_cdrom_reset((scsi_common_t *) dev); - /* Do a reset (which will also rezero it). */ - scsi_cdrom_reset((scsi_common_t *) dev); + /* Configure the drive. */ + dev->requested_blocks = 1; - /* Configure the drive. */ - dev->requested_blocks = 1; + dev->drv->bus_mode = 0; + if (dev->drv->bus_type >= CDROM_BUS_ATAPI) + dev->drv->bus_mode |= 2; + if (dev->drv->bus_type < CDROM_BUS_SCSI) + dev->drv->bus_mode |= 1; + scsi_cdrom_log(dev->log, "Bus type %i, bus mode %i\n", + dev->drv->bus_type, dev->drv->bus_mode); - dev->drv->bus_mode = 0; - if (dev->drv->bus_type >= CDROM_BUS_ATAPI) - dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < CDROM_BUS_SCSI) - dev->drv->bus_mode |= 1; - scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", - dev->id, dev->drv->bus_type, dev->drv->bus_mode); + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + /* NEC only */ + if (dev->drv->is_early) + dev->tf->status = READY_STAT | DSC_STAT; + else + dev->tf->status = 0; + dev->tf->pos = 0; + dev->packet_status = PHASE_NONE; + scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; + scsi_cdrom_info = 0x00000000; + dev->drv->cd_status &= ~CD_STATUS_TRANSITION; + dev->drv->cur_speed = dev->drv->real_speed; + scsi_cdrom_mode_sense_load(dev); - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - /* NEC only */ - if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) - dev->tf->status = READY_STAT | DSC_STAT; - else - dev->tf->status = 0; - dev->tf->pos = 0; - dev->packet_status = PHASE_NONE; - scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; - dev->drv->cur_speed = dev->drv->speed; - scsi_cdrom_mode_sense_load(dev); - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) - scsi_cdrom_drive_status_load(dev); + const char *vendor = cdrom_get_vendor(dev->drv->type); + + if ((dev->drv->bus_type == CDROM_BUS_SCSI) && !strcmp(vendor, "PIONEER")) + scsi_cdrom_drive_status_load(dev); + } } /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -scsi_cdrom_current_mode(scsi_cdrom_t *dev) +scsi_cdrom_current_mode(const scsi_cdrom_t *dev) { if (dev->drv->bus_type == CDROM_BUS_SCSI) return 2; else if (dev->drv->bus_type == CDROM_BUS_ATAPI) { - scsi_cdrom_log("CD-ROM %i: ATAPI drive, setting to %s\n", dev->id, + scsi_cdrom_log(dev->log, "ATAPI drive, setting to %s\n", (dev->tf->features & 1) ? "DMA" : "PIO", dev->id); return (dev->tf->features & 1) ? 2 : 1; @@ -554,52 +333,25 @@ scsi_cdrom_current_mode(scsi_cdrom_t *dev) } static uint32_t -scsi_cdrom_get_channel(void *priv, int channel) +scsi_cdrom_get_channel(void *priv, const int channel) { const scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; - uint32_t ret; + uint32_t ret = channel + 1; - if (!dev) - return channel + 1; - - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; - break; - default: - ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; - break; - } + if (dev != NULL) + ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; return ret; } static uint32_t -scsi_cdrom_get_volume(void *priv, int channel) +scsi_cdrom_get_volume(void *priv, const int channel) { const scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; - uint32_t ret; + uint32_t ret = 255; - if (!dev) - return 255; - - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - ret = dev->ms_pages_saved_sony.pages[dev->sony_vendor ? GPMODE_CDROM_AUDIO_PAGE_SONY : - GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; - break; - default: - ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; - break; - } + if (dev != NULL) + ret = dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; return ret; } @@ -607,133 +359,90 @@ scsi_cdrom_get_volume(void *priv, int channel) static void scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) { - FILE *fp; - char file_name[512]; + char file_name[512] = { 0 }; - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - memset(&dev->ms_pages_saved_sony, 0, sizeof(mode_sense_pages_t)); - memcpy(&dev->ms_pages_saved_sony, &scsi_cdrom_mode_sense_pages_default_sony_scsi, - sizeof(mode_sense_pages_t)); + memset(&dev->ms_pages_saved, 0x00, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &dev->ms_pages_default, + sizeof(mode_sense_pages_t)); - memset(file_name, 0, 512); - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); - fp = plat_fopen(nvr_path(file_name), "rb"); - if (fp) { - if (fread(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, - 0x10, fp) != 0x10) - fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); - fclose(fp); - } - break; - default: - memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default_scsi, - sizeof(mode_sense_pages_t)); - else - memcpy(&dev->ms_pages_saved, &scsi_cdrom_mode_sense_pages_default, - sizeof(mode_sense_pages_t)); - - memset(file_name, 0, 512); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); - else - sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); - fp = plat_fopen(nvr_path(file_name), "rb"); - if (fp) { - if (fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, fp) != 0x10) - fatal("scsi_cdrom_mode_sense_load(): Error reading data\n"); - fclose(fp); - } - break; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); + else + sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); + FILE *fp = plat_fopen(nvr_path(file_name), "rb"); + if (fp) { + if (fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, fp) != 0x10) + log_fatal(dev->log, "scsi_cdrom_mode_sense_load(): Error reading data\n"); + (void) fread(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, + 0x10, fp); + fclose(fp); } } static void -scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev) +scsi_cdrom_mode_sense_save(const scsi_cdrom_t *dev) { - FILE *fp; - char file_name[512]; + char file_name[512] = { 0 }; - memset(file_name, 0, 512); - - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_sony_bin", dev->id); - fp = plat_fopen(nvr_path(file_name), "wb"); - if (fp) { - fwrite(dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, fp); - fclose(fp); - } - break; - default: - if (dev->drv->bus_type == CDROM_BUS_SCSI) - sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); - else - sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); - fp = plat_fopen(nvr_path(file_name), "wb"); - if (fp) { - fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, fp); - fclose(fp); - } - break; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + sprintf(file_name, "scsi_cdrom_%02i_mode_sense_bin", dev->id); + else + sprintf(file_name, "cdrom_%02i_mode_sense_bin", dev->id); + FILE *fp = plat_fopen(nvr_path(file_name), "wb"); + if (fp) { + fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, fp); + fwrite(dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE_SONY], 1, 0x10, fp); + fclose(fp); } } -/*SCSI Drive Status (Pioneer only)*/ +/* SCSI Drive Status (Pioneer only). */ static void scsi_cdrom_drive_status_load(scsi_cdrom_t *dev) { - memset(&dev->ms_drive_status_pages_saved, 0, sizeof(mode_sense_pages_t)); - memcpy(&dev->ms_drive_status_pages_saved, &scsi_cdrom_drive_status_pages, sizeof(mode_sense_pages_t)); + memset(&dev->ms_drive_status_pages_saved, 0x00, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_drive_status_pages_saved, &scsi_cdrom_drive_status_pages, + sizeof(mode_sense_pages_t)); } static uint8_t -scsi_cdrom_drive_status_read(scsi_cdrom_t *dev, UNUSED(uint8_t page_control), uint8_t page, uint8_t pos) +scsi_cdrom_drive_status_read(const scsi_cdrom_t *dev, const uint8_t page, + const uint8_t pos) { return dev->ms_drive_status_pages_saved.pages[page][pos]; } static uint32_t -scsi_cdrom_drive_status(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t page) +scsi_cdrom_drive_status(const scsi_cdrom_t *dev, uint8_t *buf, uint8_t page) { - uint8_t page_control = (page >> 6) & 3; - uint16_t msplen; + uint32_t pos = 0; page &= 0x3f; for (uint8_t i = 0; i < 0x40; i++) { - if (page == i) { - if (scsi_cdrom_drive_status_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { - buf[pos++] = scsi_cdrom_drive_status_read(dev, page_control, i, 0); - msplen = (scsi_cdrom_drive_status_read(dev, page_control, i, 1) << 8); - msplen |= scsi_cdrom_drive_status_read(dev, page_control, i, 2); - buf[pos++] = (msplen >> 8) & 0xff; - buf[pos++] = msplen & 0xff; - scsi_cdrom_log("CD-ROM %i: DRIVE STATUS: Page [%02X] length %i\n", dev->id, i, msplen); - for (uint16_t j = 0; j < msplen; j++) { - if (i == 0x01) { - buf[pos++] = scsi_cdrom_drive_status_read(dev, page_control, i, 3 + j); - if (!(j & 1)) { /*MSB of Drive Status*/ - if (dev->drv->ops) /*Bit 11 of Drive Status, */ - buf[pos] &= ~0x08; /*Disc is present*/ - else - buf[pos] |= 0x08; /*Disc not present*/ - } - } else if ((i == 0x02) && (j == 0)) { - buf[pos++] = ((dev->drv->cd_status == CD_STATUS_PLAYING) ? 0x01 : 0x00); - } else - buf[pos++] = scsi_cdrom_drive_status_read(dev, page_control, i, 3 + j); - } + if ((page == i) && (scsi_cdrom_drive_status_page_flags & + (1LL << ((uint64_t) (page & 0x3f))))) { + buf[pos++] = scsi_cdrom_drive_status_read(dev, i, 0); + uint16_t len = (scsi_cdrom_drive_status_read(dev, i, 1) << 8); + len |= scsi_cdrom_drive_status_read(dev, i, 2); + buf[pos++] = (len >> 8) & 0xff; + buf[pos++] = len & 0xff; + scsi_cdrom_log(dev->log, "CD-ROM %i: DRIVE STATUS: Page [%02X] length %i\n", + i, len); + for (uint16_t j = 0; j < len; j++) { + if (i == 0x01) { + buf[pos++] = scsi_cdrom_drive_status_read(dev, i, 3 + j); + if (!(j & 1)) { /* MSB of Drive Status. */ + if (dev->drv->ops) /* Bit 11 of Drive Status, */ + buf[pos] &= ~0x08; /* Disc is present. */ + else + buf[pos] |= 0x08; /* Disc not present. */ + } + } else if ((i == 0x02) && (j == 0)) + buf[pos++] = ((dev->drv->cd_status == CD_STATUS_PLAYING) ? + 0x01 : 0x00); + else + buf[pos++] = scsi_cdrom_drive_status_read(dev, i, 3 + j); } } } @@ -743,109 +452,91 @@ scsi_cdrom_drive_status(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t p /*SCSI Mode Sense 6/10*/ static uint8_t -scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) +scsi_cdrom_mode_sense_read(const scsi_cdrom_t *dev, const uint8_t pgctl, + const uint8_t page, const uint8_t pos) { - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved_sony.pages[page][pos]; - case 1: - return scsi_cdrom_mode_sense_pages_changeable_sony.pages[page][pos]; - case 2: - return scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][pos]; + uint8_t ret = 0; - default: - break; - } + switch (pgctl) { + case 0: case 3: + ret = dev->ms_pages_saved.pages[page][pos]; break; + + case 1: + ret = dev->ms_pages_changeable.pages[page][pos]; + break; + + case 2: + ret = dev->ms_pages_default.pages[page][pos]; + break; + default: - switch (page_control) { - case 0: - case 3: - return dev->ms_pages_saved.pages[page][pos]; - case 1: - return scsi_cdrom_mode_sense_pages_changeable.pages[page][pos]; - case 2: - if (dev->drv->bus_type == CDROM_BUS_SCSI) - return scsi_cdrom_mode_sense_pages_default_scsi.pages[page][pos]; - else - return scsi_cdrom_mode_sense_pages_default.pages[page][pos]; + break; + } - default: - break; - } - break; - } - - return 0; + return ret; } static uint32_t -scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) +scsi_cdrom_mode_sense(const scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, + uint8_t page, const uint8_t block_descriptor_len) { - uint8_t page_control = (page >> 6) & 3; - uint8_t msplen; + const uint8_t pgctl = (page >> 6) & 3; page &= 0x3f; if (block_descriptor_len) { - buf[pos++] = 1; /* Density code. */ - buf[pos++] = 0; /* Number of blocks (0 = all). */ - buf[pos++] = 0; - buf[pos++] = 0; - buf[pos++] = 0; /* Reserved. */ - buf[pos++] = 0; /* Block length (0x800 = 2048 bytes). */ - buf[pos++] = 8; - buf[pos++] = 0; + buf[pos++] = 0x01; /* Density code. */ + buf[pos++] = 0x00; /* Number of blocks (0 = all). */ + buf[pos++] = 0x00; + buf[pos++] = 0x00; + buf[pos++] = 0x00; /* Reserved. */ + buf[pos++] = dev->drv->sector_size >> 16; /* Block length (default: 0x800 = 2048 bytes). */ + buf[pos++] = dev->drv->sector_size >> 8; + buf[pos++] = dev->drv->sector_size; } for (uint8_t i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { - if (scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 0); - msplen = scsi_cdrom_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - scsi_cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + if (dev->ms_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { + const uint8_t msplen = scsi_cdrom_mode_sense_read(dev, pgctl, i, 1); + + buf[pos++] = scsi_cdrom_mode_sense_read(dev, pgctl, i, 0); + buf[pos++] = msplen; + + scsi_cdrom_log(dev->log, "MODE SENSE: Page [%02X] length %i\n", + i, msplen); + for (uint8_t j = 0; j < msplen; j++) { - /* If we are returning changeable values, always return them from the page, - so they are all correctly. */ - if (page_control == 1) - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); + /* + If we are returning changeable values, always return + them from the page, so they are all correct. + */ + if (pgctl == 1) + buf[pos++] = scsi_cdrom_mode_sense_read(dev, pgctl, i, 2 + j); else { if ((i == GPMODE_CAPABILITIES_PAGE) && (j == 4)) { - buf[pos] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j) & 0x1f; - /* The early CD-ROM drives we emulate (NEC CDR-260 for ATAPI and - early vendor SCSI CD-ROM models) are caddy drives, the later - ones are tray drives. */ - if (dev->drv->bus_type == CDROM_BUS_SCSI) - buf[pos++] |= ((dev->drv->type == CDROM_TYPE_86BOX_100) ? 0x20 : 0x00); - else - buf[pos++] |= ((dev->drv->type == CDROM_TYPE_NEC_260_100) || - ((dev->drv->type == CDROM_TYPE_NEC_260_101)) ? 0x00 : 0x20); - } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && (j <= 7)) { + buf[pos] = scsi_cdrom_mode_sense_read(dev, pgctl, i, 2 + j) & 0x1f; + buf[pos++] |= (cdrom_is_caddy(dev->drv->type) ? 0x00 : 0x20); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 6) && + (j <= 7)) { if (j & 1) - buf[pos++] = ((dev->drv->speed * 176) & 0xff); + buf[pos++] = ((dev->drv->real_speed * 176) & 0xff); else - buf[pos++] = ((dev->drv->speed * 176) >> 8); - } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 8) && (j <= 9) && - (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403)) { - if (j & 1) - buf[pos++] = ((dev->drv->speed * 176) & 0xff); - else - buf[pos++] = ((dev->drv->speed * 176) >> 8); - } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && (j <= 13)) { + buf[pos++] = ((dev->drv->real_speed * 176) >> 8); + } else if ((i == GPMODE_CAPABILITIES_PAGE) && (j >= 12) && + (j <= 13)) { if (j & 1) buf[pos++] = ((dev->drv->cur_speed * 176) & 0xff); else buf[pos++] = ((dev->drv->cur_speed * 176) >> 8); - } else - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); + } else if (dev->is_sony && (i == GPMODE_CDROM_AUDIO_PAGE_SONY) && + (j >= 6) && (j <= 13)) + buf[pos++] = scsi_cdrom_mode_sense_read(dev, pgctl, + GPMODE_CDROM_AUDIO_PAGE, 2 + j); + else + buf[pos++] = scsi_cdrom_mode_sense_read(dev, pgctl, + i, 2 + j); } } } @@ -856,15 +547,17 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag } static void -scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) +scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, const int block_len) { - int32_t bt; int32_t min_len = 0; - double dlen; + int32_t bt; dev->max_transfer_len = dev->tf->request_length; - /* For media access commands, make sure the requested DRQ length matches the block length. */ + /* + For media access commands, make sure the requested DRQ length + matches the block length. + */ switch (dev->current_cdb[0]) { case 0x08: case 0x28: @@ -873,21 +566,26 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) case 0xbe: /* Round it to the nearest (block length) bytes. */ if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { - /* READ CD MSF and READ CD: Round the request length to the sector size - the device must ensure - that a media access comand does not DRQ in the middle of a sector. One of the drivers that - relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS - which uses the READ CD command to read data on some CD types. */ + /* + READ CD MSF and READ CD: Round the request length to the sector size - the + device must ensure that a media access comand does not DRQ in the middle + of a sector. One of the drivers that relies on the correctness of this + behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS which uses + the READ CD command to read data on some CD types. + */ /* Round to sector length. */ - dlen = ((double) dev->max_transfer_len) / ((double) block_len); + const double dlen = ((double) dev->max_transfer_len) / ((double) block_len); dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; } else { /* Round it to the nearest 2048 bytes. */ - dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; + dev->max_transfer_len = (dev->max_transfer_len / dev->drv->sector_size) * dev->drv->sector_size; } - /* Make sure total length is not bigger than sum of the lengths of - all the requested blocks. */ + /* + Make sure total length is not bigger than sum of the lengths of + all the requested blocks. + */ bt = (dev->requested_blocks * block_len); if (len > bt) len = bt; @@ -909,10 +607,16 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) dev->packet_len = len; break; } - /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ + /* + If the DRQ length is odd, and the total remaining length is bigger, + make sure it's even. + */ if ((dev->max_transfer_len & 1) && (dev->max_transfer_len < len)) dev->max_transfer_len &= 0xfffe; - /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ + /* + If the DRQ length is smaller or equal in size to the total remaining length, + set it to that. + */ if (!dev->max_transfer_len) dev->max_transfer_len = 65534; @@ -947,8 +651,7 @@ scsi_cdrom_bus_speed(scsi_cdrom_t *dev) static void scsi_cdrom_command_common(scsi_cdrom_t *dev) { - double bytes_per_second = 0.0; - double period; + const uint8_t cmd = dev->current_cdb[0]; /* MAP: BUSY_STAT, no DRQ, phase 1. */ dev->tf->status = BUSY_STAT; @@ -956,33 +659,46 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) dev->tf->pos = 0; dev->callback = 0; - scsi_cdrom_log("CD-ROM %i: Current speed: %ix\n", dev->id, dev->drv->cur_speed); + scsi_cdrom_log(dev->log, "Current speed: %ix\n", dev->drv->cur_speed); if (dev->packet_status == PHASE_COMPLETE) dev->callback = 0; else { - switch (dev->current_cdb[0]) { + double bytes_per_second; + double period; + + switch (cmd) { case GPCMD_REZERO_UNIT: case 0x0b: case 0x2b: /* Seek time is in us. */ period = cdrom_seek_time(dev->drv); - scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); + scsi_cdrom_log(dev->log, "Seek period: %" PRIu64 " us\n", + (uint64_t) period); dev->callback += period; scsi_cdrom_set_callback(dev); return; + case 0x43: + dev->drv->seek_diff = dev->drv->seek_pos + 150; + dev->drv->seek_pos = 0; + fallthrough; case 0x08: case 0x28: + case 0x42: case 0x44: case 0xa8: /* Seek time is in us. */ period = cdrom_seek_time(dev->drv); - scsi_cdrom_log("CD-ROM %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); + scsi_cdrom_log(dev->log, "Seek period: %" PRIu64 " us\n", + (uint64_t) period); + scsi_cdrom_log(dev->log, "Seek period: %" PRIu64 " us, speed: %" + PRIu64 " bytes per second, should be: %" + PRIu64 " bytes per second\n", + (uint64_t) period, (uint64_t) (1000000.0 / period), + (uint64_t) (176400.0 * (double) dev->drv->cur_speed)); dev->callback += period; fallthrough; case 0x25: - case 0x42 ... 0x44: + // case 0x42 ... 0x44: case 0x51 ... 0x52: case 0xad: case 0xb8 ... 0xb9: @@ -991,72 +707,25 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) dev->callback += 40.0; /* Account for seek time. */ /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + /* + TODO: This is a bit of a lie - the actual period is closer to + 75 * 2448 bytes per second, because the subchannel data + has to be read as well. + */ bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; + case 0xc0 ... 0xc3: case 0xc6 ... 0xc7: - switch (dev->drv->type) { - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: - bytes_per_second = 176400.0; - bytes_per_second *= (double) dev->drv->cur_speed; - break; - } - case 0xc0: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ - bytes_per_second = 176400.0; - bytes_per_second *= (double) dev->drv->cur_speed; - break; - } - case 0xc1: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_PIONEER_DRM604X_2403: - case CDROM_TYPE_TEXEL_DMXX24_100: - /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ - bytes_per_second = 176400.0; - bytes_per_second *= (double) dev->drv->cur_speed; - break; - } - case 0xc2 ... 0xc3: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_PIONEER_DRM604X_2403: - case CDROM_TYPE_TEXEL_DMXX24_100: - if (dev->current_cdb[0] == 0xc2) - dev->callback += 40.0; - /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ - bytes_per_second = 176400.0; - bytes_per_second *= (double) dev->drv->cur_speed; - break; - } case 0xdd ... 0xde: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ - bytes_per_second = 176400.0; - bytes_per_second *= (double) dev->drv->cur_speed; - break; + if (dev->ven_cmd_is_data[cmd]) { + if (dev->current_cdb[0] == 0xc2) + dev->callback += 40.0; + /* Account for seek time. */ + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; + bytes_per_second *= (double) dev->drv->cur_speed; + break; } fallthrough; default: @@ -1069,9 +738,23 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) } period = 1000000.0 / bytes_per_second; - scsi_cdrom_log("CD-ROM %i: Byte transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); - period = period * (double) (dev->packet_len); - scsi_cdrom_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + scsi_cdrom_log(dev->log, "Byte transfer period: %" PRIu64 " us\n", + (uint64_t) period); + switch (cmd) { + default: + period = period * (double) (dev->packet_len); + break; + case 0x42: case 0x44: + /* READ SUBCHANNEL or READ HEADER - period of 1 entire sector. */ + period = period * 2352.0; + break; + case 0x43: + /* READ TOC - period of 175 entire frames. */ + period = period * 150.0 * 2352.0; + break; + } + scsi_cdrom_log(dev->log, "Sector transfer period: %" PRIu64 " us\n", + (uint64_t) period); dev->callback += period; } scsi_cdrom_set_callback(dev); @@ -1115,16 +798,18 @@ scsi_cdrom_command_write_dma(scsi_cdrom_t *dev) scsi_cdrom_command_common(dev); } -/* id = Current CD-ROM device ID; +/* + dev = Pointer to current CD-ROM device; len = Total transfer length; block_len = Length of a single block (it matters because media access commands on ATAPI); alloc_len = Allocated transfer length; - direction = Transfer direction (0 = read from host, 1 = write to host). */ + direction = Transfer direction (0 = read from host, 1 = write to host). + */ static void scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction) { - scsi_cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, + scsi_cdrom_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; if (alloc_len >= 0) { @@ -1154,76 +839,74 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al } } - scsi_cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, - dev->tf->phase); + scsi_cdrom_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 scsi_cdrom_sense_clear(scsi_cdrom_t *dev, UNUSED(int command)) { scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; + scsi_cdrom_info = 0x00000000; } static void -scsi_cdrom_set_phase(scsi_cdrom_t *dev, uint8_t phase) +scsi_cdrom_set_phase(const scsi_cdrom_t *dev, const uint8_t phase) { - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + 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 != CDROM_BUS_SCSI) - return; - - scsi_devices[scsi_bus][scsi_id].phase = phase; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + scsi_devices[scsi_bus][scsi_id].phase = phase; } static void scsi_cdrom_cmd_error(scsi_cdrom_t *dev) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->tf->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->tf->error |= MCR_ERR; - dev->tf->status = READY_STAT | ERR_STAT; - dev->tf->phase = 3; - dev->tf->pos = 0; - dev->packet_status = PHASE_ERROR; - dev->callback = 50.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - ui_sb_update_icon(SB_CDROM | dev->id, 0); - scsi_cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq); -} - -static void -scsi_cdrom_unit_attention(scsi_cdrom_t *dev) -{ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->tf->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (dev->unit_attention) - dev->tf->error |= MCR_ERR; - dev->tf->status = READY_STAT | ERR_STAT; + dev->tf->error = ((scsi_cdrom_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 * CDROM_TIME; scsi_cdrom_set_callback(dev); ui_sb_update_icon(SB_CDROM | dev->id, 0); - scsi_cdrom_log("CD-ROM %i: UNIT ATTENTION\n", dev->id); + scsi_cdrom_log(dev->log, "ERROR: %02X/%02X/%02X\n", scsi_cdrom_sense_key, + scsi_cdrom_asc, scsi_cdrom_ascq); } static void -scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, uint32_t len) +scsi_cdrom_unit_attention(scsi_cdrom_t *dev) { - if (!dev->buffer) + scsi_cdrom_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 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + ui_sb_update_icon(SB_CDROM | dev->id, 0); + scsi_cdrom_log(dev->log, "UNIT ATTENTION\n"); +} + +static void +scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, const uint32_t len) +{ + if (dev->buffer == NULL) dev->buffer = (uint8_t *) malloc(len); - scsi_cdrom_log("CD-ROM %i: Allocated buffer length: %i, buffer = %p\n", dev->id, len, dev->buffer); + + scsi_cdrom_log(dev->log, "Allocated buffer length: %i, buffer = %p\n", + len, dev->buffer); } static void scsi_cdrom_buf_free(scsi_cdrom_t *dev) { if (dev->buffer) { - scsi_cdrom_log("CD-ROM %i: Freeing buffer...\n", dev->id); + scsi_cdrom_log(dev->log, "Freeing buffer...\n"); free(dev->buffer); dev->buffer = NULL; } @@ -1234,308 +917,266 @@ scsi_cdrom_bus_master_error(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + scsi_cdrom_log(dev->log, "Bus master error\n"); scsi_cdrom_buf_free(dev); scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; + scsi_cdrom_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + scsi_cdrom_cmd_error(dev); +} + +static void +scsi_cdrom_error_common(scsi_cdrom_t *dev, uint8_t sense_key, uint8_t asc, uint8_t ascq, uint32_t info) +{ + scsi_cdrom_log(dev->log, "Medium not present\n"); + scsi_cdrom_sense_key = sense_key; + scsi_cdrom_asc = asc; + scsi_cdrom_ascq = ascq; + scsi_cdrom_info = info; scsi_cdrom_cmd_error(dev); } static void scsi_cdrom_not_ready(scsi_cdrom_t *dev) { + scsi_cdrom_log(dev->log, "Medium not present\n"); scsi_cdrom_sense_key = SENSE_NOT_READY; scsi_cdrom_asc = ASC_MEDIUM_NOT_PRESENT; scsi_cdrom_ascq = 0; + scsi_cdrom_info = 0x00000000; scsi_cdrom_cmd_error(dev); } static void -scsi_cdrom_invalid_lun(scsi_cdrom_t *dev) +scsi_cdrom_circ_error(scsi_cdrom_t *dev) { + scsi_cdrom_log(dev->log, "CIRC unrecovered error\n"); + scsi_cdrom_sense_key = SENSE_MEDIUM_ERROR; + scsi_cdrom_asc = ASC_UNRECOVERED_READ_ERROR; + scsi_cdrom_ascq = ASCQ_CIRC_UNRECOVERED_ERROR; + scsi_cdrom_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + scsi_cdrom_cmd_error(dev); +} + +static void +scsi_cdrom_invalid_lun(scsi_cdrom_t *dev, const uint8_t lun) +{ + scsi_cdrom_log(dev->log, "Invalid LUN\n"); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_LUN; scsi_cdrom_ascq = 0; + scsi_cdrom_info = lun << 24; scsi_cdrom_cmd_error(dev); } static void -scsi_cdrom_illegal_opcode(scsi_cdrom_t *dev) +scsi_cdrom_illegal_opcode(scsi_cdrom_t *dev, const uint8_t opcode) { + scsi_cdrom_log(dev->log, "Illegal opcode\n"); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_ILLEGAL_OPCODE; scsi_cdrom_ascq = 0; + scsi_cdrom_info = opcode << 24; scsi_cdrom_cmd_error(dev); } static void scsi_cdrom_lba_out_of_range(scsi_cdrom_t *dev) { + scsi_cdrom_log(dev->log, "LBA out of range\n"); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_LBA_OUT_OF_RANGE; scsi_cdrom_ascq = 0; + scsi_cdrom_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); scsi_cdrom_cmd_error(dev); } static void -scsi_cdrom_invalid_field(scsi_cdrom_t *dev) +scsi_cdrom_invalid_field(scsi_cdrom_t *dev, const uint32_t field) { + scsi_cdrom_log(dev->log, "Invalid field in command packet\n"); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; scsi_cdrom_ascq = 0; + scsi_cdrom_info = (field >> 24) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); scsi_cdrom_cmd_error(dev); dev->tf->status = 0x53; } static void -scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev) +scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev, const uint32_t field) { + scsi_cdrom_log(dev->log, "Invalid field in parameter list\n"); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; scsi_cdrom_ascq = 0; + scsi_cdrom_info = (field >> 24) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); scsi_cdrom_cmd_error(dev); dev->tf->status = 0x53; } +static void +scsi_cdrom_incompatible_format(scsi_cdrom_t *dev, const uint32_t val) +{ + scsi_cdrom_log(dev->log, "Incompatible format\n"); + scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_cdrom_asc = ASC_INCOMPATIBLE_FORMAT; + scsi_cdrom_ascq = 2; + scsi_cdrom_info = (val >> 24) | + ((val >> 16) << 8) | + ((val >> 8) << 16) | + ( val << 24); + scsi_cdrom_cmd_error(dev); +} + +static void +scsi_cdrom_data_phase_error(scsi_cdrom_t *dev, const uint32_t info) +{ + scsi_cdrom_log(dev->log, "Data phase error\n"); + scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_cdrom_asc = ASC_DATA_PHASE_ERROR; + scsi_cdrom_ascq = 0; + scsi_cdrom_info = (info >> 24) | + ((info >> 16) << 8) | + ((info >> 8) << 16) | + ( info << 24); + scsi_cdrom_cmd_error(dev); +} + static void scsi_cdrom_illegal_mode(scsi_cdrom_t *dev) { + scsi_cdrom_log(dev->log, "Illegal mode for this track\n"); scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); -} - -static void -scsi_cdrom_incompatible_format(scsi_cdrom_t *dev) -{ - scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_INCOMPATIBLE_FORMAT; - scsi_cdrom_ascq = 2; - scsi_cdrom_cmd_error(dev); -} - -static void -scsi_cdrom_data_phase_error(scsi_cdrom_t *dev) -{ - scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - scsi_cdrom_asc = ASC_DATA_PHASE_ERROR; - scsi_cdrom_ascq = 0; + scsi_cdrom_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); scsi_cdrom_cmd_error(dev); } static int -scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *len, int vendor_type) +scsi_cdrom_read_data(scsi_cdrom_t *dev, const int msf, const int type, const int flags, + int32_t *len, const int vendor_type) { - int ret = 0; - int data_pos = 0; int temp_len = 0; - uint32_t cdsize = 0; + int ret = 0; - if (dev->drv->cd_status == CD_STATUS_EMPTY) { + if (dev->drv->cd_status == CD_STATUS_EMPTY) scsi_cdrom_not_ready(dev); - return 0; - } + else { + const uint32_t cdsize = dev->drv->cdrom_capacity; - cdsize = dev->drv->cdrom_capacity; + if (dev->sector_pos >= cdsize) { + scsi_cdrom_log(dev->log, "Trying to read from beyond the end of " + "disc (%i >= %i)\n", dev->sector_pos, cdsize); + scsi_cdrom_lba_out_of_range(dev); + ret = -1; + } else { + int data_pos = 0; - if (dev->sector_pos >= cdsize) { - scsi_cdrom_log("CD-ROM %i: Trying to read from beyond the end of disc (%i >= %i)\n", dev->id, - dev->sector_pos, cdsize); - scsi_cdrom_lba_out_of_range(dev); - return -1; - } + dev->old_len = 0; + *len = 0; -/* FIXME: Temporarily disabled this because the Triones ATAPI DMA driver seems to - always request a 4-sector read but sets the DMA bus master to transfer less - data than that. */ -#if 0 - if ((dev->sector_pos + dev->sector_len - 1) >= cdsize) { - scsi_cdrom_log("CD-ROM %i: Trying to read to beyond the end of disc (%i >= %i)\n", dev->id, - (dev->sector_pos + dev->sector_len - 1), cdsize); - scsi_cdrom_lba_out_of_range(dev); - return -1; - } -#endif + ret = 1; - dev->old_len = 0; - *len = 0; + for (int i = 0; i < dev->requested_blocks; i++) { + ret = cdrom_readsector_raw(dev->drv, dev->buffer + data_pos, + dev->sector_pos + i, msf, type, + flags, &temp_len, vendor_type); - for (int i = 0; i < dev->requested_blocks; i++) { - ret = cdrom_readsector_raw(dev->drv, dev->buffer + data_pos, - dev->sector_pos + i, msf, type, flags, &temp_len, vendor_type); + data_pos += temp_len; + dev->old_len += temp_len; - data_pos += temp_len; - dev->old_len += temp_len; + *len += temp_len; - *len += temp_len; + if (ret == 0) { + scsi_cdrom_illegal_mode(dev); + break; + } - if (!ret) { - scsi_cdrom_illegal_mode(dev); - return 0; + if (ret < 0) { + scsi_cdrom_circ_error(dev); + break; + } + } } } - return 1; + return ret; } static int -scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch, int vendor_type) +scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, const int vendor_type) { - int ret = 0; + int ret = 1; int msf = 0; - int type = 0; - int flags = 0; + int type = dev->sector_type; + int flags = dev->sector_flags; - if (dev->current_cdb[0] == GPCMD_READ_CD_MSF) - msf = 1; + /* Any of these commands stop the audio playing. */ + cdrom_stop(dev->drv); - if ((dev->current_cdb[0] == GPCMD_READ_CD_MSF) || (dev->current_cdb[0] == GPCMD_READ_CD)) { - type = (dev->current_cdb[1] >> 2) & 7; - flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); - } else { - type = 8; /* Internal type code indicating both Mode 1 and Mode 2 Form 1 are allowed. */ - flags = 0x10; - } - - if (!dev->sector_len) { - scsi_cdrom_command_complete(dev); - return -1; - } - - scsi_cdrom_log("Reading %i blocks starting from %i...\n", dev->requested_blocks, dev->sector_pos); - - ret = scsi_cdrom_read_data(dev, msf, type, flags, len, vendor_type); - - scsi_cdrom_log("Read %i bytes of blocks...\n", *len); - - if (ret == -1) - return 0; - else if (!ret || (!first_batch && (dev->old_len != *len))) { - if (!first_batch && (dev->old_len != *len)) - scsi_cdrom_illegal_mode(dev); - - return 0; - } - - dev->sector_pos += dev->requested_blocks; - dev->drv->seek_pos = dev->sector_pos; - dev->sector_len -= dev->requested_blocks; - return 1; -} - -/*SCSI Read DVD Structure*/ -static int -scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *packet, uint8_t *buf) -{ - int layer = packet[6]; - uint64_t total_sectors = 0; - - switch (format) { - case 0x00: /* Physical format information */ - if (dev->drv->cd_status == CD_STATUS_EMPTY) { - scsi_cdrom_not_ready(dev); - return 0; + switch (dev->current_cdb[0]) { + case GPCMD_READ_CD_MSF_OLD: + case GPCMD_READ_CD_MSF: + msf = 1; + fallthrough; + case GPCMD_READ_CD_OLD: + case GPCMD_READ_CD: + type = (dev->current_cdb[1] >> 2) & 7; + flags = dev->current_cdb[9] | (((uint32_t) dev->current_cdb[10]) << 8); + break; + case GPCMD_READ_HEADER: + type = 0x00; + flags = 0x20; + break; + default: + if (dev->sector_type == 0xff) { + scsi_cdrom_illegal_mode(dev); + ret = 0; } - - total_sectors = (uint64_t) dev->drv->cdrom_capacity; - - if (layer != 0) { - scsi_cdrom_invalid_field(dev); - return 0; - } - - total_sectors >>= 2; - if (total_sectors == 0) { - /* return -ASC_MEDIUM_NOT_PRESENT; */ - scsi_cdrom_not_ready(dev); - return 0; - } - - buf[4] = 18; /* Length of Layer Information */ - buf[5] = 0; - - buf[6] = 1; /* DVD-ROM, part version 1 */ - buf[7] = 0xf; /* 120mm disc, minimum rate unspecified */ - buf[8] = 1; /* one layer, read-only (per MMC-2 spec) */ - buf[9] = 0; /* default densities */ - - /* FIXME: 0x30000 per spec? */ - buf[10] = 0x00; - buf[11] = 0x03; - buf[12] = buf[13] = 0; /* start sector */ - - buf[14] = 0x00; - buf[15] = (total_sectors >> 16) & 0xff; /* end sector */ - buf[16] = (total_sectors >> 8) & 0xff; - buf[17] = total_sectors & 0xff; - - buf[18] = 0x00; - buf[19] = (total_sectors >> 16) & 0xff; /* l0 end sector */ - buf[20] = (total_sectors >> 8) & 0xff; - buf[21] = total_sectors & 0xff; - - /* 20 bytes of data + 4 byte header */ - return (20 + 4); - - case 0x01: /* DVD copyright information */ - buf[4] = 0; /* no copyright data */ - buf[5] = 0; /* no region restrictions */ - - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((4 + 2) >> 8) & 0xff; - buf[1] = (4 + 2) & 0xff; - - /* 4 byte header + 4 byte data */ - return (4 + 4); - - case 0x03: /* BCA information - invalid field for no BCA info */ - scsi_cdrom_invalid_field(dev); - return 0; - - case 0x04: /* DVD disc manufacturing information */ - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((2048 + 2) >> 8) & 0xff; - buf[1] = (2048 + 2) & 0xff; - - /* 2k data + 4 byte header */ - return (2048 + 4); - - case 0xff: - /* - * This lists all the command capabilities above. Add new ones - * in order and update the length and buffer return values. - */ - - buf[4] = 0x00; /* Physical format */ - buf[5] = 0x40; /* Not writable, is readable */ - buf[6] = ((20 + 4) >> 8) & 0xff; - buf[7] = (20 + 4) & 0xff; - - buf[8] = 0x01; /* Copyright info */ - buf[9] = 0x40; /* Not writable, is readable */ - buf[10] = ((4 + 4) >> 8) & 0xff; - buf[11] = (4 + 4) & 0xff; - - buf[12] = 0x03; /* BCA info */ - buf[13] = 0x40; /* Not writable, is readable */ - buf[14] = ((188 + 4) >> 8) & 0xff; - buf[15] = (188 + 4) & 0xff; - - buf[16] = 0x04; /* Manufacturing info */ - buf[17] = 0x40; /* Not writable, is readable */ - buf[18] = ((2048 + 4) >> 8) & 0xff; - buf[19] = (2048 + 4) & 0xff; - - /* Size of buffer, not including 2 byte size field */ - buf[6] = ((16 + 2) >> 8) & 0xff; - buf[7] = (16 + 2) & 0xff; - - /* data written + 4 byte header */ - return (16 + 4); - - default: /* TODO: formats beyond DVD-ROM requires */ - scsi_cdrom_invalid_field(dev); - return 0; + break; } + + if (ret) { + if (!dev->sector_len) { + scsi_cdrom_command_complete(dev); + return -1; + } + + scsi_cdrom_log(dev->log, "Reading %i blocks starting from %i...\n", + dev->requested_blocks, dev->sector_pos); + + ret = scsi_cdrom_read_data(dev, msf, type, flags, len, vendor_type); + + scsi_cdrom_log(dev->log, "Read %i bytes of blocks (ret = %i)...\n", *len, ret); + } + + if ((ret > 0) && (dev->current_cdb[0] != GPCMD_READ_HEADER)) { + dev->sector_pos += dev->requested_blocks; + dev->drv->seek_pos = dev->sector_pos; + + dev->sector_len -= dev->requested_blocks; + } + + return ret; } static void @@ -1543,126 +1184,152 @@ scsi_cdrom_insert(void *priv) { scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; - if (!dev) + if ((dev == NULL) || (dev->drv == NULL)) return; - dev->unit_attention = 1; - /* Turn off the medium changed status. */ - dev->drv->cd_status &= ~CD_STATUS_MEDIUM_CHANGED; - scsi_cdrom_log("CD-ROM %i: Media insert\n", dev->id); + if (dev->drv->ops == NULL) { + dev->unit_attention = 0; + dev->drv->cd_status = CD_STATUS_EMPTY; + scsi_cdrom_log(dev->log, "Media removal\n"); + } else if (dev->drv->cd_status & CD_STATUS_TRANSITION) { + dev->unit_attention = 1; + /* Turn off the medium changed status. */ + dev->drv->cd_status &= ~CD_STATUS_TRANSITION; + scsi_cdrom_log(dev->log, "Media insert\n"); + } else { + dev->unit_attention = 0; + dev->drv->cd_status |= CD_STATUS_TRANSITION; + scsi_cdrom_log(dev->log, "Media transition\n"); + } } static int -scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) +scsi_command_check_ready(const scsi_cdrom_t *dev, const uint8_t *cdb) { - int ready = 0; - int ext_medium_changed = 0; + int ret = 0; - if (dev->drv && dev->drv->ops && dev->drv->ops->ext_medium_changed) - ext_medium_changed = dev->drv->ops->ext_medium_changed(dev->drv); + if (scsi_cdrom_command_flags[cdb[0]] & CHECK_READY) { + /* + Note by TC1995: Some vendor commands from X vendor don't really + check for ready status but they do on Y vendor. + Quite confusing I know. + */ + if (!dev->is_sony || (cdb[0] != 0xc0)) + ret = 1; + } else if ((cdb[0] == GPCMD_READ_DVD_STRUCTURE) && (cdb[7] < 0xc0)) + ret = 1; - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->tf->request_length >> 5) & 7)); - scsi_cdrom_invalid_lun(dev); + return ret; +} + +static int +scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, const uint8_t *cdb) +{ + int ready; + + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && + (cdb[1] & 0xe0)) { + scsi_cdrom_log(dev->log, "Attempting to execute a unknown command targeted " + "at SCSI LUN %i\n", ((dev->tf->request_length >> 5) & 7)); + scsi_cdrom_invalid_lun(dev, cdb[1] >> 5); return 0; } if (!(scsi_cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus_type == CDROM_BUS_SCSI) ? "SCSI" : "ATAPI"); + scsi_cdrom_log(dev->log, "Attempting to execute unknown command %02X over %s\n", + cdb[0], (dev->drv->bus_type == CDROM_BUS_SCSI) ? "SCSI" : "ATAPI"); - scsi_cdrom_illegal_opcode(dev); + scsi_cdrom_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type < CDROM_BUS_SCSI) && (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - scsi_cdrom_illegal_opcode(dev); + if ((dev->drv->bus_type < CDROM_BUS_SCSI) && + (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { + scsi_cdrom_log(dev->log, "Attempting to execute SCSI-only command %02X over " + "ATAPI\n", cdb[0]); + scsi_cdrom_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->bus_type == CDROM_BUS_SCSI) && (scsi_cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { - scsi_cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - scsi_cdrom_illegal_opcode(dev); + if ((dev->drv->bus_type == CDROM_BUS_SCSI) && + (scsi_cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { + scsi_cdrom_log(dev->log, "Attempting to execute ATAPI-only command %02X over " + "SCSI\n", cdb[0]); + scsi_cdrom_illegal_opcode(dev, cdb[0]); return 0; } - if ((dev->drv->cd_status == CD_STATUS_PLAYING) || (dev->drv->cd_status == CD_STATUS_PAUSED)) { + if ((dev->drv->cd_status == CD_STATUS_PLAYING) || + (dev->drv->cd_status == CD_STATUS_PAUSED)) { ready = 1; goto skip_ready_check; } - if ((dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) || (ext_medium_changed == 1)) - scsi_cdrom_insert((void *) dev); + if (dev->drv->cd_status & CD_STATUS_TRANSITION) { + if ((cdb[0] == GPCMD_TEST_UNIT_READY) || (cdb[0] == GPCMD_REQUEST_SENSE)) + ready = 0; + else { + if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) + scsi_cdrom_insert((void *) dev); - ready = (dev->drv->cd_status != CD_STATUS_EMPTY) || (ext_medium_changed == -1); + ready = (dev->drv->cd_status != CD_STATUS_EMPTY); + } + } else + ready = (dev->drv->cd_status != CD_STATUS_EMPTY); skip_ready_check: - /* If the drive is not ready, there is no reason to keep the + /* + 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 && dev->unit_attention) + disc changes. + */ + if (!ready && (dev->unit_attention > 0)) dev->unit_attention = 0; - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ + /* + If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. + */ if (dev->unit_attention == 1) { - /* Only increment the unit attention phase if the command can not pass through it. */ + /* + Only increment the unit attention phase if the command can + not pass through it. + */ if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) { - /* scsi_cdrom_log("CD-ROM %i: Unit attention now 2\n", dev->id); */ + scsi_cdrom_log(dev->log, "Unit attention now 2\n"); dev->unit_attention++; - scsi_cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", - dev->id, cdb[0]); + scsi_cdrom_log(dev->log, "UNIT ATTENTION: Command %02X not allowed to " + "pass through\n", cdb[0]); scsi_cdrom_unit_attention(dev); return 0; } } else if (dev->unit_attention == 2) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - /* scsi_cdrom_log("CD-ROM %i: Unit attention now 0\n", dev->id); */ + scsi_cdrom_log(dev->log, "Unit attention now 0\n"); dev->unit_attention = 0; } } - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ + /* + Unless the command is REQUEST SENSE, clear the sense. This will *NOT* clear + the UNIT ATTENTION condition if it's set. + */ if (cdb[0] != GPCMD_REQUEST_SENSE) scsi_cdrom_sense_clear(dev, cdb[0]); /* Next it's time for NOT READY. */ - if (!ready) - dev->media_status = MEC_MEDIA_REMOVAL; + if (ready) + dev->media_status = dev->unit_attention ? MEC_NEW_MEDIA : MEC_NO_CHANGE; else - dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; + dev->media_status = MEC_MEDIA_REMOVAL; - if ((scsi_cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) { - if (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY) { /*Note by TC1995: Some vendor commands from X vendor don't really check for ready status - but they do on Y vendor. Quite confusing I know.*/ - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - if (cdb[0] == 0xC0) - break; - scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); - scsi_cdrom_not_ready(dev); - return 0; - default: - scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); - scsi_cdrom_not_ready(dev); - return 0; - } - } else { - scsi_cdrom_log("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); - scsi_cdrom_not_ready(dev); - return 0; - } + if (!ready && scsi_command_check_ready(dev, cdb)) { + scsi_cdrom_log(dev->log, "Not ready (%02X)\n", cdb[0]); + scsi_cdrom_not_ready(dev); + return 0; } - scsi_cdrom_log("CD-ROM %i: Continuing with command %02X\n", dev->id, cdb[0]); - + scsi_cdrom_log(dev->log, "Continuing with command %02X\n", cdb[0]); return 1; } @@ -1673,71 +1340,137 @@ scsi_cdrom_rezero(scsi_cdrom_t *dev) cdrom_seek(dev->drv, 0, 0); } +static int +scsi_cdrom_update_sector_flags(scsi_cdrom_t *dev) +{ + int ret = 0; + + switch (dev->drv->sector_size) { + default: + dev->sector_type = 0xff; + scsi_cdrom_log(dev->log, "Invalid sector size: %i\n", dev->drv->sector_size); + scsi_cdrom_invalid_field_pl(dev, dev->drv->sector_size); + ret = 1; + break; + case 128: case 256: case 512: case 2048: + /* + Internal type code indicating both Mode 1 and Mode 2 Form 1 are allowed. + Upper 4 bits indicate the divisor. + */ + dev->sector_type = 0x08 | ((2048 / dev->drv->sector_size) << 4); + dev->sector_flags = 0x0010; + break; + case 2056: + dev->sector_type = 0x18; + dev->sector_flags = 0x0050; + break; + case 2324: case 2328: + dev->sector_type = (dev->drv->sector_size == 2328) ? 0x1a : 0x1b; + dev->sector_flags = 0x0018; + break; + case 2332: case 2336: + dev->sector_type = (dev->drv->sector_size == 2336) ? 0x1c : 0x1d; + dev->sector_flags = 0x0058; + break; + case 2340: + dev->sector_type = 0x18; + dev->sector_flags = 0x0078; + break; + case 2352: + dev->sector_type = 0x00; + dev->sector_flags = 0x00f8; + break; + case 2368: + dev->sector_type = 0x00; + dev->sector_flags = 0x01f8; + break; + case 2448: + dev->sector_type = 0x00; + dev->sector_flags = 0x02f8; + break; + } + + return ret; +} + void scsi_cdrom_reset(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; - if (!dev) - return; + if (dev != NULL) { + scsi_cdrom_rezero(dev); + dev->tf->status = 0; + dev->callback = 0.0; + scsi_cdrom_set_callback(dev); + dev->tf->phase = 1; + dev->tf->request_length = 0xeb14; + dev->packet_status = PHASE_NONE; + dev->unit_attention = 0xff; + dev->cur_lun = SCSI_LUN_USE_CDB; - scsi_cdrom_rezero(dev); - dev->tf->status = 0; - dev->callback = 0.0; - scsi_cdrom_set_callback(dev); - dev->tf->phase = 1; - dev->tf->request_length = 0xeb14; - dev->packet_status = PHASE_NONE; - dev->unit_attention = 0xff; - dev->cur_lun = SCSI_LUN_USE_CDB; + dev->drv->sector_size = 2048; + (void) scsi_cdrom_update_sector_flags(dev); + + scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; + scsi_cdrom_info = 0x00000000; + dev->drv->cd_status &= ~CD_STATUS_TRANSITION; + } } static void scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length) { - /*Will return 18 bytes of 0*/ + /* Will return 18 bytes of 0x00. */ if (alloc_length != 0) { - memset(buffer, 0, alloc_length); + memset(buffer, 0x00, alloc_length); memcpy(buffer, dev->sense, alloc_length); } - buffer[0] = 0x70; + buffer[0] = 0xf0; + buffer[7] = 0x0a; if ((scsi_cdrom_sense_key > 0) && (dev->drv->cd_status == CD_STATUS_PLAYING_COMPLETED)) { buffer[2] = SENSE_ILLEGAL_REQUEST; buffer[12] = ASC_AUDIO_PLAY_OPERATION; buffer[13] = ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } else if ((scsi_cdrom_sense_key == 0) && ((dev->drv->cd_status == CD_STATUS_PAUSED) || ((dev->drv->cd_status >= CD_STATUS_PLAYING) && (dev->drv->cd_status != CD_STATUS_STOPPED)))) { + } else if ((scsi_cdrom_sense_key == 0) && + ((dev->drv->cd_status == CD_STATUS_PAUSED) || ((dev->drv->cd_status >= CD_STATUS_PLAYING) && + (dev->drv->cd_status != CD_STATUS_STOPPED)))) { buffer[2] = SENSE_ILLEGAL_REQUEST; buffer[12] = ASC_AUDIO_PLAY_OPERATION; buffer[13] = (dev->drv->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; - } else if (dev->unit_attention && (scsi_cdrom_sense_key == 0)) { + } else if (dev->unit_attention && ((scsi_cdrom_sense_key == 0) || (scsi_cdrom_sense_key == 2))) { buffer[2] = SENSE_UNIT_ATTENTION; buffer[12] = ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[13] = 0; } - scsi_cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); + scsi_cdrom_log(dev->log, "Reporting sense: %02X %02X %02X\n", buffer[2], buffer[12], + buffer[13]); if (buffer[2] == SENSE_UNIT_ATTENTION) { /* If the last remaining sense is unit attention, clear that condition. */ dev->unit_attention = 0; } + + if (dev->drv->cd_status & CD_STATUS_TRANSITION) { + scsi_cdrom_log(dev->log, "CD_STATUS_TRANSITION: scsi_cdrom_insert()\n"); + scsi_cdrom_insert((void *) dev); + } } void scsi_cdrom_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; - - if (dev->drv->cd_status & CD_STATUS_MEDIUM_CHANGED) - scsi_cdrom_insert((void *) dev); + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; if ((dev->drv->cd_status == CD_STATUS_EMPTY) && 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. */ + /* + 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. + */ dev->unit_attention = 0; } @@ -1746,7 +1479,7 @@ scsi_cdrom_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t al } static void -scsi_cdrom_set_buf_len(scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) +scsi_cdrom_set_buf_len(const scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (*BufLen == -1) @@ -1755,46 +1488,823 @@ scsi_cdrom_set_buf_len(scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) *BufLen = MIN(*src_len, *BufLen); *src_len = *BufLen; } - scsi_cdrom_log("CD-ROM %i: Actual transfer length: %i\n", dev->id, *BufLen); + scsi_cdrom_log(dev->log, "Actual transfer length: %i\n", *BufLen); } } static void -scsi_cdrom_stop(scsi_common_t *sc) +scsi_cdrom_stop(const scsi_common_t *sc) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + const scsi_cdrom_t *dev = (const scsi_cdrom_t *) sc; cdrom_stop(dev->drv); } -void -scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) +static void +scsi_cdrom_set_speed(scsi_cdrom_t *dev, const uint8_t *cdb) { - scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + /* Stop the audio playing. */ + cdrom_stop(dev->drv); + + dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; + if (dev->drv->cur_speed < 1) + dev->drv->cur_speed = 1; + else if (dev->drv->cur_speed > dev->drv->real_speed) + dev->drv->cur_speed = dev->drv->real_speed; + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); +} + +static uint8_t +scsi_cdrom_command_chinon(void *sc, const uint8_t *cdb, UNUSED(int32_t *BufLen)) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + uint8_t cmd_stat = 0x00; + + switch (cdb[0]) { + default: + break; + + case GPCMD_UNKNOWN_CHINON: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_EJECT_CHINON: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_STOP_CHINON: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_dec_sony_texel(void *sc, const uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int msf; + uint8_t cmd_stat = 0x00; + int len; + int max_len; + int alloc_length; + int real_pos; + + switch (cdb[0]) { + default: + break; + + case GPCMD_SET_ADDRESS_FORMAT_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->drv->sony_msf = cdb[8] & 1; + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_TOC_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + msf = dev->drv->sony_msf; + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 65536); + + if (dev->drv->ops == NULL) + scsi_cdrom_not_ready(dev); + else { + len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf, max_len); + + if (len == -1) + /* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */ + scsi_cdrom_invalid_field(dev, dev->drv->inv_field); + else { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCHANNEL_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + msf = dev->drv->sony_msf; + + scsi_cdrom_log(dev->log, "Getting sub-channel type (%s), code-q = %02x\n", + msf ? "MSF" : "LBA", cdb[2] & 0x40); + + if (cdb[2] & 0x40) { + scsi_cdrom_buf_alloc(dev, 9); + memset(dev->buffer, 0, 9); + len = 9; + cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log(dev->log, "Drive Status All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_HEADER_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = ((cdb[7] << 8) | cdb[8]); + scsi_cdrom_buf_alloc(dev, 4); + + dev->sector_len = 1; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); + dev->buffer[0] = ((real_pos >> 16) & 0xff); + dev->buffer[1] = ((real_pos >> 8) & 0xff); + dev->buffer[2] = real_pos & 0xff; + dev->buffer[3] = 1; /*2048 bytes user data*/ + + len = 4; + len = MIN(len, alloc_length); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + cmd_stat = 0x01; + break; + + case GPCMD_PLAYBACK_STATUS_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + msf = dev->drv->sony_msf; + + scsi_cdrom_buf_alloc(dev, 18); + + len = 18; + + memset(dev->buffer, 0, 18); + dev->buffer[0] = 0x00; /* Reserved */ + dev->buffer[1] = 0x00; /* Reserved */ + dev->buffer[2] = 0x00; /* Audio Status data length */ + dev->buffer[3] = 0x00; /* Audio Status data length */ + dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, /* Audio status */ + &dev->buffer[6], msf); + dev->buffer[5] = 0x00; + + scsi_cdrom_log(dev->log, "Audio Status = %02x\n", dev->buffer[4]); + + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + cmd_stat = 0x01; + break; + + case GPCMD_PAUSE_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_TRACK_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + + msf = 3; + if ((cdb[5] != 1) || (cdb[8] != 1)) + scsi_cdrom_illegal_mode(dev); + else { + const int pos = cdb[4]; + + if ((dev->drv->image_path[0] == 0x00) || + (dev->drv->cd_status <= CD_STATUS_DVD)) + scsi_cdrom_illegal_mode(dev); + else { + /* In this case, len is unused so just pass a fixed value of 1 intead. */ + const int ret = cdrom_audio_play(dev->drv, pos, 1, msf); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + } + } + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_MSF_SONY: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_MSF; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_MSF. + */ + break; + + case GPCMD_PLAY_AUDIO_SONY: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_10; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_10. + */ + break; + + case GPCMD_PLAYBACK_CONTROL_SONY: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); + + len = (cdb[7] << 8) | cdb[8]; + if (len == 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log(dev->log, "PlayBack Control Sony All done - " + "callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, 65536); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 1); + } + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_matsushita(void *sc, const uint8_t *cdb, UNUSED(int32_t *BufLen)) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + const uint8_t cmd_stat = 0x00; + + switch (cdb[0]) { + default: + break; + + case GPCMD_READ_SUBCHANNEL_MATSUSHITA: + dev->current_cdb[0] = GPCMD_READ_SUBCHANNEL; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_READ_SUBCHANNEL. + */ + break; + + case GPCMD_READ_TOC_MATSUSHITA: + dev->current_cdb[0] = GPCMD_READ_TOC_PMA_ATIP; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_READ_TOC_PMA_ATIP. + */ + break; + + case GPCMD_READ_HEADER_MATSUSHITA: + dev->current_cdb[0] = GPCMD_READ_HEADER; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_READ_HEADER. + */ + break; + + case GPCMD_PLAY_AUDIO_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_10; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_10. + */ + break; + + case GPCMD_PLAY_AUDIO_MSF_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_MSF; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_MSF. + */ + break; + + case GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_TRACK_INDEX. + */ + break; + + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10. + */ + break; + + case GPCMD_PAUSE_RESUME_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PAUSE_RESUME; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PAUSE_RESUME. + */ + break; + + case GPCMD_PLAY_AUDIO_12_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_12; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_12. + */ + break; + + case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA: + dev->current_cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12; + /* + Keep cmd_stat at 0x00, therefore, it's going to process it + as GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12. + */ + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_nec(void *sc, const uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + uint8_t cmd_stat = 0x00; + int pos; + int ret; + int len; + int alloc_length; + + switch (cdb[0]) { + default: + break; + + case GPCMD_NO_OPERATION_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_UNKNOWN_SCSI2_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_AUDIO_TRACK_SEARCH_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DVD)) + scsi_cdrom_illegal_mode(dev); + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_AUDIO_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DVD)) + ret = 0; + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + } + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + + cmd_stat = 0x01; + break; + + case GPCMD_STILL_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_SET_STOP_TIME_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_CADDY_EJECT_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 10; + + if (dev->drv->ops == NULL) + scsi_cdrom_not_ready(dev); + else if (alloc_length <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log(dev->log, "Subcode Q All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log(dev->log, "Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_DISC_INFORMATION_NEC: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + /* + NEC manual claims 4 bytes but the Linux kernel + (namely sr_vendor.c) actually states otherwise. + */ + scsi_cdrom_buf_alloc(dev, 22); + + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 22; + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else + scsi_cdrom_invalid_field(dev, dev->drv->inv_field); + + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_pioneer(void *sc, const uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + uint8_t cmd_stat = 0x00; + int pos; + int ret; + int len; + int max_len; + int alloc_length; + + switch (cdb[0]) { + default: + break; + + case GPCMD_MAGAZINE_EJECT_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_TOC_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 4); + + if (dev->drv->ops == NULL) + scsi_cdrom_not_ready(dev); + else { + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 4; + + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else + scsi_cdrom_invalid_field(dev, dev->drv->inv_field); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCODEQ_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 9; + + if (dev->drv->ops == NULL) + scsi_cdrom_not_ready(dev); + else if (!alloc_length) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log(dev->log, "Subcode Q All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + cdrom_get_current_subcodeq(dev->drv, &dev->buffer[1]); + scsi_cdrom_log(dev->log, "Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + cmd_stat = 0x01; + break; + + case GPCMD_AUDIO_TRACK_SEARCH_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DVD)) + ret = 0; + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search_pioneer(dev->drv, pos, cdb[1] & 1); + + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + } + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_AUDIO_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DVD)) + ret = 0; + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_pioneer(dev->drv, pos); + } + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PAUSE_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_STOP_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PLAYBACK_STATUS_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + scsi_cdrom_buf_alloc(dev, 6); + + len = 6; + + memset(dev->buffer, 0, 6); + dev->buffer[0] = cdrom_get_audio_status_pioneer(dev->drv, &dev->buffer[1]); /*Audio status*/ + + scsi_cdrom_log(dev->log, "Audio Status = %02x\n", dev->buffer[4]); + + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + cmd_stat = 0x01; + break; + + case GPCMD_DRIVE_STATUS_PIONEER: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + len = (cdb[9] | (cdb[8] << 8)); + scsi_cdrom_buf_alloc(dev, 65536); + + if (!(scsi_cdrom_drive_status_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) + scsi_cdrom_invalid_field(dev, cdb[2]); + else if (len <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log(dev->log, "Drive Status All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + memset(dev->buffer, 0, len); + alloc_length = len; + + len = scsi_cdrom_drive_status(dev, dev->buffer, cdb[2]); + len = MIN(len, alloc_length); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_log(dev->log, "Reading drive status page: %02X...\n", + cdb[2]); + + scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); + } + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +static uint8_t +scsi_cdrom_command_toshiba(void *sc, const uint8_t *cdb, int32_t *BufLen) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + uint8_t cmd_stat = 0x00; + int pos; + int ret; + int len; + int alloc_length; + + switch (cdb[0]) { + default: + break; + + case GPCMD_NO_OPERATION_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DVD)) { + scsi_cdrom_illegal_mode(dev); + break; + } + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); + dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + cmd_stat = 0x01; + break; + + case GPCMD_PLAY_AUDIO_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + + if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DVD)) + scsi_cdrom_illegal_mode(dev); + else { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); + + if (ret) + scsi_cdrom_command_complete(dev); + else + scsi_cdrom_illegal_mode(dev); + } + cmd_stat = 0x01; + break; + + case GPCMD_STILL_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + cdrom_audio_pause_resume(dev->drv, 0x00); + dev->drv->audio_op = 0x01; + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_SET_STOP_TIME_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_CADDY_EJECT_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_stop(sc); + cdrom_eject(dev->id); + scsi_cdrom_command_complete(dev); + cmd_stat = 0x01; + break; + + case GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + + alloc_length = cdb[1] & 0x1f; + len = 10; + + if (dev->drv->ops == NULL) + scsi_cdrom_not_ready(dev); + else if (alloc_length <= 0) { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + scsi_cdrom_log(dev->log, "Subcode Q All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } else { + scsi_cdrom_buf_alloc(dev, len); + len = MIN(len, alloc_length); + + memset(dev->buffer, 0, len); + dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); + scsi_cdrom_log(dev->log, "Audio Status = %02x\n", dev->buffer[0]); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } + cmd_stat = 0x01; + break; + + case GPCMD_READ_DISC_INFORMATION_TOSHIBA: + scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + scsi_cdrom_buf_alloc(dev, 4); + + if (dev->drv->ops == NULL) + scsi_cdrom_not_ready(dev); + else { + ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); + len = 4; + if (ret) { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); + } else + scsi_cdrom_invalid_field(dev, dev->drv->inv_field); + } + cmd_stat = 0x01; + break; + } + + return cmd_stat; +} + +void +scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) +{ + scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; + int pos = dev->drv->seek_pos; + int idx = 0; + int ret = 1; + int32_t blen = 0; + uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + char model[2048] = { 0 }; + int msf; + int block_desc; int len; int max_len; int used_len; int alloc_length; - int msf; - int pos = dev->drv->seek_pos; int size_idx; - int idx = 0; uint32_t feature; unsigned preamble_len; int toc_format; - int block_desc = 0; - int ret; - int format = 0; - int real_pos; - int track = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int32_t blen = 0; int32_t *BufLen; - uint8_t *b; - uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == CDROM_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -1807,42 +2317,38 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) dev->packet_len = 0; dev->request_pos = 0; - device_identify[7] = dev->id + 0x30; - - device_identify_ex[7] = dev->id + 0x30; - device_identify_ex[10] = EMU_VERSION_EX[0]; - device_identify_ex[12] = EMU_VERSION_EX[2]; - device_identify_ex[13] = EMU_VERSION_EX[3]; - memcpy(dev->current_cdb, cdb, 12); - dev->sony_vendor = 0; - if (cdb[0] != 0) { - scsi_cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, Unit attention: %i\n", - dev->id, cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq, - dev->unit_attention); - scsi_cdrom_log("CD-ROM %i: Request length: %04X\n", dev->id, dev->tf->request_length); +#if ENABLE_SCSI_CDROM_LOG == 2 + scsi_cdrom_log(dev->log, "Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, " + "Unit attention: %i\n", cdb[0], scsi_cdrom_sense_key, scsi_cdrom_asc, + scsi_cdrom_ascq, dev->unit_attention); + scsi_cdrom_log(dev->log, "Request length: %04X\n", dev->tf->request_length); - scsi_cdrom_log("CD-ROM %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - dev->id, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], + scsi_cdrom_log(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]); - } +#endif msf = cdb[1] & 2; dev->sector_len = 0; scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ + /* + This handles the Not Ready/Unit Attention check if it has to be + handled at this point. + */ if (scsi_cdrom_pre_execution_check(dev, cdb) == 0) return; -begin: if (cdb[0] != GPCMD_REQUEST_SENSE) { /* Clear the sense stuff as per the spec. */ scsi_cdrom_sense_clear(dev, cdb[0]); } - switch (cdb[0]) { + + if ((dev->ven_cmd == NULL) || (dev->ven_cmd(sc, cdb, BufLen) == 0x00)) switch (dev->current_cdb[0]) { case GPCMD_TEST_UNIT_READY: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); scsi_cdrom_command_complete(dev); @@ -1857,8 +2363,6 @@ begin: break; case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE - should forget about the not ready, and report unit attention straight away. */ scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; @@ -1876,38 +2380,16 @@ begin: scsi_cdrom_data_command_finish(dev, 18, 18, cdb[4], 0); break; - case 0xDA: /*GPCMD_SPEED_ALT*/ - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_STILL_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, 0x00); - dev->drv->audio_op = 0x01; - scsi_cdrom_command_complete(dev); - if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) - scsi_cdrom_buf_free(dev); - return; - } - fallthrough; case GPCMD_SET_SPEED: - dev->drv->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; - if (dev->drv->cur_speed < 1) - dev->drv->cur_speed = 1; - else if (dev->drv->cur_speed > dev->drv->speed) - dev->drv->cur_speed = dev->drv->speed; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); + scsi_cdrom_set_speed(dev, cdb); break; - case 0xCD: + case GPCMD_SCAN_PIONEER: case GPCMD_AUDIO_SCAN: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { + if ((dev->drv->image_path[0] == 0x00) || + (dev->drv->cd_status <= CD_STATUS_DVD)) { scsi_cdrom_illegal_mode(dev); break; } @@ -1949,294 +2431,224 @@ begin: if (toc_format == 0) toc_format = (cdb[9] >> 6) & 3; - if (!dev->drv->ops) { + if (dev->drv->ops == NULL) scsi_cdrom_not_ready(dev); - return; - } - - if (toc_format < 3) { + else if (toc_format < 3) { len = cdrom_read_toc(dev->drv, dev->buffer, toc_format, cdb[6], msf, max_len); - if (len == -1) { - /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; + /* If the returned length is -1, this means cdrom_read_toc() has encountered an error. */ + if (len == -1) + scsi_cdrom_invalid_field(dev, dev->drv->inv_field); + else { + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, len, 0); } - } else { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - - case 0xC7: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_MSF_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_MSF; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_MSF_SONY*/ - cdb[0] = GPCMD_PLAY_AUDIO_MSF; - dev->current_cdb[0] = cdb[0]; - dev->sony_vendor = 1; - goto begin; - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_READ_DISC_INFORMATION_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 4); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 4; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } + } else + scsi_cdrom_invalid_field(dev, toc_format); break; - case 0xDE: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_DISC_INFORMATION_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 22); /* NEC manual claims 4 bytes, but the Linux kernel (namely sr_vendor.c) actually states otherwise. */ - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 22; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - case GPCMD_READ_CD_OLD: - /* IMPORTANT: Convert the command to new read CD - for pass through purposes. */ - dev->current_cdb[0] = GPCMD_READ_CD; - fallthrough; - case GPCMD_READ_6: case GPCMD_READ_10: case GPCMD_READ_12: + case GPCMD_READ_CD_OLD: + case GPCMD_READ_CD_MSF_OLD: case GPCMD_READ_CD: case GPCMD_READ_CD_MSF: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - alloc_length = 2048; + alloc_length = dev->drv->sector_size; switch (cdb[0]) { case GPCMD_READ_6: dev->sector_len = cdb[4]; + /* + For READ (6) and WRITE (6), a length of 0 indicates a transfer of + 256 sectors. + */ if (dev->sector_len == 0) - dev->sector_len = 256; /* For READ (6) and WRITE (6), a length of 0 indicates a transfer of 256 sector. */ - dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); - msf = 0; + dev->sector_len = 256; + dev->sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | + (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + scsi_cdrom_log(dev->log, "READ (6): 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]; - scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, - dev->sector_pos); - msf = 0; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; + scsi_cdrom_log(dev->log, "READ (10): Length: %i, LBA: %i\n", + dev->sector_len, dev->sector_pos); break; case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); - scsi_cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", dev->id, dev->sector_len, - dev->sector_pos); - msf = 0; + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | + (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | + (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + scsi_cdrom_log(dev->log, "READ (12): Length: %i, LBA: %i\n", + dev->sector_len, dev->sector_pos); break; + case GPCMD_READ_CD_MSF_OLD: case GPCMD_READ_CD_MSF: - alloc_length = 2856; - dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); - dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - - dev->sector_len -= dev->sector_pos; - dev->sector_len++; - msf = 1; - - if ((cdb[9] & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - scsi_cdrom_invalid_field(dev); - return; - } - - /* If all the flag bits are cleared, then treat it as a non-data command. */ - if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) - dev->sector_len = 0; - else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { - scsi_cdrom_invalid_field(dev); - return; - } - break; + fallthrough; case GPCMD_READ_CD_OLD: case GPCMD_READ_CD: alloc_length = 2856; - dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - msf = 0; + if (msf) { + dev->sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); + dev->sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); - if ((cdb[9] & 0xf8) == 0x08) { - /* 0x08 is an illegal mode */ - scsi_cdrom_invalid_field(dev); - return; + dev->sector_len -= dev->sector_pos; + dev->sector_len++; + } else { + dev->sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; } - /* If all the flag bits are cleared, then treat it as a non-data command. */ - if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) + if (((cdb[9] & 0xf8) == 0x08) || ((cdb[9] == 0x00) && + ((cdb[10] & 0x07) != 0x00))) { + /* Illegal mode */ + scsi_cdrom_invalid_field(dev, cdb[9]); + ret = 0; + } else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) == 0x00)) + /* + If all the flag bits are cleared, then treat it as a + non-data command. + */ dev->sector_len = 0; - else if ((cdb[9] == 0x00) && ((cdb[10] & 0x07) != 0x00)) { - scsi_cdrom_invalid_field(dev); - return; - } break; default: break; } - if (!dev->sector_len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - /* scsi_cdrom_log("CD-ROM %i: All done - callback set\n", dev->id); */ - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } + if (ret) { + if (dev->sector_len > 0) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; - max_len = dev->sector_len; - dev->requested_blocks = max_len; /* If we're reading all blocks in one go for DMA, why not also for PIO, it should NOT - matter anyway, this step should be identical and only the way the read dat is - transferred to the host should be different. */ + dev->packet_len = max_len * alloc_length; + scsi_cdrom_buf_alloc(dev, dev->packet_len); - dev->packet_len = max_len * alloc_length; - scsi_cdrom_buf_alloc(dev, dev->packet_len); + dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); + dev->drv->seek_pos = dev->sector_pos; - dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); + if (dev->use_cdb_9 && ((cdb[0] == GPCMD_READ_10) || + (cdb[0] == GPCMD_READ_12))) + ret = scsi_cdrom_read_blocks(dev, &alloc_length, + cdb[9] & 0xc0); + else + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 0); - if ((cdb[0] == GPCMD_READ_10) || (cdb[0] == GPCMD_READ_12)) { - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, cdb[9] & 0xc0); - break; - default: - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); - break; + if (ret > 0) { + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + scsi_cdrom_set_buf_len(dev, BufLen, + (int32_t *) &dev->packet_len); + + scsi_cdrom_data_command_finish(dev, alloc_length, + alloc_length / dev->requested_blocks, + alloc_length, 0); + + if (dev->packet_status != PHASE_COMPLETE) + ui_sb_update_icon(SB_CDROM | dev->id, 1); + else + ui_sb_update_icon(SB_CDROM | dev->id, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + /* scsi_cdrom_log(dev->log, "All done - callback set\n"); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); } - } else - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1, 0); - - if (ret <= 0) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - scsi_cdrom_buf_free(dev); - return; } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - scsi_cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, - alloc_length, 0); - - if (dev->packet_status != PHASE_COMPLETE) - ui_sb_update_icon(SB_CDROM | dev->id, 1); - else - ui_sb_update_icon(SB_CDROM | dev->id, 0); - return; + break; case GPCMD_READ_HEADER: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + alloc_length = 2352; - alloc_length = ((cdb[7] << 8) | cdb[8]); - scsi_cdrom_buf_alloc(dev, 8); - + len = (cdb[7] << 8) | cdb[8]; dev->sector_len = 1; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - if (msf) - real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); - else - real_pos = dev->sector_pos; - dev->buffer[0] = 1; /*2048 bytes user data*/ - dev->buffer[1] = dev->buffer[2] = dev->buffer[3] = 0; - dev->buffer[4] = (real_pos >> 24); - dev->buffer[5] = ((real_pos >> 16) & 0xff); - dev->buffer[6] = ((real_pos >> 8) & 0xff); - dev->buffer[7] = real_pos & 0xff; + scsi_cdrom_log(dev->log, "READ HEADER: Length: %i, LBA: %i\n", + dev->sector_len, dev->sector_pos); - len = 8; - len = MIN(len, alloc_length); + if (len > 0) { + max_len = 1; + dev->requested_blocks = max_len; - scsi_cdrom_set_buf_len(dev, BufLen, &len); + dev->packet_len = len; + scsi_cdrom_buf_alloc(dev, 2352); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; + dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); + dev->drv->seek_pos = dev->sector_pos; + + ret = scsi_cdrom_read_blocks(dev, &alloc_length, 0); + + if (ret > 0) { + uint8_t header[4] = { 0 }; + + memcpy(header, dev->buffer, 4); + + dev->buffer[0] = header[3]; + + if (cdb[1] & 0x02) { + memset(&(dev->buffer[1]), 0x00, 4); + dev->buffer[5] = header[0]; + dev->buffer[6] = header[1]; + dev->buffer[7] = header[2]; + } else { + memset(&(dev->buffer[1]), 0x00, 3); + uint32_t lba = ((header[0] * 60 * 75) + + (header[1] * 75) + + header[2]) - 150; + dev->buffer[4] = (lba >> 24) & 0xff; + dev->buffer[5] = (lba >> 16) & 0xff; + dev->buffer[6] = (lba >> 8) & 0xff; + dev->buffer[7] = lba & 0xff; + } + + len = MIN(8, len); + + scsi_cdrom_set_buf_len(dev, BufLen, &len); + + scsi_cdrom_data_command_finish(dev, len, len, + len, 0); + + ui_sb_update_icon(SB_CDROM | dev->id, 0); + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + } else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + /* scsi_cdrom_log(dev->log, "All done - callback set\n"); */ + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + break; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - if (dev->drv->bus_type == CDROM_BUS_SCSI) - block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; - else + if (dev->drv->bus_type == CDROM_BUS_ATAPI) block_desc = 0; + else + block_desc = !((cdb[1] >> 3) & 1); if (cdb[0] == GPCMD_MODE_SENSE_6) { len = cdb[4]; @@ -2246,69 +2658,57 @@ begin: scsi_cdrom_buf_alloc(dev, 65536); } - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - break; - default: - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - break; - } - memset(dev->buffer, 0, len); - alloc_length = len; + if (!(dev->ms_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) + ret = 0; - /* This determines the media type ID to return - this is - a SCSI/ATAPI-specific thing, so it makes the most sense - to keep this here. - 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) - max_len = 70; /* No media inserted. */ - else if (dev->drv->cdrom_capacity > CD_MAX_SECTORS) - max_len = 65; /* DVD. */ - else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) - max_len = 1; /* Data CD. */ - else - max_len = 3; /* Audio or mixed-mode CD. */ + if (ret == 1) { + memset(dev->buffer, 0, len); + alloc_length = len; - if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_cdrom_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); - len = MIN(len, alloc_length); - dev->buffer[0] = len - 1; - dev->buffer[1] = max_len; - if (block_desc) - dev->buffer[3] = 8; - } else { - len = scsi_cdrom_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; - dev->buffer[2] = max_len; - if (block_desc) { - dev->buffer[6] = 0; - dev->buffer[7] = 8; + /* + This determines the media type ID to return which is a SCSI/ATAPI-specific + thing, so it makes the most sense to keep this here. + + 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) + max_len = 70; /* No media inserted. */ + else if (dev->drv->cd_status == CD_STATUS_DVD) + max_len = 65; /* DVD. */ + else if (dev->drv->cd_status == CD_STATUS_DATA_ONLY) + max_len = 1; /* Data CD. */ + else + max_len = 3; /* Audio or mixed-mode CD. */ + + if (cdb[0] == GPCMD_MODE_SENSE_6) { + len = scsi_cdrom_mode_sense(dev, dev->buffer, 4, cdb[2], block_desc); + len = MIN(len, alloc_length); + dev->buffer[0] = len - 1; + dev->buffer[1] = max_len; + if (block_desc) + dev->buffer[3] = 8; + } else { + len = scsi_cdrom_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; + dev->buffer[2] = max_len; + if (block_desc) { + dev->buffer[6] = 0; + dev->buffer[7] = 8; + } } - } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + scsi_cdrom_log(dev->log, "Reading mode page: %02X...\n", cdb[2]); - scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); - return; + scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); + } else + scsi_cdrom_invalid_field(dev, cdb[2]); + break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -2328,102 +2728,160 @@ begin: dev->do_page_save = cdb[1] & 1; scsi_cdrom_data_command_finish(dev, len, len, len, 1); - return; + break; case GPCMD_GET_CONFIGURATION: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - /* XXX: could result in alignment problems in some architectures */ + /* XXX: Could result in alignment problems in some architectures */ feature = (cdb[2] << 8) | cdb[3]; max_len = (cdb[7] << 8) | cdb[8]; - /* only feature 0 is supported */ - if ((cdb[2] != 0) || (cdb[3] > 2)) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + /* Only feature 0 is supported */ + if ((feature > 3) && (feature != 0x010) && (feature != 0x1d) && (feature != 0x01e) && + (feature != 0x01f) && (feature != 0x103)) + scsi_cdrom_invalid_field(dev, feature); + else { + scsi_cdrom_buf_alloc(dev, 65536); + memset(dev->buffer, 0, max_len); - scsi_cdrom_buf_alloc(dev, 65536); - memset(dev->buffer, 0, max_len); + uint8_t *b = dev->buffer; - alloc_length = 0; - b = dev->buffer; + alloc_length = 0; - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (dev->drv->cd_status != CD_STATUS_EMPTY) { - len = dev->drv->cdrom_capacity; - if (len > CD_MAX_SECTORS) { - b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_DVD_ROM & 0xff; - ret = 1; - } else { - b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; - b[7] = MMC_PROFILE_CD_ROM & 0xff; - ret = 0; + if (dev->drv->cd_status != CD_STATUS_EMPTY) { + if (dev->drv->cd_status == CD_STATUS_DVD) { + b[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; + b[7] = MMC_PROFILE_DVD_ROM & 0xff; + ret = 1; + } else { + b[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; + b[7] = MMC_PROFILE_CD_ROM & 0xff; + ret = 0; + } + } else + ret = 2; + + alloc_length = 8; + b += 8; + + if ((feature == 0) || ((cdb[1] & 3) < 2)) { + /* Persistent and current. */ + b[2] = (0 << 2) | 0x02 | 0x01; + b[3] = 8; + + alloc_length += 4; + b += 4; + + for (uint8_t i = 0; i < 2; i++) { + b[0] = (profiles[i] >> 8) & 0xff; + b[1] = profiles[i] & 0xff; + + if (ret == i) + b[2] |= 1; + + alloc_length += 4; + b += 4; + } } - } else - ret = 2; + if ((feature == 1) || ((cdb[1] & 3) < 2)) { + /* Persistent and current. */ + b[1] = 1; + b[2] = (2 << 2) | 0x02 | 0x01; + b[3] = 8; - alloc_length = 8; - b += 8; + if (dev->drv->bus_type == CDROM_BUS_SCSI) + b[7] = 1; + else + b[7] = 2; + b[8] = 1; - if ((feature == 0) || ((cdb[1] & 3) < 2)) { - b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; + alloc_length += 12; + b += 12; + } + if ((feature == 2) || ((cdb[1] & 3) < 2)) { + b[1] = 2; + b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 4; + b[4] = 2; - alloc_length += 4; - b += 4; + alloc_length += 8; + b += 8; + } + if ((feature == 3) || ((cdb[1] & 3) < 2)) { + b[1] = 2; + /* Persistent and current. */ + b[2] = (0 << 2) | 0x02 | 0x01; + b[3] = 4; + b[4] = 0x0d | (cdrom_is_caddy(dev->drv->type) ? 0x00 : 0x20); - for (uint8_t i = 0; i < 2; i++) { - b[0] = (profiles[i] >> 8) & 0xff; - b[1] = profiles[i] & 0xff; + alloc_length += 8; + b += 8; + } + if ((feature == 0x10) || ((cdb[1] & 3) < 2)) { + b[1] = 0x10; + /* Persistent and current. */ + b[2] = (0 << 2) | 0x02 | 0x01; + b[3] = 8; - if (ret == i) - b[2] |= 1; + b[6] = 8; + b[9] = 0x10; + + alloc_length += 12; + b += 12; + } + if ((feature == 0x1d) || ((cdb[1] & 3) < 2)) { + b[1] = 0x1d; + /* Persistent and current. */ + b[2] = (0 << 2) | 0x02 | 0x01; + b[3] = 0; alloc_length += 4; b += 4; } + if ((feature == 0x1e) || ((cdb[1] & 3) < 2)) { + b[1] = 0x1e; + /* Persistent and current. */ + b[2] = (2 << 2) | 0x02 | 0x01; + b[3] = 4; + b[4] = 0; + + alloc_length += 8; + b += 8; + } + if ((feature == 0x1f) || ((cdb[1] & 3) < 2)) { + b[1] = 0x1f; + b[2] = (0 << 2) | 0x02 | 0x01; /* persistent and current */ + b[3] = 0; + + alloc_length += 4; + b += 4; + } + if ((feature == 0x103) || ((cdb[1] & 3) < 2)) { + b[0] = 1; + b[1] = 3; + /* Persistent and current. */ + b[2] = (0 << 2) | 0x02 | 0x01; + b[3] = 0; + b[4] = 7; + + b[6] = 1; + + alloc_length += 8; + } + + dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff; + dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff; + dev->buffer[2] = ((alloc_length - 4) >> 8) & 0xff; + dev->buffer[3] = (alloc_length - 4) & 0xff; + + alloc_length = MIN(alloc_length, max_len); + + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + + scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, + alloc_length, 0); } - if ((feature == 1) || ((cdb[1] & 3) < 2)) { - b[1] = 1; - b[2] = (2 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 8; - - if (dev->drv->bus_type == CDROM_BUS_SCSI) - b[7] = 1; - else - b[7] = 2; - b[8] = 1; - - alloc_length += 12; - b += 12; - } - if ((feature == 2) || ((cdb[1] & 3) < 2)) { - b[1] = 2; - b[2] = (1 << 2) | 0x02 | 0x01; /* persistent and current */ - b[3] = 4; - - b[4] = 2; - - alloc_length += 8; - b += 8; - } - - dev->buffer[0] = ((alloc_length - 4) >> 24) & 0xff; - dev->buffer[1] = ((alloc_length - 4) >> 16) & 0xff; - dev->buffer[2] = ((alloc_length - 4) >> 8) & 0xff; - dev->buffer[3] = (alloc_length - 4) & 0xff; - - alloc_length = MIN(alloc_length, max_len); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); break; case GPCMD_GET_EVENT_STATUS_NOTIFICATION: @@ -2434,56 +2892,57 @@ begin: gesn_cdb = (void *) cdb; gesn_event_header = (void *) dev->buffer; - /* It is fine by the MMC spec to not support async mode operations. */ - if (!(gesn_cdb->polled & 0x01)) { - /* asynchronous mode */ - /* Only polling is supported, asynchronous mode is not. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + if (gesn_cdb->polled & 0x01) { + /* + These are the supported events. - /* - * These are the supported events. - * - * We currently only support requests of the 'media' type. - * Notification class requests and supported event classes are bitmasks, - * but they are built from the same values as the "notification class" - * field. - */ - gesn_event_header->supported_events = 1 << GESN_MEDIA; + We currently only support requests of the 'media' type. + Notification class requests and supported event classes are bitmasks, + but they are built from the same values as the "notification class" + field. + */ + gesn_event_header->supported_events = 1 << GESN_MEDIA; - /* - * We use |= below to set the class field; other bits in this byte - * are reserved now but this is useful to do if we have to use the - * reserved fields later. - */ - gesn_event_header->notification_class = 0; + /* + We use |= below to set the class field; other bits in this byte + are reserved now but this is useful to do if we have to use the + reserved fields later. + */ + gesn_event_header->notification_class = 0; - /* - * Responses to requests are to be based on request priority. The - * notification_class_request_type enum above specifies the - * priority: upper elements are higher prio than lower ones. - */ - if (gesn_cdb->class & (1 << GESN_MEDIA)) { - gesn_event_header->notification_class |= GESN_MEDIA; + /* + Responses to requests are to be based on request priority. The + notification_class_request_type enum above specifies the + priority: upper elements are higher prio than lower ones. + */ + if (gesn_cdb->class & (1 << GESN_MEDIA)) { + gesn_event_header->notification_class |= GESN_MEDIA; - dev->buffer[4] = dev->media_status; /* Bits 7-4 = Reserved, Bits 4-1 = Media Status */ - dev->buffer[5] = 1; /* Power Status (1 = Active) */ - dev->buffer[6] = 0; - dev->buffer[7] = 0; - used_len = 8; - } else { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - gesn_event_header->len = used_len - sizeof(*gesn_event_header); + /* Bits 7-4 = Reserved, Bits 4-1 = Media Status. */ + dev->buffer[4] = dev->media_status; + /* Power Status (1 = Active). */ + dev->buffer[5] = 1; + dev->buffer[6] = 0; + dev->buffer[7] = 0; + used_len = 8; + } else { + /* No event available. */ + gesn_event_header->notification_class = 0x80; + used_len = sizeof(*gesn_event_header); + } + gesn_event_header->len = used_len - sizeof(*gesn_event_header); - memmove(dev->buffer, gesn_event_header, 4); + memmove(dev->buffer, gesn_event_header, 4); - scsi_cdrom_set_buf_len(dev, BufLen, &used_len); + scsi_cdrom_set_buf_len(dev, BufLen, &used_len); - scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); + scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); + } else + /* + Only polling is supported, asynchronous mode is not. + It is fine by the MMC spec to not support async mode operations. + */ + scsi_cdrom_invalid_field(dev, gesn_cdb->polled); break; case GPCMD_READ_DISC_INFORMATION: @@ -2495,16 +2954,9 @@ begin: scsi_cdrom_buf_alloc(dev, 65536); - memset(dev->buffer, 0, 34); - memset(dev->buffer, 1, 9); - dev->buffer[0] = 0; - dev->buffer[1] = 32; - dev->buffer[2] = 0xe; /* last session complete, disc finalized */ - dev->buffer[7] = 0x20; /* unrestricted use */ - dev->buffer[8] = 0x00; /* CD-ROM */ + cdrom_read_disc_information(dev->drv, dev->buffer); - len = 34; - len = MIN(len, max_len); + len = MIN(34, max_len); scsi_cdrom_set_buf_len(dev, BufLen, &len); @@ -2520,219 +2972,21 @@ begin: scsi_cdrom_buf_alloc(dev, 65536); - track = ((uint32_t) cdb[2]) << 24; - track |= ((uint32_t) cdb[3]) << 16; - track |= ((uint32_t) cdb[4]) << 8; - track |= (uint32_t) cdb[5]; + ret = cdrom_read_track_information(dev->drv, cdb, dev->buffer); - if (((cdb[1] & 0x03) != 1) || (track != 1)) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } + if (ret > 0) { + len = ret; - len = 36; + if (len > max_len) { + len = max_len; + dev->buffer[0] = ((max_len - 2) >> 8) & 0xff; + dev->buffer[1] = (max_len - 2) & 0xff; + } - memset(dev->buffer, 0, 36); - dev->buffer[0] = 0; - dev->buffer[1] = 34; - dev->buffer[2] = 1; /* track number (LSB) */ - dev->buffer[3] = 1; /* session number (LSB) */ - dev->buffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ - dev->buffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ - dev->buffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ - - dev->buffer[24] = ((dev->drv->cdrom_capacity - 1) >> 24) & 0xff; /* track size */ - dev->buffer[25] = ((dev->drv->cdrom_capacity - 1) >> 16) & 0xff; /* track size */ - dev->buffer[26] = ((dev->drv->cdrom_capacity - 1) >> 8) & 0xff; /* track size */ - dev->buffer[27] = (dev->drv->cdrom_capacity - 1) & 0xff; /* track size */ - - if (len > max_len) { - len = max_len; - dev->buffer[0] = ((max_len - 2) >> 8) & 0xff; - dev->buffer[1] = (max_len - 2) & 0xff; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); - break; - - case 0xC0: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_SET_ADDRESS_FORMAT_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - dev->drv->sony_msf = cdb[8] & 1; - scsi_cdrom_command_complete(dev); - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_MAGAZINE_EJECT_PIONEER*/ - case CDROM_TYPE_CHINON_CDS431_H42: /*GPCMD_EJECT_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_AUDIO_TRACK_SEARCH_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xD8: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_AUDIO_TRACK_SEARCH_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search(dev->drv, pos, cdb[9] & 0xc0, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC1: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_TOC_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - dev->sony_vendor = 1; - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 65536); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - len = cdrom_read_toc_sony(dev->drv, dev->buffer, cdb[5], msf || dev->drv->sony_msf, max_len); - if (len == -1) { - /* If the returned length is -1, this means cdrom_read_toc_sony() has encountered an error. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_READ_TOC_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 4); - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - ret = cdrom_read_disc_info_toc(dev->drv, dev->buffer, cdb[2], cdb[1] & 3); - len = 4; - if (!ret) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_PLAY_AUDIO_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xD9: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_PLAY_AUDIO_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_toshiba(dev->drv, pos, cdb[9] & 0xc0); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } + scsi_cdrom_set_buf_len(dev, BufLen, &len); + scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); + } else + scsi_cdrom_invalid_field(dev, -ret); break; case GPCMD_PLAY_AUDIO_10: @@ -2741,10 +2995,10 @@ begin: case GPCMD_PLAY_AUDIO_TRACK_INDEX: case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12: - len = 0; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + len = 0; + switch (cdb[0]) { case GPCMD_PLAY_AUDIO_10: msf = 0; @@ -2763,12 +3017,11 @@ begin: break; case GPCMD_PLAY_AUDIO_TRACK_INDEX: msf = 2; - if ((cdb[5] != 1) || (cdb[8] != 1)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = cdb[4]; - len = cdb[7]; + if ((cdb[5] == 1) && (cdb[8] == 1)) { + pos = cdb[4]; + len = cdb[7]; + } else + ret = 0; break; case GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10: msf = 0x100 | cdb[6]; @@ -2785,12 +3038,11 @@ begin: break; } - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - - ret = cdrom_audio_play(dev->drv, pos, len, msf); + if (ret && (dev->drv->image_path[0] != 0x00) && + (dev->drv->cd_status > CD_STATUS_DVD)) + ret = cdrom_audio_play(dev->drv, pos, len, msf); + else + ret = 0; if (ret) scsi_cdrom_command_complete(dev); @@ -2808,31 +3060,24 @@ begin: scsi_cdrom_buf_alloc(dev, 32); - scsi_cdrom_log("CD-ROM %i: Getting page %i (%s)\n", dev->id, cdb[3], msf ? "MSF" : "LBA"); + scsi_cdrom_log(dev->log, "Getting page %i (%s)\n", cdb[3], + msf ? "MSF" : "LBA"); - if (cdb[3] > 3) { - /* scsi_cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", dev->id, - cdb[3]); */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (max_len <= 0) { + if (cdb[3] > 3) + scsi_cdrom_invalid_field(dev, cdb[3]); + else if ((cdb[3] != 3) && (cdb[6] != 0)) + scsi_cdrom_invalid_field(dev, cdb[6]); + else if (max_len <= 0) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * CDROM_TIME; scsi_cdrom_set_callback(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (!(cdb[2] & 0x40)) - alloc_length = 4; - else - switch (cdb[3]) { + } else { + if (!(cdb[2] & 0x40)) + alloc_length = 4; + else switch (cdb[3]) { case 0: - /* SCSI-2: Q-type subchannel, ATAPI: reserved */ + /* SCSI-2: Q-type subchannel, ATAPI: reserved. */ alloc_length = (dev->drv->bus_type == CDROM_BUS_SCSI) ? 48 : 4; break; case 1: @@ -2843,163 +3088,30 @@ begin: break; } - len = alloc_length; + len = alloc_length; - memset(dev->buffer, 0, 24); - pos = 0; - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; /*Audio status*/ - dev->buffer[pos++] = 0; - dev->buffer[pos++] = 0; /*Subchannel length*/ - /* Mode 0 = Q subchannel mode, first 16 bytes are indentical to mode 1 (current position), - the rest are stuff like ISRC etc., which can be all zeroes. */ - if (cdb[3] <= 3) { - dev->buffer[pos++] = cdb[3]; /*Format code*/ + memset(dev->buffer, 0, 24); + pos = 0x00; + dev->buffer[pos++] = 0x00; + dev->buffer[pos++] = 0x00; /* Audio status */ + dev->buffer[pos++] = 0x00; + dev->buffer[pos++] = 0x00; /* Subchannel length */ + dev->buffer[pos++] = cdb[3]; /* Format code */ if (alloc_length != 4) { - dev->buffer[1] = cdrom_get_current_subchannel(dev->drv, &dev->buffer[4], msf); + cdrom_get_current_subchannel(dev->drv, &dev->buffer[4], msf); + dev->buffer[2] = alloc_length - 4; } - switch (dev->drv->cd_status) { - case CD_STATUS_PLAYING: - dev->buffer[1] = 0x11; - break; - case CD_STATUS_PAUSED: - dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x15 : 0x12; - break; - case CD_STATUS_DATA_ONLY: - dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x00 : 0x15; - break; - default: - dev->buffer[1] = (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) ? 0x00 : 0x13; - break; - } + dev->buffer[1] = cdrom_get_current_status(dev->drv); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[1]); - } + scsi_cdrom_log(dev->log, "Audio Status = %02x\n", dev->buffer[1]); - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + len = MIN(len, max_len); + scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - - case 0xC6: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_TRACK_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - - msf = 3; - if ((cdb[5] != 1) || (cdb[8] != 1)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = cdb[4]; - - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - - /* In this case, len is unused so just pass a fixed value of 1 intead. */ - ret = cdrom_audio_play(dev->drv, pos, 1 /*len*/, msf); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - case CDROM_TYPE_CHINON_CDS431_H42: /*GPCMD_STOP_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - len = 10; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); - - memset(dev->buffer, 0, len); - dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xDD: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_READ_SUBCODEQ_PLAYING_STATUS_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - len = 10; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); - - memset(dev->buffer, 0, len); - dev->buffer[0] = cdrom_get_current_subcodeq_playstatus(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; + scsi_cdrom_data_command_finish(dev, len, len, len, 0); } break; @@ -3010,43 +3122,37 @@ begin: scsi_cdrom_buf_alloc(dev, alloc_length); - if ((cdb[7] < 0xc0) && (dev->drv->cdrom_capacity <= CD_MAX_SECTORS)) { - scsi_cdrom_incompatible_format(dev); - scsi_cdrom_buf_free(dev); - return; - } + if ((cdb[7] < 0xc0) && (dev->drv->cd_status != CD_STATUS_DVD)) + scsi_cdrom_incompatible_format(dev, cdb[7]); + else { + memset(dev->buffer, 0, alloc_length); - memset(dev->buffer, 0, alloc_length); + if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { + uint32_t info = 0x00000000; - if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { - if (cdb[1] == 0) { - format = cdb[7]; - ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, dev->buffer); - dev->buffer[0] = (ret >> 8); - dev->buffer[1] = (ret & 0xff); - dev->buffer[2] = dev->buffer[3] = 0x00; - if (ret) { - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, - alloc_length, 0); - } else - scsi_cdrom_buf_free(dev); - return; - } - } else { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - break; + if (cdb[1] == 0) { + ret = cdrom_read_dvd_structure(dev->drv, cdb[6], cdb[7], dev->buffer, &info); + if (ret > 0) { + dev->buffer[0] = (ret >> 8); + dev->buffer[1] = (ret & 0xff); + dev->buffer[2] = dev->buffer[3] = 0x00; - case 0x26: - if (dev->drv->type == CDROM_TYPE_CHINON_CDS431_H42) { /*GPCMD_UNKNOWN_CHINON*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - } else { - scsi_cdrom_illegal_opcode(dev); + scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + scsi_cdrom_data_command_finish(dev, alloc_length, + alloc_length, + alloc_length, 0); + } else if (ret < 0) + scsi_cdrom_error_common(dev, (ret >> 16) & 0xff, + (ret >> 8) & 0xff, ret & 0xff, info); + else { + scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * CDROM_TIME; + scsi_cdrom_set_callback(dev); + } + } + } else + scsi_cdrom_invalid_field(dev, cdb[7]); } break; @@ -3058,8 +3164,10 @@ begin: scsi_cdrom_stop(sc); break; case 1: /* Start the disc and read the TOC. */ - /* This makes no sense under emulation as this would do - absolutely nothing, so just break. */ + /* + This makes no sense under emulation as this would do + absolutely nothing, so just break. + */ break; case 2: /* Eject the disc if possible. */ scsi_cdrom_stop(sc); @@ -3076,80 +3184,6 @@ begin: scsi_cdrom_command_complete(dev); break; - case 0xC4: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_HEADER_MATSUSHITA*/ - cdb[0] = GPCMD_READ_HEADER; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAYBACK_STATUS_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - - scsi_cdrom_buf_alloc(dev, 18); - - len = 18; - - memset(dev->buffer, 0, 18); - dev->buffer[0] = 0x00; /*Reserved*/ - dev->buffer[1] = 0x00; /*Reserved*/ - dev->buffer[2] = 0x00; /*Audio Status data length*/ - dev->buffer[3] = 0x00; /*Audio Status data length*/ - dev->buffer[4] = cdrom_get_audio_status_sony(dev->drv, &dev->buffer[6], msf || dev->drv->sony_msf); /*Audio status*/ - dev->buffer[5] = 0x00; - - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); - - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_CADDY_EJECT_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xDC: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_CADDY_EJECT_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - cdrom_eject(dev->id); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - case GPCMD_INQUIRY: scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); @@ -3163,11 +3197,15 @@ begin: preamble_len = 4; size_idx = 3; - dev->buffer[idx++] = 5; - dev->buffer[idx++] = cdb[2]; - dev->buffer[idx++] = 0; + if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) + dev->buffer[idx++] = 0x7f; /* No physical device on this LUN */ + else + dev->buffer[idx++] = 0x05; /* CD-ROM */ - idx++; + dev->buffer[idx++] = cdb[2]; + + dev->buffer[idx++] = 0x00; + dev->buffer[idx++] = 0x00; switch (cdb[2]) { case 0x00: @@ -3176,7 +3214,7 @@ begin: break; case 0x83: if (idx + 24 > max_len) { - scsi_cdrom_data_phase_error(dev); + scsi_cdrom_data_phase_error(dev, idx + 24); scsi_cdrom_buf_free(dev); return; } @@ -3184,37 +3222,33 @@ begin: dev->buffer[idx++] = 0x02; dev->buffer[idx++] = 0x00; dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 20; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ + dev->buffer[idx++] = 0x14; + ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ idx += 20; if (idx + 72 > cdb[4]) goto atapi_out; + dev->buffer[idx++] = 0x02; dev->buffer[idx++] = 0x01; dev->buffer[idx++] = 0x00; - dev->buffer[idx++] = 68; - - if (dev->drv->type == CDROM_TYPE_86BOX_100) - ide_padstr8(dev->buffer + idx, 8, EMU_NAME); /* Vendor */ - else - ide_padstr8(dev->buffer + idx, 8, cdrom_drive_types[dev->drv->type].vendor); /* Vendor */ + dev->buffer[idx++] = 34; + ide_padstr8(dev->buffer + idx, 8, + cdrom_get_vendor(dev->drv->type)); /* Vendor */ idx += 8; - if (dev->drv->type == CDROM_TYPE_86BOX_100) - ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ - else - ide_padstr8(dev->buffer + idx, 40, cdrom_drive_types[dev->drv->type].model); /* Product */ + cdrom_get_model(dev->drv->type, model, dev->id); + ide_padstr8(dev->buffer + idx, 16, model); /* Product */ + idx += 16; - idx += 40; - ide_padstr8(dev->buffer + idx, 20, "53R141"); /* Serial */ - idx += 20; + ide_padstr8(dev->buffer + idx, 10, "53R141"); /* Serial */ + idx += 10; break; default: - scsi_cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - scsi_cdrom_invalid_field(dev); + scsi_cdrom_log(dev->log, "INQUIRY: Invalid page: %02X\n", cdb[2]); + scsi_cdrom_invalid_field(dev, cdb[2]); scsi_cdrom_buf_free(dev); return; } @@ -3224,106 +3258,46 @@ begin: memset(dev->buffer, 0, 8); if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) - dev->buffer[0] = 0x7f; /*No physical device on this LUN*/ + dev->buffer[0] = 0x7f; /* No physical device on this LUN */ else - dev->buffer[0] = 5; /*CD-ROM*/ - dev->buffer[1] = 0x80; /*Removable*/ + dev->buffer[0] = 0x05; /* CD-ROM */ + + dev->buffer[1] = 0x80; /* Removable */ if (dev->drv->bus_type == CDROM_BUS_SCSI) { - dev->buffer[3] = 0x02; - switch (dev->drv->type) { - case CDROM_TYPE_CHINON_CDS431_H42: - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_MATSHITA_501_10b: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEAC_CD50_100: - case CDROM_TYPE_TEAC_R55S_10R: - case CDROM_TYPE_TEXEL_DMXX24_100: - dev->buffer[2] = 0x00; - dev->buffer[3] = 0x01; /*SCSI-1 compliant*/ - break; - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - dev->buffer[3] = 0x00; /*SCSI unknown version per NEC manuals*/ - break; - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - dev->buffer[2] = 0x01; - dev->buffer[3] = 0x01; /*SCSI-1 compliant*/ - break; - default: - dev->buffer[2] = 0x02; /*SCSI-2 compliant*/ - break; - } + dev->buffer[3] = cdrom_get_scsi_std(dev->drv->type); + + if (!strcmp(cdrom_get_vendor(dev->drv->type), "TOSHIBA")) + /* Linked Command and Relative Addressing supported */ + dev->buffer[7] = 0x88; } else { dev->buffer[2] = 0x00; dev->buffer[3] = 0x21; } - dev->buffer[4] = 31; - if (dev->drv->bus_type == CDROM_BUS_SCSI) { - switch (dev->drv->type) { - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - dev->buffer[4] = 91; /* Always 91 on Toshiba SCSI-1 (or SCSI-2) CD-ROM drives from 1989-1990*/ - dev->buffer[7] = 0x88; /* Linked Command and Relative Addressing supported */ - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: - dev->buffer[4] = 42; - break; - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - break; - default: - dev->buffer[6] = 0x01; /* 16-bit transfers supported */ - dev->buffer[7] = 0x20; /* Wide bus supported */ - break; - } + if (cdrom_is_generic(dev->drv->type)) { + dev->buffer[6] = 0x01; /* 16-bit transfers supported */ + dev->buffer[7] = 0x20; /* Wide bus supported */ } - if (dev->drv->type == CDROM_TYPE_86BOX_100) { - ide_padstr8(dev->buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->buffer + 32, 4, EMU_VERSION_EX); /* Revision */ - } else { - ide_padstr8(dev->buffer + 8, 8, cdrom_drive_types[dev->drv->type].vendor); /* Vendor */ - ide_padstr8(dev->buffer + 16, 16, cdrom_drive_types[dev->drv->type].model); /* Product */ - ide_padstr8(dev->buffer + 32, 4, cdrom_drive_types[dev->drv->type].revision); /* Revision */ - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { - dev->buffer[36] = 0x20; - ide_padstr8(dev->buffer + 37, 10, "1991/01/01"); /* Date */ - } + ide_padstr8(dev->buffer + 8, 8, + cdrom_get_vendor(dev->drv->type)); /* Vendor */ + cdrom_get_model(dev->drv->type, model, dev->id); + ide_padstr8(dev->buffer + 16, 16, model); /* Product */ + ide_padstr8(dev->buffer + 32, 4, + cdrom_get_revision(dev->drv->type)); /* Revision */ + + if (cdrom_has_date(dev->drv->type)) { + dev->buffer[36] = 0x20; + ide_padstr8(dev->buffer + 37, 10, "1991/01/01"); /* Date */ } - idx = 36; - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) - idx = 47; - else { - switch (dev->drv->type) { - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - idx = 96; - break; - default: - if (max_len == 96) { - dev->buffer[4] = 91; - idx = 96; - } - break; - } - } + if (max_len == 96) + idx = 96; + else + idx = cdrom_get_inquiry_len(dev->drv->bus_type); + + dev->buffer[4] = idx - 5; } atapi_out: @@ -3332,17 +3306,13 @@ atapi_out: len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_log("Inquiry = %d, max = %d, BufLen = %d.\n", len, max_len, *BufLen); + scsi_cdrom_set_buf_len(dev, BufLen, &max_len); + scsi_cdrom_log(dev->log, "Inquiry = %d, max = %d, BufLen = %d.\n", len, + max_len, *BufLen); scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); break; - case 0x0D: /*GPCMD_NO_OPERATION_TOSHIBA and GPCMD_NO_OPERATION_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - case GPCMD_PREVENT_REMOVAL: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); scsi_cdrom_command_complete(dev); @@ -3355,154 +3325,6 @@ atapi_out: scsi_cdrom_command_complete(dev); break; - case 0xC3: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_TOC_MATSUSHITA*/ - cdb[0] = GPCMD_READ_TOC_PMA_ATIP; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_HEADER_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; - - alloc_length = ((cdb[7] << 8) | cdb[8]); - scsi_cdrom_buf_alloc(dev, 4); - - dev->sector_len = 1; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - real_pos = cdrom_lba_to_msf_accurate(dev->sector_pos); - dev->buffer[0] = ((real_pos >> 16) & 0xff); - dev->buffer[1] = ((real_pos >> 8) & 0xff); - dev->buffer[2] = real_pos & 0xff; - dev->buffer[3] = 1; /*2048 bytes user data*/ - - len = 4; - len = MIN(len, alloc_length); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - return; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_SET_STOP_TIME_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xDB: - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: /*GPCMD_SET_STOP_TIME_NEC*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC2: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_READ_SUBCHANNEL_MATSUSHITA*/ - cdb[0] = GPCMD_READ_SUBCHANNEL; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_READ_SUBCHANNEL_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - dev->sony_vendor = 1; - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - msf = dev->ms_pages_saved_sony.pages[GPMODE_CDROM_PAGE_SONY][2] & 0x01; - - scsi_cdrom_log("CD-ROM %i: Getting sub-channel type (%s), code-q = %02x\n", dev->id, msf ? "MSF" : "LBA", cdb[2] & 0x40); - - if (cdb[2] & 0x40) { - scsi_cdrom_buf_alloc(dev, 9); - memset(dev->buffer, 0, 9); - len = 9; - cdrom_get_current_subchannel_sony(dev->drv, dev->buffer, msf || dev->drv->sony_msf); - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - } else { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - } - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_READ_SUBCODEQ_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - alloc_length = cdb[1] & 0x1f; - len = 9; - - if (!dev->drv->ops) { - scsi_cdrom_not_ready(dev); - return; - } - - if (!alloc_length) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Subcode Q All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - scsi_cdrom_buf_alloc(dev, len); - len = MIN(len, alloc_length); - - memset(dev->buffer, 0, len); - cdrom_get_current_subcodeq(dev->drv, &dev->buffer[1]); - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[0]); - - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - break; - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: /*GPCMD_STILL_TOSHIBA*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, 0x00); - dev->drv->audio_op = 0x01; - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - case GPCMD_SEEK_6: case GPCMD_SEEK_10: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); @@ -3518,27 +3340,15 @@ atapi_out: default: break; } + dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos)); - if (cdb[0] == GPCMD_SEEK_10) { - switch (dev->drv->type) { - case CDROM_TYPE_NEC_25_10a: - case CDROM_TYPE_NEC_38_103: - case CDROM_TYPE_NEC_75_103: - case CDROM_TYPE_NEC_77_106: - case CDROM_TYPE_NEC_211_100: - case CDROM_TYPE_NEC_464_105: - case CDROM_TYPE_TOSHIBA_XM_3433: - case CDROM_TYPE_TOSHIBA_XM3201B_3232: - case CDROM_TYPE_TOSHIBA_XM3301TA_0272: - case CDROM_TYPE_TOSHIBA_XM5701TA_3136: - case CDROM_TYPE_TOSHIBA_SDM1401_1008: - cdrom_seek(dev->drv, pos, cdb[9] & 0xc0); - break; - default: - cdrom_seek(dev->drv, pos, 0); - break; - } - } else + + /* Stop the audio playing. */ + cdrom_stop(dev->drv); + + if (dev->use_cdb_9 && (cdb[0] == GPCMD_SEEK_10)) + cdrom_seek(dev->drv, pos, cdb[9] & 0xc0); + else cdrom_seek(dev->drv, pos, 0); scsi_cdrom_command_complete(dev); @@ -3558,6 +3368,8 @@ atapi_out: dev->buffer[6] = 8; len = 8; + scsi_cdrom_log(dev->log, "CD-ROM Capacity: %08X\n", + dev->drv->cdrom_capacity - 1); scsi_cdrom_set_buf_len(dev, BufLen, &len); scsi_cdrom_data_command_finish(dev, len, len, len, 0); @@ -3566,7 +3378,7 @@ atapi_out: case GPCMD_STOP_PLAY_SCAN: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if (dev->drv->cd_status <= CD_STATUS_DATA_ONLY) { + if (dev->drv->cd_status <= CD_STATUS_DVD) { scsi_cdrom_illegal_mode(dev); break; } @@ -3575,232 +3387,12 @@ atapi_out: scsi_cdrom_command_complete(dev); break; - case 0xC5: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_10; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PAUSE_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - dev->sony_vendor = 1; - cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC8: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_TRACK_INDEX_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_INDEX; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAY_AUDIO_SONY*/ - cdb[0] = GPCMD_PLAY_AUDIO_10; - dev->current_cdb[0] = cdb[0]; - dev->sony_vendor = 1; - goto begin; - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_AUDIO_TRACK_SEARCH_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_track_search_pioneer(dev->drv, pos, cdb[1] & 1); - dev->drv->audio_op = (cdb[1] & 1) ? 0x03 : 0x02; - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xC9: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_10; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: /*GPCMD_PLAYBACK_CONTROL_SONY*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); - dev->sony_vendor = 1; - - len = (cdb[7] << 8) | cdb[8]; - if (!len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: PlayBack Control Sony All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - scsi_cdrom_buf_alloc(dev, 65536); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 1); - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_PLAY_AUDIO_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - if ((dev->drv->image_path[0] == 0x00) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); - break; - } - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - ret = cdrom_audio_play_pioneer(dev->drv, pos); - - if (ret) - scsi_cdrom_command_complete(dev); - else - scsi_cdrom_illegal_mode(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xCA: - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_PAUSE_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - cdrom_audio_pause_resume(dev->drv, !(cdb[1] & 0x10)); - scsi_cdrom_command_complete(dev); - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xCB: - switch (dev->drv->type) { - case CDROM_TYPE_MATSHITA_501_10b: /*GPCMD_PAUSE_RESUME_MATSUSHITA*/ - cdb[0] = GPCMD_PAUSE_RESUME; - dev->current_cdb[0] = cdb[0]; - goto begin; - break; - case CDROM_TYPE_PIONEER_DRM604X_2403: /*GPCMD_STOP_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_stop(sc); - scsi_cdrom_command_complete(dev); - break; - default: - scsi_cdrom_illegal_opcode(dev); - break; - } - break; - - case 0xCC: - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_PLAYBACK_STATUS_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - max_len = cdb[7]; - max_len <<= 8; - max_len |= cdb[8]; - - scsi_cdrom_buf_alloc(dev, 6); - - len = 6; - - memset(dev->buffer, 0, 6); - dev->buffer[0] = cdrom_get_audio_status_pioneer(dev->drv, &dev->buffer[1]); /*Audio status*/ - - scsi_cdrom_log("Audio Status = %02x\n", dev->buffer[4]); - - len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_data_command_finish(dev, len, len, len, 0); - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xE0: - if (dev->drv->type == CDROM_TYPE_PIONEER_DRM604X_2403) { /*GPCMD_DRIVE_STATUS_PIONEER*/ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); - - len = (cdb[9] | (cdb[8] << 8)); - scsi_cdrom_buf_alloc(dev, 65536); - - if (!(scsi_cdrom_drive_status_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); - return; - } - - if (!len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_log("CD-ROM %i: Drive Status All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * CDROM_TIME; - scsi_cdrom_set_callback(dev); - break; - } - - memset(dev->buffer, 0, len); - alloc_length = len; - - len = scsi_cdrom_drive_status(dev, dev->buffer, 0, cdb[2]); - len = MIN(len, alloc_length); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); - - scsi_cdrom_log("CD-ROM %i: Reading drive status page: %02X...\n", dev->id, cdb[2]); - - scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); - return; - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xE5: - if (dev->drv->type == CDROM_TYPE_MATSHITA_501_10b) { /*GPCMD_PLAY_AUDIO_12_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_12; - dev->current_cdb[0] = cdb[0]; - goto begin; - } else { - scsi_cdrom_illegal_opcode(dev); - } - break; - - case 0xE9: - if (dev->drv->type == CDROM_TYPE_MATSHITA_501_10b) { /*GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12_MATSUSHITA*/ - cdb[0] = GPCMD_PLAY_AUDIO_TRACK_RELATIVE_12; - dev->current_cdb[0] = cdb[0]; - goto begin; - } - fallthrough; default: - scsi_cdrom_illegal_opcode(dev); + scsi_cdrom_illegal_opcode(dev, cdb[0]); break; } - /* scsi_cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", dev->tf->phase, + /* scsi_cdrom_log(dev->log, "Phase: %02X, request length: %i\n", dev->tf->phase, dev->tf->request_length); */ if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) @@ -3824,15 +3416,14 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) uint16_t block_desc_len; uint16_t pos; uint16_t param_list_len; - uint16_t i = 0; - - uint8_t error = 0; - uint8_t page; - uint8_t page_len; - uint8_t hdr_len; - uint8_t val; - uint8_t old_val; - uint8_t ch; + uint16_t i; + uint8_t error = 0; + uint8_t page; + uint8_t page_len; + uint8_t hdr_len; + uint8_t val; + uint8_t old_val; + uint8_t ch; switch (dev->current_cdb[0]) { case GPCMD_MODE_SELECT_6: @@ -3852,6 +3443,8 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) block_desc_len = dev->buffer[2]; block_desc_len <<= 8; block_desc_len |= dev->buffer[3]; + scsi_cdrom_log(dev->log, "BlockDescLen (6): %d, " + "ParamListLen (6): %d\n", block_desc_len, param_list_len); } else { block_desc_len = dev->buffer[6]; block_desc_len <<= 8; @@ -3860,11 +3453,31 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) } else block_desc_len = 0; + if (block_desc_len >= 8) { + pos = hdr_len + 5; + + dev->drv->sector_size = (dev->drv->sector_size & 0x0000ffff) | + (dev->buffer[pos++] << 16); + dev->drv->sector_size = (dev->drv->sector_size & 0x00ff00ff) | + (dev->buffer[pos++] << 8); + dev->drv->sector_size = (dev->drv->sector_size & 0x00ffff00) | + (dev->buffer[pos]); + scsi_cdrom_log(dev->log, "Sector size now %i bytes\n", + dev->drv->sector_size); + + error |= scsi_cdrom_update_sector_flags(dev); + } + pos = hdr_len + block_desc_len; - while (1) { +#ifdef ENABLE_SCSI_CDROM_LOG + for (uint16_t j = 0; j < pos; j++) + scsi_cdrom_log(dev->log, "Buffer Mode Select, pos=%d, data=%02x.\n", + j, dev->buffer[j]); +#endif + if (!error) while (1) { if (pos >= param_list_len) { - scsi_cdrom_log("CD-ROM %i: Buffer has only block descriptor\n", dev->id); + scsi_cdrom_log(dev->log, "Buffer has only block descriptor\n"); break; } @@ -3873,70 +3486,39 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) pos += 2; - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - if (!(scsi_cdrom_mode_sense_page_flags_sony & (1LL << ((uint64_t) page)))) { - scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); - error |= 1; - } else { - for (i = 0; i < page_len; i++) { - ch = scsi_cdrom_mode_sense_pages_changeable_sony.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved_sony.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved_sony.pages[page][i + 2] = val; - else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); - error |= 1; - } - } + if (dev->is_sony && (page == 0x08) && (page_len == 0x02)) + dev->drv->sony_msf = dev->buffer[pos] & 0x01; + + if (!(dev->ms_page_flags & (1LL << ((uint64_t) page)))) { + scsi_cdrom_log(dev->log, "Unimplemented page %02X\n", page); + error |= 1; + } else { + for (i = 0; i < page_len; i++) { + uint8_t pg = page; + + if (dev->is_sony && (page == GPMODE_CDROM_AUDIO_PAGE_SONY) && (i >= 6) && (i <= 13)) + pg = GPMODE_CDROM_AUDIO_PAGE; + + ch = dev->ms_pages_changeable.pages[pg][i + 2]; + val = dev->buffer[pos + i]; + old_val = dev->ms_pages_saved.pages[pg][i + 2]; + if (val != old_val) { + if (ch) + dev->ms_pages_saved.pages[pg][i + 2] = val; + else { + scsi_cdrom_log(dev->log, "Unchangeable value on position " + "%02X on page %02X\n", i + 2, page); + scsi_cdrom_invalid_field_pl(dev, val); + error |= 1; } } - break; - default: - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { - scsi_cdrom_log("CD-ROM %i: Unimplemented page %02X\n", dev->id, page); - error |= 1; - } else { - for (i = 0; i < page_len; i++) { - ch = scsi_cdrom_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else { - scsi_cdrom_log("CD-ROM %i: Unchangeable value on position %02X on page %02X\n", dev->id, i + 2, page); - error |= 1; - } - } - } - } - break; + } } pos += page_len; - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - val = scsi_cdrom_mode_sense_pages_default_sony_scsi.pages[page][0] & 0x80; - break; - default: - if (dev->drv->bus_type == CDROM_BUS_SCSI) - val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; - else - val = scsi_cdrom_mode_sense_pages_default.pages[page][0] & 0x80; - break; - } + val = dev->ms_pages_default.pages[page][0] & 0x80; + if (dev->do_page_save && val) scsi_cdrom_mode_sense_save(dev); @@ -3945,24 +3527,20 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) } if (error) { - scsi_cdrom_invalid_field_pl(dev); scsi_cdrom_buf_free(dev); return 0; } break; - case 0xC9: - switch (dev->drv->type) { - case CDROM_TYPE_DEC_RRD45_0436: - case CDROM_TYPE_SONY_CDU541_10i: - case CDROM_TYPE_SONY_CDU561_18k: - case CDROM_TYPE_SONY_CDU76S_100: - case CDROM_TYPE_TEXEL_DMXX24_100: - for (i = 0; i < 18; i++) { - dev->ms_pages_saved_sony.pages[GPMODE_CDROM_AUDIO_PAGE_SONY][i] = dev->buffer[i]; - } - break; - default: - break; + case 0xc9: + if (dev->is_sony) { + for (i = 0; i < 18; i++) { + if ((i >= 8) && (i <= 15)) + dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE][i] = + dev->buffer[i]; + else + dev->ms_pages_saved.pages[GPMODE_CDROM_AUDIO_PAGE_SONY][i] = + dev->buffer[i]; + } } break; @@ -3979,30 +3557,31 @@ scsi_cdrom_close(void *priv) { scsi_cdrom_t *dev = (scsi_cdrom_t *) priv; - if (dev->tf) - free(dev->tf); + if (dev != NULL) { + if (dev->tf != NULL) + free(dev->tf); + + if (dev->log != NULL) { + scsi_cdrom_log(dev->log, "Log closed\n"); + + log_close(dev->log); + dev->log = NULL; + } - if (dev) free(dev); + } } static int -scsi_cdrom_get_max(int ide_has_dma, int type) +scsi_cdrom_get_max(const ide_t *ide, UNUSED(const int ide_has_dma), const int type) { - int ret; + const scsi_cdrom_t *dev = (scsi_cdrom_t *) ide->sc; + int ret; switch (type) { - case TYPE_PIO: - ret = ide_has_dma ? 4 : 0; - break; - case TYPE_SDMA: - ret = ide_has_dma ? 2 : -1; - break; - case TYPE_MDMA: - ret = ide_has_dma ? 2 : -1; - break; - case TYPE_UDMA: - ret = ide_has_dma ? 5 : -1; + case TYPE_PIO: case TYPE_SDMA: + case TYPE_MDMA: case TYPE_UDMA: + ret = cdrom_get_transfer_max(dev->drv->type, type); break; default: ret = -1; @@ -4013,16 +3592,18 @@ scsi_cdrom_get_max(int ide_has_dma, int type) } static int -scsi_cdrom_get_timings(int ide_has_dma, int type) +scsi_cdrom_get_timings(const ide_t *ide, UNUSED(const int ide_has_dma), const int type) { - int ret; + const scsi_cdrom_t *dev = (scsi_cdrom_t *) ide->sc; + int has_dma = cdrom_has_dma(dev->drv->type); + int ret; switch (type) { case TIMINGS_DMA: - ret = ide_has_dma ? 120 : 0; + ret = has_dma ? 120 : 0; break; case TIMINGS_PIO: - ret = ide_has_dma ? 120 : 0; + ret = has_dma ? 120 : 0; break; case TIMINGS_PIO_FC: ret = 0; @@ -4039,114 +3620,29 @@ scsi_cdrom_get_timings(int ide_has_dma, int type) * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command */ static void -scsi_cdrom_identify(ide_t *ide, int ide_has_dma) +scsi_cdrom_identify(const ide_t *ide, UNUSED(const int ide_has_dma)) { - const scsi_cdrom_t *dev; - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + const scsi_cdrom_t *dev = (scsi_cdrom_t *) ide->sc; + char model[2048] = { 0 }; + const int has_dma = cdrom_has_dma(dev->drv->type); - dev = (scsi_cdrom_t *) ide->sc; + cdrom_get_identify_model(dev->drv->type, model, dev->id); - device_identify[7] = dev->id + 0x30; - scsi_cdrom_log("ATAPI Identify: %s\n", device_identify); + scsi_cdrom_log(dev->log, "ATAPI Identify: %s\n", model); - if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) /*NEC only*/ + if (dev->drv->is_early) ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (1 << 5); /* ATAPI device, CD-ROM drive, removable media, interrupt DRQ */ else ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - if (dev->drv->type == CDROM_TYPE_86BOX_100) { - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - } else { - switch (dev->drv->type) { - case CDROM_TYPE_AZT_CDA46802I_115: - ide_padstr((char *) (ide->buffer + 23), "1.15 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "AZT CDA46802I ", 40); /* Model */ - break; - case CDROM_TYPE_BTC_BCD36XH_U10: - ide_padstr((char *) (ide->buffer + 23), "U1.0 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "BTC CD-ROM BCD36XH ", 40); /* Model */ - break; - case CDROM_TYPE_GOLDSTAR_CRD_8160B_314: - ide_padstr((char *) (ide->buffer + 23), "3.14 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "GOLDSTAR CRD-8160B ", 40); /* Model */ - break; - case CDROM_TYPE_HITACHI_CDR_8130_0020: - ide_padstr((char *) (ide->buffer + 23), "0020 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "HITACHI CDR-8130 ", 40); /* Model */ - break; - case CDROM_TYPE_KENWOOD_UCR_421_208E: - ide_padstr((char *) (ide->buffer + 23), "208E ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "KENWOOD CD-ROM UCR-421 ", 40); /* Model */ - break; - case CDROM_TYPE_MATSHITA_587_7S13: - ide_padstr((char *) (ide->buffer + 23), "7S13 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CD-ROM CR-587 ", 40); /* Model */ - break; - case CDROM_TYPE_MATSHITA_588_LS15: - ide_padstr((char *) (ide->buffer + 23), "LS15 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CD-ROM CR-588 ", 40); /* Model */ - break; - case CDROM_TYPE_MATSHITA_571_10e: - ide_padstr((char *) (ide->buffer + 23), "1.0e ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CR-571 ", 40); /* Model */ - break; - case CDROM_TYPE_MATSHITA_572_10j: - ide_padstr((char *) (ide->buffer + 23), "1.0j ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MATSHITA CR-572 ", 40); /* Model */ - break; - case CDROM_TYPE_MITSUMI_FX4820T_D02A: - ide_padstr((char *) (ide->buffer + 23), "D02A ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "MITSUMI CRMC-FX4820T ", 40); /* Model */ - break; - case CDROM_TYPE_NEC_260_100: - ide_padstr((char *) (ide->buffer + 23), ".100 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ - break; - case CDROM_TYPE_NEC_260_101: - ide_padstr((char *) (ide->buffer + 23), ".110 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ - break; - case CDROM_TYPE_NEC_273_420: - ide_padstr((char *) (ide->buffer + 23), "4.20 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:273 ", 40); /* Model */ - break; - case CDROM_TYPE_NEC_280_105: - ide_padstr((char *) (ide->buffer + 23), "1.05 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:280 ", 40); /* Model */ - break; - case CDROM_TYPE_NEC_280_308: - ide_padstr((char *) (ide->buffer + 23), "3.08 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:280 ", 40); /* Model */ - break; - case CDROM_TYPE_PHILIPS_PCA403CD_U31P: - ide_padstr((char *) (ide->buffer + 23), "U31P ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "PHILIPS CD-ROM PCA403CD ", 40); /* Model */ - break; - case CDROM_TYPE_SONY_CDU76_10i: - ide_padstr((char *) (ide->buffer + 23), "1.0i ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "SONY CD-ROM CDU76 ", 40); /* Model */ - break; - case CDROM_TYPE_SONY_CDU311_30h: - ide_padstr((char *) (ide->buffer + 23), "3.0h ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "SONY CD-ROM CDU311 ", 40); /* Model */ - break; - case CDROM_TYPE_TOSHIBA_5302TA_0305: - ide_padstr((char *) (ide->buffer + 23), "0305 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "TOSHIBA CD-ROM XM-5302TA ", 40); /* Model */ - break; - case CDROM_TYPE_TOSHIBA_5702B_TA70: - ide_padstr((char *) (ide->buffer + 23), "TA70 ", 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "TOSHIBA CD-ROM XM-5702B ", 40); /* Model */ - break; - } - } + ide_padstr((char *) (ide->buffer + 23), cdrom_get_revision(dev->drv->type), 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), model, 40); /* Model */ ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ - if (ide_has_dma) { + if (has_dma) { ide->buffer[71] = 30; ide->buffer[72] = 30; ide->buffer[80] = 0x7e; /*ATA-1 to ATA-6 supported*/ @@ -4155,14 +3651,11 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) } void -scsi_cdrom_drive_reset(int c) +scsi_cdrom_drive_reset(const int c) { cdrom_t *drv = &cdrom[c]; - scsi_cdrom_t *dev; - scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = drv->scsi_device_id & 0x0f; + const uint8_t scsi_bus = (drv->scsi_device_id >> 4) & 0x0f; + const uint8_t scsi_id = drv->scsi_device_id & 0x0f; uint8_t valid = 0; if (drv->bus_type == CDROM_BUS_SCSI) { @@ -4179,12 +3672,17 @@ scsi_cdrom_drive_reset(int c) if ((drv->bus_type == CDROM_BUS_ATAPI) && (drv->ide_channel > 7)) return; - if (!drv->priv) { - drv->priv = (scsi_cdrom_t *) malloc(sizeof(scsi_cdrom_t)); - memset(drv->priv, 0, sizeof(scsi_cdrom_t)); + if (drv->priv == NULL) { + drv->priv = (scsi_cdrom_t *) calloc(1, sizeof(scsi_cdrom_t)); + scsi_cdrom_t *dev = (scsi_cdrom_t *) drv->priv; + + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i SCSI ", c + 1); + dev->log = log_open(n); } - dev = (scsi_cdrom_t *) drv->priv; + scsi_cdrom_t *dev = (scsi_cdrom_t *) drv->priv; dev->id = c; dev->drv = drv; @@ -4196,53 +3694,107 @@ scsi_cdrom_drive_reset(int c) drv->get_channel = scsi_cdrom_get_channel; drv->close = scsi_cdrom_close; - if (drv->bus_type == CDROM_BUS_SCSI) { - valid = 1; + drv->sector_size = 2048; + (void) scsi_cdrom_update_sector_flags(dev); - if (!dev->tf) - dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); + if (drv->bus_type == CDROM_BUS_SCSI) { + char *vendor = cdrom_get_vendor(dev->drv->type); + + dev->ven_cmd = NULL; + memset(dev->ven_cmd_is_data, 0x00, sizeof(dev->ven_cmd_is_data)); + dev->is_sony = 0; + dev->use_cdb_9 = 0; + dev->ms_page_flags = scsi_cdrom_ms_page_flags_scsi; + dev->ms_pages_default = scsi_cdrom_ms_pages_default_scsi; + dev->ms_pages_changeable = scsi_cdrom_ms_pages_changeable_scsi; + + if (!strcmp(vendor, "CHINON")) + dev->ven_cmd = scsi_cdrom_command_chinon; + else if (!strcmp(vendor, "DEC") || !strcmp(vendor, "ShinaKen") || + !strcmp(vendor, "SONY") || !strcmp(vendor, "TEXEL")) { + dev->ven_cmd = scsi_cdrom_command_dec_sony_texel; + dev->ven_cmd_is_data[0xc0] = 1; + dev->ven_cmd_is_data[0xc1] = 1; + dev->ven_cmd_is_data[0xc2] = 1; + dev->ven_cmd_is_data[0xc3] = 1; + dev->is_sony = 1; + dev->ms_page_flags = scsi_cdrom_ms_page_flags_sony_scsi; + dev->ms_pages_default = scsi_cdrom_ms_pages_default_sony_scsi; + dev->ms_pages_changeable = scsi_cdrom_ms_pages_changeable_sony_scsi; + } else if (!strcmp(vendor, "MATSHITA")) + dev->ven_cmd = scsi_cdrom_command_matsushita; + else if (!strcmp(vendor, "NEC")) { + dev->ven_cmd = scsi_cdrom_command_nec; + dev->ven_cmd_is_data[0xdd] = 1; + dev->ven_cmd_is_data[0xde] = 1; + } else if (!strcmp(vendor, "PIONEER")) { + dev->ven_cmd = scsi_cdrom_command_pioneer; + dev->ven_cmd_is_data[0xc1] = 1; + dev->ven_cmd_is_data[0xc2] = 1; + dev->ven_cmd_is_data[0xc3] = 1; + } else if (!strcmp(vendor, "TOSHIBA")) { + dev->ven_cmd = scsi_cdrom_command_toshiba; + dev->ven_cmd_is_data[0xc6] = 1; + dev->ven_cmd_is_data[0xc7] = 1; + dev->use_cdb_9 = 1; + } + + if (dev->tf == NULL) + dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); /* SCSI CD-ROM, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + scsi_device_t *sd = &scsi_devices[scsi_bus][scsi_id]; - sd->sc = (scsi_common_t *) dev; - sd->command = scsi_cdrom_command; - sd->request_sense = scsi_cdrom_request_sense_for_scsi; - sd->reset = scsi_cdrom_reset; - sd->phase_data_out = scsi_cdrom_phase_data_out; - sd->command_stop = scsi_cdrom_command_stop; - sd->type = SCSI_REMOVABLE_CDROM; + sd->sc = (scsi_common_t *) dev; + sd->command = scsi_cdrom_command; + sd->request_sense = scsi_cdrom_request_sense_for_scsi; + sd->reset = scsi_cdrom_reset; + sd->phase_data_out = scsi_cdrom_phase_data_out; + sd->command_stop = scsi_cdrom_command_stop; + sd->type = SCSI_REMOVABLE_CDROM; - scsi_cdrom_log("SCSI CD-ROM drive %i attached to SCSI ID %i\n", c, cdrom[c].scsi_device_id); + valid = 1; + + scsi_cdrom_log(dev->log, "SCSI CD-ROM drive %i attached to SCSI ID %i\n", + c, cdrom[c].scsi_device_id); } else if (drv->bus_type == CDROM_BUS_ATAPI) { /* ATAPI CD-ROM, attach to the IDE bus. */ - id = ide_get_drive(drv->ide_channel); - /* If the IDE channel is initialized, we attach to it, - otherwise, we do nothing - it's going to be a drive - that's not attached to anything. */ - if (id) { - valid = 1; + ide_t *id = ide_get_drive(drv->ide_channel); - id->sc = (scsi_common_t *) dev; - dev->tf = id->tf; - if ((dev->drv->type == CDROM_TYPE_NEC_260_100) || (dev->drv->type == CDROM_TYPE_NEC_260_101)) - IDE_ATAPI_IS_EARLY = 1; - id->get_max = scsi_cdrom_get_max; - id->get_timings = scsi_cdrom_get_timings; - id->identify = scsi_cdrom_identify; - id->stop = scsi_cdrom_stop; - id->packet_command = scsi_cdrom_command; - id->device_reset = scsi_cdrom_reset; - id->phase_data_out = scsi_cdrom_phase_data_out; - id->command_stop = scsi_cdrom_command_stop; - id->bus_master_error = scsi_cdrom_bus_master_error; - id->interrupt_drq = ((dev->drv->type == CDROM_TYPE_NEC_260_100) || - (dev->drv->type == CDROM_TYPE_NEC_260_101)); + /* + If the IDE channel is initialized, we attach to it, otherwise, we do + nothing - it's going to be a drive that's not attached to anything. + */ + if (id) { + dev->ven_cmd = NULL; + memset(dev->ven_cmd_is_data, 0x00, sizeof(dev->ven_cmd_is_data)); + dev->is_sony = 0; + dev->use_cdb_9 = 0; + dev->ms_page_flags = scsi_cdrom_ms_page_flags; + dev->ms_pages_default = scsi_cdrom_ms_pages_default; + dev->ms_pages_changeable = scsi_cdrom_ms_pages_changeable; + + id->sc = (scsi_common_t *) dev; + dev->tf = id->tf; + IDE_ATAPI_IS_EARLY = dev->drv->is_early; + id->get_max = scsi_cdrom_get_max; + id->get_timings = scsi_cdrom_get_timings; + id->identify = scsi_cdrom_identify; + id->stop = scsi_cdrom_stop; + id->packet_command = scsi_cdrom_command; + id->device_reset = scsi_cdrom_reset; + id->phase_data_out = scsi_cdrom_phase_data_out; + id->command_stop = scsi_cdrom_command_stop; + id->bus_master_error = scsi_cdrom_bus_master_error; + id->interrupt_drq = dev->drv->is_early; + + valid = 1; ide_atapi_attach(id); } - scsi_cdrom_log("ATAPI CD-ROM drive %i attached to IDE channel %i\n", c, cdrom[c].ide_channel); + scsi_cdrom_log(dev->log, "ATAPI CD-ROM drive %i attached to IDE channel %i\n", + c, cdrom[c].ide_channel); } if (valid) diff --git a/src/scsi/scsi_device.c b/src/scsi/scsi_device.c index 4442b2680..33d3fa89a 100644 --- a/src/scsi/scsi_device.c +++ b/src/scsi/scsi_device.c @@ -16,10 +16,14 @@ * Copyright 2016-2018 Miran Grca. * Copyright 2017-2018 Fred N. van Kempen. */ +#include #include #include #include +#include +#include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/hdd.h> @@ -29,9 +33,29 @@ #include <86box/plat_unused.h> scsi_device_t scsi_devices[SCSI_BUS_MAX][SCSI_ID_MAX]; - +int scsi_command_length[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; uint8_t scsi_null_device_sense[18] = { 0x70, 0, SENSE_ILLEGAL_REQUEST, 0, 0, 0, 0, 0, 0, 0, 0, 0, ASC_INV_LUN, 0, 0, 0, 0, 0 }; +#define SET_BUS_STATE(scsi_bus, state) scsi_bus->bus_out = (scsi_bus->bus_out & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) + +#ifdef ENABLE_SCSI_DEVICE_LOG +int scsi_device_do_log = ENABLE_SCSI_DEVICE_LOG; + +static void +scsi_device_log(const char *fmt, ...) +{ + va_list ap; + + if (scsi_device_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define scsi_device_log(fmt, ...) +#endif + static uint8_t scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb) { @@ -189,3 +213,311 @@ scsi_device_init(void) } } } + +int +scsi_device_get_id(uint8_t data) +{ + for (uint8_t c = 0; c < SCSI_ID_MAX; c++) { + if (data & (1 << c)) + return c; + } + + return -1; +} + + +static int +scsi_device_get_msg(uint8_t *msgp, int len) +{ + uint8_t msg = msgp[0]; + if ((msg == 0) || ((msg >= 0x02) && (msg <= 0x1f)) || (msg >= 0x80)) + return 1; + + if ((msg >= 0x20) && (msg <= 0x2f)) + return 2; + + if (len < 2) + return 3; + + return msgp[1]; +} + +int +scsi_bus_read(scsi_bus_t *scsi_bus) +{ + scsi_device_t *dev; + int phase; + + /*Wait processes to handle bus requests*/ + if (scsi_bus->clear_req) { + scsi_bus->clear_req--; + if (!scsi_bus->clear_req) { + scsi_device_log("Prelude to command data\n"); + SET_BUS_STATE(scsi_bus, scsi_bus->bus_phase); + scsi_bus->bus_out |= BUS_REQ; + } + } + + if (scsi_bus->wait_data) { + scsi_bus->wait_data--; + if (!scsi_bus->wait_data) { + dev = &scsi_devices[scsi_bus->bus_device][scsi_bus->target_id]; + SET_BUS_STATE(scsi_bus, scsi_bus->bus_phase); + phase = scsi_bus->bus_out & SCSI_PHASE_MESSAGE_IN; + + switch (phase) { + case SCSI_PHASE_DATA_IN: + scsi_device_log("DataIn.\n"); + scsi_bus->state = STATE_DATAIN; + if ((dev->sc != NULL) && (dev->sc->temp_buffer != NULL)) + scsi_bus->data = dev->sc->temp_buffer[scsi_bus->data_pos++]; + + scsi_bus->bus_out = (scsi_bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(scsi_bus->data) | BUS_DBP; + break; + case SCSI_PHASE_DATA_OUT: + if (scsi_bus->bus_phase & BUS_IDLE) { + scsi_device_log("Bus Idle.\n"); + scsi_bus->state = STATE_IDLE; + scsi_bus->bus_out &= ~BUS_BSY; + scsi_bus->timer(scsi_bus->priv, 0.0); + } else { + scsi_device_log("DataOut.\n"); + scsi_bus->state = STATE_DATAOUT; + } + break; + case SCSI_PHASE_STATUS: + scsi_device_log("Status.\n"); + scsi_bus->bus_out |= BUS_REQ; + scsi_bus->state = STATE_STATUS; + scsi_bus->bus_out = (scsi_bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP; + break; + case SCSI_PHASE_MESSAGE_IN: + scsi_device_log("Message In.\n"); + scsi_bus->state = STATE_MESSAGEIN; + scsi_bus->bus_out = (scsi_bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; + break; + case SCSI_PHASE_MESSAGE_OUT: + scsi_device_log("Message Out.\n"); + scsi_bus->bus_out |= BUS_REQ; + scsi_bus->state = STATE_MESSAGEOUT; + scsi_bus->bus_out = (scsi_bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(scsi_bus->target_id >> 5) | BUS_DBP; + break; + default: + break; + } + } + } + + if (scsi_bus->wait_complete) { + scsi_bus->wait_complete--; + if (!scsi_bus->wait_complete) + scsi_bus->bus_out |= BUS_REQ; + } + + return scsi_bus->bus_out; +} + +void +scsi_bus_update(scsi_bus_t *scsi_bus, int bus) +{ + scsi_device_t *dev = &scsi_devices[scsi_bus->bus_device][scsi_bus->target_id]; + double p; + uint8_t sel_data; + int msglen; + + /*Start the SCSI command layer, which will also make the timings*/ + if (bus & BUS_ARB) + scsi_bus->state = STATE_IDLE; + + scsi_device_log("State = %i\n", scsi_bus->state); + + switch (scsi_bus->state) { + case STATE_IDLE: + scsi_bus->clear_req = scsi_bus->wait_data = scsi_bus->wait_complete = 0; + if ((bus & BUS_SEL) && !(bus & BUS_BSY)) { + sel_data = BUS_GETDATA(bus); + + scsi_bus->target_id = scsi_device_get_id(sel_data); + + /*Once the device has been found and selected, mark it as busy*/ + if ((scsi_bus->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[scsi_bus->bus_device][scsi_bus->target_id])) { + scsi_bus->bus_out |= BUS_BSY; + scsi_bus->state = STATE_SELECT; + scsi_device_log("Select - target ID = %i, moving to state = %d.\n", scsi_bus->target_id, scsi_bus->state); + } else { + scsi_device_log("Device not found at ID %i, Current Bus BSY=%02x\n", scsi_bus->target_id, scsi_bus->bus_out); + scsi_bus->bus_out = 0; + } + } + break; + case STATE_SELECT: + if (!(bus & BUS_SEL)) { + if (!(bus & BUS_ATN)) { + if ((scsi_bus->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[scsi_bus->bus_device][scsi_bus->target_id])) { + scsi_device_log("Device found at ID %i, Current Bus BSY=%02x\n", scsi_bus->target_id, scsi_bus->bus_out); + scsi_bus->state = STATE_COMMAND; + scsi_bus->bus_out = BUS_BSY | BUS_REQ; + scsi_bus->command_pos = 0; + SET_BUS_STATE(scsi_bus, SCSI_PHASE_COMMAND); + } else { + scsi_device_log("Device not found at ID %i again.\n", scsi_bus->target_id); + scsi_bus->state = STATE_IDLE; + scsi_bus->bus_out = 0; + } + } else { + scsi_device_log("Set to SCSI Message Out\n"); + scsi_bus->bus_phase = SCSI_PHASE_MESSAGE_OUT; + scsi_bus->wait_data = 4; + scsi_bus->msgout_pos = 0; + scsi_bus->is_msgout = 1; + } + } + break; + case STATE_COMMAND: + if ((bus & BUS_ACK) && !(scsi_bus->bus_in & BUS_ACK)) { + /*Write command byte to the output data register*/ + scsi_bus->command[scsi_bus->command_pos++] = BUS_GETDATA(bus); + scsi_bus->clear_req = 3; + scsi_bus->bus_phase = scsi_bus->bus_out & SCSI_PHASE_MESSAGE_IN; + scsi_bus->bus_out &= ~BUS_REQ; + + scsi_device_log("Command pos=%i, output data=%02x\n", scsi_bus->command_pos, BUS_GETDATA(bus)); + + if (scsi_bus->command_pos == scsi_command_length[(scsi_bus->command[0] >> 5) & 7]) { + if (scsi_bus->is_msgout) { + scsi_bus->is_msgout = 0; +#if 0 + scsi_bus->command[1] = (scsi_bus->command[1] & 0x1f) | (scsi_bus->msglun << 5); +#endif + } + + /*Reset data position to default*/ + scsi_bus->data_pos = 0; + + dev = &scsi_devices[scsi_bus->bus_device][scsi_bus->target_id]; + + scsi_device_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", scsi_bus->command[0], scsi_bus->target_id, dev->status); + dev->buffer_length = -1; + scsi_device_command_phase0(dev, scsi_bus->command); + scsi_device_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", scsi_bus->target_id, scsi_bus->command[0], dev->buffer_length, dev->phase); + + scsi_bus->period = 1.0; + scsi_bus->wait_data = 4; + scsi_bus->data_wait = 0; + scsi_bus->command_issued = 1; + + if (dev->status == SCSI_STATUS_OK) { + /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ + if (dev->buffer_length && ((dev->phase == SCSI_PHASE_DATA_IN) || (dev->phase == SCSI_PHASE_DATA_OUT))) { + p = scsi_device_get_callback(dev); + scsi_bus->period = (p > 0.0) ? ((p / scsi_bus->divider) * scsi_bus->multi) : (((double) dev->buffer_length) * scsi_bus->speed); + scsi_device_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", scsi_bus->target_id, scsi_bus->command[0], scsi_device_get_callback(dev), scsi_bus->period, dev->buffer_length, scsi_bus->tx_mode); + } + } + scsi_bus->bus_phase = dev->phase; + } + } + break; + case STATE_DATAIN: + dev = &scsi_devices[scsi_bus->bus_device][scsi_bus->target_id]; + if ((bus & BUS_ACK) && !(scsi_bus->bus_in & BUS_ACK)) { + if (scsi_bus->data_pos >= dev->buffer_length) { + scsi_bus->bus_out &= ~BUS_REQ; + scsi_device_command_phase1(dev); + scsi_bus->bus_phase = SCSI_PHASE_STATUS; + scsi_bus->wait_data = 4; + scsi_bus->wait_complete = 8; + } else { + if ((dev->sc != NULL) && (dev->sc->temp_buffer != NULL)) + scsi_bus->data = dev->sc->temp_buffer[scsi_bus->data_pos++]; + + scsi_device_log("TXMode DataIn=%x, cmd=%02x.\n", scsi_bus->tx_mode, scsi_bus->command[0]); + scsi_bus->bus_out = (scsi_bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(scsi_bus->data) | BUS_DBP | BUS_REQ; + if (scsi_bus->tx_mode == PIO_TX_BUS) { /*If a data in command that is not read 6/10 has been issued*/ + scsi_device_log("DMA mode idle IN=%d.\n", scsi_bus->data_pos); + scsi_bus->data_wait |= 1; + scsi_bus->timer(scsi_bus->priv, scsi_bus->period); + } else { + scsi_device_log("DMA mode IN=%d.\n", scsi_bus->data_pos); + scsi_bus->clear_req = 3; + } + scsi_bus->bus_out &= ~BUS_REQ; + scsi_bus->bus_phase = SCSI_PHASE_DATA_IN; + } + } + break; + case STATE_DATAOUT: + dev = &scsi_devices[scsi_bus->bus_device][scsi_bus->target_id]; + if ((bus & BUS_ACK) && !(scsi_bus->bus_in & BUS_ACK)) { + if ((dev->sc != NULL) && (dev->sc->temp_buffer != NULL)) + dev->sc->temp_buffer[scsi_bus->data_pos++] = BUS_GETDATA(bus); + + if (scsi_bus->data_pos >= dev->buffer_length) { + scsi_bus->bus_out &= ~BUS_REQ; + scsi_device_command_phase1(dev); + scsi_bus->bus_phase = SCSI_PHASE_STATUS; + scsi_bus->wait_data = 4; + scsi_bus->wait_complete = 8; + } else { + /*More data is to be transferred, place a request*/ + if (scsi_bus->tx_mode == PIO_TX_BUS) { /*If a data in command that is not write 6/10 has been issued*/ + scsi_device_log("DMA mode idle OUT=%d.\n", scsi_bus->data_pos); + scsi_bus->data_wait |= 1; + scsi_bus->timer(scsi_bus->priv, scsi_bus->period); + scsi_bus->bus_out &= ~BUS_REQ; + } else { + scsi_device_log("DMA mode OUT=%d.\n", scsi_bus->data_pos); + scsi_bus->bus_out |= BUS_REQ; + } + } + } + break; + case STATE_STATUS: + if ((bus & BUS_ACK) && !(scsi_bus->bus_in & BUS_ACK)) { + /*All transfers done, wait until next transfer*/ + scsi_device_identify(&scsi_devices[scsi_bus->bus_device][scsi_bus->target_id], SCSI_LUN_USE_CDB); + scsi_bus->bus_out &= ~BUS_REQ; + scsi_bus->bus_phase = SCSI_PHASE_MESSAGE_IN; + scsi_bus->wait_data = 4; + scsi_bus->wait_complete = 8; + scsi_bus->command_issued = 0; + } + break; + case STATE_MESSAGEIN: + if ((bus & BUS_ACK) && !(scsi_bus->bus_in & BUS_ACK)) { + scsi_bus->bus_out &= ~BUS_REQ; + scsi_bus->bus_phase = BUS_IDLE; + scsi_bus->wait_data = 4; + } + break; + case STATE_MESSAGEOUT: + if ((bus & BUS_ACK) && !(scsi_bus->bus_in & BUS_ACK)) { + scsi_bus->msgout[scsi_bus->msgout_pos++] = BUS_GETDATA(bus); + msglen = scsi_device_get_msg(scsi_bus->msgout, scsi_bus->msgout_pos); + if (scsi_bus->msgout_pos >= msglen) { + if ((scsi_bus->msgout[0] & (0x80 | 0x20)) == 0x80) + scsi_bus->msglun = scsi_bus->msgout[0] & 7; + + scsi_bus->bus_out &= ~BUS_REQ; + scsi_bus->state = STATE_MESSAGE_ID; + } + } + break; + case STATE_MESSAGE_ID: + if ((scsi_bus->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[scsi_bus->bus_device][scsi_bus->target_id])) { + scsi_device_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", scsi_bus->target_id, scsi_bus->bus_out); + scsi_device_identify(&scsi_devices[scsi_bus->bus_device][scsi_bus->target_id], scsi_bus->msglun); + scsi_bus->state = STATE_COMMAND; + scsi_bus->bus_out = BUS_BSY | BUS_REQ; + scsi_bus->command_pos = 0; + SET_BUS_STATE(scsi_bus, SCSI_PHASE_COMMAND); + } + break; + + default: + break; + } + + scsi_bus->bus_in = bus; +} + diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 792dad31b..878259094 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -12,26 +12,24 @@ * * Copyright 2017-2018 Miran Grca. */ -#include #include #include -#include +#ifdef ENABLE_SCSI_DISK_LOG +#include +#endif #include +#include #include #include -#include -#define HAVE_STDARG_H #include <86box/86box.h> -#include <86box/config.h> #include <86box/timer.h> #include <86box/device.h> +#include <86box/log.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/machine.h> #include <86box/nvr.h> -#include <86box/hdc.h> #include <86box/hdc_ide.h> -#include <86box/sound.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/hdd.h> @@ -42,86 +40,71 @@ #define scsi_disk_sense_error dev->sense[0] #define scsi_disk_sense_key dev->sense[2] +#define scsi_disk_info *(uint32_t *) &(dev->sense[3]) #define scsi_disk_asc dev->sense[12] #define scsi_disk_ascq dev->sense[13] -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ +// clang-format off +/* + Table of all SCSI commands and their flags, needed for the new disc change / + not ready handler. + */ const uint8_t scsi_disk_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, - IMPLEMENTED, /* 0x15 */ - IMPLEMENTED | SCSI_ONLY, /* 0x16 */ - IMPLEMENTED | SCSI_ONLY, /* 0x17 */ - 0, 0, - IMPLEMENTED, /* 0x1A */ - 0, 0, - IMPLEMENTED, /* 0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x25 */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, - IMPLEMENTED | CHECK_READY, /* 0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - IMPLEMENTED | CHECK_READY, /* 0x41 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, - IMPLEMENTED, /* 0x5A */ - 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - 0, - IMPLEMENTED | CHECK_READY, /* 0xAA */ - 0, 0, 0, - IMPLEMENTED | CHECK_READY, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - IMPLEMENTED, /* 0xBD */ - 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, 0, 0 + [0x00] = IMPLEMENTED | CHECK_READY, + [0x01] = IMPLEMENTED | ALLOW_UA | SCSI_ONLY, + [0x03] = IMPLEMENTED | ALLOW_UA, + [0x04] = IMPLEMENTED | CHECK_READY | ALLOW_UA | SCSI_ONLY, + [0x08] = IMPLEMENTED | CHECK_READY, + [0x0a ... 0x0b] = IMPLEMENTED | CHECK_READY, + [0x12] = IMPLEMENTED | ALLOW_UA, + [0x13] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x15] = IMPLEMENTED, + [0x16 ... 0x17] = IMPLEMENTED | SCSI_ONLY, + [0x1a] = IMPLEMENTED, + [0x1d] = IMPLEMENTED, + [0x1e] = IMPLEMENTED | CHECK_READY, + [0x25] = IMPLEMENTED | CHECK_READY, + [0x28] = IMPLEMENTED | CHECK_READY, + [0x2a ... 0x2b] = IMPLEMENTED | CHECK_READY, + [0x2e] = IMPLEMENTED | CHECK_READY, + [0x2f] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0x41] = IMPLEMENTED | CHECK_READY, + [0x55] = IMPLEMENTED, + [0x5a] = IMPLEMENTED, + [0xa8] = IMPLEMENTED | CHECK_READY, + [0xaa] = IMPLEMENTED | CHECK_READY, + [0xae] = IMPLEMENTED | CHECK_READY, + [0xaf] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [0xbd] = IMPLEMENTED }; -uint64_t scsi_disk_mode_sense_page_flags = (GPMODEP_FORMAT_DEVICE_PAGE | GPMODEP_RIGID_DISK_PAGE | GPMODEP_UNK_VENDOR_PAGE | GPMODEP_ALL_PAGES); +uint64_t scsi_disk_mode_sense_page_flags = (GPMODEP_FORMAT_DEVICE_PAGE | GPMODEP_RIGID_DISK_PAGE | + GPMODEP_UNK_VENDOR_PAGE | GPMODEP_ALL_PAGES); -/* This should be done in a better way but for time being, it's been done this way so it's not as huge and more readable. */ static const mode_sense_pages_t scsi_disk_mode_sense_pages_default = { - {[GPMODE_FORMAT_DEVICE_PAGE] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [GPMODE_RIGID_DISK_PAGE] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0, 0x10, 0, 64, 0, 0, 0, 0, 0, 0, 0, 200, 0xff, 0xff, 0xff, 0, 0, 0, 0x15, 0x18, 0, 0 }, - [GPMODE_UNK_VENDOR_PAGE] = { 0xB0, 0x16, '8', '6', 'B', 'o', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }} + { [0x03] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x04] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x15, 0x18, 0x00, 0x00 }, + [0x30] = { GPMODE_UNK_VENDOR_PAGE | 0x80, 0x16, '8' , '6' , 'B' , 'o' , 'x' , ' ' , + ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , + ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' } } }; static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable = { - {[GPMODE_FORMAT_DEVICE_PAGE] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [GPMODE_RIGID_DISK_PAGE] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - [GPMODE_UNK_VENDOR_PAGE] = { 0xB0, 0x16, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }} + { [0x03] = { GPMODE_FORMAT_DEVICE_PAGE, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x04] = { GPMODE_RIGID_DISK_PAGE, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + [0x30] = { GPMODE_UNK_VENDOR_PAGE | 0x80, 0x16, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }; +// clang-format on static void scsi_disk_command_complete(scsi_disk_t *dev); @@ -133,116 +116,116 @@ static void scsi_disk_init(scsi_disk_t *dev); int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG; static void -scsi_disk_log(const char *fmt, ...) +scsi_disk_log(void *priv, const char *fmt, ...) { va_list ap; if (scsi_disk_do_log) { va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define scsi_disk_log(fmt, ...) +# define scsi_disk_log(priv, fmt, ...) #endif static void -scsi_disk_set_callback(scsi_disk_t *dev) +scsi_disk_set_callback(const scsi_disk_t *dev) { - if (dev->drv->bus != HDD_BUS_SCSI) + if (dev->drv->bus_type != HDD_BUS_SCSI) ide_set_callback(ide_drives[dev->drv->ide_channel], dev->callback); } static void scsi_disk_init(scsi_disk_t *dev) { - if (!dev) - return; + if (dev != NULL) { + /* Do a reset (which will also rezero it). */ + scsi_disk_reset((scsi_common_t *) dev); - /* Do a reset (which will also rezero it). */ - scsi_disk_reset((scsi_common_t *) dev); + /* Configure the drive. */ + dev->requested_blocks = 1; - /* Configure the drive. */ - dev->requested_blocks = 1; + dev->drv->bus_mode = 0; + if (dev->drv->bus_type >= HDD_BUS_ATAPI) + dev->drv->bus_mode |= 2; + if (dev->drv->bus_type < HDD_BUS_SCSI) + dev->drv->bus_mode |= 1; + scsi_disk_log(dev->log, "Bus type %i, bus mode %i\n", + dev->drv->bus_type, dev->drv->bus_mode); - dev->drv->bus_mode = 0; - if (dev->drv->bus >= HDD_BUS_ATAPI) - dev->drv->bus_mode |= 2; - if (dev->drv->bus < HDD_BUS_SCSI) - dev->drv->bus_mode |= 1; - scsi_disk_log("SCSI HDD %i: Bus type %i, bus mode %i\n", - dev->id, dev->drv->bus, dev->drv->bus_mode); + dev->sense[0] = 0xf0; + dev->sense[7] = 10; - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - /* NEC only */ - dev->tf->status = 0; - dev->tf->pos = 0; - dev->packet_status = PHASE_NONE; - scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = dev->unit_attention = 0; - scsi_disk_mode_sense_load(dev); + dev->tf->status = 0; + dev->tf->pos = 0; + dev->packet_status = PHASE_NONE; + scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = dev->unit_attention = 0; + scsi_disk_info = 0x00; + scsi_disk_mode_sense_load(dev); + } } /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -scsi_disk_current_mode(scsi_disk_t *dev) +scsi_disk_current_mode(const scsi_disk_t *dev) { - if (dev->drv->bus == HDD_BUS_SCSI) - return 2; - else if (dev->drv->bus == HDD_BUS_ATAPI) { - scsi_disk_log("SCSI DISK %i: ATAPI drive, setting to %s\n", dev->id, + int ret = 0; + + if (dev->drv->bus_type == HDD_BUS_SCSI) + ret = 2; + else if (dev->drv->bus_type == HDD_BUS_ATAPI) { + scsi_disk_log(dev->log, "ATAPI drive, setting to %s\n", (dev->tf->features & 1) ? "DMA" : "PIO", dev->id); - return (dev->tf->features & 1) ? 2 : 1; + ret = (dev->tf->features & 1) ? 2 : 1; } - return 0; + return ret; } -void +static void scsi_disk_mode_sense_load(scsi_disk_t *dev) { - FILE *fp; - char file_name[512]; + char file_name[512] = { 0 }; memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); - memcpy(&dev->ms_pages_saved, &scsi_disk_mode_sense_pages_default, sizeof(mode_sense_pages_t)); + memcpy(&dev->ms_pages_saved, &scsi_disk_mode_sense_pages_default, + sizeof(mode_sense_pages_t)); - memset(file_name, 0, 512); sprintf(file_name, "scsi_disk_%02i_mode_sense.bin", dev->id); - fp = plat_fopen(nvr_path(file_name), "rb"); + FILE *fp = plat_fopen(nvr_path(file_name), "rb"); if (fp) { if (fread(dev->ms_pages_saved.pages[0x30], 1, 0x18, fp) != 0x18) - fatal("scsi_disk_mode_sense_load(): Error reading data\n"); + log_fatal(dev->log, "scsi_disk_mode_sense_load(): Error reading data\n"); fclose(fp); } } -void -scsi_disk_mode_sense_save(scsi_disk_t *dev) +static void +scsi_disk_mode_sense_save(const scsi_disk_t *dev) { - FILE *fp; - char file_name[512]; + char file_name[512] = { 0 }; - memset(file_name, 0, 512); sprintf(file_name, "scsi_disk_%02i_mode_sense.bin", dev->id); - fp = plat_fopen(nvr_path(file_name), "wb"); + FILE *fp = plat_fopen(nvr_path(file_name), "wb"); if (fp) { fwrite(dev->ms_pages_saved.pages[0x30], 1, 0x18, fp); fclose(fp); } } -/*SCSI Mode Sense 6/10*/ +/* SCSI Mode Sense 6/10 */ uint8_t -scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) +scsi_disk_mode_sense_read(const scsi_disk_t *dev, const uint8_t pgctl, + const uint8_t page, const uint8_t pos) { - if (page_control == 1) + if (pgctl == 1) return scsi_disk_mode_sense_pages_changeable.pages[page][pos]; if (page == GPMODE_RIGID_DISK_PAGE) - switch (page_control) { + switch (pgctl) { /* Rigid disk geometry page. */ case 0: case 2: @@ -272,7 +255,7 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, break; } else if (page == GPMODE_FORMAT_DEVICE_PAGE) - switch (page_control) { + switch (pgctl) { /* Format device page. */ case 0: case 2: @@ -293,7 +276,7 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, break; } else - switch (page_control) { + switch (pgctl) { case 0: case 3: return dev->ms_pages_saved.pages[page][pos]; @@ -308,16 +291,13 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, } uint32_t -scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) +scsi_disk_mode_sense(const scsi_disk_t *dev, uint8_t *buf, uint32_t pos, + uint8_t page, const uint8_t block_descriptor_len) { - uint8_t msplen; - uint8_t page_control = (page >> 6) & 3; - int size = 0; + int size = hdd_image_get_last_sector(dev->id); page &= 0x3f; - size = hdd_image_get_last_sector(dev->id); - if (block_descriptor_len) { buf[pos++] = 1; /* Density code. */ buf[pos++] = (size >> 16) & 0xff; /* Number of blocks (0 = all). */ @@ -332,12 +312,14 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, for (uint8_t i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { if (scsi_disk_mode_sense_page_flags & (1LL << (uint64_t) page)) { - buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 0); - msplen = scsi_disk_mode_sense_read(dev, page_control, i, 1); - buf[pos++] = msplen; - scsi_disk_log("SCSI HDD %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); + const uint8_t pgctl = (page >> 6) & 3; + const uint8_t msplen = scsi_disk_mode_sense_read(dev, pgctl, i, 1); + buf[pos++] = scsi_disk_mode_sense_read(dev, pgctl, i, 0); + buf[pos++] = msplen; + scsi_disk_log(dev->log, "MODE SENSE: Page [%02X] length %i\n", + i, msplen); for (uint8_t j = 0; j < msplen; j++) - buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 2 + j); + buf[pos++] = scsi_disk_mode_sense_read(dev, pgctl, i, 2 + j); } } } @@ -346,7 +328,7 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, } static void -scsi_disk_update_request_length(scsi_disk_t *dev, int len, int block_len) +scsi_disk_update_request_length(scsi_disk_t *dev, int len, const int block_len) { int bt; int min_len = 0; @@ -407,7 +389,7 @@ scsi_disk_bus_speed(scsi_disk_t *dev) { double ret = -1.0; - if (dev && dev->drv && (dev->drv->bus == HDD_BUS_SCSI)) { + if (dev && dev->drv && (dev->drv->bus_type == HDD_BUS_SCSI)) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return 0.0; } else { @@ -425,7 +407,7 @@ scsi_disk_bus_speed(scsi_disk_t *dev) void scsi_disk_command_common(scsi_disk_t *dev) { - double bytes_per_second = 0.0; + double bytes_per_second; double period; /* MAP: BUSY_STAT, no DRQ, phase 1. */ @@ -435,6 +417,7 @@ scsi_disk_command_common(scsi_disk_t *dev) dev->callback = 0; if (dev->packet_status == PHASE_COMPLETE) { + switch (dev->current_cdb[0]) { case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: @@ -446,18 +429,19 @@ scsi_disk_command_common(scsi_disk_t *dev) case GPCMD_WRITE_AND_VERIFY_12: case GPCMD_WRITE_SAME_10: /* Seek time is in us. */ - period = hdd_timing_write(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); - scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); + period = hdd_timing_write(dev->drv, dev->drv->seek_pos, + dev->drv->seek_len); + scsi_disk_log(dev->log, "Seek period: %" PRIu64 " us\n", + (uint64_t) period); dev->callback += period; /* Account for seek time. */ bytes_per_second = scsi_bus_get_speed(dev->drv->scsi_id >> 4); period = 1000000.0 / bytes_per_second; - scsi_disk_log("SCSI HD %i: Byte transfer period: %" PRIu64 " us\n", dev->id, + scsi_disk_log(dev->log, "Byte transfer period: %" PRIu64 " us\n", (uint64_t) period); period = period * (double) (dev->packet_len); - scsi_disk_log("CD-ROM %i: Sector transfer period: %" PRIu64 " us\n", dev->id, + scsi_disk_log(dev->log, "Sector transfer period: %" PRIu64 " us\n", (uint64_t) period); dev->callback += period; break; @@ -473,8 +457,8 @@ scsi_disk_command_common(scsi_disk_t *dev) /* Seek time is in us. */ period = hdd_seek_get_time(dev->drv, (dev->current_cdb[0] == GPCMD_REZERO_UNIT) ? 0 : dev->sector_pos, HDD_OP_SEEK, 0, 0.0); - scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); + scsi_disk_log(dev->log, "Seek period: %" PRIu64 " us\n", + (uint64_t) period); dev->callback += period; scsi_disk_set_callback(dev); return; @@ -482,9 +466,10 @@ scsi_disk_command_common(scsi_disk_t *dev) case 0x28: case 0xa8: /* Seek time is in us. */ - period = hdd_timing_read(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); - scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", - dev->id, (uint64_t) period); + period = hdd_timing_read(dev->drv, dev->drv->seek_pos, + dev->drv->seek_len); + scsi_disk_log(dev->log, "Seek period: %" PRIu64 " us\n", + (uint64_t) period); dev->callback += period; /* Account for seek time. */ bytes_per_second = scsi_bus_get_speed(dev->drv->scsi_id >> 4); @@ -500,9 +485,11 @@ scsi_disk_command_common(scsi_disk_t *dev) } period = 1000000.0 / bytes_per_second; - scsi_disk_log("SCSI HD %i: Byte transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + scsi_disk_log(dev->log, "Byte transfer period: %" PRIu64 " us\n", + (uint64_t) period); period = period * (double) (dev->packet_len); - scsi_disk_log("SCSI HD %i: Sector transfer period: %" PRIu64 " us\n", dev->id, (uint64_t) period); + scsi_disk_log(dev->log, "Sector transfer period: %" PRIu64 " us\n", + (uint64_t) period); dev->callback += period; } scsi_disk_set_callback(dev); @@ -543,16 +530,19 @@ scsi_disk_command_write_dma(scsi_disk_t *dev) scsi_disk_command_common(dev); } -/* id = Current ZIP device ID; +/* + dev = Pointer to current SCSI disk 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). */ + direction = Transfer direction (0 = read from host, 1 = write to host). + */ static void -scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int alloc_len, int direction) +scsi_disk_data_command_finish(scsi_disk_t *dev, int len, const int block_len, + const int alloc_len, const int direction) { - scsi_disk_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", - dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, + scsi_disk_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; if (alloc_len >= 0) { @@ -560,13 +550,13 @@ scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int allo len = alloc_len; } if ((len == 0) || (scsi_disk_current_mode(dev) == 0)) { - if (dev->drv->bus != HDD_BUS_SCSI) + if (dev->drv->bus_type != HDD_BUS_SCSI) dev->packet_len = 0; scsi_disk_command_complete(dev); } else { if (scsi_disk_current_mode(dev) == 2) { - if (dev->drv->bus != HDD_BUS_SCSI) + if (dev->drv->bus_type != HDD_BUS_SCSI) dev->packet_len = alloc_len; if (direction == 0) @@ -582,27 +572,27 @@ scsi_disk_data_command_finish(scsi_disk_t *dev, int len, int block_len, int allo } } - scsi_disk_log("SCSI HD %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", - dev->id, dev->packet_status, dev->tf->request_length, dev->packet_len, dev->tf->pos, - dev->tf->phase); + scsi_disk_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 scsi_disk_sense_clear(scsi_disk_t *dev, UNUSED(int command)) { scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; + scsi_disk_info = 0x00000000; } static void -scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase) +scsi_disk_set_phase(const scsi_disk_t *dev, const uint8_t phase) { - uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + const uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; + const uint8_t scsi_id = dev->drv->scsi_id & 0x0f; - if (dev->drv->bus != HDD_BUS_SCSI) - return; - - scsi_devices[scsi_bus][scsi_id].phase = phase; + if (dev->drv->bus_type == HDD_BUS_SCSI) + scsi_devices[scsi_bus][scsi_id].phase = phase; } static void @@ -615,15 +605,16 @@ scsi_disk_cmd_error(scsi_disk_t *dev) dev->packet_status = PHASE_ERROR; dev->callback = 50.0 * SCSI_TIME; scsi_disk_set_callback(dev); - ui_sb_update_icon(SB_HDD | dev->drv->bus, 0); - scsi_disk_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); + ui_sb_update_icon(SB_HDD | dev->drv->bus_type, 0); + scsi_disk_log(dev->log, "ERROR: %02X/%02X/%02X\n", scsi_disk_sense_key, + scsi_disk_asc, scsi_disk_ascq); } static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { - scsi_disk_log("SCSI HD %i: Allocated buffer length: %i\n", dev->id, len); - if (!dev->temp_buffer) + scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); + if (dev->temp_buffer == NULL) dev->temp_buffer = (uint8_t *) malloc(len); } @@ -631,7 +622,7 @@ static void scsi_disk_buf_free(scsi_disk_t *dev) { if (dev->temp_buffer) { - scsi_disk_log("SCSI HD %i: Freeing buffer...\n", dev->id); + scsi_disk_log(dev->log, "Freeing buffer...\n"); free(dev->temp_buffer); dev->temp_buffer = NULL; } @@ -644,25 +635,57 @@ scsi_disk_bus_master_error(scsi_common_t *sc) scsi_disk_buf_free(dev); scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = 0; + scsi_disk_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); scsi_disk_cmd_error(dev); } static void -scsi_disk_invalid_lun(scsi_disk_t *dev) +scsi_disk_write_error(scsi_disk_t *dev) +{ + scsi_disk_sense_key = SENSE_MEDIUM_ERROR; + scsi_disk_asc = ASC_WRITE_ERROR; + scsi_disk_ascq = 0; + scsi_disk_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + scsi_disk_cmd_error(dev); +} + +static void +scsi_disk_read_error(scsi_disk_t *dev) +{ + scsi_disk_sense_key = SENSE_MEDIUM_ERROR; + scsi_disk_asc = ASC_UNRECOVERED_READ_ERROR; + scsi_disk_ascq = 0; + scsi_disk_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); + scsi_disk_cmd_error(dev); +} + +static void +scsi_disk_invalid_lun(scsi_disk_t *dev, const uint8_t lun) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; scsi_disk_asc = ASC_INV_LUN; scsi_disk_ascq = 0; scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_info = lun << 24; scsi_disk_cmd_error(dev); } static void -scsi_disk_illegal_opcode(scsi_disk_t *dev) +scsi_disk_illegal_opcode(scsi_disk_t *dev, const uint8_t opcode) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; scsi_disk_asc = ASC_ILLEGAL_OPCODE; scsi_disk_ascq = 0; + scsi_disk_info = opcode << 24; scsi_disk_cmd_error(dev); } @@ -672,54 +695,72 @@ scsi_disk_lba_out_of_range(scsi_disk_t *dev) scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; scsi_disk_asc = ASC_LBA_OUT_OF_RANGE; scsi_disk_ascq = 0; + scsi_disk_info = (dev->sector_pos >> 24) | + ((dev->sector_pos >> 16) << 8) | + ((dev->sector_pos >> 8) << 16) | + ( dev->sector_pos << 24); scsi_disk_cmd_error(dev); } static void -scsi_disk_invalid_field(scsi_disk_t *dev) +scsi_disk_invalid_field(scsi_disk_t *dev, const uint32_t field) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; scsi_disk_asc = ASC_INV_FIELD_IN_CMD_PACKET; scsi_disk_ascq = 0; + scsi_disk_info = (field >> 24) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); scsi_disk_cmd_error(dev); dev->tf->status = 0x53; } static void -scsi_disk_invalid_field_pl(scsi_disk_t *dev) +scsi_disk_invalid_field_pl(scsi_disk_t *dev, const uint32_t field) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; scsi_disk_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; scsi_disk_ascq = 0; + scsi_disk_info = (field >> 24) | + ((field >> 16) << 8) | + ((field >> 8) << 16) | + ( field << 24); scsi_disk_cmd_error(dev); dev->tf->status = 0x53; } static void -scsi_disk_data_phase_error(scsi_disk_t *dev) +scsi_disk_data_phase_error(scsi_disk_t *dev, const uint32_t info) { scsi_disk_sense_key = SENSE_ILLEGAL_REQUEST; scsi_disk_asc = ASC_DATA_PHASE_ERROR; scsi_disk_ascq = 0; + scsi_disk_info = (info >> 24) | + ((info >> 16) << 8) | + ((info >> 8) << 16) | + ( info << 24); scsi_disk_cmd_error(dev); } static int -scsi_disk_blocks(scsi_disk_t *dev, int32_t *len, UNUSED(int first_batch), int out) +scsi_disk_blocks(scsi_disk_t *dev, int32_t *len, UNUSED(int first_batch), const int out) { + const uint32_t medium_size = hdd_image_get_last_sector(dev->id) + 1; + *len = 0; - uint32_t medium_size = hdd_image_get_last_sector(dev->id) + 1; if (!dev->sector_len) { scsi_disk_command_complete(dev); return -1; } - scsi_disk_log("%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", + scsi_disk_log(dev->log, "%sing %i blocks starting from %i...\n", out ? "Writ" : "Read", dev->requested_blocks, dev->sector_pos); if (dev->sector_pos >= medium_size) { - scsi_disk_log("SCSI HD %i: Trying to %s beyond the end of disk\n", dev->id, out ? "write" : "read"); + scsi_disk_log(dev->log, "Trying to %s beyond the end of disk\n", + out ? "write" : "read"); scsi_disk_lba_out_of_range(dev); return 0; } @@ -727,62 +768,91 @@ scsi_disk_blocks(scsi_disk_t *dev, int32_t *len, UNUSED(int first_batch), int ou *len = dev->requested_blocks << 9; for (int i = 0; i < dev->requested_blocks; i++) { - if (out) - hdd_image_write(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9)); - else - hdd_image_read(dev->id, dev->sector_pos + i, 1, dev->temp_buffer + (i << 9)); + if (out) { + if (hdd_image_write(dev->id, dev->sector_pos, 1, dev->temp_buffer + + (i << 9)) < 0) { + scsi_disk_write_error(dev); + return -1; + } + } else { + if (hdd_image_read(dev->id, dev->sector_pos, 1, dev->temp_buffer + + (i << 9)) < 0) { + scsi_disk_read_error(dev); + return -1; + } + } + dev->sector_pos++; } - scsi_disk_log("%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); + scsi_disk_log(dev->log, "%s %i bytes of blocks...\n", out ? "Written" : "Read", *len); - dev->sector_pos += dev->requested_blocks; dev->sector_len -= dev->requested_blocks; return 1; } static int -scsi_disk_pre_execution_check(scsi_disk_t *dev, uint8_t *cdb) +scsi_disk_pre_execution_check(scsi_disk_t *dev, const uint8_t *cdb) { - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && (cdb[1] & 0xe0)) { - scsi_disk_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", - dev->id, ((dev->tf->request_length >> 5) & 7)); - scsi_disk_invalid_lun(dev); + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (dev->cur_lun == SCSI_LUN_USE_CDB) && + (cdb[1] & 0xe0)) { + scsi_disk_log(dev->log, "Attempting to execute a unknown command " + "targeted at SCSI LUN %i\n", + ((dev->tf->request_length >> 5) & 7)); + scsi_disk_invalid_lun(dev, cdb[1] >> 5); return 0; } if (!(scsi_disk_command_flags[cdb[0]] & IMPLEMENTED)) { - scsi_disk_log("SCSI HD %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], - (dev->drv->bus == HDD_BUS_SCSI) ? "SCSI" : "ATAPI"); - scsi_disk_illegal_opcode(dev); + scsi_disk_log(dev->log, "Attempting to execute unknown " + "command %02X over %s\n", cdb[0], + (dev->drv->bus_type == HDD_BUS_SCSI) ? "SCSI" : "ATAPI"); + scsi_disk_illegal_opcode(dev, cdb[0]); return 0; } - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ + if ((dev->drv->bus_type < HDD_BUS_SCSI) && + (scsi_disk_command_flags[cdb[0]] & SCSI_ONLY)) { + scsi_disk_log(dev->log, "Attempting to execute SCSI-only command %02X " + "over ATAPI\n", cdb[0]); + scsi_disk_illegal_opcode(dev, cdb[0]); + return 0; + } + + if ((dev->drv->bus_type == HDD_BUS_SCSI) && + (scsi_disk_command_flags[cdb[0]] & ATAPI_ONLY)) { + scsi_disk_log(dev->log, "Attempting to execute ATAPI-only command %02X " + "over SCSI\n", cdb[0]); + scsi_disk_illegal_opcode(dev, cdb[0]); + return 0; + } + + /* + Unless the command is REQUEST SENSE, clear the sense. This will *NOT* + the UNIT ATTENTION condition if it's set. + */ if (cdb[0] != GPCMD_REQUEST_SENSE) scsi_disk_sense_clear(dev, cdb[0]); - scsi_disk_log("SCSI HD %i: Continuing with command\n", dev->id); + scsi_disk_log(dev->log, "Continuing with command %02X\n", cdb[0]); return 1; } static void -scsi_disk_seek(scsi_disk_t *dev, uint32_t pos) +scsi_disk_seek(const scsi_disk_t *dev, const uint32_t pos) { - /* scsi_disk_log("SCSI HD %i: Seek %08X\n", dev->id, pos); */ + /* scsi_disk_log(dev->log, "Seek %08X\n", pos); */ hdd_image_seek(dev->id, pos); } static void scsi_disk_rezero(scsi_disk_t *dev) { - if (dev->id == 0xff) - return; - - dev->sector_pos = dev->sector_len = 0; - scsi_disk_seek(dev, 0); + if (dev->id != 0xff) { + dev->sector_pos = dev->sector_len = 0; + scsi_disk_seek(dev, 0); + } } void @@ -799,34 +869,38 @@ scsi_disk_reset(scsi_common_t *sc) dev->packet_status = PHASE_NONE; dev->unit_attention = 0; dev->cur_lun = SCSI_LUN_USE_CDB; + scsi_disk_sense_key = scsi_disk_asc = scsi_disk_ascq = dev->unit_attention = 0; + scsi_disk_info = 0x00; } void -scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc) +scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, + const uint8_t alloc_length, const int desc) { - /*Will return 18 bytes of 0*/ + /* Will return 18 bytes of 0. */ if (alloc_length != 0) { memset(buffer, 0, alloc_length); - if (!desc) - memcpy(buffer, dev->sense, alloc_length); - else { + if (desc) { buffer[1] = scsi_disk_sense_key; buffer[2] = scsi_disk_asc; buffer[3] = scsi_disk_ascq; - } - } else - return; + } else + memcpy(buffer, dev->sense, alloc_length); - buffer[0] = 0x70; + buffer[0] = desc ? 0x70 : 0xf0; + buffer[7] = 10; - scsi_disk_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", dev->id, buffer[2], buffer[12], buffer[13]); + scsi_disk_log(dev->log, "Reporting sense: %02X %02X %02X\n", + buffer[2], buffer[12], buffer[13]); - /* Clear the sense stuff as per the spec. */ - scsi_disk_sense_clear(dev, GPCMD_REQUEST_SENSE); + /* Clear the sense stuff as per the spec. */ + scsi_disk_sense_clear(dev, GPCMD_REQUEST_SENSE); + } } static void -scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t alloc_length) +scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, + const uint8_t alloc_length) { scsi_disk_t *dev = (scsi_disk_t *) sc; @@ -834,41 +908,42 @@ scsi_disk_request_sense_for_scsi(scsi_common_t *sc, uint8_t *buffer, uint8_t all } static void -scsi_disk_set_buf_len(scsi_disk_t *dev, int32_t *BufLen, int32_t *src_len) +scsi_disk_set_buf_len(const scsi_disk_t *dev, int32_t *BufLen, int32_t *src_len) { - if (dev->drv->bus == HDD_BUS_SCSI) { + if (dev->drv->bus_type == HDD_BUS_SCSI) { if (*BufLen == -1) *BufLen = *src_len; else { *BufLen = MIN(*src_len, *BufLen); *src_len = *BufLen; } - scsi_disk_log("SCSI HD %i: Actual transfer length: %i\n", dev->id, *BufLen); + scsi_disk_log(dev->log, "Actual transfer length: %i\n", *BufLen); } } static void -scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) +scsi_disk_command(scsi_common_t *sc, const uint8_t *cdb) { - scsi_disk_t *dev = (scsi_disk_t *) sc; - int ret; - int32_t blen = 0; - int32_t *BufLen; - int32_t len; - int32_t max_len; - int32_t alloc_length; - int pos = 0; - int idx = 0; - unsigned size_idx; - unsigned preamble_len; - uint32_t last_sector = 0; - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - int block_desc = 0; - uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', + 'v', '1', '.', '0', '0', 0 }; + scsi_disk_t * dev = (scsi_disk_t *) sc; + const uint32_t last_sector = hdd_image_get_last_sector(dev->id); + const uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; + const uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + int32_t blen = 0; + int pos = 0; + int idx = 0; + int block_desc; + int ret; + int32_t * BufLen; + int32_t len; + int32_t max_len; + int32_t alloc_length; + unsigned size_idx; + unsigned preamble_len; - if (dev->drv->bus == HDD_BUS_SCSI) { + if (dev->drv->bus_type == HDD_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; dev->tf->status &= ~ERR_STAT; } else { @@ -876,8 +951,6 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->tf->error = 0; } - last_sector = hdd_image_get_last_sector(dev->id); - dev->packet_len = 0; dev->request_pos = 0; @@ -893,11 +966,12 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) memcpy(dev->current_cdb, cdb, 12); if (cdb[0] != 0) { - scsi_disk_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", - dev->id, cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); - scsi_disk_log("SCSI HD %i: Request length: %04X\n", dev->id, dev->tf->request_length); + scsi_disk_log(dev->log, "Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X\n", + cdb[0], scsi_disk_sense_key, scsi_disk_asc, scsi_disk_ascq); + scsi_disk_log(dev->log, "Request length: %04X\n", dev->tf->request_length); - scsi_disk_log("SCSI HD %i: CDB: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id, + scsi_disk_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]); } @@ -906,14 +980,17 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ + /* + This handles the Not Ready/Unit Attention check if it has to be + handled at this point. + */ if (scsi_disk_pre_execution_check(dev, cdb) == 0) return; switch (cdb[0]) { case GPCMD_SEND_DIAGNOSTIC: if (!(cdb[1] & (1 << 2))) { - scsi_disk_invalid_field(dev); + scsi_disk_invalid_field(dev, cdb[1]); return; } fallthrough; @@ -936,9 +1013,6 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) break; case GPCMD_REQUEST_SENSE: - /* If there's a unit attention condition and there's a buffered not - ready, a standalone REQUEST SENSE should forget about the not - ready, and report unit attention straight away. */ len = cdb[4]; if (!len) { @@ -952,14 +1026,11 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) scsi_disk_buf_alloc(dev, 256); scsi_disk_set_buf_len(dev, BufLen, &len); - if (*BufLen < cdb[4]) - cdb[4] = *BufLen; - len = (cdb[1] & 1) ? 8 : 18; scsi_disk_request_sense(dev, dev->temp_buffer, *BufLen, cdb[1] & 1); scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_disk_data_command_finish(dev, len, len, cdb[4], 0); + scsi_disk_data_command_finish(dev, len, len, *BufLen, 0); break; case GPCMD_MECHANISM_STATUS: @@ -995,12 +1066,15 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) 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]; + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; break; case GPCMD_READ_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; @@ -1008,54 +1082,45 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) break; } - if (dev->sector_pos > last_sector) { + if (dev->sector_pos > last_sector) scsi_disk_lba_out_of_range(dev); - return; + else { + if (dev->sector_len) { + max_len = dev->sector_len; + dev->requested_blocks = max_len; + + dev->packet_len = max_len * alloc_length; + scsi_disk_buf_alloc(dev, dev->packet_len); + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + + ret = scsi_disk_blocks(dev, &alloc_length, 1, 0); + if (ret > 0) { + dev->requested_blocks = max_len; + dev->packet_len = alloc_length; + + scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + scsi_disk_data_command_finish(dev, alloc_length, 512, alloc_length, 0); + + ui_sb_update_icon(SB_HDD | dev->drv->bus_type, dev->packet_status != PHASE_COMPLETE); + } else { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + dev->packet_status = (ret < 0) ? PHASE_ERROR : PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); + scsi_disk_buf_free(dev); + } + } else { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_log(dev->log, "All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); + } } - - if (!dev->sector_len) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - scsi_disk_set_callback(dev); - break; - } - - max_len = dev->sector_len; - /* - If we're reading all blocks in one go for DMA, why not also for - PIO, it should NOT matter anyway, this step should be identical - and only the way the read dat is transferred to the host should - be different. - */ - dev->requested_blocks = max_len; - - dev->packet_len = max_len * alloc_length; - scsi_disk_buf_alloc(dev, dev->packet_len); - - dev->drv->seek_pos = dev->sector_pos; - dev->drv->seek_len = dev->sector_len; - - ret = scsi_disk_blocks(dev, &alloc_length, 1, 0); - if (ret <= 0) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - scsi_disk_set_callback(dev); - scsi_disk_buf_free(dev); - return; - } - - dev->requested_blocks = max_len; - dev->packet_len = alloc_length; - - scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - scsi_disk_data_command_finish(dev, alloc_length, 512, alloc_length, 0); - - ui_sb_update_icon(SB_HDD | dev->drv->bus, dev->packet_status != PHASE_COMPLETE); - return; + break; case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: @@ -1086,23 +1151,26 @@ scsi_disk_command(scsi_common_t *sc, 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]); - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, + scsi_disk_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_10: case GPCMD_WRITE_10: case GPCMD_WRITE_AND_VERIFY_10: dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - scsi_disk_log("SCSI HD %i: Length: %i, LBA: %i\n", dev->id, + dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | + (cdb[4] << 8) | cdb[5]; + scsi_disk_log(dev->log, "Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; case GPCMD_VERIFY_12: case GPCMD_WRITE_12: case GPCMD_WRITE_AND_VERIFY_12: - dev->sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | + dev->sector_len = (((uint32_t) cdb[6]) << 24) | + (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - dev->sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | + dev->sector_pos = (((uint32_t) cdb[2]) << 24) | + (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); break; @@ -1110,90 +1178,79 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) break; } - if (dev->sector_pos > last_sector) { + if (dev->sector_pos > last_sector) scsi_disk_lba_out_of_range(dev); - return; + else { + if (dev->sector_len) { + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + + max_len = dev->sector_len; + dev->requested_blocks = max_len; + + dev->packet_len = max_len * alloc_length; + scsi_disk_buf_alloc(dev, dev->packet_len); + + dev->requested_blocks = max_len; + dev->packet_len = max_len << 9; + + scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + scsi_disk_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); + + ui_sb_update_icon(SB_HDD | dev->drv->bus_type, dev->packet_status != PHASE_COMPLETE); + } else { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_log(dev->log, "All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); + } } - - if (!dev->sector_len) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - scsi_disk_set_callback(dev); - break; - } - - dev->drv->seek_pos = dev->sector_pos; - dev->drv->seek_len = dev->sector_len; - - max_len = dev->sector_len; - /* - If we're writing all blocks in one go for DMA, why not also for - PIO, it should NOT matter anyway, this step should be identical - and only the way the read dat is transferred to the host should - be different. - */ - dev->requested_blocks = max_len; - - dev->packet_len = max_len * alloc_length; - scsi_disk_buf_alloc(dev, dev->packet_len); - - dev->requested_blocks = max_len; - dev->packet_len = max_len << 9; - - scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - scsi_disk_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1); - - ui_sb_update_icon(SB_HDD | dev->drv->bus, dev->packet_status != PHASE_COMPLETE); - return; + break; case GPCMD_WRITE_SAME_10: alloc_length = 512; - if ((cdb[1] & 6) == 6) { - scsi_disk_invalid_field(dev); - return; + if ((cdb[1] & 6) == 6) + scsi_disk_invalid_field(dev, cdb[1]); + 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 > last_sector) + scsi_disk_lba_out_of_range(dev); + else { + if (dev->sector_len) { + scsi_disk_buf_alloc(dev, alloc_length); + scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + + dev->requested_blocks = 1; + + dev->packet_len = alloc_length; + + scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); + + scsi_disk_data_command_finish(dev, 512, 512, alloc_length, 1); + + ui_sb_update_icon(SB_HDD | dev->drv->bus_type, + dev->packet_status != PHASE_COMPLETE); + } else { + scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + scsi_disk_log(dev->log, "All done - callback set\n"); + dev->packet_status = PHASE_COMPLETE; + dev->callback = 20.0 * SCSI_TIME; + scsi_disk_set_callback(dev); + } + } } - - dev->sector_len = (cdb[7] << 8) | cdb[8]; - dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - if (dev->sector_pos > last_sector) { - scsi_disk_lba_out_of_range(dev); - return; - } - - if (!dev->sector_len) { - scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); - dev->packet_status = PHASE_COMPLETE; - dev->callback = 20.0 * SCSI_TIME; - scsi_disk_set_callback(dev); - break; - } - - scsi_disk_buf_alloc(dev, alloc_length); - scsi_disk_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - - max_len = 1; - dev->requested_blocks = 1; - - dev->packet_len = alloc_length; - - scsi_disk_set_phase(dev, SCSI_PHASE_DATA_OUT); - - scsi_disk_data_command_finish(dev, 512, 512, alloc_length, 1); - - ui_sb_update_icon(SB_HDD | dev->drv->bus, dev->packet_status != PHASE_COMPLETE); - return; + break; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: scsi_disk_set_phase(dev, SCSI_PHASE_DATA_IN); - if (dev->drv->bus == HDD_BUS_SCSI) + if (dev->drv->bus_type == HDD_BUS_SCSI) block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; else block_desc = 0; @@ -1210,7 +1267,8 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) alloc_length = len; if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_disk_mode_sense(dev, dev->temp_buffer, 4, cdb[2], block_desc); + len = scsi_disk_mode_sense(dev, dev->temp_buffer, 4, + cdb[2], block_desc); if (len > alloc_length) len = alloc_length; dev->temp_buffer[0] = len - 1; @@ -1236,10 +1294,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) alloc_length = len; scsi_disk_set_buf_len(dev, BufLen, &alloc_length); - scsi_disk_log("SCSI HDD %i: Reading mode page: %02X...\n", dev->id, cdb[2]); + scsi_disk_log(dev->log, "Reading mode page: %02X...\n", cdb[2]); scsi_disk_data_command_finish(dev, len, len, alloc_length, 0); - return; + break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: @@ -1257,7 +1315,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->total_length = len; dev->do_page_save = cdb[1] & 1; scsi_disk_data_command_finish(dev, len, len, len, 1); - return; + break; case GPCMD_INQUIRY: max_len = cdb[3]; @@ -1266,7 +1324,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) if ((!max_len) || (*BufLen == 0)) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); - /* scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); */ + /* scsi_disk_log(dev->log, "All done - callback set\n"); */ dev->packet_status = PHASE_COMPLETE; dev->callback = 20.0 * SCSI_TIME; break; @@ -1292,7 +1350,7 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) case 0x83: if (idx + 24 > max_len) { scsi_disk_buf_free(dev); - scsi_disk_data_phase_error(dev); + scsi_disk_data_phase_error(dev, idx + 24); return; } @@ -1300,7 +1358,8 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->temp_buffer[idx++] = 0x00; dev->temp_buffer[idx++] = 0x00; dev->temp_buffer[idx++] = 20; - ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Serial */ + /* Serial */ + ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); idx += 20; if (idx + 72 > cdb[4]) @@ -1309,16 +1368,19 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->temp_buffer[idx++] = 0x01; dev->temp_buffer[idx++] = 0x00; dev->temp_buffer[idx++] = 68; - ide_padstr8(dev->temp_buffer + idx, 8, EMU_NAME); /* Vendor */ + /* Vendor */ + ide_padstr8(dev->temp_buffer + idx, 8, EMU_NAME); idx += 8; - ide_padstr8(dev->temp_buffer + idx, 40, device_identify_ex); /* Product */ + /* Product */ + ide_padstr8(dev->temp_buffer + idx, 40, device_identify_ex); idx += 40; - ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); /* Product */ + /* Product */ + ide_padstr8(dev->temp_buffer + idx, 20, "53R141"); idx += 20; break; default: - scsi_disk_log("INQUIRY: Invalid page: %02X\n", cdb[2]); - scsi_disk_invalid_field(dev); + scsi_disk_log(dev->log, "INQUIRY: Invalid page: %02X\n", cdb[2]); + scsi_disk_invalid_field(dev, cdb[2]); scsi_disk_buf_free(dev); return; } @@ -1328,19 +1390,23 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) memset(dev->temp_buffer, 0, 8); if ((cdb[1] & 0xe0) || ((dev->cur_lun > 0x00) && (dev->cur_lun < 0xff))) - dev->temp_buffer[0] = 0x7f; /*No physical device on this LUN*/ + dev->temp_buffer[0] = 0x7f; /* No physical device on this LUN */ else - dev->temp_buffer[0] = 0; /*SCSI HD*/ - dev->temp_buffer[1] = 0; /*Fixed*/ - dev->temp_buffer[2] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - dev->temp_buffer[3] = (dev->drv->bus == HDD_BUS_SCSI) ? 0x02 : 0x21; + dev->temp_buffer[0] = 0; /* SCSI HD */ + dev->temp_buffer[1] = 0; /* Fixed */ + /* SCSI-2 compliant */ + dev->temp_buffer[2] = (dev->drv->bus_type == HDD_BUS_SCSI) ? 0x02 : 0x00; + dev->temp_buffer[3] = (dev->drv->bus_type == HDD_BUS_SCSI) ? 0x02 : 0x21; dev->temp_buffer[4] = 31; - dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ - dev->temp_buffer[7] = 0x20; /* Wide bus supported */ + dev->temp_buffer[6] = 1; /* 16-bit transfers supported */ + dev->temp_buffer[7] = 0x20; /* Wide bus supported */ - ide_padstr8(dev->temp_buffer + 8, 8, EMU_NAME); /* Vendor */ - ide_padstr8(dev->temp_buffer + 16, 16, device_identify); /* Product */ - ide_padstr8(dev->temp_buffer + 32, 4, EMU_VERSION_EX); /* Revision */ + /* Vendor */ + ide_padstr8(dev->temp_buffer + 8, 8, EMU_NAME); + /* Product */ + ide_padstr8(dev->temp_buffer + 16, 16, device_identify); + /* Revision */ + ide_padstr8(dev->temp_buffer + 32, 4, EMU_VERSION_EX); idx = 36; if (max_len == 96) { @@ -1412,12 +1478,12 @@ atapi_out: break; default: - scsi_disk_illegal_opcode(dev); + scsi_disk_illegal_opcode(dev, cdb[0]); break; } - /* scsi_disk_log("SCSI HD %i: Phase: %02X, request length: %i\n", dev->id, dev->tf->phase, - dev->tf->request_length); */ + /* scsi_disk_log(dev->log, "Phase: %02X, request length: %i\n", + dev->tf->phase, dev->tf->request_length); */ if ((dev->packet_status == PHASE_COMPLETE) || (dev->packet_status == PHASE_ERROR)) scsi_disk_buf_free(dev); @@ -1435,35 +1501,30 @@ scsi_disk_command_stop(scsi_common_t *sc) static uint8_t scsi_disk_phase_data_out(scsi_common_t *sc) { - scsi_disk_t *dev = (scsi_disk_t *) sc; - uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + scsi_disk_t *dev = (scsi_disk_t *) sc; + const uint8_t scsi_bus = (dev->drv->scsi_id >> 4) & 0x0f; + const uint8_t scsi_id = dev->drv->scsi_id & 0x0f; + const int32_t *BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; + const uint32_t last_sector = hdd_image_get_last_sector(dev->id); + int len = 0; + uint8_t error = 0; + int ret = 1; int i; - const int32_t *BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; - uint32_t last_sector = hdd_image_get_last_sector(dev->id); - uint32_t c; - uint32_t h; - uint32_t s; - int len = 0; - uint32_t last_to_write = 0; + uint32_t last_to_write; uint16_t block_desc_len; uint16_t pos; uint16_t param_list_len; uint8_t hdr_len; uint8_t val; - uint8_t old_val; - uint8_t ch; - uint8_t error = 0; - uint8_t page; - uint8_t page_len; - if (!*BufLen) { + if (!*BufLen) scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); + else switch (dev->current_cdb[0]) { + default: + log_fatal(dev->log, "Bad Command for phase 2 (%02X)\n", dev->current_cdb[0]); + ret = 0; + break; - return 1; - } - - switch (dev->current_cdb[0]) { case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: @@ -1489,9 +1550,9 @@ scsi_disk_phase_data_out(scsi_common_t *sc) dev->temp_buffer[2] = (i >> 8) & 0xff; dev->temp_buffer[3] = i & 0xff; } else if (dev->current_cdb[1] & 4) { - s = (i % dev->drv->spt); - h = ((i - s) / dev->drv->spt) % dev->drv->hpc; - c = ((i - s) / dev->drv->spt) / dev->drv->hpc; + uint32_t s = (i % dev->drv->spt); + uint32_t h = ((i - s) / dev->drv->spt) % dev->drv->hpc; + uint32_t c = ((i - s) / dev->drv->spt) / dev->drv->hpc; dev->temp_buffer[0] = (c >> 16) & 0xff; dev->temp_buffer[1] = (c >> 8) & 0xff; dev->temp_buffer[2] = c & 0xff; @@ -1501,7 +1562,8 @@ scsi_disk_phase_data_out(scsi_common_t *sc) dev->temp_buffer[6] = (s >> 8) & 0xff; dev->temp_buffer[7] = s & 0xff; } - hdd_image_write(dev->id, i, 1, dev->temp_buffer); + if (hdd_image_write(dev->id, i, 1, dev->temp_buffer) < 0) + scsi_disk_write_error(dev); } break; case GPCMD_MODE_SELECT_6: @@ -1516,7 +1578,7 @@ scsi_disk_phase_data_out(scsi_common_t *sc) param_list_len = dev->current_cdb[4]; } - if (dev->drv->bus == HDD_BUS_SCSI) { + if (dev->drv->bus_type == HDD_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = dev->temp_buffer[2]; block_desc_len <<= 8; @@ -1533,27 +1595,29 @@ scsi_disk_phase_data_out(scsi_common_t *sc) while (1) { if (pos >= param_list_len) { - scsi_disk_log("SCSI HD %i: Buffer has only block descriptor\n", dev->id); + scsi_disk_log(dev->log, "Buffer has only block descriptor\n"); break; } - page = dev->temp_buffer[pos] & 0x3F; - page_len = dev->temp_buffer[pos + 1]; + const uint8_t page = dev->temp_buffer[pos] & 0x3f; + const uint8_t page_len = dev->temp_buffer[pos + 1]; pos += 2; if (!(scsi_disk_mode_sense_page_flags & (1LL << ((uint64_t) page)))) error |= 1; - else { - for (i = 0; i < page_len; i++) { - ch = scsi_disk_mode_sense_pages_changeable.pages[page][i + 2]; - val = dev->temp_buffer[pos + i]; - old_val = dev->ms_pages_saved.pages[page][i + 2]; - if (val != old_val) { - if (ch) - dev->ms_pages_saved.pages[page][i + 2] = val; - else - error |= 1; + else for (i = 0; i < page_len; i++) { + const uint8_t old = dev->ms_pages_saved.pages[page][i + 2]; + const uint8_t ch = scsi_disk_mode_sense_pages_changeable.pages[page][i + 2]; + + val = dev->temp_buffer[pos + i]; + + if (val != old) { + if (ch) + dev->ms_pages_saved.pages[page][i + 2] = val; + else { + scsi_disk_invalid_field_pl(dev, val); + error |= 1; } } } @@ -1568,22 +1632,17 @@ scsi_disk_phase_data_out(scsi_common_t *sc) break; } - if (error) { + if (error) scsi_disk_buf_free(dev); - scsi_disk_invalid_field_pl(dev); - } - break; - default: - fatal("SCSI HDD %i: Bad Command for phase 2 (%02X)\n", dev->id, dev->current_cdb[0]); break; } scsi_disk_command_stop((scsi_common_t *) dev); - return 1; + return ret; } static int -scsi_disk_get_max(int ide_has_dma, int type) +scsi_disk_get_max(UNUSED(const ide_t *ide), int ide_has_dma, const int type) { int ret; @@ -1609,7 +1668,7 @@ scsi_disk_get_max(int ide_has_dma, int type) } static int -scsi_disk_get_timings(int ide_has_dma, int type) +scsi_disk_get_timings(UNUSED(const ide_t *ide), const int ide_has_dma, const int type) { int ret; @@ -1631,29 +1690,28 @@ scsi_disk_get_timings(int ide_has_dma, int type) return ret; } -/** - * Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command +/* + Fill in ide->buffer with the output of the "IDENTIFY PACKET DEVICE" command */ static void -scsi_disk_identify(ide_t *ide, int ide_has_dma) +scsi_disk_identify(const ide_t *ide, const int ide_has_dma) { - const scsi_disk_t *dev; - char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; - - dev = (scsi_disk_t *) ide->sc; + const scsi_disk_t *dev = (scsi_disk_t *) ide->sc; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; device_identify[7] = dev->id + 0x30; - scsi_disk_log("ATAPI Identify: %s\n", device_identify); + scsi_disk_log(dev->log, "ATAPI Identify: %s\n", device_identify); /* ATAPI device, direct-access device, non-removable media, accelerated DRQ */ ide->buffer[0] = 0x8000 | (0 << 8) | 0x00 | (2 << 5); - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + ide->buffer[49] = 0x200; /* LBA supported */ + /* Interpret zero byte count limit as maximum length. */ + ide->buffer[126] = 0xfffe; if (ide_has_dma) { ide->buffer[71] = 30; @@ -1667,19 +1725,13 @@ void scsi_disk_hard_reset(void) { scsi_disk_t *dev; - scsi_device_t *sd; - ide_t *id; - uint8_t scsi_bus; - uint8_t scsi_id; - uint8_t valid = 0; for (uint8_t c = 0; c < HDD_NUM; c++) { - valid = 0; - if (hdd[c].bus == HDD_BUS_SCSI) { - scsi_disk_log("SCSI disk hard_reset drive=%d\n", c); + uint8_t valid = 0; - scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; - scsi_id = hdd[c].scsi_id & 0x0f; + if (hdd[c].bus_type == HDD_BUS_SCSI) { + const uint8_t scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; + const uint8_t scsi_id = hdd[c].scsi_id & 0x0f; /* Make sure to ignore any SCSI disk that has an out of range SCSI bus. */ if (scsi_bus >= SCSI_BUS_MAX) @@ -1701,16 +1753,25 @@ scsi_disk_hard_reset(void) hdd_preset_apply(c); - if (!hdd[c].priv) - hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t)); + if (hdd[c].priv == NULL) { + hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t)); + dev = (scsi_disk_t *) hdd[c].priv; + + char n[1024] = { 0 }; + + sprintf(n, "HDD %i SCSI ", c + 1); + dev->log = log_open(n); + } dev = (scsi_disk_t *) hdd[c].priv; - if (!dev->tf) + scsi_disk_log(dev->log, "SCSI disk hard_reset drive=%d\n", c); + + if (dev->tf == NULL) dev->tf = (ide_tf_t *) calloc(1, sizeof(ide_tf_t)); /* SCSI disk, attach to the SCSI bus. */ - sd = &scsi_devices[scsi_bus][scsi_id]; + scsi_device_t *sd = &scsi_devices[scsi_bus][scsi_id]; sd->sc = (scsi_common_t *) dev; sd->command = scsi_disk_command; @@ -1720,18 +1781,22 @@ scsi_disk_hard_reset(void) sd->command_stop = scsi_disk_command_stop; sd->type = SCSI_FIXED_DISK; - scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); - } else if (hdd[c].bus == HDD_BUS_ATAPI) { + scsi_disk_log(dev->log, "SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id); + } else if (hdd[c].bus_type == HDD_BUS_ATAPI) { /* Make sure to ignore any SCSI disk whose image file name is empty. */ if (strlen(hdd[c].fn) == 0) continue; /* Make sure to ignore any SCSI disk whose image fails to load. */ + /* ATAPI hard disk, attach to the IDE bus. */ - id = ide_get_drive(hdd[c].ide_channel); - /* If the IDE channel is initialized, we attach to it, + ide_t *id = ide_get_drive(hdd[c].ide_channel); + + /* + If the IDE channel is initialized, we attach to it, otherwise, we do nothing - it's going to be a drive - that's not attached to anything. */ + that's not attached to anything. + */ if (id) { if (!hdd_image_load(c)) continue; @@ -1740,7 +1805,7 @@ scsi_disk_hard_reset(void) hdd_preset_apply(c); - if (!hdd[c].priv) + if (hdd[c].priv == NULL) hdd[c].priv = (scsi_disk_t *) calloc(1, sizeof(scsi_disk_t)); dev = (scsi_disk_t *) hdd[c].priv; @@ -1760,12 +1825,15 @@ scsi_disk_hard_reset(void) id->interrupt_drq = 0; ide_atapi_attach(id); - } - scsi_disk_log("ATAPI hard disk drive %i attached to IDE channel %i\n", c, hdd[c].ide_channel); + scsi_disk_log(dev->log, "ATAPI hard disk drive %i attached to IDE channel %i\n", + c, hdd[c].ide_channel); + } } if (valid) { + dev = (scsi_disk_t *) hdd[c].priv; + dev->id = c; dev->drv = &hdd[c]; @@ -1781,28 +1849,32 @@ scsi_disk_hard_reset(void) void scsi_disk_close(void) { - scsi_disk_t *dev; - uint8_t scsi_bus; - uint8_t scsi_id; - for (uint8_t c = 0; c < HDD_NUM; c++) { - if ((hdd[c].bus == HDD_BUS_SCSI) || (hdd[c].bus == HDD_BUS_ATAPI)) { - if (hdd[c].bus == HDD_BUS_SCSI) { - scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; - scsi_id = hdd[c].scsi_id & 0x0f; + if ((hdd[c].bus_type == HDD_BUS_SCSI) || (hdd[c].bus_type == HDD_BUS_ATAPI)) { + if (hdd[c].bus_type == HDD_BUS_SCSI) { + const uint8_t scsi_bus = (hdd[c].scsi_id >> 4) & 0x0f; + const uint8_t scsi_id = hdd[c].scsi_id & 0x0f; memset(&scsi_devices[scsi_bus][scsi_id], 0x00, sizeof(scsi_device_t)); } hdd_image_close(c); - dev = hdd[c].priv; + scsi_disk_t *dev = hdd[c].priv; if (dev) { if (dev->tf) free(dev->tf); + if (dev->log != NULL) { + scsi_disk_log(dev->log, "Log closed\n"); + + log_close(dev->log); + dev->log = NULL; + } + free(dev); + hdd[c].priv = NULL; } } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 527ff373f..048194a96 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -42,8 +42,6 @@ #include <86box/scsi_device.h> #include <86box/scsi_ncr5380.h> -int ncr5380_cmd_len[8] = { 6, 10, 10, 6, 16, 12, 10, 6 }; - #ifdef ENABLE_NCR5380_LOG int ncr5380_do_log = ENABLE_NCR5380_LOG; @@ -62,8 +60,6 @@ ncr5380_log(const char *fmt, ...) # define ncr5380_log(fmt, ...) #endif -#define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) - void ncr5380_irq(ncr_t *ncr, int set_irq) { @@ -86,45 +82,15 @@ ncr5380_set_irq(ncr_t *ncr, int irq) ncr->irq = irq; } -static int -ncr5380_get_dev_id(uint8_t data) -{ - for (uint8_t c = 0; c < SCSI_ID_MAX; c++) { - if (data & (1 << c)) - return c; - } - - return -1; -} - -static int -ncr5380_getmsglen(uint8_t *msgp, int len) -{ - uint8_t msg = msgp[0]; - if (msg == 0 || (msg >= 0x02 && msg <= 0x1f) || msg >= 0x80) - return 1; - if (msg >= 0x20 && msg <= 0x2f) - return 2; - if (len < 2) - return 3; - return msgp[1]; -} - static void ncr5380_reset(ncr_t *ncr) { - ncr->command_pos = 0; - ncr->data_pos = 0; - ncr->state = STATE_IDLE; - ncr->clear_req = 0; - ncr->cur_bus = 0; - ncr->tx_data = 0; + scsi_bus_t *scsi_bus = &ncr->scsibus; + ncr->output_data = 0; - ncr->data_wait = 0; ncr->mode = 0; ncr->tcr = 0; ncr->icr = 0; - ncr->dma_mode = DMA_IDLE; ncr5380_log("NCR Reset\n"); ncr->timer(ncr->priv, 0.0); @@ -132,6 +98,17 @@ ncr5380_reset(ncr_t *ncr) for (int i = 0; i < 8; i++) scsi_device_reset(&scsi_devices[ncr->bus][i]); + scsi_bus->state = STATE_IDLE; + scsi_bus->clear_req = 0; + scsi_bus->wait_complete = 0; + scsi_bus->wait_data = 0; + scsi_bus->bus_in = 0; + scsi_bus->bus_out = 0; + scsi_bus->command_pos = 0; + scsi_bus->data_wait = 0; + scsi_bus->data = 0; + scsi_bus->command_issued = 0; + ncr5380_irq(ncr, 0); } @@ -173,283 +150,29 @@ ncr5380_get_bus_host(ncr_t *ncr) return (bus_host | BUS_SETDATA(ncr->output_data)); } -void -ncr5380_bus_read(ncr_t *ncr) -{ - const scsi_device_t *dev; - int phase; - - /*Wait processes to handle bus requests*/ - if (ncr->clear_req) { - ncr->clear_req--; - if (!ncr->clear_req) { - ncr5380_log("Prelude to command data\n"); - SET_BUS_STATE(ncr, ncr->new_phase); - ncr->cur_bus |= BUS_REQ; - } - } - - if (ncr->wait_data) { - ncr->wait_data--; - if (!ncr->wait_data) { - dev = &scsi_devices[ncr->bus][ncr->target_id]; - SET_BUS_STATE(ncr, ncr->new_phase); - phase = (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN); - - if (phase == SCSI_PHASE_DATA_IN) { - ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++]; - ncr->state = STATE_DATAIN; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP; - } else if (phase == SCSI_PHASE_DATA_OUT) { - if (ncr->new_phase & BUS_IDLE) { - ncr->state = STATE_IDLE; - ncr->cur_bus &= ~BUS_BSY; - } else - ncr->state = STATE_DATAOUT; - } else if (phase == SCSI_PHASE_STATUS) { - ncr->cur_bus |= BUS_REQ; - ncr->state = STATE_STATUS; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP; - } else if (phase == SCSI_PHASE_MESSAGE_IN) { - ncr->state = STATE_MESSAGEIN; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; - } else if (phase == SCSI_PHASE_MESSAGE_OUT) { - ncr->cur_bus |= BUS_REQ; - ncr->state = STATE_MESSAGEOUT; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->target_id >> 5) | BUS_DBP; - } - } - } - - if (ncr->wait_complete) { - ncr->wait_complete--; - if (!ncr->wait_complete) - ncr->cur_bus |= BUS_REQ; - } -} - -void -ncr5380_bus_update(ncr_t *ncr, int bus) -{ - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - double p; - uint8_t sel_data; - int msglen; - - /*Start the SCSI command layer, which will also make the timings*/ - if (bus & BUS_ARB) - ncr->state = STATE_IDLE; - - ncr5380_log("State = %i\n", ncr->state); - - switch (ncr->state) { - case STATE_IDLE: - ncr->clear_req = ncr->wait_data = ncr->wait_complete = 0; - if ((bus & BUS_SEL) && !(bus & BUS_BSY)) { - ncr5380_log("Selection phase\n"); - sel_data = BUS_GETDATA(bus); - - ncr->target_id = ncr5380_get_dev_id(sel_data); - - ncr5380_log("Select - target ID = %i\n", ncr->target_id); - - /*Once the device has been found and selected, mark it as busy*/ - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { - ncr->cur_bus |= BUS_BSY; - ncr->state = STATE_SELECT; - } else { - ncr5380_log("Device not found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - ncr->cur_bus = 0; - } - } - break; - case STATE_SELECT: - if (!(bus & BUS_SEL)) { - if (!(bus & BUS_ATN)) { - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { - ncr5380_log("Device found at ID %i, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - ncr->state = STATE_COMMAND; - ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr5380_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); - ncr->command_pos = 0; - SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); - } else { - ncr->state = STATE_IDLE; - ncr->cur_bus = 0; - } - } else { - ncr5380_log("Set to SCSI Message Out\n"); - ncr->new_phase = SCSI_PHASE_MESSAGE_OUT; - ncr->wait_data = 4; - ncr->msgout_pos = 0; - ncr->is_msgout = 1; - } - } - break; - case STATE_COMMAND: - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - /*Write command byte to the output data register*/ - ncr->command[ncr->command_pos++] = BUS_GETDATA(bus); - ncr->clear_req = 3; - ncr->new_phase = ncr->cur_bus & SCSI_PHASE_MESSAGE_IN; - ncr->cur_bus &= ~BUS_REQ; - - ncr5380_log("Command pos=%i, output data=%02x\n", ncr->command_pos, BUS_GETDATA(bus)); - - if (ncr->command_pos == ncr5380_cmd_len[(ncr->command[0] >> 5) & 7]) { - if (ncr->is_msgout) { - ncr->is_msgout = 0; -#if 0 - ncr->command[1] = (ncr->command[1] & 0x1f) | (ncr->msglun << 5); -#endif - } - - /*Reset data position to default*/ - ncr->data_pos = 0; - - dev = &scsi_devices[ncr->bus][ncr->target_id]; - - ncr5380_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status); - dev->buffer_length = -1; - scsi_device_command_phase0(dev, ncr->command); - ncr5380_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase); - - ncr->period = 1.0; - ncr->wait_data = 4; - ncr->data_wait = 0; - - if (dev->status == SCSI_STATUS_OK) { - /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ - if (dev->buffer_length && ((dev->phase == SCSI_PHASE_DATA_IN) || (dev->phase == SCSI_PHASE_DATA_OUT))) { - p = scsi_device_get_callback(dev); - ncr->period = (p > 0.0) ? p : (((double) dev->buffer_length) * 0.2); - ncr5380_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i, dmamode = %x\n", ncr->target_id, ncr->command[0], scsi_device_get_callback(dev), ncr->period, dev->buffer_length, ncr->dma_mode); - } - } - ncr->new_phase = dev->phase; - } - } - break; - case STATE_DATAIN: - dev = &scsi_devices[ncr->bus][ncr->target_id]; - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - if (ncr->data_pos >= dev->buffer_length) { - ncr->cur_bus &= ~BUS_REQ; - scsi_device_command_phase1(dev); - ncr->new_phase = SCSI_PHASE_STATUS; - ncr->wait_data = 4; - ncr->wait_complete = 8; - } else { - ncr->tx_data = dev->sc->temp_buffer[ncr->data_pos++]; - ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; - if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ - ncr->data_wait |= 1; - ncr5380_log("DMA mode idle in\n"); - ncr->timer(ncr->priv, ncr->period); - } else { - ncr5380_log("DMA mode IN.\n"); - ncr->clear_req = 3; - } - - ncr->cur_bus &= ~BUS_REQ; - ncr->new_phase = SCSI_PHASE_DATA_IN; - } - } - break; - case STATE_DATAOUT: - dev = &scsi_devices[ncr->bus][ncr->target_id]; - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus); - - if (ncr->data_pos >= dev->buffer_length) { - ncr->cur_bus &= ~BUS_REQ; - scsi_device_command_phase1(dev); - ncr->new_phase = SCSI_PHASE_STATUS; - ncr->wait_data = 4; - ncr->wait_complete = 8; - } else { - /*More data is to be transferred, place a request*/ - if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ - ncr->data_wait |= 1; - ncr5380_log("DMA mode idle out\n"); - ncr->timer(ncr->priv, ncr->period); - } else - ncr->clear_req = 3; - - ncr->cur_bus &= ~BUS_REQ; - ncr5380_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); - } - } - break; - case STATE_STATUS: - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - /*All transfers done, wait until next transfer*/ - scsi_device_identify(&scsi_devices[ncr->bus][ncr->target_id], SCSI_LUN_USE_CDB); - ncr->cur_bus &= ~BUS_REQ; - ncr->new_phase = SCSI_PHASE_MESSAGE_IN; - ncr->wait_data = 4; - ncr->wait_complete = 8; - } - break; - case STATE_MESSAGEIN: - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - ncr->cur_bus &= ~BUS_REQ; - ncr->new_phase = BUS_IDLE; - ncr->wait_data = 4; - } - break; - case STATE_MESSAGEOUT: - ncr5380_log("Ack on MSGOUT = %02x\n", (bus & BUS_ACK)); - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { - ncr->msgout[ncr->msgout_pos++] = BUS_GETDATA(bus); - msglen = ncr5380_getmsglen(ncr->msgout, ncr->msgout_pos); - if (ncr->msgout_pos >= msglen) { - if ((ncr->msgout[0] & (0x80 | 0x20)) == 0x80) - ncr->msglun = ncr->msgout[0] & 7; - ncr->cur_bus &= ~BUS_REQ; - ncr->state = STATE_MESSAGE_ID; - } - } - break; - case STATE_MESSAGE_ID: - if ((ncr->target_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[ncr->bus][ncr->target_id])) { - ncr5380_log("Device found at ID %i on MSGOUT, Current Bus BSY=%02x\n", ncr->target_id, ncr->cur_bus); - scsi_device_identify(&scsi_devices[ncr->bus][ncr->target_id], ncr->msglun); - ncr->state = STATE_COMMAND; - ncr->cur_bus = BUS_BSY | BUS_REQ; - ncr5380_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); - ncr->command_pos = 0; - SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); - } - break; - - default: - break; - } - - ncr->bus_in = bus; -} - void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) { + scsi_bus_t *scsi_bus = &ncr->scsibus; int bus_host = 0; ncr5380_log("NCR5380 write(%04x,%02x)\n", port & 7, val); switch (port & 7) { case 0: /* Output data register */ - ncr5380_log("Write: Output data register, val = %02x\n", val); + ncr5380_log("[%04X:%08X]: Write: Output data register, val=%02x\n", CS, cpu_state.pc, val); ncr->output_data = val; break; case 1: /* Initiator Command Register */ - ncr5380_log("Write: Initiator command register\n"); + ncr5380_log("[%04X:%08X]: Write: Initiator command register, val=%02x.\n", CS, cpu_state.pc, val); if ((val & 0x80) && !(ncr->icr & 0x80)) { ncr5380_log("Resetting the 5380\n"); ncr5380_reset(ncr); + ncr5380_irq(ncr, 1); } ncr->icr = val; + ncr5380_log("ICR WaitData=%d, ClearReq=%d.\n", scsi_bus->wait_data, scsi_bus->clear_req); break; case 2: /* Mode register */ @@ -458,14 +181,12 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) ncr->icr &= ~ICR_ARB_LOST; ncr->icr |= ICR_ARB_IN_PROGRESS; } - ncr->mode = val; - - ncr->dma_mode_ext(ncr, ncr->priv); + ncr->dma_mode_ext(ncr, ncr->priv, val); break; case 3: /* Target Command Register */ - ncr5380_log("Write: Target Command register\n"); + ncr5380_log("Write: Target Command register, val=%02x.\n", val); ncr->tcr = val; break; @@ -476,15 +197,15 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) case 5: /* start DMA Send */ ncr5380_log("Write: start DMA send register\n"); /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ - ncr->dma_mode = DMA_SEND; + scsi_bus->tx_mode = DMA_OUT_TX_BUS; if (ncr->dma_send_ext) ncr->dma_send_ext(ncr, ncr->priv); break; case 7: /* start DMA Initiator Receive */ - ncr5380_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); + ncr5380_log("[%04X:%08X]: Write: start DMA initiator receive register, waitdata=%d, clearreq=%d.\n", CS, cpu_state.pc, scsi_bus->wait_data, scsi_bus->clear_req); /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ - ncr->dma_mode = DMA_INITIATOR_RECEIVE; + scsi_bus->tx_mode = DMA_IN_TX_BUS; if (ncr->dma_initiator_receive_ext) ncr->dma_initiator_receive_ext(ncr, ncr->priv); break; @@ -495,12 +216,13 @@ ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr) } bus_host = ncr5380_get_bus_host(ncr); - ncr5380_bus_update(ncr, bus_host); + scsi_bus_update(scsi_bus, bus_host); } uint8_t ncr5380_read(uint16_t port, ncr_t *ncr) { + scsi_bus_t *scsi_bus = &ncr->scsibus; uint8_t ret = 0xff; int bus; int bus_state; @@ -510,13 +232,18 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ncr5380_log("Read: Current SCSI data register\n"); if (ncr->icr & ICR_DBP) { /*Return the data from the output register if on data bus phase from ICR*/ - ncr5380_log("Data Bus Phase, ret = %02x\n", ncr->output_data); - ret = ncr->output_data; + if (scsi_bus->command_issued) { + bus = scsi_bus_read(scsi_bus); + ret = BUS_GETDATA(bus); + } else + ret = ncr->output_data; + + ncr5380_log("[%04X:%08X]: Data Bus Phase, CMDissued=%d, ret=%02x, clearreq=%d, waitdata=%x, txmode=%x.\n", CS, cpu_state.pc, scsi_bus->command_issued, ret, scsi_bus->clear_req, scsi_bus->wait_data, scsi_bus->tx_mode); } else { /*Return the data from the SCSI bus*/ - ncr5380_bus_read(ncr); - ncr5380_log("NCR GetData=%02x\n", BUS_GETDATA(ncr->cur_bus)); - ret = BUS_GETDATA(ncr->cur_bus); + bus = scsi_bus_read(scsi_bus); + ret = BUS_GETDATA(bus); + ncr5380_log("[%04X:%08X]: NCR Get SCSI bus data=%02x.\n", CS, cpu_state.pc, ret); } break; @@ -538,15 +265,12 @@ ncr5380_read(uint16_t port, ncr_t *ncr) case 4: /* Current SCSI Bus status */ ncr5380_log("Read: SCSI bus status register\n"); ret = 0; - ncr5380_bus_read(ncr); - ncr5380_log("NCR cur bus stat=%02x\n", ncr->cur_bus & 0xff); - ret |= (ncr->cur_bus & 0xff); + bus = scsi_bus_read(scsi_bus); + ret |= (bus & 0xff); if (ncr->icr & ICR_SEL) ret |= BUS_SEL; if (ncr->icr & ICR_BSY) ret |= BUS_BSY; - // if ((ret & SCSI_PHASE_MESSAGE_IN) == SCSI_PHASE_MESSAGE_IN) - // ret &= ~BUS_REQ; break; case 5: /* Bus and Status register */ @@ -557,13 +281,12 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ncr5380_log("Get host from Interrupt\n"); /*Check if the phase in process matches with TCR's*/ - if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { + if ((bus & SCSI_PHASE_MESSAGE_IN) == (scsi_bus->bus_out & SCSI_PHASE_MESSAGE_IN)) { ncr5380_log("Phase match\n"); ret |= STATUS_PHASE_MATCH; } - ncr5380_bus_read(ncr); - bus = ncr->cur_bus; + bus = scsi_bus_read(scsi_bus); if ((bus & BUS_ACK) || (ncr->icr & ICR_ACK)) ret |= STATUS_ACK; @@ -592,10 +315,13 @@ ncr5380_read(uint16_t port, ncr_t *ncr) ret |= STATUS_BUSY_ERROR; } ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); + ncr->isr_reg = ret; break; case 6: - ret = ncr->tx_data; + ncr5380_log("Read: Input Data.\n"); + bus = scsi_bus_read(scsi_bus); + ret = BUS_GETDATA(bus); break; case 7: /* reset Parity/Interrupt */ diff --git a/src/scsi/scsi_ncr53c400.c b/src/scsi/scsi_ncr53c400.c index 0e772c16c..10934880f 100644 --- a/src/scsi/scsi_ncr53c400.c +++ b/src/scsi/scsi_ncr53c400.c @@ -121,7 +121,8 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; addr &= 0x3fff; @@ -146,10 +147,9 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr400->busy = 1; - if (!(ncr->mode & MODE_MONITOR_BUSY) && ((scsi_device_get_callback(dev) > 0.0))) - timer_on_auto(&ncr400->timer, ncr->period / 250.0); } - } + } else + ncr53c400_log("No Write.\n"); break; case 0x3980: @@ -167,7 +167,7 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf.\n", val, ncr->dma_mode, ncr->period); + ncr53c400_log("Write block counter register: val=%d, dma mode=%x, period=%lf.\n", val, scsi_bus->tx_mode, scsi_bus->period); ncr400->block_count = val; ncr400->block_count_loaded = 1; @@ -180,15 +180,14 @@ ncr53c400_write(uint32_t addr, uint8_t val, void *priv) } if ((ncr->mode & MODE_DMA) && (dev->buffer_length > 0)) { memset(ncr400->buffer, 0, MIN(128, dev->buffer_length)); - if (ncr->mode & MODE_MONITOR_BUSY) - timer_on_auto(&ncr400->timer, ncr->period); - else if (scsi_device_get_callback(dev) > 0.0) - timer_on_auto(&ncr400->timer, 40.0); + if (ncr400->type == ROM_T130B) + timer_on_auto(&ncr400->timer, 10.0); else - timer_on_auto(&ncr400->timer, ncr->period); - - ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, datawait=%d, enabled=%d.\n", ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, ncr->wait_complete, ncr->wait_data, ncr->wait_complete, ncr->clear_req, ncr->data_wait, timer_is_enabled(&ncr400->timer)); - } + timer_on_auto(&ncr400->timer, scsi_bus->period); + ncr53c400_log("DMA timer on=%02x, callback=%lf, scsi buflen=%d, waitdata=%d, waitcomplete=%d, clearreq=%d, p=%lf enabled=%d.\n", + ncr->mode & MODE_MONITOR_BUSY, scsi_device_get_callback(dev), dev->buffer_length, scsi_bus->wait_data, scsi_bus->wait_complete, scsi_bus->clear_req, scsi_bus->period, timer_is_enabled(&ncr400->timer)); + } else + ncr53c400_log("No Timer.\n"); break; default: @@ -208,7 +207,8 @@ ncr53c400_read(uint32_t addr, void *priv) { ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; uint8_t ret = 0xff; addr &= 0x3fff; @@ -232,7 +232,7 @@ ncr53c400_read(uint32_t addr, void *priv) break; case 0x3900: - if (ncr400->buffer_host_pos >= MIN(128, dev->buffer_length) || (!(ncr400->status_ctrl & CTRL_DATA_DIR))) { + if ((ncr400->buffer_host_pos >= MIN(128, dev->buffer_length)) || (!(ncr400->status_ctrl & CTRL_DATA_DIR))) { ret = 0xff; ncr53c400_log("No Read.\n"); } else { @@ -241,9 +241,6 @@ ncr53c400_read(uint32_t addr, void *priv) if (ncr400->buffer_host_pos == MIN(128, dev->buffer_length)) { ncr400->status_ctrl |= STATUS_BUFFER_NOT_READY; - ncr53c400_log("Transfer busy read, status = %02x.\n", ncr400->status_ctrl); - if (!(ncr->mode & MODE_MONITOR_BUSY) && (scsi_device_get_callback(dev) > 0.0)) - timer_on_auto(&ncr400->timer, ncr->period / 250.0); } } break; @@ -258,7 +255,7 @@ ncr53c400_read(uint32_t addr, void *priv) if (ncr->mode & 0x30) { /*Parity bits*/ if (!(ncr->mode & MODE_DMA)) { /*This is to avoid RTBios 8.10R BIOS problems with the hard disk and detection.*/ ret |= 0x01; /*If the parity bits are set, bit 0 of the 53c400 status port should be set as well.*/ - ncr->mode = 0; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ + ncr->mode = 0x00; /*Required by RTASPI10.SYS otherwise it won't initialize.*/ } } ncr53c400_log("NCR 53c400 status=%02x.\n", ret); @@ -397,42 +394,55 @@ t130b_in(uint16_t port, void *priv) } static void -ncr53c400_dma_mode_ext(void *priv, UNUSED(void *ext_priv)) +ncr53c400_dma_mode_ext(void *priv, void *ext_priv, uint8_t val) { - ncr_t *ncr = (ncr_t *) priv; + ncr53c400_t *ncr400 = (ncr53c400_t *) ext_priv; + ncr_t *ncr = (ncr_t *) priv; + scsi_bus_t *scsi_bus = &ncr->scsibus; /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ - if (!(ncr->mode & MODE_DMA)) { - ncr53c400_log("No DMA mode\n"); - ncr->tcr &= ~TCR_LAST_BYTE_SENT; - ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; + ncr53c400_log("NCR 53c400: Loaded?=%d, DMA mode enabled=%02x, valDMA=%02x.\n", ncr400->block_count_loaded, ncr->mode & MODE_DMA, val & MODE_DMA); + if (!ncr400->block_count_loaded) { + if (!(val & MODE_DMA)) { + ncr->tcr &= ~TCR_LAST_BYTE_SENT; + ncr->isr &= ~STATUS_END_OF_DMA; + scsi_bus->tx_mode = PIO_TX_BUS; + } } } static void ncr53c400_callback(void *priv) { - ncr53c400_t *ncr400 = (void *) priv; + ncr53c400_t *ncr400 = (ncr53c400_t *) priv; ncr_t *ncr = &ncr400->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; int bus; uint8_t c; uint8_t temp; + uint8_t status; - if (ncr->dma_mode != DMA_IDLE) - timer_on_auto(&ncr400->timer, 1.0); - - if (ncr->data_wait & 1) { - ncr->clear_req = 3; - ncr->data_wait &= ~1; + if (scsi_bus->tx_mode != PIO_TX_BUS) { + if (ncr400->type == ROM_T130B) { + ncr53c400_log("PERIOD T130B DMA=%lf.\n", scsi_bus->period / 200.0); + timer_on_auto(&ncr400->timer, scsi_bus->period / 200.0); + } else + timer_on_auto(&ncr400->timer, 1.0); } - if (ncr->dma_mode == DMA_IDLE) - return; + if (scsi_bus->data_wait & 1) { + scsi_bus->clear_req = 3; + scsi_bus->data_wait &= ~1; + } - switch (ncr->dma_mode) { - case DMA_SEND: + if (scsi_bus->tx_mode == PIO_TX_BUS) { + ncr53c400_log("Timer CMD=%02x.\n", scsi_bus->command[0]); + return; + } + + switch (scsi_bus->tx_mode) { + case DMA_OUT_TX_BUS: if (ncr400->status_ctrl & CTRL_DATA_DIR) { ncr53c400_log("DMA_SEND with DMA direction set wrong\n"); break; @@ -450,8 +460,8 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { - ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) + status = scsi_bus_read(scsi_bus); + if (status & BUS_REQ) break; } /* Data ready. */ @@ -460,8 +470,8 @@ ncr53c400_callback(void *priv) bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK; bus |= BUS_SETDATA(temp); - ncr5380_bus_update(ncr, bus | BUS_ACK); - ncr5380_bus_update(ncr, bus & ~BUS_ACK); + scsi_bus_update(scsi_bus, bus | BUS_ACK); + scsi_bus_update(scsi_bus, bus & ~BUS_ACK); ncr400->buffer_pos++; ncr53c400_log("NCR 53c400 Buffer pos for writing = %d\n", ncr400->buffer_pos); @@ -474,6 +484,7 @@ ncr53c400_callback(void *priv) ncr400->block_count = (ncr400->block_count - 1) & 0xff; ncr53c400_log("NCR 53c400 Remaining blocks to be written=%d\n", ncr400->block_count); if (!ncr400->block_count) { + scsi_bus->tx_mode = PIO_TX_BUS; ncr400->block_count_loaded = 0; ncr53c400_log("IO End of write transfer\n"); ncr->tcr |= TCR_LAST_BYTE_SENT; @@ -488,7 +499,7 @@ ncr53c400_callback(void *priv) } break; - case DMA_INITIATOR_RECEIVE: + case DMA_IN_TX_BUS: if (!(ncr400->status_ctrl & CTRL_DATA_DIR)) { ncr53c400_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); break; @@ -504,18 +515,18 @@ ncr53c400_callback(void *priv) while (1) { for (c = 0; c < 10; c++) { - ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) + status = scsi_bus_read(scsi_bus); + if (status & BUS_REQ) break; } /* Data ready. */ - ncr5380_bus_read(ncr); - temp = BUS_GETDATA(ncr->cur_bus); + bus = scsi_bus_read(scsi_bus); + temp = BUS_GETDATA(bus); bus = ncr5380_get_bus_host(ncr); - ncr5380_bus_update(ncr, bus | BUS_ACK); - ncr5380_bus_update(ncr, bus & ~BUS_ACK); + scsi_bus_update(scsi_bus, bus | BUS_ACK); + scsi_bus_update(scsi_bus, bus & ~BUS_ACK); ncr400->buffer[ncr400->buffer_pos++] = temp; ncr53c400_log("NCR 53c400 Buffer pos for reading = %d\n", ncr400->buffer_pos); @@ -527,6 +538,7 @@ ncr53c400_callback(void *priv) ncr400->block_count = (ncr400->block_count - 1) & 0xff; ncr53c400_log("NCR 53c400 Remaining blocks to be read=%d\n", ncr400->block_count); if (!ncr400->block_count) { + scsi_bus->tx_mode = PIO_TX_BUS; ncr400->block_count_loaded = 0; ncr53c400_log("IO End of read transfer\n"); ncr->isr |= STATUS_END_OF_DMA; @@ -544,12 +556,12 @@ ncr53c400_callback(void *priv) break; } - ncr5380_bus_read(ncr); + status = scsi_bus_read(scsi_bus); - if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + if (!(status & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { ncr53c400_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; + scsi_bus->tx_mode = PIO_TX_BUS; ncr400->block_count_loaded = 0; } } @@ -620,16 +632,14 @@ ncr53c400_init(const device_t *info) { const char *bios_ver = NULL; const char *fn; - ncr53c400_t *ncr400; - ncr_t *ncr; - - ncr400 = malloc(sizeof(ncr53c400_t)); - memset(ncr400, 0x00, sizeof(ncr53c400_t)); - ncr = &ncr400->ncr; + ncr53c400_t *ncr400 = calloc(1, sizeof(ncr53c400_t)); + ncr_t *ncr = &ncr400->ncr; + scsi_bus_t *scsi_bus; ncr400->type = info->local; ncr->bus = scsi_get_bus(); + scsi_bus = &ncr->scsibus; switch (ncr400->type) { case ROM_LCS6821N: /* Longshine LCS6821N */ @@ -713,12 +723,17 @@ ncr53c400_init(const device_t *info) ncr->dma_send_ext = NULL; ncr->dma_initiator_receive_ext = NULL; ncr->timer = ncr53c400_timer_on_auto; + scsi_bus->bus_device = ncr->bus; + scsi_bus->timer = ncr->timer; + scsi_bus->priv = ncr->priv; ncr400->status_ctrl = STATUS_BUFFER_NOT_READY; ncr400->buffer_host_pos = 128; timer_add(&ncr400->timer, ncr53c400_callback, ncr400, 0); scsi_bus_set_speed(ncr->bus, 5000000.0); - + scsi_bus->speed = 0.2; + scsi_bus->divider = 2.0; + scsi_bus->multi = 1.750; return ncr400; } @@ -763,14 +778,14 @@ corel_ls2000_available(void) // clang-format off static const device_config_t ncr53c400_mmio_config[] = { { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, { .description = "D000H", .value = 0xd0000 }, @@ -779,36 +794,38 @@ static const device_config_t ncr53c400_mmio_config[] = { { .description = "DC00H", .value = 0xdc000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "None", .value = -1 }, - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t rt1000b_config[] = { { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, { .description = "D000H", .value = 0xd0000 }, @@ -817,36 +834,53 @@ static const device_config_t rt1000b_config[] = { { .description = "DC00H", .value = 0xdc000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "None", .value = -1 }, - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } }, + .bios = { { 0 } } }, { - .name = "bios_ver", - .description = "BIOS Version", - .type = CONFIG_BIOS, + .name = "bios_ver", + .description = "BIOS Revision", + .type = CONFIG_BIOS, .default_string = "v8_10r", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ + .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, "" } }, + { + .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 } }, }, @@ -855,34 +889,35 @@ static const device_config_t rt1000b_config[] = { static const device_config_t rt1000b_mc_config[] = { { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "None", .value = -1 }, - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t t130b_config[] = { { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "Disabled", .value = 0 }, { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, @@ -890,38 +925,41 @@ static const device_config_t t130b_config[] = { { .description = "DC00H", .value = 0xdc000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0350, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0350, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "240H", .value = 0x0240 }, { .description = "250H", .value = 0x0250 }, { .description = "340H", .value = 0x0340 }, { .description = "350H", .value = 0x0350 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "None", .value = -1 }, - { .description = "IRQ 3", .value = 3 }, - { .description = "IRQ 5", .value = 5 }, - { .description = "IRQ 7", .value = 7 }, - { .description = "" } + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -935,7 +973,7 @@ const device_t scsi_lcs6821n_device = { .init = ncr53c400_init, .close = ncr53c400_close, .reset = NULL, - { .available = lcs6821n_available }, + .available = lcs6821n_available, .speed_changed = NULL, .force_redraw = NULL, .config = ncr53c400_mmio_config @@ -949,7 +987,7 @@ const device_t scsi_rt1000b_device = { .init = ncr53c400_init, .close = ncr53c400_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = rt1000b_config @@ -963,7 +1001,7 @@ const device_t scsi_rt1000mc_device = { .init = ncr53c400_init, .close = ncr53c400_close, .reset = NULL, - { .available = rt1000b_mc_available }, + .available = rt1000b_mc_available, .speed_changed = NULL, .force_redraw = NULL, .config = rt1000b_mc_config @@ -977,7 +1015,7 @@ const device_t scsi_t130b_device = { .init = ncr53c400_init, .close = ncr53c400_close, .reset = NULL, - { .available = t130b_available }, + .available = t130b_available, .speed_changed = NULL, .force_redraw = NULL, .config = t130b_config @@ -991,7 +1029,7 @@ const device_t scsi_ls2000_device = { .init = ncr53c400_init, .close = ncr53c400_close, .reset = NULL, - { .available = corel_ls2000_available }, + .available = corel_ls2000_available, .speed_changed = NULL, .force_redraw = NULL, .config = ncr53c400_mmio_config diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 1395c2f6f..f87f22452 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2530,10 +2530,7 @@ ncr53c8xx_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) static void * ncr53c8xx_init(const device_t *info) { - ncr53c8xx_t *dev; - - dev = malloc(sizeof(ncr53c8xx_t)); - memset(dev, 0x00, sizeof(ncr53c8xx_t)); + ncr53c8xx_t *dev = calloc(1, sizeof(ncr53c8xx_t)); dev->bus = scsi_get_bus(); @@ -2666,19 +2663,20 @@ ncr53c8xx_close(void *priv) static const device_config_t ncr53c8xx_pci_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios", + .description = "BIOS Revision", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "SDMS 4.x BIOS", .value = 2 }, { .description = "SDMS 3.x BIOS", .value = 1 }, { .description = "Disable BIOS", .value = 0 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -2692,7 +2690,7 @@ const device_t ncr53c810_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2706,7 +2704,7 @@ const device_t ncr53c810_onboard_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2720,7 +2718,7 @@ const device_t ncr53c815_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, ncr53c8xx_pci_config @@ -2734,7 +2732,7 @@ const device_t ncr53c820_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2748,7 +2746,7 @@ const device_t ncr53c825a_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ncr53c8xx_pci_config @@ -2762,7 +2760,7 @@ const device_t ncr53c860_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ncr53c8xx_pci_config @@ -2776,7 +2774,7 @@ const device_t ncr53c875_pci_device = { .init = ncr53c8xx_init, .close = ncr53c8xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = ncr53c8xx_pci_config diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index be50d9a89..7c991bdb1 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -114,6 +114,7 @@ #define INTR_FC 0x08 #define INTR_BS 0x10 #define INTR_DC 0x20 +#define INTR_ILL 0x40 #define INTR_RST 0x80 #define SEQ_0 0x0 @@ -174,12 +175,11 @@ typedef struct esp_t { uint8_t bus; uint8_t id, lun; Fifo8 cmdfifo; - uint32_t do_cmd; uint8_t cmdfifo_cdb_offset; int data_ready; - int32_t xfer_counter; - int dma_enabled; + int32_t xfer_counter; + int dma_enabled; uint32_t buffer_pos; uint32_t dma_regs[8]; @@ -198,6 +198,7 @@ typedef struct esp_t { struct { uint8_t mode; uint8_t status; + int interrupt; int pos; } dma_86c01; @@ -239,7 +240,7 @@ static void esp_dma_ti_check(esp_t *dev); static void esp_nodma_ti_dataout(esp_t *dev); static void esp_pci_soft_reset(esp_t *dev); static void esp_pci_hard_reset(esp_t *dev); -static void handle_ti(void *priv); +static void handle_ti(esp_t *dev); static int esp_cdb_length(uint8_t *buf) @@ -253,7 +254,7 @@ esp_cdb_length(uint8_t *buf) break; case 1: case 2: - case 6: + case 6: /*Vendor unique*/ cdb_len = 10; break; case 4: @@ -292,9 +293,11 @@ esp_irq(esp_t *dev, int level) if (dev->mca) { if (level) { picintlevel(1 << dev->irq, &dev->irq_state); + dev->dma_86c01.mode |= 0x40; esp_log("Raising IRQ...\n"); } else { picintclevel(1 << dev->irq, &dev->irq_state); + dev->dma_86c01.mode &= ~0x40; esp_log("Lowering IRQ...\n"); } } else { @@ -307,8 +310,8 @@ 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 */ - if ((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x3 && - dev->dma_regs[DMA_WBC] == 0) + if (((dev->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x03) && + (dev->dma_regs[DMA_WBC] == 0)) dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; } else dev->dma_regs[DMA_STAT] &= ~DMA_STAT_SCSIINT; @@ -383,7 +386,7 @@ esp_get_tc(esp_t *dev) { uint32_t dmalen; - dmalen = dev->rregs[ESP_TCLO]; + dmalen = dev->rregs[ESP_TCLO] & 0xff; dmalen |= dev->rregs[ESP_TCMID] << 8; dmalen |= dev->rregs[ESP_TCHI] << 16; @@ -395,10 +398,11 @@ esp_set_tc(esp_t *dev, uint32_t dmalen) { uint32_t old_tc = esp_get_tc(dev); - dev->rregs[ESP_TCLO] = dmalen; + dev->rregs[ESP_TCLO] = dmalen & 0xff; dev->rregs[ESP_TCMID] = dmalen >> 8; dev->rregs[ESP_TCHI] = dmalen >> 16; + esp_log("OLDTC=%d, DMALEN=%d.\n", old_tc, dmalen); if (old_tc && !dmalen) dev->rregs[ESP_RSTAT] |= STAT_TC; } @@ -408,10 +412,11 @@ esp_get_stc(esp_t *dev) { uint32_t dmalen; - dmalen = dev->wregs[ESP_TCLO]; - dmalen |= dev->wregs[ESP_TCMID] << 8; - dmalen |= dev->wregs[ESP_TCHI] << 16; + dmalen = dev->wregs[ESP_TCLO] & 0xff; + dmalen |= (dev->wregs[ESP_TCMID] << 8); + dmalen |= (dev->wregs[ESP_TCHI] << 16); + esp_log("STCW=%d.\n", dmalen); return dmalen; } @@ -459,25 +464,25 @@ esp_transfer_data(esp_t *dev) dev->rregs[ESP_RSEQ] = SEQ_CD; break; - case CMD_SELATNS: - case (CMD_SELATNS | CMD_DMA): - /* - * Initial incoming data xfer is complete so raise command - * completion interrupt - */ - dev->rregs[ESP_RINTR] |= INTR_BS; - dev->rregs[ESP_RSEQ] = SEQ_MO; - break; + case CMD_SELATNS: + case (CMD_SELATNS | CMD_DMA): + /* + * Initial incoming data xfer is complete so raise command + * completion interrupt + */ + dev->rregs[ESP_RINTR] |= INTR_BS; + dev->rregs[ESP_RSEQ] = SEQ_MO; + break; - case CMD_TI: - case (CMD_TI | CMD_DMA): - /* - * Bus service interrupt raised because of initial change to - * DATA phase - */ - dev->rregs[ESP_CMD] = 0; - dev->rregs[ESP_RINTR] |= INTR_BS; - break; + case CMD_TI: + case (CMD_TI | CMD_DMA): + /* + * Bus service interrupt raised because of initial change to + * DATA phase + */ + dev->rregs[ESP_CMD] = 0; + dev->rregs[ESP_RINTR] |= INTR_BS; + break; } esp_raise_irq(dev); @@ -621,16 +626,13 @@ esp_hard_reset(esp_t *dev) { memset(dev->rregs, 0, ESP_REGS); memset(dev->wregs, 0, ESP_REGS); - dev->tchi_written = 0; dev->ti_size = 0; fifo8_reset(&dev->fifo); fifo8_reset(&dev->cmdfifo); dev->dma = 0; - dev->do_cmd = 0; + dev->tchi_written = 0; dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; esp_log("ESP Reset\n"); - for (uint8_t i = 0; i < 16; i++) - scsi_device_reset(&scsi_devices[dev->bus][i]); timer_stop(&dev->timer); } @@ -681,7 +683,7 @@ esp_do_dma(esp_t *dev) len = esp_get_tc(dev); - switch (esp_get_phase(dev)) { + switch (esp_get_phase(dev)) { case STAT_MO: len = MIN(len, fifo8_num_free(&dev->cmdfifo)); if (dev->mca) { @@ -787,7 +789,6 @@ esp_do_dma(esp_t *dev) 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); - dev->buffer_pos += len; dev->xfer_counter -= len; dev->ti_size += len; @@ -827,6 +828,7 @@ esp_do_dma(esp_t *dev) /* Defer until data is available. */ return; } + if (len > dev->xfer_counter) len = dev->xfer_counter; @@ -861,14 +863,6 @@ esp_do_dma(esp_t *dev) break; } - if ((dev->xfer_counter <= 0) && !dev->ti_size && esp_get_tc(dev)) { - /* If the guest underflows TC then terminate SCSI request */ - esp_log("ESP SCSI Read finished (underflow).\n"); - scsi_device_command_phase1(sd); - esp_command_complete(dev, sd->status); - return; - } - if ((dev->xfer_counter <= 0) && (fifo8_num_used(&dev->fifo) < 2)) { /* Defer until the scsi layer has completed */ if (dev->ti_size <= 0) { @@ -1241,10 +1235,8 @@ handle_pad(esp_t *dev) } static void -handle_ti(void *priv) +handle_ti(esp_t *dev) { - esp_t *dev = (esp_t *) priv; - if (dev->dma) { esp_log("ESP Handle TI, do data, minlen = %i\n", esp_get_tc(dev)); esp_do_dma(dev); @@ -1329,8 +1321,6 @@ esp_callback(void *priv) handle_pad(dev); } } - - esp_log("ESP DMA activated = %d, CMD activated = %d, CMD = %02x\n", dev->dma_enabled, dev->do_cmd, (dev->rregs[ESP_CMD] & CMD_CMD)); } static uint32_t @@ -1353,13 +1343,15 @@ esp_reg_read(esp_t *dev, uint32_t saddr) esp_lower_irq(dev); esp_log("ESP RINTR read old val = %02x\n", ret); break; - case ESP_TCHI: - /* Return the unique id if the value has never been written */ - if (!dev->tchi_written && !dev->mca) { - esp_log("ESP TCHI read id 0x12\n"); - ret = TCHI_AM53C974; - } else - ret = dev->rregs[saddr]; + case ESP_TCHI: /* Return the unique id if the value has never been written */ + if (dev->mca) { + ret = dev->rregs[ESP_TCHI]; + } else { + if (!dev->tchi_written) + ret = TCHI_AM53C974; + else + ret = dev->rregs[ESP_TCHI]; + } break; case ESP_RFLAGS: ret = fifo8_num_used(&dev->fifo); @@ -1376,14 +1368,13 @@ static void esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) { esp_log("Write reg %02x = %02x\n", saddr, val); - switch (saddr) { case ESP_TCHI: dev->tchi_written = 1; fallthrough; case ESP_TCLO: case ESP_TCMID: - esp_log("Transfer count regs %02x = %i\n", saddr, val); + esp_log("ESP TCW reg%02x = %02x.\n", saddr, val); dev->rregs[ESP_RSTAT] &= ~STAT_TC; break; case ESP_FIFO: @@ -1393,14 +1384,18 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_do_nodma(dev); break; case ESP_CMD: - dev->rregs[saddr] = val; + dev->rregs[ESP_CMD] = val; if (val & CMD_DMA) { dev->dma = 1; /* Reload DMA counter. */ esp_set_tc(dev, esp_get_stc(dev)); - if (!esp_get_stc(dev)) - esp_set_tc(dev, 0x10000); + if (!esp_get_stc(dev)) { + if (dev->rregs[ESP_CFG2] & 0x40) + esp_set_tc(dev, 0x1000000); + else + esp_set_tc(dev, 0x10000); + } } else { dev->dma = 0; esp_log("ESP Command not for DMA\n"); @@ -1481,6 +1476,8 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) } break; case ESP_WBUSID: + esp_log("ESP BUS ID=%d.\n", val & BUSID_DID); + break; case ESP_WSEL: case ESP_WSYNTP: case ESP_WSYNO: @@ -1505,6 +1502,7 @@ 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; @@ -1513,31 +1511,58 @@ esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) else expected_dir = WRITE_TO_DEVICE; - esp_log("ESP DMA WBC = %d, addr = %06x, expected direction = %d, dir = %i\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir, dir); - if (dir != expected_dir) { esp_log("ESP unexpected direction\n"); return; } - addr = dev->dma_regs[DMA_WAC]; - if (dev->dma_regs[DMA_WBC] < len) - len = dev->dma_regs[DMA_WBC]; + 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 (expected_dir) - dma_bm_write(addr, buf, len, 4); - else - dma_bm_read(addr, buf, len, 4); + 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]; - esp_log("DMA: Address = %08X, Length = %08X (%02X %02X %02X %02X -> %02X %02X %02X %02X)\n", dev->dma_regs[DMA_SPA], len, - ram[dev->dma_regs[DMA_SPA]], ram[dev->dma_regs[DMA_SPA] + 1], ram[dev->dma_regs[DMA_SPA] + 2], ram[dev->dma_regs[DMA_SPA] + 3], - buf[0], buf[1], buf[2], buf[3]); + 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); - /* 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; + 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 (dev->dma_regs[DMA_WBC] <= 0) { + dev->dma_regs[DMA_WBC] = 0; + dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; + } + } + } + } else { + if (dev->dma_regs[DMA_WBC] < len) + len = dev->dma_regs[DMA_WBC]; + + addr = dev->dma_regs[DMA_WAC]; + + if (expected_dir) + dma_bm_write(addr, buf, len, 4); + else + dma_bm_read(addr, buf, len, 4); + + /* 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; + } } static uint32_t @@ -1566,7 +1591,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) switch (saddr) { case DMA_CMD: - dev->dma_regs[saddr] = val; + dev->dma_regs[DMA_CMD] = val; esp_log("ESP PCI DMA Write CMD = %02x\n", val & DMA_CMD_MASK); switch (val & DMA_CMD_MASK) { case 0: /*IDLE*/ @@ -1580,21 +1605,32 @@ 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_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]; - dev->dma_regs[DMA_WAC] = dev->dma_regs[DMA_SPA]; - dev->dma_regs[DMA_WMAC] = dev->dma_regs[DMA_SMDLA]; 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\n"); + 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]); break; default: /* can't happen */ abort(); + break; } break; case DMA_STC: + dev->dma_regs[DMA_STC] = val; + esp_log("DMASTC PCI write=%08x.\n", val); + break; case DMA_SPA: + dev->dma_regs[DMA_SPA] = val; + esp_log("DMASPA PCI write=%08x.\n", val); + break; case DMA_SMDLA: - dev->dma_regs[saddr] = val; + dev->dma_regs[DMA_SMDLA] = val; + esp_log("DMASMDLA PCI write=%08x.\n", val); break; case DMA_STAT: if (dev->sbac & SBAC_STATUS) { @@ -1629,7 +1665,7 @@ esp_pci_hard_reset(esp_t *dev) dev->dma_regs[DMA_STAT] &= ~(DMA_STAT_BCMBLT | DMA_STAT_SCSIINT | DMA_STAT_DONE | DMA_STAT_ABORT | DMA_STAT_ERROR); - dev->dma_regs[DMA_WMAC] = 0xfffffffd; + dev->dma_regs[DMA_WMAC] = 0xfffffffc; } static uint32_t @@ -1680,7 +1716,7 @@ esp_io_pci_write(esp_t *dev, uint32_t addr, uint32_t val, unsigned int size) current = dev->wregs[addr >> 2]; } else if (addr < 0x60) { current = dev->dma_regs[(addr - 0x40) >> 2]; - } else if (addr < 0x74) { + } else if (addr == 0x70) { current = dev->sbac; } @@ -2008,7 +2044,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) case 0x07: return esp_pci_regs[0x07] | 0x02; case 0x08: - return 0; /*Revision ID*/ + return 0x10; /*Revision ID*/ case 0x09: return 0; /*Programming interface*/ case 0x0A: @@ -2018,7 +2054,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) case 0x0E: return 0; /*Header type */ case 0x10: - return (esp_pci_bar[0].addr_regs[0] & 0x80) | 0x01; /*I/O space*/ + return esp_pci_bar[0].addr_regs[0] | 0x01; /*I/O space*/ case 0x11: return esp_pci_bar[0].addr_regs[1]; case 0x12: @@ -2082,7 +2118,7 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) switch (addr) { case 0x04: - valxor = (val & 3) ^ esp_pci_regs[addr]; + valxor = (val & 0x01) ^ esp_pci_regs[addr]; if (valxor & PCI_COMMAND_IO) { esp_io_remove(dev, dev->PCIBase, 0x80); if ((val & PCI_COMMAND_IO) && (dev->PCIBase != 0)) @@ -2168,10 +2204,7 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) static void * dc390_init(UNUSED(const device_t *info)) { - esp_t *dev; - - dev = malloc(sizeof(esp_t)); - memset(dev, 0x00, sizeof(esp_t)); + esp_t *dev = calloc(1, sizeof(esp_t)); dev->bus = scsi_get_bus(); @@ -2215,6 +2248,8 @@ dc390_init(UNUSED(const device_t *info)) } esp_pci_hard_reset(dev); + for (uint8_t i = 0; i < 16; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); timer_add(&dev->timer, esp_callback, dev, 0); @@ -2240,12 +2275,12 @@ ncr53c9x_in(uint16_t port, void *priv) break; case 0x0c: - if (dev->rregs[ESP_RSTAT] & STAT_INT) + if (dev->dma_86c01.mode & 0x40) dev->dma_86c01.status |= 0x01; else dev->dma_86c01.status &= ~0x01; - if ((dev->dma_86c01.mode & 0x40) || dev->dma_enabled) + if (dev->dma_enabled) dev->dma_86c01.status |= 0x02; else dev->dma_86c01.status &= ~0x02; @@ -2258,7 +2293,7 @@ ncr53c9x_in(uint16_t port, void *priv) } } - esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x.\n\n", CS, cpu_state.pc, port, ret); + esp_log("[%04X:%08X]: NCR53c9x DMA read port = %02x, ret = %02x, local = %d.\n\n", CS, cpu_state.pc, port, ret, dev->local); return ret; } @@ -2282,7 +2317,7 @@ ncr53c9x_out(uint16_t port, uint16_t val, void *priv) port &= 0x1f; - esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); + esp_log("[%04X:%08X]: NCR53c9x DMA write port = %02x, val = %02x.\n\n", CS, cpu_state.pc, port, val); if (port >= 0x10) esp_reg_write(dev, port - 0x10, val); @@ -2360,6 +2395,8 @@ ncr53c9x_mca_write(int port, uint8_t val, void *priv) ncr53c9x_outb, ncr53c9x_outw, NULL, dev); esp_hard_reset(dev); + for (uint8_t i = 0; i < 8; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); } /* Say hello. */ @@ -2377,16 +2414,14 @@ ncr53c9x_mca_feedb(void *priv) } static void * -ncr53c9x_mca_init(UNUSED(const device_t *info)) +ncr53c9x_mca_init(const device_t *info) { - esp_t *dev; - - dev = malloc(sizeof(esp_t)); - memset(dev, 0x00, sizeof(esp_t)); + esp_t *dev = calloc(1, sizeof(esp_t)); dev->bus = scsi_get_bus(); dev->mca = 1; + dev->local = info->local; fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); @@ -2396,6 +2431,8 @@ ncr53c9x_mca_init(UNUSED(const device_t *info)) mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); esp_hard_reset(dev); + for (uint8_t i = 0; i < 8; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); timer_add(&dev->timer, esp_callback, dev, 0); @@ -2421,11 +2458,15 @@ esp_close(void *priv) static const device_config_t bios_enable_config[] = { // clang-format off { - .name = "bios", - .description = "Enable BIOS", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 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 @@ -2439,21 +2480,21 @@ const device_t dc390_pci_device = { .init = dc390_init, .close = esp_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = bios_enable_config }; const device_t am53c974_pci_device = { - .name = "AMD 53c974 PCI", + .name = "AMD 53c974A PCI", .internal_name = "am53c974", .flags = DEVICE_PCI, .local = 1, .init = dc390_init, .close = esp_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -2467,7 +2508,7 @@ const device_t ncr53c90a_mca_device = { .init = ncr53c9x_mca_init, .close = esp_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index ba2817fe3..d6a26b7d0 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -455,11 +455,8 @@ spock_process_imm_cmd(spock_t *scsi) int phys_id; int lun_id; - scsi->assign = 0; - switch (scsi->command & CMD_MASK) { case CMD_ASSIGN: - scsi->assign = 1; adapter_id = (scsi->command >> 16) & 15; phys_id = (scsi->command >> 20) & 7; lun_id = (scsi->command >> 24) & 7; @@ -512,6 +509,7 @@ spock_process_imm_cmd(spock_t *scsi) 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); } } @@ -566,6 +564,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) 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); } } @@ -699,7 +698,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) break; case CMD_DEVICE_INQUIRY: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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); scsi->cdb[0] = GPCMD_INQUIRY; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ @@ -715,9 +718,13 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_SEND_OTHER_SCSI: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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\n", scsi->scb_id, scsi->dev_id[scsi->scb_id].phys_id, scsi->cdb[0], scsi->cdb_id); + 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]); 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; @@ -725,7 +732,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_READ_DEVICE_CAPACITY: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ @@ -743,7 +754,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_READ_DATA: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ @@ -761,7 +776,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_WRITE_DATA: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ @@ -779,7 +798,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_VERIFY: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ @@ -798,7 +821,11 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) return; case CMD_REQUEST_SENSE: - scsi->cdb_id = scsi->assign ? scsi->dev_id[scsi->scb_id].phys_id : scsi->present[scsi->scb_id]; + if (scsi->present[scsi->scb_id] != 0xff) + 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; scsi->cdb[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ @@ -818,7 +845,7 @@ spock_execute_cmd(spock_t *scsi, scb_t *scb) case 2: /* Wait */ if (scsi->scsi_state == SCSI_STATE_IDLE) { - if (scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) { + 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); @@ -878,7 +905,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb) case SCSI_STATE_SELECT: spock_log("Selecting ID %d, SCB ID %d, LUN %d, adapter id = %d.\n", scsi->cdb_id, scsi->scb_id, scsi->dev_id[scsi->scb_id].lun_id, scsi->attention); - if ((scsi->cdb_id != (uint8_t) -1) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) { + if ((scsi->cdb_id != 0xff) && scsi_device_present(&scsi_devices[scsi->bus][scsi->cdb_id])) { scsi->scsi_state = SCSI_STATE_SEND_COMMAND; spock_log("Device selected at ID %i.\n", scsi->cdb_id); } else { @@ -893,6 +920,7 @@ spock_process_scsi(spock_t *scsi, scb_t *scb) break; case SCSI_STATE_SEND_COMMAND: + spock_log("Send Command ID=%d.\n", scsi->cdb_id); sd = &scsi_devices[scsi->bus][scsi->cdb_id]; memset(scsi->temp_cdb, 0x00, 12); @@ -954,9 +982,9 @@ spock_process_scsi(spock_t *scsi, scb_t *scb) } } else { spock_log("Normal Transfer\n"); - if (sd->phase == SCSI_PHASE_DATA_IN) { + if (sd->phase == SCSI_PHASE_DATA_IN) dma_bm_write(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int) scsi->data_len), 2); - } else if (sd->phase == SCSI_PHASE_DATA_OUT) + else if (sd->phase == SCSI_PHASE_DATA_OUT) dma_bm_read(scsi->data_ptr, sd->sc->temp_buffer, MIN(sd->buffer_length, (int) scsi->data_len), 2); } @@ -1077,9 +1105,11 @@ spock_mca_write(int port, uint8_t val, void *priv) if (scsi->pos_regs[2] & 1) { io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, spock_read, spock_readw, NULL, spock_write, spock_writew, NULL, scsi); - if ((scsi->pos_regs[2] & 0xf0) != 0xf0) { - mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); - mem_mapping_enable(&scsi->bios_rom.mapping); + if (scsi->pos_regs[4] & 2) { + if (((scsi->pos_regs[2] >> 4) & 0x0f) != 0x0f) { + mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); + mem_mapping_enable(&scsi->bios_rom.mapping); + } } } spock_log("[%04X:%08X]: POS Write Port = %x, val = %02x, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000); @@ -1120,19 +1150,19 @@ spock_mca_reset(void *priv) /* Reset all devices on controller reset. */ for (uint8_t i = 0; i < 8; i++) { scsi_device_reset(&scsi_devices[scsi->bus][i]); - scsi->present[i] = 0; + scsi->present[i] = 0xff; } spock_log("Reset.\n"); mem_mapping_disable(&scsi->bios_rom.mapping); + scsi->pos_regs[4] = 0x02; spock_mca_write(0x102, 0, scsi); } static void * spock_init(const device_t *info) { - spock_t *scsi = malloc(sizeof(spock_t)); - memset(scsi, 0x00, sizeof(spock_t)); + spock_t *scsi = calloc(1, sizeof(spock_t)); scsi->bus = scsi_get_bus(); @@ -1158,6 +1188,7 @@ spock_init(const device_t *info) scsi->pos_regs[0] = scsi->spock_16bit ? 0xfe : 0xff; scsi->pos_regs[1] = 0x8e; + scsi->pos_regs[4] = 0x02; mca_add(spock_mca_read, spock_mca_write, spock_mca_feedb, spock_mca_reset, scsi); scsi->in_reset = 2; @@ -1200,18 +1231,19 @@ spock_available(void) static const device_config_t spock_rom_config[] = { // clang-format off { - .name = "bios_ver", - .description = "BIOS Version", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_ver", + .description = "BIOS Revision", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "1991 BIOS (>1GB)", .value = 1 }, { .description = "1990 BIOS", .value = 0 }, { .description = "" } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1225,7 +1257,7 @@ const device_t spock_device = { .init = spock_init, .close = spock_close, .reset = NULL, - { .available = spock_available }, + .available = spock_available, .speed_changed = NULL, .force_redraw = NULL, .config = spock_rom_config @@ -1239,7 +1271,7 @@ const device_t tribble_device = { .init = spock_init, .close = spock_close, .reset = NULL, - { .available = spock_available }, + .available = spock_available, .speed_changed = NULL, .force_redraw = NULL, .config = spock_rom_config diff --git a/src/scsi/scsi_t128.c b/src/scsi/scsi_t128.c index 7e42a089d..a40d803f1 100644 --- a/src/scsi/scsi_t128.c +++ b/src/scsi/scsi_t128.c @@ -69,7 +69,8 @@ t128_write(uint32_t addr, uint8_t val, void *priv) { t128_t *t128 = (t128_t *) priv; ncr_t *ncr = &t128->ncr; - const scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + const scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; addr &= 0x3fff; if ((addr >= 0x1800) && (addr < 0x1880)) @@ -84,7 +85,7 @@ t128_write(uint32_t addr, uint8_t val, void *priv) ncr5380_write((addr - 0x1d00) >> 5, val, ncr); else if ((addr >= 0x1e00) && (addr < 0x2000)) { if ((t128->host_pos < MIN(512, dev->buffer_length)) && - (ncr->dma_mode == DMA_SEND)) { + (scsi_bus->tx_mode == DMA_OUT_TX_BUS)) { t128->buffer[t128->host_pos] = val; t128->host_pos++; @@ -106,7 +107,8 @@ t128_read(uint32_t addr, void *priv) { t128_t *t128 = (t128_t *) priv; ncr_t *ncr = &t128->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; uint8_t ret = 0xff; addr &= 0x3fff; @@ -124,7 +126,7 @@ t128_read(uint32_t addr, void *priv) ret = ncr5380_read((addr - 0x1d00) >> 5, ncr); else if (addr >= 0x1e00 && addr < 0x2000) { if ((t128->host_pos >= MIN(512, dev->buffer_length)) || - (ncr->dma_mode != DMA_INITIATOR_RECEIVE)) + (scsi_bus->tx_mode != DMA_IN_TX_BUS)) ret = 0xff; else { ret = t128->buffer[t128->host_pos++]; @@ -135,8 +137,8 @@ t128_read(uint32_t addr, void *priv) if (t128->host_pos == MIN(512, dev->buffer_length)) { t128->status &= ~0x04; t128_log("T128 Transfer busy read, status = %02x, period = %lf\n", - t128->status, ncr->period); - if ((ncr->period == 0.2) || (ncr->period == 0.02)) + t128->status, scsi_bus->period); + if ((scsi_bus->period == 0.2) || (scsi_bus->period == 0.02)) timer_on_auto(&t128->timer, 40.2); } else if ((t128->host_pos < MIN(512, dev->buffer_length)) && (scsi_device_get_callback(dev) > 100.0)) @@ -148,15 +150,16 @@ t128_read(uint32_t addr, void *priv) } static void -t128_dma_mode_ext(void *priv, void *ext_priv) +t128_dma_mode_ext(void *priv, void *ext_priv, UNUSED(uint8_t val)) { t128_t *t128 = (t128_t *) ext_priv; ncr_t *ncr = (ncr_t *) priv; + scsi_bus_t *scsi_bus = &ncr->scsibus; /*Don't stop the timer until it finishes the transfer*/ if (t128->block_loaded && (ncr->mode & MODE_DMA)) { t128_log("Continuing DMA mode\n"); - timer_on_auto(&t128->timer, ncr->period + 1.0); + timer_on_auto(&t128->timer, scsi_bus->period + 1.0); } /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ @@ -164,7 +167,7 @@ t128_dma_mode_ext(void *priv, void *ext_priv) t128_log("No DMA mode\n"); ncr->tcr &= ~TCR_LAST_BYTE_SENT; ncr->isr &= ~STATUS_END_OF_DMA; - ncr->dma_mode = DMA_IDLE; + scsi_bus->tx_mode = PIO_TX_BUS; } } @@ -173,7 +176,8 @@ t128_dma_send_ext(void *priv, void *ext_priv) { t128_t *t128 = (t128_t *) ext_priv; ncr_t *ncr = (ncr_t *) priv; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) { memset(t128->buffer, 0, MIN(512, dev->buffer_length)); @@ -194,7 +198,8 @@ t128_dma_initiator_receive_ext(void *priv, void *ext_priv) { t128_t *t128 = (t128_t *) ext_priv; ncr_t *ncr = (ncr_t *) priv; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; if ((ncr->mode & MODE_DMA) && !timer_is_on(&t128->timer) && (dev->buffer_length > 0)) { memset(t128->buffer, 0, MIN(512, dev->buffer_length)); @@ -227,27 +232,29 @@ t128_callback(void *priv) { t128_t *t128 = (void *) priv; ncr_t *ncr = &t128->ncr; - scsi_device_t *dev = &scsi_devices[ncr->bus][ncr->target_id]; - int bus; - uint8_t c; - uint8_t temp; + scsi_bus_t *scsi_bus = &ncr->scsibus; + scsi_device_t *dev = &scsi_devices[ncr->bus][scsi_bus->target_id]; + int bus; + uint8_t c; + uint8_t temp; + uint8_t status; - if ((ncr->dma_mode != DMA_IDLE) && (ncr->mode & MODE_DMA) && t128->block_loaded) { + if ((scsi_bus->tx_mode != PIO_TX_BUS) && (ncr->mode & MODE_DMA) && t128->block_loaded) { if ((t128->host_pos == MIN(512, dev->buffer_length)) && t128->block_count) t128->status |= 0x04; - timer_on_auto(&t128->timer, ncr->period / 55.0); + timer_on_auto(&t128->timer, scsi_bus->period / 55.0); } - if (ncr->data_wait & 1) { - ncr->clear_req = 3; - ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) + if (scsi_bus->data_wait & 1) { + scsi_bus->clear_req = 3; + scsi_bus->data_wait &= ~1; + if (scsi_bus->tx_mode == PIO_TX_BUS) return; } - switch (ncr->dma_mode) { - case DMA_SEND: + switch (scsi_bus->tx_mode) { + case DMA_OUT_TX_BUS: if (!(t128->status & 0x04)) { t128_log("Write status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos); break; @@ -263,8 +270,8 @@ t128_callback(void *priv) write_again: for (c = 0; c < 10; c++) { - ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) + status = scsi_bus_read(scsi_bus); + if (status & BUS_REQ) break; } @@ -274,8 +281,8 @@ write_again: bus = ncr5380_get_bus_host(ncr) & ~BUS_DATAMASK; bus |= BUS_SETDATA(temp); - ncr5380_bus_update(ncr, bus | BUS_ACK); - ncr5380_bus_update(ncr, bus & ~BUS_ACK); + scsi_bus_update(scsi_bus, bus | BUS_ACK); + scsi_bus_update(scsi_bus, bus & ~BUS_ACK); t128->pos++; t128_log("T128 Buffer pos for writing = %d\n", t128->pos); @@ -302,7 +309,7 @@ write_again: goto write_again; break; - case DMA_INITIATOR_RECEIVE: + case DMA_IN_TX_BUS: if (!(t128->status & 0x04)) { t128_log("Read status busy, block count = %i, host pos = %i\n", t128->block_count, t128->host_pos); break; @@ -318,19 +325,19 @@ write_again: read_again: for (c = 0; c < 10; c++) { - ncr5380_bus_read(ncr); - if (ncr->cur_bus & BUS_REQ) + status = scsi_bus_read(scsi_bus); + if (status & BUS_REQ) break; } /* Data ready. */ - ncr5380_bus_read(ncr); - temp = BUS_GETDATA(ncr->cur_bus); + bus = scsi_bus_read(scsi_bus); + temp = BUS_GETDATA(bus); bus = ncr5380_get_bus_host(ncr); - ncr5380_bus_update(ncr, bus | BUS_ACK); - ncr5380_bus_update(ncr, bus & ~BUS_ACK); + scsi_bus_update(scsi_bus, bus | BUS_ACK); + scsi_bus_update(scsi_bus, bus & ~BUS_ACK); t128->buffer[t128->pos++] = temp; t128_log("T128 Buffer pos for reading=%d, temp=%02x, len=%d.\n", t128->pos, temp, dev->buffer_length); @@ -360,12 +367,12 @@ read_again: break; } - ncr5380_bus_read(ncr); + status = scsi_bus_read(scsi_bus); - if (!(ncr->cur_bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + if (!(status & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { t128_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; + scsi_bus->tx_mode = PIO_TX_BUS; timer_on_auto(&t128->timer, 10.0); } } @@ -465,14 +472,12 @@ t228_feedb(void *priv) static void * t128_init(const device_t *info) { - t128_t *t128; - ncr_t *ncr; - - t128 = malloc(sizeof(t128_t)); - memset(t128, 0x00, sizeof(t128_t)); - ncr = &t128->ncr; + t128_t *t128 = calloc(1, sizeof(t128_t)); + ncr_t *ncr = &t128->ncr; + scsi_bus_t *scsi_bus; ncr->bus = scsi_get_bus(); + scsi_bus = &ncr->scsibus; if (info->flags & DEVICE_MCA) { rom_init(&t128->bios_rom, T128_ROM, @@ -504,15 +509,24 @@ t128_init(const device_t *info) ncr->dma_send_ext = t128_dma_send_ext; ncr->dma_initiator_receive_ext = t128_dma_initiator_receive_ext; ncr->timer = t128_timer_on_auto; + scsi_bus->bus_device = ncr->bus; + scsi_bus->timer = ncr->timer; + scsi_bus->priv = ncr->priv; t128->status = 0x00 /*0x04*/; t128->host_pos = 512; if (!t128->bios_enabled && !(info->flags & DEVICE_MCA)) t128->status |= 0x80; + if (info->flags & DEVICE_MCA) + t128->status |= 0x08; + if (info->local == 0) timer_add(&t128->timer, t128_callback, t128, 0); scsi_bus_set_speed(ncr->bus, 5000000.0); + scsi_bus->speed = 0.2; + scsi_bus->divider = 1.0; + scsi_bus->multi = 1.0; return t128; } @@ -540,43 +554,49 @@ t128_available(void) // clang-format off static const device_config_t t128_config[] = { { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = "", - .default_int = 0xD8000, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xD8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "C800H", .value = 0xc8000 }, { .description = "CC00H", .value = 0xcc000 }, { .description = "D800H", .value = 0xd8000 }, { .description = "DC00H", .value = 0xdc000 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "None", .value = -1 }, { .description = "IRQ 3", .value = 3 }, { .description = "IRQ 5", .value = 5 }, { .description = "IRQ 7", .value = 7 }, { .description = "" } }, + .bios = { { 0 } } }, { - .name = "boot", - .description = "Enable Boot ROM", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "boot", + .description = "Enable BIOS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -590,13 +610,12 @@ const device_t scsi_t128_device = { .init = t128_init, .close = t128_close, .reset = NULL, - { .available = t128_available }, + .available = t128_available, .speed_changed = NULL, .force_redraw = NULL, .config = t128_config }; - const device_t scsi_t228_device = { .name = "Trantor T228", .internal_name = "t228", @@ -605,7 +624,7 @@ const device_t scsi_t228_device = { .init = t128_init, .close = t128_close, .reset = NULL, - { .available = t128_available }, + .available = t128_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -619,7 +638,7 @@ const device_t scsi_pas_device = { .init = t128_init, .close = t128_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/scsi/scsi_x54x.c b/src/scsi/scsi_x54x.c index 6876e4385..c248fbe92 100644 --- a/src/scsi/scsi_x54x.c +++ b/src/scsi/scsi_x54x.c @@ -287,10 +287,9 @@ x54x_bios_scsi_command(scsi_device_t *dev, uint8_t *cdb, uint8_t *buf, int len, static uint8_t x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf, int transfer_size) { - uint8_t *cdb; + uint8_t *cdb = (uint8_t *) malloc(12);; uint8_t ret; - cdb = (uint8_t *) malloc(12); memset(cdb, 0, 12); cdb[0] = GPCMD_READ_CDROM_CAPACITY; @@ -305,10 +304,9 @@ x54x_bios_read_capacity(scsi_device_t *sd, uint8_t *buf, int transfer_size) static uint8_t x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf, int transfer_size) { - uint8_t *cdb; + uint8_t *cdb = (uint8_t *) malloc(12); uint8_t ret; - cdb = (uint8_t *) malloc(12); memset(cdb, 0, 12); cdb[0] = GPCMD_INQUIRY; cdb[4] = 36; @@ -324,14 +322,13 @@ x54x_bios_inquiry(scsi_device_t *sd, uint8_t *buf, int transfer_size) static uint8_t x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer, int transfer_size) { - uint8_t *rcbuf; + uint8_t *rcbuf = (uint8_t *) malloc(8); uint8_t ret; int i; memset(buffer, 0x00, 6); - rcbuf = (uint8_t *) malloc(8); - ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size); + ret = x54x_bios_read_capacity(sd, rcbuf, transfer_size); if (ret) { free(rcbuf); return ret; @@ -353,13 +350,12 @@ x54x_bios_command_08(scsi_device_t *sd, uint8_t *buffer, int transfer_size) static int x54x_bios_command_15(scsi_device_t *sd, uint8_t *buffer, int transfer_size) { - uint8_t *inqbuf; + uint8_t *inqbuf = (uint8_t *) malloc(36); uint8_t *rcbuf; uint8_t ret; memset(buffer, 0x00, 6); - inqbuf = (uint8_t *) malloc(36); ret = x54x_bios_inquiry(sd, inqbuf, transfer_size); if (ret) { free(inqbuf); @@ -1896,13 +1892,11 @@ x54x_mem_disable(x54x_t *dev) void * x54x_init(const device_t *info) { - x54x_t *dev; + x54x_t *dev = calloc(1, sizeof(x54x_t)); /* Allocate control block and set up basic stuff. */ - dev = malloc(sizeof(x54x_t)); if (dev == NULL) return dev; - memset(dev, 0x00, sizeof(x54x_t)); dev->type = info->local; dev->card_bus = info->flags; diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index ecb780a9b..6106871bc 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -9,18 +9,39 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c - sio_fdc37c6xx.c sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c +add_library(sio OBJECT + sio_acc3221.c + sio_ali5123.c + sio_f82c710.c + sio_82091aa.c + sio_fdc37c6xx.c + sio_fdc37c67x.c + sio_fdc37c669.c + sio_fdc37c93x.c + sio_fdc37m60x.c sio_it86x1f.c - sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c - sio_prime3b.c sio_prime3c.c - sio_w83787f.c sio_w83877f.c sio_w83977f.c - sio_um8663f.c sio_um8669f.c - sio_vl82c113.c sio_vt82c686.c) + sio_pc87306.c + sio_pc87307.c + sio_pc87309.c + sio_pc87310.c + sio_pc87311.c + sio_pc87332.c + sio_prime3b.c + sio_prime3c.c + sio_w83787f.c + sio_w83877f.c + sio_w83977f.c + sio_um8663f.c + sio_um8669f.c + sio_vl82c113.c + sio_vt82c686.c +) if(SIO_DETECT) target_sources(sio PRIVATE sio_detect.c) diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c index cbe89c682..d3cd5017a 100644 --- a/src/sio/sio_82091aa.c +++ b/src/sio/sio_82091aa.c @@ -78,7 +78,7 @@ lpt1_handler(i82091aa_t *dev) } if ((dev->regs[0x20] & 0x01) && lpt_port) - lpt1_init(lpt_port); + lpt1_setup(lpt_port); lpt1_irq((dev->regs[0x20] & 0x08) ? LPT1_IRQ : LPT2_IRQ); } @@ -257,8 +257,7 @@ i82091aa_close(void *priv) static void * i82091aa_init(const device_t *info) { - i82091aa_t *dev = (i82091aa_t *) malloc(sizeof(i82091aa_t)); - memset(dev, 0, sizeof(i82091aa_t)); + i82091aa_t *dev = (i82091aa_t *) calloc(1, sizeof(i82091aa_t)); dev->fdc = device_add(&fdc_at_device); @@ -290,7 +289,7 @@ const device_t i82091aa_device = { .init = i82091aa_init, .close = i82091aa_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -304,7 +303,7 @@ const device_t i82091aa_398_device = { .init = i82091aa_init, .close = i82091aa_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -318,7 +317,7 @@ const device_t i82091aa_ide_pri_device = { .init = i82091aa_init, .close = i82091aa_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -332,7 +331,7 @@ const device_t i82091aa_ide_device = { .init = i82091aa_init, .close = i82091aa_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_acc3221.c b/src/sio/sio_acc3221.c index 275d9ae2e..203b1c1f1 100644 --- a/src/sio/sio_acc3221.c +++ b/src/sio/sio_acc3221.c @@ -305,7 +305,7 @@ acc3221_lpt_handle(acc3221_t *dev) lpt1_remove(); if (!(dev->regs[0xbe] & REG_BE_LPT1_DISABLE)) - lpt1_init(dev->regs[0xbf] << 2); + lpt1_setup(dev->regs[0xbf] << 2); } static void @@ -437,7 +437,7 @@ acc3221_reset(acc3221_t *dev) serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); lpt1_remove(); - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); lpt1_irq(LPT1_IRQ); fdc_reset(dev->fdc); @@ -454,8 +454,7 @@ acc3221_close(void *priv) static void * acc3221_init(UNUSED(const device_t *info)) { - acc3221_t *dev = (acc3221_t *) malloc(sizeof(acc3221_t)); - memset(dev, 0, sizeof(acc3221_t)); + acc3221_t *dev = (acc3221_t *) calloc(1, sizeof(acc3221_t)); dev->fdc = device_add(&fdc_at_device); @@ -477,7 +476,7 @@ const device_t acc3221_device = { .init = acc3221_init, .close = acc3221_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index 78c585c11..398d00839 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -93,7 +93,7 @@ ali5123_lpt_handler(ali5123_t *dev) if (global_enable && local_enable) { ld_port = make_port(dev, 3) & 0xFFFC; if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - lpt1_init(ld_port); + lpt1_setup(ld_port); } lpt1_irq(lpt_irq); } @@ -133,8 +133,10 @@ ali5123_serial_handler(ali5123_t *dev, int uart) } static void -ali5123_reset(ali5123_t *dev) +ali5123_reset(void *priv) { + ali5123_t *dev = (ali5123_t *) priv; + memset(dev->regs, 0, 48); dev->regs[0x20] = 0x43; @@ -463,8 +465,7 @@ ali5123_close(void *priv) static void * ali5123_init(const device_t *info) { - ali5123_t *dev = (ali5123_t *) malloc(sizeof(ali5123_t)); - memset(dev, 0, sizeof(ali5123_t)); + ali5123_t *dev = (ali5123_t *) calloc(1, sizeof(ali5123_t)); dev->fdc = device_add(&fdc_at_ali_device); @@ -491,8 +492,8 @@ const device_t ali5123_device = { .local = 0x40, .init = ali5123_init, .close = ali5123_close, - .reset = NULL, - { .available = NULL }, + .reset = ali5123_reset, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_detect.c b/src/sio/sio_detect.c index 38faf3c2c..ffa0ec9d0 100644 --- a/src/sio/sio_detect.c +++ b/src/sio/sio_detect.c @@ -65,8 +65,7 @@ sio_detect_close(void *priv) static void * sio_detect_init(UNUSED(const device_t *info)) { - sio_detect_t *dev = (sio_detect_t *) malloc(sizeof(sio_detect_t)); - memset(dev, 0, sizeof(sio_detect_t)); + sio_detect_t *dev = (sio_detect_t *) calloc(1, sizeof(sio_detect_t)); device_add(&fdc_at_smc_device); @@ -110,7 +109,7 @@ const device_t sio_detect_device = { .init = sio_detect_init, .close = sio_detect_close, .reset = NULL, - { .available = NULL }, + .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 d4afb11da..a7aa101c6 100644 --- a/src/sio/sio_f82c710.c +++ b/src/sio/sio_f82c710.c @@ -104,7 +104,7 @@ f82c710_update_ports(upc_t *dev, int set) if (dev->regs[0] & 8) { lpt_addr = dev->regs[6] * 4; - lpt1_init(lpt_addr); + lpt1_setup(lpt_addr); if ((lpt_addr == LPT1_ADDR) || (lpt_addr == LPT_MDA_ADDR)) lpt1_irq(LPT1_IRQ); else if (lpt_addr == LPT2_ADDR) @@ -215,7 +215,7 @@ f82c606_update_ports(upc_t *dev, int set) } if (dev->regs[0] & 8) { - lpt1_init(((uint16_t) dev->regs[6]) << 2); + 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); } @@ -364,8 +364,7 @@ f82c710_close(void *priv) static void * f82c710_init(const device_t *info) { - upc_t *dev = (upc_t *) malloc(sizeof(upc_t)); - memset(dev, 0, sizeof(upc_t)); + upc_t *dev = (upc_t *) calloc(1, sizeof(upc_t)); dev->local = info->local; if (dev->local == 606) { @@ -393,7 +392,7 @@ const device_t f82c606_device = { .init = f82c710_init, .close = f82c710_close, .reset = f82c710_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -407,7 +406,7 @@ const device_t f82c710_device = { .init = f82c710_init, .close = f82c710_close, .reset = f82c710_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_fdc37c669.c b/src/sio/sio_fdc37c669.c index 0cd686991..3be28c6ba 100644 --- a/src/sio/sio_fdc37c669.c +++ b/src/sio/sio_fdc37c669.c @@ -107,7 +107,7 @@ fdc37c669_lpt_handler(fdc37c669_t *dev) lpt_port_remove(dev->id); if ((dev->regs[0x01] & 0x04) && (dev->regs[0x23] >= 0x40)) - lpt_port_init(dev->id, ((uint16_t) (dev->regs[0x23] & mask)) << 2); + lpt_port_setup(dev->id, ((uint16_t) (dev->regs[0x23] & mask)) << 2); } static void @@ -335,8 +335,7 @@ fdc37c669_close(void *priv) static void * fdc37c669_init(const device_t *info) { - fdc37c669_t *dev = (fdc37c669_t *) malloc(sizeof(fdc37c669_t)); - memset(dev, 0, sizeof(fdc37c669_t)); + fdc37c669_t *dev = (fdc37c669_t *) calloc(1, sizeof(fdc37c669_t)); dev->id = next_id; @@ -364,7 +363,7 @@ const device_t fdc37c669_device = { .init = fdc37c669_init, .close = fdc37c669_close, .reset = fdc37c669_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -378,7 +377,7 @@ const device_t fdc37c669_370_device = { .init = fdc37c669_init, .close = fdc37c669_close, .reset = fdc37c669_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_fdc37c67x.c b/src/sio/sio_fdc37c67x.c index 871f3b1c8..931734048 100644 --- a/src/sio/sio_fdc37c67x.c +++ b/src/sio/sio_fdc37c67x.c @@ -134,7 +134,7 @@ fdc37c67x_lpt_handler(fdc37c67x_t *dev) if (global_enable && local_enable) { ld_port = make_port(dev, 3) & 0xFFFC; if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - lpt1_init(ld_port); + lpt1_setup(ld_port); } lpt1_irq(lpt_irq); } @@ -591,8 +591,7 @@ fdc37c67x_close(void *priv) static void * fdc37c67x_init(const device_t *info) { - fdc37c67x_t *dev = (fdc37c67x_t *) malloc(sizeof(fdc37c67x_t)); - memset(dev, 0, sizeof(fdc37c67x_t)); + fdc37c67x_t *dev = (fdc37c67x_t *) calloc(1, sizeof(fdc37c67x_t)); dev->fdc = device_add(&fdc_at_smc_device); @@ -625,7 +624,7 @@ const device_t fdc37c67x_device = { .init = fdc37c67x_init, .close = fdc37c67x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_fdc37c6xx.c b/src/sio/sio_fdc37c6xx.c index c1fb2c1a5..0f3460565 100644 --- a/src/sio/sio_fdc37c6xx.c +++ b/src/sio/sio_fdc37c6xx.c @@ -111,16 +111,16 @@ lpt1_handler(fdc37c6xx_t *dev) lpt1_remove(); switch (dev->regs[1] & 3) { case 1: - lpt1_init(LPT_MDA_ADDR); - lpt1_irq(7); + lpt1_setup(LPT_MDA_ADDR); + lpt1_irq(LPT_MDA_IRQ); break; case 2: - lpt1_init(LPT1_ADDR); - lpt1_irq(7 /*5*/); + lpt1_setup(LPT1_ADDR); + lpt1_irq(LPT1_IRQ /*LPT2_IRQ*/); break; case 3: - lpt1_init(LPT2_ADDR); - lpt1_irq(7 /*5*/); + lpt1_setup(LPT2_ADDR); + lpt1_irq(LPT1_IRQ /*LPT2_IRQ*/); break; default: @@ -252,7 +252,7 @@ fdc37c6xx_reset(fdc37c6xx_t *dev) serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); lpt1_remove(); - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); fdc_reset(dev->fdc); fdc_remove(dev->fdc); @@ -312,8 +312,7 @@ fdc37c6xx_close(void *priv) static void * fdc37c6xx_init(const device_t *info) { - fdc37c6xx_t *dev = (fdc37c6xx_t *) malloc(sizeof(fdc37c6xx_t)); - memset(dev, 0, sizeof(fdc37c6xx_t)); + fdc37c6xx_t *dev = (fdc37c6xx_t *) calloc(1, sizeof(fdc37c6xx_t)); dev->fdc = device_add(&fdc_at_smc_device); @@ -346,7 +345,7 @@ const device_t fdc37c651_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -360,7 +359,7 @@ const device_t fdc37c651_ide_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -374,7 +373,7 @@ const device_t fdc37c661_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -388,7 +387,7 @@ const device_t fdc37c661_ide_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -402,7 +401,7 @@ const device_t fdc37c661_ide_sec_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -416,7 +415,7 @@ const device_t fdc37c663_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -430,7 +429,7 @@ const device_t fdc37c663_ide_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -444,7 +443,7 @@ const device_t fdc37c665_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -458,7 +457,7 @@ const device_t fdc37c665_ide_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -472,7 +471,7 @@ const device_t fdc37c665_ide_pri_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -486,7 +485,7 @@ const device_t fdc37c665_ide_sec_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -500,7 +499,7 @@ const device_t fdc37c666_device = { .init = fdc37c6xx_init, .close = fdc37c6xx_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 949c59552..8d8f76cb6 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -32,26 +32,18 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/keyboard.h> +#include <86box/machine.h> #include <86box/nvr.h> #include <86box/apm.h> +#include <86box/access_bus.h> #include <86box/acpi.h> #include <86box/sio.h> #include <86box/plat_unused.h> -#define AB_RST 0x80 - -typedef struct access_bus_t { - uint8_t control; - uint8_t status; - uint8_t own_addr; - uint8_t data; - uint8_t clock; - uint16_t base; -} access_bus_t; - typedef struct fdc37c93x_t { uint8_t chip_id; uint8_t is_apm; + uint8_t is_compaq; uint8_t has_nvr; uint8_t tries; uint8_t port_370; @@ -60,51 +52,56 @@ typedef struct fdc37c93x_t { uint8_t regs[48]; uint8_t ld_regs[11][256]; uint16_t superio_base; + uint16_t fdc_base; + uint16_t lpt_base; + uint16_t nvr_pri_base; + uint16_t nvr_sec_base; + uint16_t kbc_base; uint16_t gpio_base; /* Set to EA */ uint16_t auxio_base; - uint16_t nvr_sec_base; + uint16_t uart_base[2]; int locked; int cur_reg; fdc_t *fdc; - serial_t *uart[2]; access_bus_t *access_bus; nvr_t *nvr; acpi_t *acpi; void *kbc; + serial_t *uart[2]; } 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 uint16_t -make_port_superio(fdc37c93x_t *dev) +make_port_superio(const fdc37c93x_t *dev) { - uint16_t r0 = dev->regs[0x26]; - uint16_t r1 = dev->regs[0x27]; + const uint16_t r0 = dev->regs[0x26]; + const uint16_t r1 = dev->regs[0x27]; - uint16_t p = (r1 << 8) + r0; + const uint16_t p = (r1 << 8) + r0; return p; } static uint16_t -make_port(fdc37c93x_t *dev, uint8_t ld) +make_port(const fdc37c93x_t *dev, const uint8_t ld) { - uint16_t r0 = dev->ld_regs[ld][0x60]; - uint16_t r1 = dev->ld_regs[ld][0x61]; + const uint16_t r0 = dev->ld_regs[ld][0x60]; + const uint16_t r1 = dev->ld_regs[ld][0x61]; - uint16_t p = (r0 << 8) + r1; + const uint16_t p = (r0 << 8) + r1; return p; } static uint16_t -make_port_sec(fdc37c93x_t *dev, uint8_t ld) +make_port_sec(const fdc37c93x_t *dev, const uint8_t ld) { - uint16_t r0 = dev->ld_regs[ld][0x62]; - uint16_t r1 = dev->ld_regs[ld][0x63]; + const uint16_t r0 = dev->ld_regs[ld][0x62]; + const uint16_t r1 = dev->ld_regs[ld][0x63]; - uint16_t p = (r0 << 8) + r1; + const uint16_t p = (r0 << 8) + r1; return p; } @@ -131,7 +128,8 @@ fdc37c93x_gpio_read(uint16_t port, void *priv) const fdc37c93x_t *dev = (fdc37c93x_t *) priv; uint8_t ret = 0xff; - ret = dev->gpio_regs[port & 1]; + if (strcmp(machine_get_internal_name(), "vectra54")) + ret = dev->gpio_regs[port & 1]; return ret; } @@ -148,66 +146,91 @@ fdc37c93x_gpio_write(uint16_t port, uint8_t val, void *priv) static void fdc37c93x_superio_handler(fdc37c93x_t *dev) { - io_removehandler(dev->superio_base, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); - dev->superio_base = make_port_superio(dev); - io_sethandler(dev->superio_base, 0x0002, - fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); + if (!dev->is_compaq) { + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); + dev->superio_base = make_port_superio(dev); + if (dev->superio_base != 0x0000) + io_sethandler(dev->superio_base, 0x0002, + fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); + } } static void fdc37c93x_fdc_handler(fdc37c93x_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 fdc37c93x_lpt_handler(fdc37c93x_t *dev) { - uint16_t ld_port = 0; - 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]; + 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; 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_init(ld_port); + dev->lpt_base = 0x0000; + + 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); } + lpt1_irq(lpt_irq); } static void -fdc37c93x_serial_handler(fdc37c93x_t *dev, int uart) +fdc37c93x_serial_handler(fdc37c93x_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]; - 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]); } + + serial_irq(dev->uart[uart], dev->ld_regs[uart_no][0x70]); } static void -fdc37c93x_nvr_pri_handler(fdc37c93x_t *dev) +fdc37c93x_nvr_pri_handler(const fdc37c93x_t *dev) { uint8_t local_enable = !!dev->ld_regs[6][0x30]; @@ -222,18 +245,24 @@ fdc37c93x_nvr_pri_handler(fdc37c93x_t *dev) static void fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) { - uint16_t ld_port = 0; - uint8_t local_enable = !!dev->ld_regs[6][0x30]; + uint8_t local_enable = !!dev->ld_regs[6][0x30]; + const uint16_t old_base = dev->nvr_sec_base; local_enable &= (((dev->ld_regs[6][0xf0] & 0xe0) == 0x80) || ((dev->ld_regs[6][0xf0] & 0xe0) == 0xe0)); - nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr); - if (local_enable) { - dev->nvr_sec_base = ld_port = make_port_sec(dev, 6) & 0xFFFE; + dev->nvr_sec_base = 0x0000; + + if (local_enable) + dev->nvr_sec_base = make_port_sec(dev, 6) & 0xfffe; + + if (dev->nvr_sec_base != old_base) { + if ((old_base > 0x0000) && (old_base <= 0x0ffe)) + nvr_at_sec_handler(0, dev->nvr_sec_base, dev->nvr); + /* Datasheet erratum: First it says minimum address is 0x0100, but later implies that it's 0x0000 and that default is 0x0070, same as (unrelocatable) primary NVR. */ - if (ld_port <= 0x0FFE) + if ((dev->nvr_sec_base > 0x0000) && (dev->nvr_sec_base <= 0x0ffe)) nvr_at_sec_handler(1, dev->nvr_sec_base, dev->nvr); } } @@ -241,22 +270,32 @@ fdc37c93x_nvr_sec_handler(fdc37c93x_t *dev) static void fdc37c93x_kbc_handler(fdc37c93x_t *dev) { - uint8_t local_enable = !!dev->ld_regs[7][0x30]; + const uint8_t local_enable = !!dev->ld_regs[7][0x30]; + const uint16_t old_base = dev->kbc_base; - kbc_at_handler(local_enable, dev->kbc); + dev->kbc_base = local_enable ? 0x0060 : 0x0000; + + if (dev->kbc_base != old_base) + kbc_at_handler(local_enable, dev->kbc); } static void fdc37c93x_auxio_handler(fdc37c93x_t *dev) { - uint16_t ld_port = 0; - uint8_t local_enable = !!dev->ld_regs[8][0x30]; + const uint8_t local_enable = !!dev->ld_regs[8][0x30]; + const uint16_t old_base = dev->auxio_base; - io_removehandler(dev->auxio_base, 0x0001, - fdc37c93x_auxio_read, NULL, NULL, fdc37c93x_auxio_write, NULL, NULL, dev); - if (local_enable) { - dev->auxio_base = ld_port = make_port(dev, 8); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFF)) + if (local_enable) + dev->auxio_base = make_port(dev, 8); + else + dev->auxio_base = 0x0000; + + if (dev->auxio_base != old_base) { + if ((old_base >= 0x0100) && (old_base <= 0x0fff)) + io_removehandler(old_base, 0x0001, + fdc37c93x_auxio_read, NULL, NULL, fdc37c93x_auxio_write, NULL, NULL, dev); + + if ((dev->auxio_base >= 0x0100) && (dev->auxio_base <= 0x0fff)) io_sethandler(dev->auxio_base, 0x0001, fdc37c93x_auxio_read, NULL, NULL, fdc37c93x_auxio_write, NULL, NULL, dev); } @@ -265,113 +304,55 @@ fdc37c93x_auxio_handler(fdc37c93x_t *dev) static void fdc37c93x_gpio_handler(fdc37c93x_t *dev) { - uint16_t ld_port = 0; - uint8_t local_enable; + const uint8_t local_enable = !dev->locked && !!(dev->regs[0x03] & 0x80); + const uint16_t old_base = dev->gpio_base; - local_enable = !!(dev->regs[0x03] & 0x80); + dev->gpio_base = 0x0000; - io_removehandler(dev->gpio_base, 0x0002, - fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_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, + fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, dev); + + if (dev->gpio_base > 0x0000) io_sethandler(dev->gpio_base, 0x0002, fdc37c93x_gpio_read, NULL, NULL, fdc37c93x_gpio_write, NULL, NULL, dev); } } -static uint8_t -fdc37c93x_access_bus_read(uint16_t port, void *priv) -{ - const access_bus_t *dev = (access_bus_t *) priv; - uint8_t ret = 0xff; - - switch (port & 3) { - case 0: - ret = (dev->status & 0xBF); - break; - case 1: - ret = (dev->own_addr & 0x7F); - break; - case 2: - ret = dev->data; - break; - case 3: - ret = (dev->clock & 0x87); - break; - - default: - break; - } - - return ret; -} - -static void -fdc37c93x_access_bus_write(uint16_t port, uint8_t val, void *priv) -{ - access_bus_t *dev = (access_bus_t *) priv; - - switch (port & 3) { - case 0: - dev->control = (val & 0xCF); - break; - case 1: - dev->own_addr = (val & 0x7F); - break; - case 2: - dev->data = val; - break; - case 3: - dev->clock &= 0x80; - dev->clock |= (val & 0x07); - break; - - default: - break; - } -} - static void fdc37c93x_access_bus_handler(fdc37c93x_t *dev) { - uint16_t ld_port = 0; - uint8_t global_enable = !!(dev->regs[0x22] & (1 << 6)); - uint8_t local_enable = !!dev->ld_regs[9][0x30]; + const uint8_t global_enable = !!(dev->regs[0x22] & (1 << 6)); + const uint8_t local_enable = !!dev->ld_regs[9][0x30]; + const uint16_t ld_port = dev->access_bus->base = make_port(dev, 9); - io_removehandler(dev->access_bus->base, 0x0004, - fdc37c93x_access_bus_read, NULL, NULL, fdc37c93x_access_bus_write, NULL, NULL, dev->access_bus); - if (global_enable && local_enable) { - dev->access_bus->base = ld_port = make_port(dev, 9); - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) - io_sethandler(dev->access_bus->base, 0x0004, - fdc37c93x_access_bus_read, NULL, NULL, fdc37c93x_access_bus_write, NULL, NULL, dev->access_bus); - } + access_bus_handler(dev->access_bus, global_enable && local_enable, ld_port); } static void fdc37c93x_acpi_handler(fdc37c93x_t *dev) { - uint16_t ld_port = 0; - uint8_t local_enable = !!dev->ld_regs[0x0a][0x30]; - uint8_t sci_irq = dev->ld_regs[0x0a][0x70]; + uint16_t ld_port; + const uint8_t local_enable = !!dev->ld_regs[0x0a][0x30]; + const uint8_t sci_irq = dev->ld_regs[0x0a][0x70]; acpi_update_io_mapping(dev->acpi, 0x0000, local_enable); if (local_enable) { @@ -390,41 +371,49 @@ fdc37c93x_acpi_handler(fdc37c93x_t *dev) acpi_set_irq_line(dev->acpi, sci_irq); } +static void +fdc37c93x_state_change(fdc37c93x_t *dev, const uint8_t locked) +{ + dev->locked = locked; + fdc_3f1_enable(dev->fdc, !locked); + fdc37c93x_gpio_handler(dev); +} + 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 valxor = 0x00; - uint8_t keep = 0x00; + uint8_t valxor; /* Compaq Presario 4500: Unlock at FB, Register at EA, Data at EB, Lock at F9. */ - if ((port == 0xea) || (port == 0xf9) || (port == 0xfb)) + if (port == 0xea) index = 1; else if (port == 0xeb) index = 0; - if (index) { - if ((val == 0x55) && !dev->locked) { + if (port == 0xfb) { + fdc37c93x_state_change(dev, 1); + dev->tries = 0; + return; + } else if (port == 0xf9) { + fdc37c93x_state_change(dev, 0); + return; + } else if (index) { + if ((!dev->is_compaq) && (val == 0x55) && !dev->locked) { if (dev->tries) { - dev->locked = 1; - fdc_3f1_enable(dev->fdc, 0); + fdc37c93x_state_change(dev, 1); dev->tries = 0; } else dev->tries++; - } else { - if (dev->locked) { - if (val == 0xaa) { - dev->locked = 0; - fdc_3f1_enable(dev->fdc, 1); - return; - } - dev->cur_reg = val; - } else { - if (dev->tries) - dev->tries = 0; + } else if (dev->locked) { + if ((!dev->is_compaq) && (val == 0xaa)) { + fdc37c93x_state_change(dev, 0); + return; } - } + dev->cur_reg = val; + } else if ((!dev->is_compaq) && dev->tries) + dev->tries = 0; return; } else { if (dev->locked) { @@ -434,6 +423,8 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) return; dev->regs[dev->cur_reg] = val; } else { + uint8_t keep = 0x00; + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; if (((dev->cur_reg & 0xF0) == 0x70) && (dev->regs[7] < 4)) return; @@ -477,9 +468,11 @@ fdc37c93x_write(uint16_t port, uint8_t val, void *priv) if (dev->cur_reg < 48) { switch (dev->cur_reg) { + case 0x02: + if (val == 0x02) + fdc37c93x_state_change(dev, 0); + break; case 0x03: - if (valxor & 0x83) - fdc37c93x_gpio_handler(dev); dev->regs[0x03] &= 0x83; break; case 0x22: @@ -786,91 +779,95 @@ fdc37c93x_read(uint16_t port, void *priv) static void fdc37c93x_reset(fdc37c93x_t *dev) { - memset(dev->regs, 0, 48); + memset(dev->regs, 0x00, sizeof(dev->regs)); dev->regs[0x03] = 0x03; dev->regs[0x20] = dev->chip_id; dev->regs[0x21] = 0x01; dev->regs[0x22] = 0x39; dev->regs[0x24] = 0x04; - if (dev->chip_id != 0x02) { - dev->regs[0x26] = dev->port_370 ? 0x70 : 0xF0; - dev->regs[0x27] = 0x03; - } + 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); + memset(dev->ld_regs, 0x00, sizeof(dev->ld_regs)); /* Logical device 0: FDD */ - dev->ld_regs[0][0x30] = 0; - 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] = 0xE; - 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 1: IDE1 */ - dev->ld_regs[1][0x30] = 0; - dev->ld_regs[1][0x60] = 1; - dev->ld_regs[1][0x61] = 0xF0; - dev->ld_regs[1][0x62] = 3; - dev->ld_regs[1][0x63] = 0xF6; - dev->ld_regs[1][0x70] = 0xE; - dev->ld_regs[1][0xF0] = 0xC; + dev->ld_regs[0x01][0x30] = 0x00; + dev->ld_regs[0x01][0x60] = 0x01; + dev->ld_regs[0x01][0x61] = 0xf0; + dev->ld_regs[0x01][0x62] = 0x03; + dev->ld_regs[0x01][0x63] = 0xf6; + dev->ld_regs[0x01][0x70] = 0x0e; + dev->ld_regs[0x01][0xf0] = 0x0c; /* Logical device 2: IDE2 */ - dev->ld_regs[2][0x30] = 0; - dev->ld_regs[2][0x60] = 1; - dev->ld_regs[2][0x61] = 0x70; - dev->ld_regs[2][0x62] = 3; - dev->ld_regs[2][0x63] = 0x76; - dev->ld_regs[2][0x70] = 0xF; + dev->ld_regs[0x02][0x30] = 0x00; + dev->ld_regs[0x02][0x60] = 0x01; + dev->ld_regs[0x02][0x61] = 0x70; + dev->ld_regs[0x02][0x62] = 0x03; + dev->ld_regs[0x02][0x63] = 0x76; + dev->ld_regs[0x02][0x70] = 0x0f; /* Logical device 3: Parallel Port */ - dev->ld_regs[3][0x30] = 0; - 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] = 0; - 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; + dev->ld_regs[0x04][0xf0] = 0x03; + serial_irq(dev->uart[0], dev->ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ - dev->ld_regs[5][0x30] = 0; - 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 6: RTC */ - dev->ld_regs[6][0x30] = 0; - dev->ld_regs[6][0x60] = 0x70; - if (dev->chip_id != 0x02) - dev->ld_regs[6][0x63] = (dev->has_nvr) ? 0x70 : 0x00; - dev->ld_regs[6][0xF0] = 0; - dev->ld_regs[6][0xF4] = 3; + dev->ld_regs[0x06][0x30] = 0x00; + dev->ld_regs[0x06][0x63] = (dev->has_nvr) ? 0x70 : 0x00; + dev->ld_regs[0x06][0xf0] = 0x00; + dev->ld_regs[0x06][0xf4] = 0x03; /* Logical device 7: Keyboard */ - dev->ld_regs[7][0x30] = 0; - dev->ld_regs[7][0x61] = 0x60; - dev->ld_regs[7][0x70] = 1; + 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; /* Logical device 9: ACCESS.bus */ + 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; fdc37c93x_gpio_handler(dev); fdc37c93x_lpt_handler(dev); @@ -905,37 +902,6 @@ fdc37c93x_reset(fdc37c93x_t *dev) dev->locked = 0; } -static void -access_bus_close(void *priv) -{ - access_bus_t *dev = (access_bus_t *) priv; - - free(dev); -} - -static void * -access_bus_init(UNUSED(const device_t *info)) -{ - access_bus_t *dev = (access_bus_t *) malloc(sizeof(access_bus_t)); - memset(dev, 0, sizeof(access_bus_t)); - - return dev; -} - -static const device_t access_bus_device = { - .name = "SMC FDC37C932FR ACCESS.bus", - .internal_name = "access_bus", - .flags = 0, - .local = 0x03, - .init = access_bus_init, - .close = access_bus_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - static void fdc37c93x_close(void *priv) { @@ -947,20 +913,18 @@ fdc37c93x_close(void *priv) static void * fdc37c93x_init(const device_t *info) { - int is_compaq; - fdc37c93x_t *dev = (fdc37c93x_t *) malloc(sizeof(fdc37c93x_t)); - memset(dev, 0, sizeof(fdc37c93x_t)); + fdc37c93x_t *dev = (fdc37c93x_t *) calloc(1, sizeof(fdc37c93x_t)); dev->fdc = device_add(&fdc_at_smc_device); - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->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; - is_compaq = (info->local >> 8) & 0x02; - dev->has_nvr = !((info->local >> 8) & 0x04); - dev->port_370 = ((info->local >> 8) & 0x08); + 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->gpio_regs[0] = 0xff; #if 0 @@ -981,7 +945,7 @@ fdc37c93x_init(const device_t *info) if (dev->is_apm) dev->acpi = device_add(&acpi_smc_device); - if (is_compaq) { + if (dev->is_compaq) { io_sethandler(0x0ea, 0x0002, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, dev); io_sethandler(0x0f9, 0x0001, @@ -992,6 +956,16 @@ fdc37c93x_init(const device_t *info) dev->kbc = device_add(&keyboard_ps2_ami_pci_device); + /* Set the defaults here so the ports can be removed by fdc37c93x_reset(). */ + dev->fdc_base = 0x03f0; + dev->lpt_base = 0x0378; + dev->uart_base[0] = 0x03f8; + dev->uart_base[1] = 0x02f8; + dev->nvr_pri_base = 0x0070; + dev->nvr_sec_base = 0x0070; + dev->kbc_base = 0x0060; + dev->gpio_base = 0x00ea; + fdc37c93x_reset(dev); if (dev->chip_id == 0x02) { @@ -1012,7 +986,7 @@ const device_t fdc37c931apm_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1026,7 +1000,7 @@ const device_t fdc37c931apm_compaq_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1040,7 +1014,7 @@ const device_t fdc37c932_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1054,7 +1028,7 @@ const device_t fdc37c932fr_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1068,7 +1042,7 @@ const device_t fdc37c932qf_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1082,7 +1056,7 @@ const device_t fdc37c935_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1096,7 +1070,7 @@ const device_t fdc37c935_370_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1110,9 +1084,8 @@ const device_t fdc37c935_no_nvr_device = { .init = fdc37c93x_init, .close = fdc37c93x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; - diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c index 38a163538..11d2f3349 100644 --- a/src/sio/sio_fdc37m60x.c +++ b/src/sio/sio_fdc37m60x.c @@ -216,7 +216,7 @@ fdc37m60x_lpt_handler(fdc37m60x_t *dev) lpt1_remove(); if (ENABLED(3) || (POWER_CONTROL & 0x08)) { - lpt1_init(BASE_ADDRESS(3)); + 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); } @@ -306,8 +306,7 @@ fdc37m60x_close(void *priv) static void * fdc37m60x_init(const device_t *info) { - fdc37m60x_t *dev = (fdc37m60x_t *) malloc(sizeof(fdc37m60x_t)); - memset(dev, 0, sizeof(fdc37m60x_t)); + fdc37m60x_t *dev = (fdc37m60x_t *) calloc(1, sizeof(fdc37m60x_t)); SIO_INDEX_PORT = info->local; dev->fdc = device_add(&fdc_at_smc_device); @@ -329,7 +328,7 @@ const device_t fdc37m60x_device = { .init = fdc37m60x_init, .close = fdc37m60x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -343,7 +342,7 @@ const device_t fdc37m60x_370_device = { .init = fdc37m60x_init, .close = fdc37m60x_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index 00524863a..b3553bf54 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -294,7 +294,7 @@ it8661f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri if (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) { it86x1f_log("IT86x1F: LPT enabled at port %04X IRQ %d\n", config->io[0].base, config->irq[0].irq); - lpt1_init(config->io[0].base); + lpt1_setup(config->io[0].base); } else { it86x1f_log("IT86x1F: LPT disabled\n"); } @@ -602,7 +602,7 @@ it86x1f_pnp_write_vendor_reg(uint8_t ld, uint8_t reg, uint8_t val, void *priv) } static void -it86x1f_write_addr(uint16_t port, uint8_t val, void *priv) +it86x1f_write_addr(UNUSED(uint16_t port), uint8_t val, void *priv) { it86x1f_t *dev = (it86x1f_t *) priv; @@ -623,7 +623,7 @@ it86x1f_write_addr(uint16_t port, uint8_t val, void *priv) } static void -it86x1f_write_data(uint16_t port, uint8_t val, void *priv) +it86x1f_write_data(UNUSED(uint16_t port), uint8_t val, void *priv) { it86x1f_t *dev = (it86x1f_t *) priv; @@ -659,7 +659,7 @@ it86x1f_write_data(uint16_t port, uint8_t val, void *priv) } static uint8_t -it86x1f_read_addr(uint16_t port, void *priv) +it86x1f_read_addr(UNUSED(uint16_t port), void *priv) { it86x1f_t *dev = (it86x1f_t *) priv; uint8_t ret = dev->locked ? 0xff : dev->cur_reg; @@ -670,7 +670,7 @@ it86x1f_read_addr(uint16_t port, void *priv) } static uint8_t -it86x1f_read_data(uint16_t port, void *priv) +it86x1f_read_data(UNUSED(uint16_t port), void *priv) { it86x1f_t *dev = (it86x1f_t *) priv; uint8_t ret = 0xff; @@ -799,8 +799,7 @@ it86x1f_close(void *priv) static void * it86x1f_init(UNUSED(const device_t *info)) { - it86x1f_t *dev = (it86x1f_t *) malloc(sizeof(it86x1f_t)); - memset(dev, 0, sizeof(it86x1f_t)); + it86x1f_t *dev = (it86x1f_t *) calloc(1, sizeof(it86x1f_t)); uint8_t i; for (i = 0; i < (sizeof(it86x1f_models) / sizeof(it86x1f_models[0])); i++) { @@ -844,7 +843,7 @@ const device_t it8661f_device = { .init = it86x1f_init, .close = it86x1f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -858,7 +857,7 @@ const device_t it8671f_device = { .init = it86x1f_init, .close = it86x1f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index ab7f8597e..41d69b0cc 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -68,7 +68,7 @@ pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) } uint8_t -pc87306_gpio_read(uint16_t port, void *priv) +pc87306_gpio_read(uint16_t port, UNUSED(void *priv)) { uint32_t ret = machine_handle_gpio(0, 0xffffffff); @@ -154,7 +154,7 @@ lpt1_handler(pc87306_t *dev) lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5; if (lpt_port) - lpt1_init(lpt_port); + lpt1_setup(lpt_port); lpt1_irq(lpt_irq); } @@ -303,26 +303,26 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } break; case 0x02: - if (valxor & 1) { + if (valxor & 0x01) { lpt1_remove(); - serial_remove(dev->uart[0]); - serial_remove(dev->uart[1]); + serial_remove(dev->uart[0x00]); + serial_remove(dev->uart[0x01]); fdc_remove(dev->fdc); if (!(val & 1)) { - if (dev->regs[0] & 1) + if (dev->regs[0x00] & 0x01) lpt1_handler(dev); - if (dev->regs[0] & 2) + if (dev->regs[0x00] & 0x02) serial_handler(dev, 0); - if (dev->regs[0] & 4) + if (dev->regs[0x00] & 0x04) serial_handler(dev, 1); - if (dev->regs[0] & 8) - fdc_set_base(dev->fdc, (dev->regs[0] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); + if (dev->regs[0x00] & 0x08) + fdc_set_base(dev->fdc, (dev->regs[0x00] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); } } - if (valxor & 8) { + if (valxor & 0x08) { lpt1_remove(); - if ((dev->regs[0] & 1) && !(dev->regs[2] & 1)) + if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) lpt1_handler(dev); } break; @@ -359,7 +359,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) lpt1_handler(dev); } break; - case 0x1B: + case 0x1b: if (valxor & 0x70) { lpt1_remove(); if (!(val & 0x40)) @@ -368,7 +368,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) lpt1_handler(dev); } break; - case 0x1C: + case 0x1c: if (valxor) { serial_remove(dev->uart[0]); serial_remove(dev->uart[1]); @@ -467,8 +467,7 @@ pc87306_close(void *priv) static void * pc87306_init(UNUSED(const device_t *info)) { - pc87306_t *dev = (pc87306_t *) malloc(sizeof(pc87306_t)); - memset(dev, 0, sizeof(pc87306_t)); + pc87306_t *dev = (pc87306_t *) calloc(1, sizeof(pc87306_t)); dev->fdc = device_add(&fdc_at_nsc_device); @@ -495,7 +494,7 @@ const device_t pc87306_device = { .init = pc87306_init, .close = pc87306_close, .reset = pc87306_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index 63e19c03d..ae21d34af 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -34,6 +34,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_fallthrough.h> typedef struct pc87307_t { uint8_t id; @@ -199,7 +200,7 @@ lpt1_handler(pc87307_t *dev) irq = (dev->ld_regs[0x04][0x40] & 0x0f); if (active && (addr <= 0xfffc)) { - lpt1_init(addr); + lpt1_setup(addr); lpt1_irq(irq); } } @@ -323,8 +324,12 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) } break; case 0x60: + if (dev->regs[0x07] == 0x04) { + val &= 0x03; + } + fallthrough; case 0x62: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07; + 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]) { @@ -588,8 +593,7 @@ pc87307_close(void *priv) static void * pc87307_init(const device_t *info) { - pc87307_t *dev = (pc87307_t *) malloc(sizeof(pc87307_t)); - memset(dev, 0, sizeof(pc87307_t)); + pc87307_t *dev = (pc87307_t *) calloc(1, sizeof(pc87307_t)); dev->id = info->local & 0xff; @@ -620,7 +624,7 @@ const device_t pc87307_device = { .init = pc87307_init, .close = pc87307_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -634,7 +638,7 @@ const device_t pc87307_15c_device = { .init = pc87307_init, .close = pc87307_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -648,7 +652,7 @@ const device_t pc87307_both_device = { .init = pc87307_init, .close = pc87307_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -662,7 +666,7 @@ const device_t pc97307_device = { .init = pc87307_init, .close = pc87307_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_pc87309.c b/src/sio/sio_pc87309.c index d10cb3e0b..da53802c1 100644 --- a/src/sio/sio_pc87309.c +++ b/src/sio/sio_pc87309.c @@ -137,7 +137,7 @@ lpt1_handler(pc87309_t *dev) irq = (dev->ld_regs[0x01][0x40] & 0x0f); if (active) { - lpt1_init(addr); + lpt1_setup(addr); lpt1_irq(irq); } } @@ -466,8 +466,7 @@ pc87309_close(void *priv) static void * pc87309_init(const device_t *info) { - pc87309_t *dev = (pc87309_t *) malloc(sizeof(pc87309_t)); - memset(dev, 0, sizeof(pc87309_t)); + pc87309_t *dev = (pc87309_t *) calloc(1, sizeof(pc87309_t)); dev->id = info->local & 0xff; @@ -497,7 +496,7 @@ const device_t pc87309_device = { .init = pc87309_init, .close = pc87309_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -511,7 +510,7 @@ const device_t pc87309_15c_device = { .init = pc87309_init, .close = pc87309_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_pc87310.c b/src/sio/sio_pc87310.c index 075b819ff..5bd595f05 100644 --- a/src/sio/sio_pc87310.c +++ b/src/sio/sio_pc87310.c @@ -106,7 +106,7 @@ lpt1_handler(pc87310_t *dev) } if (lpt_port) - lpt1_init(lpt_port); + lpt1_setup(lpt_port); lpt1_irq(lpt_irq); } @@ -309,7 +309,7 @@ const device_t pc87310_device = { .init = pc87310_init, .close = pc87310_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -323,7 +323,7 @@ const device_t pc87310_ide_device = { .init = pc87310_init, .close = pc87310_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -337,7 +337,7 @@ const device_t ali5105_device = { .init = pc87310_init, .close = pc87310_close, .reset = NULL, - { .available = 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 9740753d1..b560ef425 100644 --- a/src/sio/sio_pc87311.c +++ b/src/sio/sio_pc87311.c @@ -220,7 +220,7 @@ pc87311_lpt_handler(pc87311_t *dev) default: break; } - lpt1_init(dev->base); + lpt1_setup(dev->base); lpt1_irq(dev->irq); pc87311_log("PC87311-LPT: BASE %04x IRQ %01x\n", dev->base, dev->irq); } @@ -269,8 +269,7 @@ pc87311_close(void *priv) static void * pc87311_init(const device_t *info) { - pc87311_t *dev = (pc87311_t *) malloc(sizeof(pc87311_t)); - memset(dev, 0, sizeof(pc87311_t)); + pc87311_t *dev = (pc87311_t *) calloc(1, sizeof(pc87311_t)); /* Avoid conflicting with machines that make no use of the PC87311 Internal IDE */ HAS_IDE_FUNCTIONALITY = info->local; @@ -298,7 +297,7 @@ const device_t pc87311_device = { .init = pc87311_init, .close = pc87311_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -312,7 +311,7 @@ const device_t pc87311_ide_device = { .init = pc87311_init, .close = pc87311_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_pc87332.c b/src/sio/sio_pc87332.c index 5cbf9f694..d9fb0b211 100644 --- a/src/sio/sio_pc87332.c +++ b/src/sio/sio_pc87332.c @@ -77,7 +77,7 @@ lpt1_handler(pc87332_t *dev) } if (lpt_port) - lpt1_init(lpt_port); + lpt1_setup(lpt_port); lpt1_irq(lpt_irq); } @@ -323,8 +323,7 @@ pc87332_close(void *priv) static void * pc87332_init(const device_t *info) { - pc87332_t *dev = (pc87332_t *) malloc(sizeof(pc87332_t)); - memset(dev, 0, sizeof(pc87332_t)); + pc87332_t *dev = (pc87332_t *) calloc(1, sizeof(pc87332_t)); dev->fdc = device_add(&fdc_at_nsc_device); @@ -354,7 +353,7 @@ const device_t pc87332_device = { .init = pc87332_init, .close = pc87332_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -368,7 +367,7 @@ const device_t pc87332_398_device = { .init = pc87332_init, .close = pc87332_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -382,7 +381,7 @@ const device_t pc87332_398_ide_device = { .init = pc87332_init, .close = pc87332_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -396,7 +395,7 @@ const device_t pc87332_398_ide_sec_device = { .init = pc87332_init, .close = pc87332_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -410,7 +409,7 @@ const device_t pc87332_398_ide_fdcon_device = { .init = pc87332_init, .close = pc87332_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_prime3b.c b/src/sio/sio_prime3b.c index c93630516..1cc0be3aa 100644 --- a/src/sio/sio_prime3b.c +++ b/src/sio/sio_prime3b.c @@ -176,7 +176,7 @@ prime3b_lpt_handler(prime3b_t *dev) { uint16_t lpt_base = (ASR & 2) ? LPT_MDA_ADDR : (!(ASR & 1) ? LPT1_ADDR : LPT2_ADDR); lpt1_remove(); - lpt1_init(lpt_base); + lpt1_setup(lpt_base); lpt1_irq(LPT1_IRQ); prime3b_log("Prime3B-LPT: Enabled with base %03x\n", lpt_base); } @@ -257,8 +257,7 @@ prime3b_close(void *priv) static void * prime3b_init(const device_t *info) { - prime3b_t *dev = (prime3b_t *) malloc(sizeof(prime3b_t)); - memset(dev, 0, sizeof(prime3b_t)); + prime3b_t *dev = (prime3b_t *) calloc(1, sizeof(prime3b_t)); /* Avoid conflicting with machines that make no use of the Prime3B Internal IDE */ HAS_IDE_FUNCTIONALITY = info->local; @@ -290,7 +289,7 @@ const device_t prime3b_device = { .init = prime3b_init, .close = prime3b_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -304,7 +303,7 @@ const device_t prime3b_ide_device = { .init = prime3b_init, .close = prime3b_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_prime3c.c b/src/sio/sio_prime3c.c index b19f861bf..f70f9f372 100644 --- a/src/sio/sio_prime3c.c +++ b/src/sio/sio_prime3c.c @@ -241,7 +241,7 @@ prime3c_lpt_handler(prime3c_t *dev) lpt1_remove(); if (!(FUNCTION_SELECT & 0x03)) { - lpt1_init(LPT_BASE_ADDRESS << 2); + 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); } @@ -296,8 +296,7 @@ prime3c_close(void *priv) static void * prime3c_init(const device_t *info) { - prime3c_t *dev = (prime3c_t *) malloc(sizeof(prime3c_t)); - memset(dev, 0, sizeof(prime3c_t)); + prime3c_t *dev = (prime3c_t *) calloc(1, sizeof(prime3c_t)); /* Avoid conflicting with machines that make no use of the Prime3C Internal IDE */ HAS_IDE_FUNCTIONALITY = info->local; @@ -335,7 +334,7 @@ const device_t prime3c_device = { .init = prime3c_init, .close = prime3c_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -349,7 +348,7 @@ const device_t prime3c_ide_device = { .init = prime3c_init, .close = prime3c_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_um8663f.c b/src/sio/sio_um8663f.c index 7391b029f..54f12dda6 100644 --- a/src/sio/sio_um8663f.c +++ b/src/sio/sio_um8663f.c @@ -106,12 +106,12 @@ um8663f_lpt_handler(um8663f_t *dev) if (dev->regs[0] & 0x08) { switch ((dev->regs[1] >> 3) & 0x01) { case 0x01: - lpt1_init(LPT1_ADDR); - lpt1_irq(7); + lpt1_setup(LPT1_ADDR); + lpt1_irq(LPT1_IRQ); break; case 0x00: - lpt1_init(LPT2_ADDR); - lpt1_irq(5); + lpt1_setup(LPT2_ADDR); + lpt1_irq(LPT2_IRQ); break; default: @@ -231,7 +231,7 @@ um8663f_reset(void *priv) serial_setup(dev->uart[1], COM2_ADDR, COM2_IRQ); lpt1_remove(); - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); fdc_reset(dev->fdc); fdc_remove(dev->fdc); @@ -289,7 +289,7 @@ const device_t um8663af_device = { .init = um8663f_init, .close = um8663f_close, .reset = um8663f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -303,7 +303,7 @@ const device_t um8663af_ide_device = { .init = um8663f_init, .close = um8663f_close, .reset = um8663f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -317,7 +317,7 @@ const device_t um8663af_ide_sec_device = { .init = um8663f_init, .close = um8663f_close, .reset = um8663f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -331,7 +331,7 @@ const device_t um8663bf_device = { .init = um8663f_init, .close = um8663f_close, .reset = um8663f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -345,7 +345,7 @@ const device_t um8663bf_ide_device = { .init = um8663f_init, .close = um8663f_close, .reset = um8663f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -359,7 +359,7 @@ const device_t um8663bf_ide_sec_device = { .init = um8663f_init, .close = um8663f_close, .reset = um8663f_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index 136b1add6..6da9ef6e9 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -207,7 +207,7 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri 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_init(config->io[0].base); + lpt1_setup(config->io[0].base); } else { um8669f_log("UM8669F: LPT disabled\n"); } @@ -328,8 +328,7 @@ um8669f_init(const device_t *info) { um8669f_log("UM8669F: init(%02X)\n", info->local); - um8669f_t *dev = (um8669f_t *) malloc(sizeof(um8669f_t)); - memset(dev, 0, sizeof(um8669f_t)); + um8669f_t *dev = (um8669f_t *) calloc(1, sizeof(um8669f_t)); dev->pnp_card = isapnp_add_card(um8669f_pnp_rom, sizeof(um8669f_pnp_rom), um8669f_pnp_config_changed, NULL, NULL, NULL, dev); for (uint8_t i = 0; i < (sizeof(um8669f_pnp_defaults) / sizeof(isapnp_device_config_t)); i++) @@ -362,7 +361,7 @@ const device_t um8669f_device = { .init = um8669f_init, .close = um8669f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -376,7 +375,7 @@ const device_t um8669f_ide_device = { .init = um8669f_init, .close = um8669f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -390,7 +389,7 @@ const device_t um8669f_ide_sec_device = { .init = um8669f_init, .close = um8669f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_vl82c113.c b/src/sio/sio_vl82c113.c index 6a02ef359..ee18b1893 100644 --- a/src/sio/sio_vl82c113.c +++ b/src/sio/sio_vl82c113.c @@ -24,6 +24,7 @@ #include <86box/keyboard.h> #include <86box/nvr.h> #include <86box/sio.h> +#include <86box/plat_unused.h> typedef struct vl82c113_t { uint8_t index; @@ -128,7 +129,7 @@ vl82c113_close(void *priv) } static void * -vl82c113_init(const device_t *info) +vl82c113_init(UNUSED(const device_t *info)) { vl82c113_t *dev = (vl82c113_t *) calloc(1, sizeof(vl82c113_t)); @@ -155,7 +156,7 @@ const device_t vl82c113_device = { .init = vl82c113_init, .close = vl82c113_close, .reset = vl82c113_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_vt82c686.c b/src/sio/sio_vt82c686.c index f22af07df..0e874210d 100644 --- a/src/sio/sio_vt82c686.c +++ b/src/sio/sio_vt82c686.c @@ -86,7 +86,7 @@ vt82c686_lpt_handler(vt82c686_t *dev) lpt1_remove(); if (((dev->regs[0x02] & 0x03) != 0x03) && !(dev->regs[0x0f] & 0x11) && (io_base >= 0x100) && (io_base <= io_mask)) - lpt1_init(io_base); + lpt1_setup(io_base); if (dev->lpt_irq) { lpt1_irq(dev->lpt_irq); @@ -287,8 +287,7 @@ vt82c686_close(void *priv) static void * vt82c686_init(UNUSED(const device_t *info)) { - vt82c686_t *dev = (vt82c686_t *) malloc(sizeof(vt82c686_t)); - memset(dev, 0, sizeof(vt82c686_t)); + vt82c686_t *dev = (vt82c686_t *) calloc(1, sizeof(vt82c686_t)); dev->fdc = device_add(&fdc_at_smc_device); dev->fdc_dma = 2; @@ -311,7 +310,7 @@ const device_t via_vt82c686_sio_device = { .init = vt82c686_init, .close = vt82c686_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index 2e4b82059..f4971ddce 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -197,7 +197,7 @@ w83787f_lpt_handler(w83787f_t *dev) lpt1_remove(); if (enable) { - lpt1_init(addr); + lpt1_setup(addr); lpt1_irq(irq); } } @@ -378,7 +378,7 @@ w83787f_reset(w83787f_t *dev) uint16_t hefere = dev->reg_init & 0x0100; lpt1_remove(); - lpt1_init(LPT1_ADDR); + lpt1_setup(LPT1_ADDR); lpt1_irq(LPT1_IRQ); memset(dev->regs, 0, 0x2A); @@ -443,8 +443,7 @@ w83787f_close(void *priv) static void * w83787f_init(const device_t *info) { - w83787f_t *dev = (w83787f_t *) malloc(sizeof(w83787f_t)); - memset(dev, 0, sizeof(w83787f_t)); + w83787f_t *dev = (w83787f_t *) calloc(1, sizeof(w83787f_t)); HAS_IDE_FUNCTIONALITY = (info->local & 0x30); @@ -474,7 +473,7 @@ const device_t w83787f_88h_device = { .init = w83787f_init, .close = w83787f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -488,7 +487,7 @@ const device_t w83787f_device = { .init = w83787f_init, .close = w83787f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -502,7 +501,7 @@ const device_t w83787f_ide_device = { .init = w83787f_init, .close = w83787f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -516,7 +515,7 @@ const device_t w83787f_ide_en_device = { .init = w83787f_init, .close = w83787f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -530,7 +529,7 @@ const device_t w83787f_ide_sec_device = { .init = w83787f_init, .close = w83787f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_w83877f.c b/src/sio/sio_w83877f.c index c9a437630..7c92d6e71 100644 --- a/src/sio/sio_w83877f.c +++ b/src/sio/sio_w83877f.c @@ -168,7 +168,7 @@ w83877f_lpt_handler(w83877f_t *dev) lpt1_remove(); if (!(dev->regs[4] & 0x80) && (dev->regs[0x23] & 0xc0)) - lpt1_init(make_port(dev, 0x23)); + lpt1_setup(make_port(dev, 0x23)); lpt_irq = 0xff; @@ -444,8 +444,7 @@ w83877f_close(void *priv) static void * w83877f_init(const device_t *info) { - w83877f_t *dev = (w83877f_t *) malloc(sizeof(w83877f_t)); - memset(dev, 0, sizeof(w83877f_t)); + w83877f_t *dev = (w83877f_t *) calloc(1, sizeof(w83877f_t)); dev->fdc = device_add(&fdc_at_winbond_device); @@ -467,7 +466,7 @@ const device_t w83877f_device = { .init = w83877f_init, .close = w83877f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -481,7 +480,7 @@ const device_t w83877f_president_device = { .init = w83877f_init, .close = w83877f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -495,7 +494,7 @@ const device_t w83877tf_device = { .init = w83877f_init, .close = w83877f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -509,7 +508,7 @@ const device_t w83877tf_acorp_device = { .init = w83877f_init, .close = w83877f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sio/sio_w83977f.c b/src/sio/sio_w83977f.c index 063f0ca69..fd177bc19 100644 --- a/src/sio/sio_w83977f.c +++ b/src/sio/sio_w83977f.c @@ -112,14 +112,14 @@ w83977f_lpt_handler(w83977f_t *dev) lpt2_remove(); if ((dev->dev_regs[1][0x00] & 0x01) && (dev->regs[0x22] & 0x08) && (io_base >= 0x100) && (io_base <= io_mask)) - lpt2_init(io_base); + lpt2_setup(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_init(io_base); + lpt1_setup(io_base); lpt1_irq(dev->dev_regs[1][0x40] & 0x0f); } @@ -593,8 +593,7 @@ w83977f_close(void *priv) static void * w83977f_init(const device_t *info) { - w83977f_t *dev = (w83977f_t *) malloc(sizeof(w83977f_t)); - memset(dev, 0, sizeof(w83977f_t)); + w83977f_t *dev = (w83977f_t *) calloc(1, sizeof(w83977f_t)); dev->type = info->local & 0x0f; dev->hefras = info->local & 0x40; @@ -624,7 +623,7 @@ const device_t w83977f_device = { .init = w83977f_init, .close = w83977f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -638,7 +637,7 @@ const device_t w83977f_370_device = { .init = w83977f_init, .close = w83977f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -652,7 +651,7 @@ const device_t w83977tf_device = { .init = w83977f_init, .close = w83977f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -666,7 +665,7 @@ const device_t w83977ef_device = { .init = w83977f_init, .close = w83977f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -680,7 +679,7 @@ const device_t w83977ef_370_device = { .init = w83977f_init, .close = w83977f_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 2d57a42e0..a381051ba 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -9,16 +9,49 @@ # CMake build script. # # Authors: David Hrdlička, +# Jasmine Iwanek, # # Copyright 2020-2021 David Hrdlička. +# Copyright 2024 Jasmine Iwanek. # -add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_resid.cpp - midi.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c - snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c - snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c - snd_emu8k.c snd_mpu401.c snd_pas16.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c - snd_optimc.c esfmu/esfm.c esfmu/esfm_registers.c snd_opl_esfm.c) +add_library(snd OBJECT + sound.c + snd_opl.c + snd_opl_nuked.c + snd_opl_ymfm.cpp + snd_resid.cpp + midi.c + snd_speaker.c + snd_pssj.c + snd_lpt_dac.c + snd_ac97_codec.c + snd_ac97_via.c + snd_lpt_dss.c + snd_ps1.c + snd_adlib.c + snd_adlibgold.c + snd_ad1848.c + snd_audiopci.c + snd_azt2316a.c + snd_cms.c + snd_cmi8x38.c + snd_cs423x.c + snd_gus.c + snd_sb.c + snd_sb_dsp.c + snd_emu8k.c + snd_mpu401.c + snd_pas16.c + snd_sn76489.c + snd_ssi2001.c + snd_wss.c + snd_ym7128.c + snd_optimc.c + esfmu/esfm.c + esfmu/esfm_registers.c + snd_opl_esfm.c +) if(OPENAL) if(VCPKG_TOOLCHAIN) @@ -31,8 +64,14 @@ if(OPENAL) if(TARGET OpenAL::OpenAL) target_link_libraries(86Box OpenAL::OpenAL) + if(WIN32 AND STATIC_BUILD) + target_link_libraries(OpenAL::OpenAL INTERFACE avrt) + endif() else() target_link_libraries(86Box ${OPENAL_LIBRARY}) + if(WIN32 AND STATIC_BUILD) + target_link_libraries(${OPENAL_LIBRARY} INTERFACE avrt) + endif() endif() include_directories(${OPENAL_INCLUDE_DIR}) @@ -131,6 +170,28 @@ 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) + +if(SERIALPORT_FOUND OR DEFINED LIBSERIALPORT_ROOT) + add_compile_definitions(USE_LIBSERIALPORT=1) + + if(APPLE) + include_directories(${LIBSERIALPORT_ROOT}/include) + target_link_libraries(86Box ${LIBSERIALPORT_ROOT}/lib/libserialport.dylib) + elseif(WIN32) + include_directories(${SERIALPORT_INCLUDE_DIRS}) + target_link_libraries(86Box ${SERIALPORT_LIBRARIES} SetupAPI) + else() + include_directories(${SERIALPORT_INCLUDE_DIRS}) + target_link_libraries(86Box ${SERIALPORT_LIBRARIES}) + endif() + target_sources(snd PRIVATE + snd_opl2board.c + snd_opl_opl2board.cpp +) +endif() add_subdirectory(resid-fp) target_link_libraries(86Box resid-fp) diff --git a/src/sound/midi.c b/src/sound/midi.c index bf92249c4..9f83e88dc 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -71,24 +71,24 @@ typedef struct const device_t *device; } MIDI_OUT_DEVICE, MIDI_IN_DEVICE; -static const MIDI_OUT_DEVICE devices[] = { +static const MIDI_OUT_DEVICE midi_out_devices[] = { // clang-format off { &device_none }, #ifdef USE_FLUIDSYNTH { &fluidsynth_device }, -#endif +#endif /* USE_FLUIDSYNTH */ #ifdef USE_MUNT { &mt32_old_device }, { &mt32_new_device }, { &cm32l_device }, { &cm32ln_device }, -#endif +#endif /*USE_MUNT */ +#ifdef USE_OPL4ML + { &opl4_midi_device }, +#endif /* USE_OPL4ML */ #ifdef USE_RTMIDI { &rtmidi_output_device }, -#endif -#if defined(DEV_BRANCH) && defined(USE_OPL4ML) - { &opl4_midi_device }, -#endif +#endif /* USE_RTMIDI */ { NULL } // clang-format on }; @@ -98,7 +98,7 @@ static const MIDI_IN_DEVICE midi_in_devices[] = { { &device_none }, #ifdef USE_RTMIDI { &rtmidi_input_device }, -#endif +#endif /* USE_RTMIDI */ { NULL } // clang-format on }; @@ -106,8 +106,8 @@ static const MIDI_IN_DEVICE midi_in_devices[] = { int midi_out_device_available(int card) { - if (devices[card].device) - return device_available(devices[card].device); + if (midi_out_devices[card].device) + return device_available(midi_out_devices[card].device); return 1; } @@ -115,21 +115,21 @@ midi_out_device_available(int card) const device_t * midi_out_device_getdevice(int card) { - return devices[card].device; + return midi_out_devices[card].device; } int midi_out_device_has_config(int card) { - if (!devices[card].device) + if (!midi_out_devices[card].device) return 0; - return devices[card].device->config ? 1 : 0; + return midi_out_devices[card].device->config ? 1 : 0; } const char * midi_out_device_get_internal_name(int card) { - return device_get_internal_name(devices[card].device); + return device_get_internal_name(midi_out_devices[card].device); } int @@ -137,8 +137,8 @@ midi_out_device_get_from_internal_name(char *s) { int c = 0; - while (devices[c].device != NULL) { - if (!strcmp(devices[c].device->internal_name, s)) + while (midi_out_devices[c].device != NULL) { + if (!strcmp(midi_out_devices[c].device->internal_name, s)) return c; c++; } @@ -149,16 +149,15 @@ midi_out_device_get_from_internal_name(char *s) void midi_out_device_init(void) { - if ((midi_output_device_current > 0) && devices[midi_output_device_current].device) - device_add(devices[midi_output_device_current].device); + if ((midi_output_device_current > 0) && midi_out_devices[midi_output_device_current].device) + device_add(midi_out_devices[midi_output_device_current].device); midi_output_device_last = midi_output_device_current; } void midi_out_init(midi_device_t *device) { - midi_out = (midi_t *) malloc(sizeof(midi_t)); - memset(midi_out, 0, sizeof(midi_t)); + midi_out = (midi_t *) calloc(1, sizeof(midi_t)); midi_out->m_out_device = device; } @@ -166,8 +165,7 @@ midi_out_init(midi_device_t *device) void midi_in_init(midi_device_t *device, midi_t **mididev) { - *mididev = (midi_t *) malloc(sizeof(midi_t)); - memset(*mididev, 0, sizeof(midi_t)); + *mididev = (midi_t *) calloc(1, sizeof(midi_t)); (*mididev)->m_in_device = device; } @@ -394,8 +392,7 @@ midi_in_handler(int set, void (*msg)(void *priv, uint8_t *msg, uint32_t len), in if ((mih_first != NULL) && (mih_last == NULL)) fatal("First MIDI IN handler present with no last MIDI IN handler\n"); - temp = (midi_in_handler_t *) malloc(sizeof(midi_in_handler_t)); - memset(temp, 0, sizeof(midi_in_handler_t)); + temp = (midi_in_handler_t *) calloc(1, sizeof(midi_in_handler_t)); temp->msg = msg; temp->sysex = sysex; temp->priv = priv; diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index f8c7964f7..027c85b79 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -262,8 +262,7 @@ fluidsynth_init(UNUSED(const device_t *info)) al_set_midi(data->samplerate, data->buf_size); - dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); + dev = calloc(1, sizeof(midi_device_t)); dev->play_msg = fluidsynth_msg; dev->play_sysex = fluidsynth_sysex; @@ -320,164 +319,195 @@ fluidsynth_close(void *priv) static const device_config_t fluidsynth_config[] = { // clang-format off { - .name = "sound_font", - .description = "Sound Font", - .type = CONFIG_FNAME, - .default_string = "", - .file_filter = "SF2 Sound Fonts (*.sf2)|*.sf2" + .name = "sound_font", + .description = "SoundFont", + .type = CONFIG_FNAME, + .default_string = NULL, + .default_int = 0, + .file_filter = "SF2 Sound Fonts (*.sf2)|*.sf2", + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "output_gain", - .description = "Output Gain", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "output_gain", + .description = "Output Gain", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 100, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 100 }, - .default_int = 100 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "chorus", - .description = "Chorus", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "chorus", + .description = "Chorus", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "chorus_voices", - .description = "Chorus Voices", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "chorus_voices", + .description = "Chorus Voices", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 3, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 99 }, - .default_int = 3 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "chorus_level", - .description = "Chorus Level", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "chorus_level", + .description = "Chorus Level", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 20, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 100 }, - .default_int = 20 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "chorus_speed", - .description = "Chorus Speed", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 10, + .name = "chorus_speed", + .description = "Chorus Speed", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 30, + .file_filter = NULL, + .spinner = { + .min = 10, .max = 500 }, - .default_int = 30 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "chorus_depth", - .description = "Chorus Depth", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "chorus_depth", + .description = "Chorus Depth", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 80, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 2560 }, - .default_int = 80 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "chorus_waveform", - .description = "Chorus Waveform", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Sine", - .value = 0 - }, - { - .description = "Triangle", - .value = 1 - } + .name = "chorus_waveform", + .description = "Chorus Waveform", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Sine", .value = 0 }, + { .description = "Triangle", .value = 1 }, + { .description = "" } }, - .default_int = 0 + .bios = { { 0 } } }, { - .name = "reverb", - .description = "Reverb", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "reverb", + .description = "Reverb", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "reverb_room_size", - .description = "Reverb Room Size", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "reverb_room_size", + .description = "Reverb Room Size", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 20, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 100 }, - .default_int = 20 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "reverb_damping", - .description = "Reverb Damping", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "reverb_damping", + .description = "Reverb Damping", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 100 }, - .default_int = 0 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "reverb_width", - .description = "Reverb Width", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "reverb_width", + .description = "Reverb Width", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 1000 }, - .default_int = 5 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "reverb_level", - .description = "Reverb Level", - .type = CONFIG_SPINNER, - .spinner = - { - .min = 0, + .name = "reverb_level", + .description = "Reverb Level", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 90, + .file_filter = NULL, + .spinner = { + .min = 0, .max = 100 }, - .default_int = 90 + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "interpolation", - .description = "Interpolation Method", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "None", - .value = 0 - }, - { - .description = "Linear", - .value = 1 - }, - { - .description = "4th Order", - .value = 2 - }, - { - .description = "7th Order", - .value = 3 - } + .name = "interpolation", + .description = "Interpolation Method", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "None", .value = 0 }, + { .description = "Linear", .value = 1 }, + { .description = "4th Order", .value = 2 }, + { .description = "7th Order", .value = 3 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -491,9 +521,8 @@ const device_t fluidsynth_device = { .init = fluidsynth_init, .close = fluidsynth_close, .reset = NULL, - { .available = fluidsynth_available }, + .available = fluidsynth_available, .speed_changed = NULL, .force_redraw = NULL, .config = fluidsynth_config }; - diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index f38474ac8..67f1d26c8 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -298,8 +298,7 @@ mt32emu_init(char *control_rom, char *pcm_rom) al_set_midi(samplerate, buf_size); - dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); + dev = calloc(1, sizeof(midi_device_t)); dev->play_msg = mt32_msg; dev->play_sysex = mt32_sysex; @@ -378,42 +377,60 @@ mt32_close(void *priv) static const device_config_t mt32_config[] = { // clang-format off { - .name = "output_gain", - .description = "Output Gain", - .type = CONFIG_SPINNER, - .spinner = { + .name = "output_gain", + .description = "Output Gain", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 100, + .file_filter = NULL, + .spinner = { + .min = 0, + .max = 100 + }, + .selection = { { 0 } } + }, + { + .name = "reverb", + .description = "Reverb", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } } + }, + { + .name = "reverb_output_gain", + .description = "Reverb Output Gain", + .type = CONFIG_SPINNER, + .default_string = NULL, + .default_int = 100, + .file_filter = NULL, + .spinner = { .min = 0, .max = 100 }, - .default_int = 100 + .selection = { { 0 } } }, { - .name = "reverb", - .description = "Reverb", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "reversed_stereo", + .description = "Reversed stereo", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } } }, { - .name = "reverb_output_gain", - .description = "Reverb Output Gain", - .type = CONFIG_SPINNER, - .spinner = { - .min = 0, - .max = 100 - }, - .default_int = 100 - }, - { - .name = "reversed_stereo", - .description = "Reversed stereo", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "nice_ramp", - .description = "Nice ramp", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "nice_ramp", + .description = "Nice ramp", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -427,7 +444,7 @@ const device_t mt32_old_device = { .init = mt32_old_init, .close = mt32_close, .reset = NULL, - { .available = mt32_old_available }, + .available = mt32_old_available, .speed_changed = NULL, .force_redraw = NULL, .config = mt32_config @@ -441,7 +458,7 @@ const device_t mt32_new_device = { .init = mt32_new_init, .close = mt32_close, .reset = NULL, - { .available = mt32_new_available }, + .available = mt32_new_available, .speed_changed = NULL, .force_redraw = NULL, .config = mt32_config @@ -455,7 +472,7 @@ const device_t cm32l_device = { .init = cm32l_init, .close = mt32_close, .reset = NULL, - { .available = cm32l_available }, + .available = cm32l_available, .speed_changed = NULL, .force_redraw = NULL, .config = mt32_config @@ -469,7 +486,7 @@ const device_t cm32ln_device = { .init = cm32ln_init, .close = mt32_close, .reset = NULL, - { .available = cm32ln_available }, + .available = cm32ln_available, .speed_changed = NULL, .force_redraw = NULL, .config = mt32_config diff --git a/src/sound/midi_opl4.c b/src/sound/midi_opl4.c index 9708db150..5ec15cc7c 100644 --- a/src/sound/midi_opl4.c +++ b/src/sound/midi_opl4.c @@ -557,7 +557,7 @@ program_change(uint8_t midi_channel, uint8_t program, opl4_midi_t *opl4_midi) } static void -opl4_midi_thread(void *arg) +opl4_midi_thread(UNUSED(void *arg)) { opl4_midi_t *opl4_midi = opl4_midi_cur; uint32_t i = 0; @@ -648,18 +648,18 @@ opl4_midi_msg(uint8_t *val) } void -opl4_midi_sysex(uint8_t *data, unsigned int len) +opl4_midi_sysex(UNUSED(uint8_t *data), UNUSED(unsigned int len)) { + // } void * -opl4_init(const device_t *info) +opl4_init(UNUSED(const device_t *info)) { midi_device_t *dev; extern void al_set_midi(int freq, int buf_size); - dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); + dev = calloc(1, sizeof(midi_device_t)); dev->play_msg = opl4_midi_msg; dev->play_sysex = opl4_midi_sysex; @@ -724,7 +724,7 @@ const device_t opl4_midi_device = { .init = opl4_init, .close = opl4_close, .reset = NULL, - { .available = opl4_midi_available }, + .available = opl4_midi_available, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index 72df8fd32..11203c3f2 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -73,8 +73,7 @@ rtmidi_play_sysex(uint8_t *sysex, unsigned int len) void * rtmidi_output_init(UNUSED(const device_t *info)) { - midi_device_t *dev = (midi_device_t *) malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); + midi_device_t *dev = (midi_device_t *) calloc(1, sizeof(midi_device_t)); dev->play_msg = rtmidi_play_msg; dev->play_sysex = rtmidi_play_sysex; @@ -156,8 +155,7 @@ rtmidi_input_callback(UNUSED(double timeStamp), std::vector *mess void * rtmidi_input_init(UNUSED(const device_t *info)) { - midi_device_t *dev = (midi_device_t *) malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); + midi_device_t *dev = (midi_device_t *) calloc(1, sizeof(midi_device_t)); try { if (!midiin) @@ -233,11 +231,15 @@ rtmidi_in_get_dev_name(int num, char *s) static const device_config_t system_midi_config[] = { // clang-format off { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI_OUT, - .default_string = "", - .default_int = 0 + .name = "midi", + .description = "MIDI Output Device", + .type = CONFIG_MIDI_OUT, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -246,32 +248,48 @@ static const device_config_t system_midi_config[] = { static const device_config_t midi_input_config[] = { // clang-format off { - .name = "midi_input", - .description = "MIDI in device", - .type = CONFIG_MIDI_IN, - .default_string = "", - .default_int = 0 + .name = "midi_input", + .description = "MIDI Input Device", + .type = CONFIG_MIDI_IN, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "realtime", - .description = "MIDI Real time", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "realtime", + .description = "MIDI Real time", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "thruchan", - .description = "MIDI Thru", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "thruchan", + .description = "MIDI Thru", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "clockout", - .description = "MIDI Clockout", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "clockout", + .description = "MIDI Clockout", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -285,7 +303,7 @@ const device_t rtmidi_output_device = { .init = rtmidi_output_init, .close = rtmidi_output_close, .reset = NULL, - { .available = rtmidi_out_get_num_devs }, + .available = rtmidi_out_get_num_devs, .speed_changed = NULL, .force_redraw = NULL, .config = system_midi_config @@ -299,7 +317,7 @@ const device_t rtmidi_input_device = { .init = rtmidi_input_init, .close = rtmidi_input_close, .reset = NULL, - { .available = rtmidi_in_get_num_devs }, + .available = rtmidi_in_get_num_devs, .speed_changed = NULL, .force_redraw = NULL, .config = midi_input_config diff --git a/src/sound/resid-fp/CMakeLists.txt b/src/sound/resid-fp/CMakeLists.txt index 5246dd73b..b91b48bba 100644 --- a/src/sound/resid-fp/CMakeLists.txt +++ b/src/sound/resid-fp/CMakeLists.txt @@ -13,6 +13,8 @@ # Copyright 2020-2021 David Hrdlička. # +set(CMAKE_CXX_STANDARD 17) + add_library(resid-fp STATIC Dac.cpp EnvelopeGenerator.cpp ExternalFilter.cpp Filter.cpp Filter6581.cpp Filter8580.cpp FilterModelConfig.cpp FilterModelConfig6581.cpp FilterModelConfig8580.cpp diff --git a/src/sound/resid-fp/Dac.cpp b/src/sound/resid-fp/Dac.cpp index 0665da817..5ae5429b6 100644 --- a/src/sound/resid-fp/Dac.cpp +++ b/src/sound/resid-fp/Dac.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2016 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -22,9 +22,14 @@ #include "Dac.h" +#include "sidcxx11.h" + namespace reSIDfp { +constexpr double MOSFET_LEAKAGE_6581 = 0.0075; +constexpr double MOSFET_LEAKAGE_8580 = 0.0035; + Dac::Dac(unsigned int bits) : dac(new double[bits]), dacLength(bits) @@ -41,10 +46,8 @@ double Dac::getOutput(unsigned int input) const for (unsigned int i = 0; i < dacLength; i++) { - if ((input & (1 << i)) != 0) - { - dacValue += dac[i]; - } + const bool transistor_on = (input & (1 << i)) != 0; + dacValue += transistor_on ? dac[i] : dac[i] * leakage; } return dacValue; @@ -52,7 +55,7 @@ double Dac::getOutput(unsigned int input) const void Dac::kinkedDac(ChipModel chipModel) { - const double R_INFINITY = 1e6; + constexpr double R_INFINITY = 1e6; // Non-linearity parameter, 8580 DACs are perfectly linear const double _2R_div_R = chipModel == MOS6581 ? 2.20 : 2.00; @@ -60,6 +63,10 @@ void Dac::kinkedDac(ChipModel chipModel) // 6581 DACs are not terminated by a 2R resistor const bool term = chipModel == MOS8580; + leakage = chipModel == MOS6581 ? MOSFET_LEAKAGE_6581 : MOSFET_LEAKAGE_8580; + + double Vsum = 0.; + // Calculate voltage contribution by each individual bit in the R-2R ladder. for (unsigned int set_bit = 0; set_bit < dacLength; set_bit++) { @@ -102,18 +109,10 @@ void Dac::kinkedDac(ChipModel chipModel) } dac[set_bit] = Vn; + Vsum += Vn; } // Normalize to integerish behavior - double Vsum = 0.; - - for (unsigned int i = 0; i < dacLength; i++) - { - Vsum += dac[i]; - } - - Vsum /= 1 << dacLength; - for (unsigned int i = 0; i < dacLength; i++) { dac[i] /= Vsum; diff --git a/src/sound/resid-fp/Dac.h b/src/sound/resid-fp/Dac.h index 35bc0b2ca..757f12e4e 100644 --- a/src/sound/resid-fp/Dac.h +++ b/src/sound/resid-fp/Dac.h @@ -75,6 +75,15 @@ namespace reSIDfp class Dac { private: + /** + * DAC leakage + * + * "Even in standard transistors a small amount of current leaks even when they are technically switched off." + * + * https://en.wikipedia.org/wiki/Subthreshold_conduction + */ + double leakage; + /// analog values double * const dac; diff --git a/src/sound/resid-fp/EnvelopeGenerator.cpp b/src/sound/resid-fp/EnvelopeGenerator.cpp index af636ac7f..e7f5f4e8a 100644 --- a/src/sound/resid-fp/EnvelopeGenerator.cpp +++ b/src/sound/resid-fp/EnvelopeGenerator.cpp @@ -79,7 +79,7 @@ void EnvelopeGenerator::reset() exponential_counter_period = 1; new_exponential_counter_period = 0; - state = RELEASE; + state = State::RELEASE; counter_enabled = true; rate = adsrtable[release]; } @@ -98,7 +98,7 @@ void EnvelopeGenerator::writeCONTROL_REG(unsigned char control) if (gate_next) { // Gate bit on: Start attack, decay, sustain. - next_state = ATTACK; + next_state = State::ATTACK; state_pipeline = 2; if (resetLfsr || (exponential_pipeline == 2)) @@ -113,7 +113,7 @@ void EnvelopeGenerator::writeCONTROL_REG(unsigned char control) else { // Gate bit off: Start release. - next_state = RELEASE; + next_state = State::RELEASE; state_pipeline = envelope_pipeline > 0 ? 3 : 2; } } @@ -124,11 +124,11 @@ void EnvelopeGenerator::writeATTACK_DECAY(unsigned char attack_decay) attack = (attack_decay >> 4) & 0x0f; decay = attack_decay & 0x0f; - if (state == ATTACK) + if (state == State::ATTACK) { rate = adsrtable[attack]; } - else if (state == DECAY_SUSTAIN) + else if (state == State::DECAY_SUSTAIN) { rate = adsrtable[decay]; } @@ -146,7 +146,7 @@ void EnvelopeGenerator::writeSUSTAIN_RELEASE(unsigned char sustain_release) release = sustain_release & 0x0f; - if (state == RELEASE) + if (state == State::RELEASE) { rate = adsrtable[release]; } diff --git a/src/sound/resid-fp/EnvelopeGenerator.h b/src/sound/resid-fp/EnvelopeGenerator.h index f2aab3874..554b814b1 100644 --- a/src/sound/resid-fp/EnvelopeGenerator.h +++ b/src/sound/resid-fp/EnvelopeGenerator.h @@ -47,68 +47,68 @@ private: * The envelope state machine's distinct states. In addition to this, * envelope has a hold mode, which freezes envelope counter to zero. */ - enum State + enum class State { ATTACK, DECAY_SUSTAIN, RELEASE }; private: /// XOR shift register for ADSR prescaling. - unsigned int lfsr; + unsigned int lfsr = 0x7fff; /// Comparison value (period) of the rate counter before next event. - unsigned int rate; + unsigned int rate = 0; /** * During release mode, the SID approximates envelope decay via piecewise * linear decay rate. */ - unsigned int exponential_counter; + unsigned int exponential_counter = 0; /** * Comparison value (period) of the exponential decay counter before next * decrement. */ - unsigned int exponential_counter_period; - unsigned int new_exponential_counter_period; + unsigned int exponential_counter_period = 1; + unsigned int new_exponential_counter_period = 0; - unsigned int state_pipeline; + unsigned int state_pipeline = 0; /// - unsigned int envelope_pipeline; + unsigned int envelope_pipeline = 0; - unsigned int exponential_pipeline; + unsigned int exponential_pipeline = 0; /// Current envelope state - State state; - State next_state; + State state = State::RELEASE; + State next_state = State::RELEASE; /// Whether counter is enabled. Only switching to ATTACK can release envelope. - bool counter_enabled; + bool counter_enabled = true; /// Gate bit - bool gate; + bool gate = false; /// - bool resetLfsr; + bool resetLfsr = false; /// The current digital value of envelope output. - unsigned char envelope_counter; + unsigned char envelope_counter = 0xaa; /// Attack register - unsigned char attack; + unsigned char attack = 0; /// Decay register - unsigned char decay; + unsigned char decay = 0; /// Sustain register - unsigned char sustain; + unsigned char sustain = 0; /// Release register - unsigned char release; + unsigned char release = 0; /// The ENV3 value, sampled at the first phase of the clock - unsigned char env3; + unsigned char env3 = 0; private: static const unsigned int adsrtable[16]; @@ -129,31 +129,6 @@ public: */ unsigned int output() const { return envelope_counter; } - /** - * Constructor. - */ - EnvelopeGenerator() : - lfsr(0x7fff), - rate(0), - exponential_counter(0), - exponential_counter_period(1), - new_exponential_counter_period(0), - state_pipeline(0), - envelope_pipeline(0), - exponential_pipeline(0), - state(RELEASE), - next_state(RELEASE), - counter_enabled(true), - gate(false), - resetLfsr(false), - envelope_counter(0xaa), - attack(0), - decay(0), - sustain(0), - release(0), - env3(0) - {} - /** * SID reset. */ @@ -218,15 +193,15 @@ void EnvelopeGenerator::clock() { if (likely(counter_enabled)) { - if (state == ATTACK) + if (state == State::ATTACK) { if (++envelope_counter==0xff) { - next_state = DECAY_SUSTAIN; + next_state = State::DECAY_SUSTAIN; state_pipeline = 3; } } - else if ((state == DECAY_SUSTAIN) || (state == RELEASE)) + else if ((state == State::DECAY_SUSTAIN) || (state == State::RELEASE)) { if (--envelope_counter==0x00) { @@ -241,8 +216,8 @@ void EnvelopeGenerator::clock() { exponential_counter = 0; - if (((state == DECAY_SUSTAIN) && (envelope_counter != sustain)) - || (state == RELEASE)) + if (((state == State::DECAY_SUSTAIN) && (envelope_counter != sustain)) + || (state == State::RELEASE)) { // The envelope counter can flip from 0x00 to 0xff by changing state to // attack, then to release. The envelope counter will then continue @@ -257,7 +232,7 @@ void EnvelopeGenerator::clock() lfsr = 0x7fff; resetLfsr = false; - if (state == ATTACK) + if (state == State::ATTACK) { // The first envelope step in the attack state also resets the exponential // counter. This has been verified by sampling ENV3. @@ -344,7 +319,7 @@ void EnvelopeGenerator::state_change() switch (next_state) { - case ATTACK: + case State::ATTACK: if (state_pipeline == 1) { // The decay rate is "accidentally" enabled during first cycle of attack phase @@ -352,24 +327,24 @@ void EnvelopeGenerator::state_change() } else if (state_pipeline == 0) { - state = ATTACK; + state = State::ATTACK; // The attack rate is correctly enabled during second cycle of attack phase rate = adsrtable[attack]; counter_enabled = true; } break; - case DECAY_SUSTAIN: + case State::DECAY_SUSTAIN: if (state_pipeline == 0) { - state = DECAY_SUSTAIN; + state = State::DECAY_SUSTAIN; rate = adsrtable[decay]; } break; - case RELEASE: - if (((state == ATTACK) && (state_pipeline == 0)) - || ((state == DECAY_SUSTAIN) && (state_pipeline == 1))) + case State::RELEASE: + if (((state == State::ATTACK) && (state_pipeline == 0)) + || ((state == State::DECAY_SUSTAIN) && (state_pipeline == 1))) { - state = RELEASE; + state = State::RELEASE; rate = adsrtable[release]; } break; diff --git a/src/sound/resid-fp/ExternalFilter.cpp b/src/sound/resid-fp/ExternalFilter.cpp index eac790b31..7f44715b5 100644 --- a/src/sound/resid-fp/ExternalFilter.cpp +++ b/src/sound/resid-fp/ExternalFilter.cpp @@ -38,9 +38,7 @@ inline double getRC(double res, double cap) return res * cap; } -ExternalFilter::ExternalFilter() : - w0lp_1_s7(0), - w0hp_1_s17(0) +ExternalFilter::ExternalFilter() { reset(); } diff --git a/src/sound/resid-fp/ExternalFilter.h b/src/sound/resid-fp/ExternalFilter.h index 760ee5c22..17e8b1649 100644 --- a/src/sound/resid-fp/ExternalFilter.h +++ b/src/sound/resid-fp/ExternalFilter.h @@ -34,8 +34,6 @@ namespace reSIDfp * acts as a high-pass filter with a cutoff dependent on the attached audio * equipment impedance. Here we suppose an impedance of 10kOhm resulting * in a 3 dB attenuation at 1.6Hz. - * To operate properly the 6581 audio output needs a pull-down resistor - *(1KOhm recommended, not needed on 8580) * * ~~~ * 9/12V @@ -47,15 +45,18 @@ namespace reSIDfp * | | pF +-C----o-----C-----+ 10k * 470 | | * GND GND pF R 1K | amp - * * * | +----- + * * ** | +----- * * GND * ~~~ * * The STC networks are connected with a [BJT] based [common collector] * used as a voltage follower (featuring a 2SC1815 NPN transistor). - * * The C64c board additionally includes a [bootstrap] condenser to increase - * the input impedance of the common collector. + * + * * To operate properly the 6581 audio output needs a pull-down resistor + * (1KOhm recommended, not needed on 8580) + * ** The C64c board additionally includes a [bootstrap] condenser to increase + * the input impedance of the common collector. * * [BJT]: https://en.wikipedia.org/wiki/Bipolar_junction_transistor * [common collector]: https://en.wikipedia.org/wiki/Common_collector @@ -70,9 +71,9 @@ private: /// Highpass filter voltage int Vhp; - int w0lp_1_s7; + int w0lp_1_s7 = 0; - int w0hp_1_s17; + int w0hp_1_s17 = 0; public: /** @@ -80,7 +81,7 @@ public: * * @param input */ - int clock(unsigned short input); + int clock(int input); /** * Constructor. @@ -108,9 +109,9 @@ namespace reSIDfp { RESID_INLINE -int ExternalFilter::clock(unsigned short input) +int ExternalFilter::clock(int input) { - const int Vi = (static_cast(input)<<11) - (1 << (11+15)); + const int Vi = (input<<11) - (1 << (11+15)); const int dVlp = (w0lp_1_s7 * (Vi - Vlp) >> 7); const int dVhp = (w0hp_1_s17 * (Vlp - Vhp) >> 17); Vlp += dVlp; diff --git a/src/sound/resid-fp/Filter.cpp b/src/sound/resid-fp/Filter.cpp index 2a2dd24f7..6255c5729 100644 --- a/src/sound/resid-fp/Filter.cpp +++ b/src/sound/resid-fp/Filter.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2013 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem * @@ -20,11 +20,87 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#define FILTER_CPP + #include "Filter.h" namespace reSIDfp { +void Filter::updateMixing() +{ + currentVolume = volume[vol]; + + unsigned int Nsum = 0; + unsigned int Nmix = 0; + + (filt1 ? Nsum : Nmix)++; + (filt2 ? Nsum : Nmix)++; + + if (filt3) Nsum++; + else if (!voice3off) Nmix++; + + (filtE ? Nsum : Nmix)++; + + currentSummer = summer[Nsum]; + + if (lp) Nmix++; + if (bp) Nmix++; + if (hp) Nmix++; + + currentMixer = mixer[Nmix]; +} + +void Filter::writeFC_LO(unsigned char fc_lo) +{ + fc = (fc & 0x7f8) | (fc_lo & 0x007); + updateCenterFrequency(); +} + +void Filter::writeFC_HI(unsigned char fc_hi) +{ + fc = (fc_hi << 3 & 0x7f8) | (fc & 0x007); + updateCenterFrequency(); +} + +void Filter::writeRES_FILT(unsigned char res_filt) +{ + filt = res_filt; + + updateResonance((res_filt >> 4) & 0x0f); + + if (enabled) + { + filt1 = (filt & 0x01) != 0; + filt2 = (filt & 0x02) != 0; + filt3 = (filt & 0x04) != 0; + filtE = (filt & 0x08) != 0; + } + + updateMixing(); +} + +void Filter::writeMODE_VOL(unsigned char mode_vol) +{ + vol = mode_vol & 0x0f; + lp = (mode_vol & 0x10) != 0; + bp = (mode_vol & 0x20) != 0; + hp = (mode_vol & 0x40) != 0; + voice3off = (mode_vol & 0x80) != 0; + + updateMixing(); +} + +Filter::Filter(FilterModelConfig& fmc) : + mixer(fmc.getMixer()), + summer(fmc.getSummer()), + resonance(fmc.getResonance()), + volume(fmc.getVolume()), + fmc(fmc) +{ + input(0); +} + void Filter::enable(bool enable) { enabled = enable; @@ -47,44 +123,4 @@ void Filter::reset() writeRES_FILT(0); } -void Filter::writeFC_LO(unsigned char fc_lo) -{ - fc = (fc & 0x7f8) | (fc_lo & 0x007); - updatedCenterFrequency(); -} - -void Filter::writeFC_HI(unsigned char fc_hi) -{ - fc = (fc_hi << 3 & 0x7f8) | (fc & 0x007); - updatedCenterFrequency(); -} - -void Filter::writeRES_FILT(unsigned char res_filt) -{ - filt = res_filt; - - updateResonance((res_filt >> 4) & 0x0f); - - if (enabled) - { - filt1 = (filt & 0x01) != 0; - filt2 = (filt & 0x02) != 0; - filt3 = (filt & 0x04) != 0; - filtE = (filt & 0x08) != 0; - } - - updatedMixing(); -} - -void Filter::writeMODE_VOL(unsigned char mode_vol) -{ - vol = mode_vol & 0x0f; - lp = (mode_vol & 0x10) != 0; - bp = (mode_vol & 0x20) != 0; - hp = (mode_vol & 0x40) != 0; - voice3off = (mode_vol & 0x80) != 0; - - updatedMixing(); -} - } // namespace reSIDfp diff --git a/src/sound/resid-fp/Filter.h b/src/sound/resid-fp/Filter.h index 4b3473369..6873d9906 100644 --- a/src/sound/resid-fp/Filter.h +++ b/src/sound/resid-fp/Filter.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2017 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem * @@ -23,6 +23,10 @@ #ifndef FILTER_H #define FILTER_H +#include "FilterModelConfig.h" + +#include "siddefs-fp.h" + namespace reSIDfp { @@ -31,93 +35,97 @@ namespace reSIDfp */ class Filter { +private: + unsigned short** mixer; + unsigned short** summer; + unsigned short** resonance; + unsigned short** volume; + protected: - /// Current volume amplifier setting. - unsigned short* currentGain; + FilterModelConfig& fmc; /// Current filter/voice mixer setting. - unsigned short* currentMixer; + unsigned short* currentMixer = nullptr; /// Filter input summer setting. - unsigned short* currentSummer; + unsigned short* currentSummer = nullptr; /// Filter resonance value. - unsigned short* currentResonance; + unsigned short* currentResonance = nullptr; + + /// Current volume amplifier setting. + unsigned short* currentVolume = nullptr; /// Filter highpass state. - int Vhp; + int Vhp = 0; /// Filter bandpass state. - int Vbp; + int Vbp = 0; /// Filter lowpass state. - int Vlp; + int Vlp = 0; /// Filter external input. - int ve; + int Ve = 0; /// Filter cutoff frequency. - unsigned int fc; + unsigned int fc = 0; /// Routing to filter or outside filter - bool filt1, filt2, filt3, filtE; + //@{ + bool filt1 = false; + bool filt2 = false; + bool filt3 = false; + bool filtE = false; + //@} /// Switch voice 3 off. - bool voice3off; + bool voice3off = false; /// Highpass, bandpass, and lowpass filter modes. - bool hp, bp, lp; - - /// Current volume. - unsigned char vol; + //@{ + bool hp = false; + bool bp = false; + bool lp = false; + //@} private: + /// Current volume. + unsigned char vol = 0; + /// Filter enabled. - bool enabled; + bool enabled = true; /// Selects which inputs to route through filter. - unsigned char filt; + unsigned char filt = 0; protected: /** - * Set filter cutoff frequency. + * Update filter cutoff frequency. */ - virtual void updatedCenterFrequency() = 0; + virtual void updateCenterFrequency() = 0; /** - * Set filter resonance. + * Update filter resonance. + * + * @param res the new resonance value */ - virtual void updateResonance(unsigned char res) = 0; + void updateResonance(unsigned char res) { currentResonance = resonance[res]; } /** * Mixing configuration modified (offsets change) */ - virtual void updatedMixing() = 0; + void updateMixing(); + + /** + * Get the filter cutoff register value + */ + unsigned int getFC() const { return fc; } public: - Filter() : - currentGain(nullptr), - currentMixer(nullptr), - currentSummer(nullptr), - currentResonance(nullptr), - Vhp(0), - Vbp(0), - Vlp(0), - ve(0), - fc(0), - filt1(false), - filt2(false), - filt3(false), - filtE(false), - voice3off(false), - hp(false), - bp(false), - lp(false), - vol(0), - enabled(true), - filt(0) {} + Filter(FilterModelConfig& fmc); - virtual ~Filter() {} + virtual ~Filter() = default; /** * SID clocking - 1 cycle @@ -169,7 +177,14 @@ public: */ void writeMODE_VOL(unsigned char mode_vol); - virtual void input(int input) = 0; + /** + * Apply a signal to EXT-IN + * + * @param input a signed 16 bit sample + */ + void input(short input) { Ve = fmc.getNormalizedVoice(input/32768.f, 0); } + + inline int getNormalizedVoice(float value, unsigned int env) const { return fmc.getNormalizedVoice(value, env); } }; } // namespace reSIDfp diff --git a/src/sound/resid-fp/Filter6581.cpp b/src/sound/resid-fp/Filter6581.cpp index c064a8801..b761c22ea 100644 --- a/src/sound/resid-fp/Filter6581.cpp +++ b/src/sound/resid-fp/Filter6581.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2015 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define FILTER6581_CPP - #include "Filter6581.h" #include "Integrator6581.h" @@ -29,47 +27,60 @@ namespace reSIDfp { +unsigned short Filter6581::clock(int voice1, int voice2, int voice3) +{ + const int V1 = voice1; + const int V2 = voice2; + // Voice 3 is silenced by voice3off if it is not routed through the filter. + const int V3 = (filt3 || !voice3off) ? voice3 : 0; + + int Vsum = 0; + int Vmix = 0; + + (filt1 ? Vsum : Vmix) += V1; + (filt2 ? Vsum : Vmix) += V2; + (filt3 ? Vsum : Vmix) += V3; + (filtE ? Vsum : Vmix) += Ve; + + Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vsum]; + Vbp = hpIntegrator.solve(Vhp); + Vlp = bpIntegrator.solve(Vbp); + + int Vfilt = 0; + if (lp) Vfilt += Vlp; + if (bp) Vfilt += Vbp; + if (hp) Vfilt += Vhp; + + // The filter input resistors are slightly bigger than the voice ones + // Scale the values accordingly + constexpr int filterGain = static_cast(0.93 * (1 << 12)); + Vfilt = (Vfilt * filterGain) >> 12; + + return currentVolume[currentMixer[Vmix + Vfilt]]; +} + Filter6581::~Filter6581() { delete [] f0_dac; } -void Filter6581::updatedCenterFrequency() +void Filter6581::updateCenterFrequency() { - const unsigned short Vw = f0_dac[fc]; - hpIntegrator->setVw(Vw); - bpIntegrator->setVw(Vw); -} - -void Filter6581::updatedMixing() -{ - currentGain = gain_vol[vol]; - - unsigned int ni = 0; - unsigned int no = 0; - - (filt1 ? ni : no)++; - (filt2 ? ni : no)++; - - if (filt3) ni++; - else if (!voice3off) no++; - - (filtE ? ni : no)++; - - currentSummer = summer[ni]; - - if (lp) no++; - if (bp) no++; - if (hp) no++; - - currentMixer = mixer[no]; + const unsigned short Vw = f0_dac[getFC()]; + hpIntegrator.setVw(Vw); + bpIntegrator.setVw(Vw); } void Filter6581::setFilterCurve(double curvePosition) { delete [] f0_dac; f0_dac = FilterModelConfig6581::getInstance()->getDAC(curvePosition); - updatedCenterFrequency(); + updateCenterFrequency(); +} + +void Filter6581::setFilterRange(double adjustment) +{ + FilterModelConfig6581::getInstance()->setFilterRange(adjustment); } } // namespace reSIDfp diff --git a/src/sound/resid-fp/Filter6581.h b/src/sound/resid-fp/Filter6581.h index 7fca331ab..27b97b991 100644 --- a/src/sound/resid-fp/Filter6581.h +++ b/src/sound/resid-fp/Filter6581.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2022 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -23,12 +23,9 @@ #ifndef FILTER6581_H #define FILTER6581_H -#include "siddefs-fp.h" - -#include - #include "Filter.h" #include "FilterModelConfig6581.h" +#include "Integrator6581.h" #include "sidcxx11.h" @@ -108,7 +105,7 @@ class Integrator6581; * | | | v1 | | | | * D0 | | | \ ---R8--+ | | +---------------------------+ * | | | | | | | - * R6 R6 R6 R6 R6 R6 R6 + * R6 R6 R6 R6 R6* R6* R6* * | | | | $18 | | | $18 * | \ | | D7: 1=open \ \ \ D6 - D4: 0=open * | | | | | | | @@ -143,6 +140,7 @@ class Integrator6581; * * R2 ~ 2.0*R1 * R6 ~ 6.0*R1 + * R6* ~ 1.07*R6 * R8 ~ 8.0*R1 * R24 ~ 24.0*R1 * @@ -322,104 +320,49 @@ class Integrator6581; class Filter6581 final : public Filter { private: - const unsigned short* f0_dac; - - unsigned short** mixer; - unsigned short** summer; - unsigned short** gain_res; - unsigned short** gain_vol; - - const int voiceScaleS11; - const int voiceDC; - /// VCR + associated capacitor connected to highpass output. - std::unique_ptr const hpIntegrator; + Integrator6581 hpIntegrator; /// VCR + associated capacitor connected to bandpass output. - std::unique_ptr const bpIntegrator; + Integrator6581 bpIntegrator; + + const unsigned short* f0_dac; protected: /** * Set filter cutoff frequency. */ - void updatedCenterFrequency() override; - - /** - * Set filter resonance. - * - * In the MOS 6581, 1/Q is controlled linearly by res. - */ - void updateResonance(unsigned char res) override { currentResonance = gain_res[res]; } - - void updatedMixing() override; + void updateCenterFrequency() override; public: Filter6581() : - f0_dac(FilterModelConfig6581::getInstance()->getDAC(0.5)), - mixer(FilterModelConfig6581::getInstance()->getMixer()), - summer(FilterModelConfig6581::getInstance()->getSummer()), - gain_res(FilterModelConfig6581::getInstance()->getGainRes()), - gain_vol(FilterModelConfig6581::getInstance()->getGainVol()), - voiceScaleS11(FilterModelConfig6581::getInstance()->getVoiceScaleS11()), - voiceDC(FilterModelConfig6581::getInstance()->getNormalizedVoiceDC()), - hpIntegrator(FilterModelConfig6581::getInstance()->buildIntegrator()), - bpIntegrator(FilterModelConfig6581::getInstance()->buildIntegrator()) - { - input(0); - } + Filter(*FilterModelConfig6581::getInstance()), + hpIntegrator(*FilterModelConfig6581::getInstance()), + bpIntegrator(*FilterModelConfig6581::getInstance()), + f0_dac(FilterModelConfig6581::getInstance()->getDAC(0.5)) + {} - ~Filter6581(); + ~Filter6581() override; - unsigned short clock(int voice1, int voice2, int voice3) override; - - void input(int sample) override { ve = (sample * voiceScaleS11 * 3 >> 11) + mixer[0][0]; } + unsigned short clock(int v1, int v2, int v3) override; /** * Set filter curve type based on single parameter. * - * @param curvePosition 0 .. 1, where 0 sets center frequency high ("light") and 1 sets it low ("dark"), default is 0.5 + * @param curvePosition 0 .. 1, where 0 sets center frequency high ("bright") and 1 sets it low ("dark"). + * Default is 0.5 */ void setFilterCurve(double curvePosition); + + /** + * Set filter offset and range based on single parameter. + * + * @param adjustment 0 .. 1, where 0 sets center frequency low ("dark"), 1 sets it high ("bright"). + * This also affects the range. Default is 0.5 + */ + void setFilterRange(double adjustment); }; } // namespace reSIDfp -#if RESID_INLINING || defined(FILTER6581_CPP) - -#include "Integrator6581.h" - -namespace reSIDfp -{ - -RESID_INLINE -unsigned short Filter6581::clock(int voice1, int voice2, int voice3) -{ - voice1 = (voice1 * voiceScaleS11 >> 15) + voiceDC; - voice2 = (voice2 * voiceScaleS11 >> 15) + voiceDC; - // Voice 3 is silenced by voice3off if it is not routed through the filter. - voice3 = (filt3 || !voice3off) ? (voice3 * voiceScaleS11 >> 15) + voiceDC : 0; - - int Vi = 0; - int Vo = 0; - - (filt1 ? Vi : Vo) += voice1; - (filt2 ? Vi : Vo) += voice2; - (filt3 ? Vi : Vo) += voice3; - (filtE ? Vi : Vo) += ve; - - Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi]; - Vbp = hpIntegrator->solve(Vhp); - Vlp = bpIntegrator->solve(Vbp); - - if (lp) Vo += Vlp; - if (bp) Vo += Vbp; - if (hp) Vo += Vhp; - - return currentGain[currentMixer[Vo]]; -} - -} // namespace reSIDfp - -#endif - #endif diff --git a/src/sound/resid-fp/Filter8580.cpp b/src/sound/resid-fp/Filter8580.cpp index a70285a8a..c54e2b741 100644 --- a/src/sound/resid-fp/Filter8580.cpp +++ b/src/sound/resid-fp/Filter8580.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2019 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define FILTER8580_CPP - #include "Filter8580.h" #include "Integrator8580.h" @@ -29,6 +27,32 @@ namespace reSIDfp { +unsigned short Filter8580::clock(int voice1, int voice2, int voice3) +{ + const int V1 = voice1; + const int V2 = voice2; + // Voice 3 is silenced by voice3off if it is not routed through the filter. + const int V3 = (filt3 || !voice3off) ? voice3 : 0; + + int Vsum = 0; + int Vmix = 0; + + (filt1 ? Vsum : Vmix) += V1; + (filt2 ? Vsum : Vmix) += V2; + (filt3 ? Vsum : Vmix) += V3; + (filtE ? Vsum : Vmix) += Ve; + + Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vsum]; + Vbp = hpIntegrator.solve(Vhp); + Vlp = bpIntegrator.solve(Vbp); + + if (lp) Vmix += Vlp; + if (bp) Vmix += Vbp; + if (hp) Vmix += Vhp; + + return currentVolume[currentMixer[Vmix]]; +} + /** * W/L ratio of frequency DAC bit 0, * other bit are proportional. @@ -37,18 +61,18 @@ namespace reSIDfp */ const double DAC_WL0 = 0.00615; -Filter8580::~Filter8580() {} +Filter8580::~Filter8580() = default; -void Filter8580::updatedCenterFrequency() +void Filter8580::updateCenterFrequency() { double wl; double dacWL = DAC_WL0; - if (fc) + if (getFC()) { wl = 0.; for (unsigned int i = 0; i < 11; i++) { - if (fc & (1 << i)) + if (getFC() & (1 << i)) { wl += dacWL; } @@ -60,32 +84,8 @@ void Filter8580::updatedCenterFrequency() wl = dacWL/2.; } - hpIntegrator->setFc(wl); - bpIntegrator->setFc(wl); -} - -void Filter8580::updatedMixing() -{ - currentGain = gain_vol[vol]; - - unsigned int ni = 0; - unsigned int no = 0; - - (filt1 ? ni : no)++; - (filt2 ? ni : no)++; - - if (filt3) ni++; - else if (!voice3off) no++; - - (filtE ? ni : no)++; - - currentSummer = summer[ni]; - - if (lp) no++; - if (bp) no++; - if (hp) no++; - - currentMixer = mixer[no]; + hpIntegrator.setFc(wl); + bpIntegrator.setFc(wl); } void Filter8580::setFilterCurve(double curvePosition) @@ -94,8 +94,8 @@ void Filter8580::setFilterCurve(double curvePosition) // 1.2 <= cp <= 1.8 cp = 1.8 - curvePosition * 3./5.; - hpIntegrator->setV(cp); - bpIntegrator->setV(cp); + hpIntegrator.setV(cp); + bpIntegrator.setV(cp); } } // namespace reSIDfp diff --git a/src/sound/resid-fp/Filter8580.h b/src/sound/resid-fp/Filter8580.h index 2166ec0da..59dbfceee 100644 --- a/src/sound/resid-fp/Filter8580.h +++ b/src/sound/resid-fp/Filter8580.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2022 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -23,10 +23,6 @@ #ifndef FILTER8580_H #define FILTER8580_H -#include "siddefs-fp.h" - -#include - #include "Filter.h" #include "FilterModelConfig8580.h" #include "Integrator8580.h" @@ -281,58 +277,32 @@ class Integrator8580; class Filter8580 final : public Filter { private: - unsigned short** mixer; - unsigned short** summer; - unsigned short** gain_res; - unsigned short** gain_vol; - - const int voiceScaleS11; - const int voiceDC; - - double cp; - /// VCR + associated capacitor connected to highpass output. - std::unique_ptr const hpIntegrator; + Integrator8580 hpIntegrator; /// VCR + associated capacitor connected to bandpass output. - std::unique_ptr const bpIntegrator; + Integrator8580 bpIntegrator; + + double cp; protected: /** * Set filter cutoff frequency. */ - void updatedCenterFrequency() override; - - /** - * Set filter resonance. - * - * @param res the new resonance value - */ - void updateResonance(unsigned char res) override { currentResonance = gain_res[res]; } - - void updatedMixing() override; + void updateCenterFrequency() override; public: Filter8580() : - mixer(FilterModelConfig8580::getInstance()->getMixer()), - summer(FilterModelConfig8580::getInstance()->getSummer()), - gain_res(FilterModelConfig8580::getInstance()->getGainRes()), - gain_vol(FilterModelConfig8580::getInstance()->getGainVol()), - voiceScaleS11(FilterModelConfig8580::getInstance()->getVoiceScaleS11()), - voiceDC(FilterModelConfig8580::getInstance()->getNormalizedVoiceDC()), - cp(0.5), - hpIntegrator(FilterModelConfig8580::getInstance()->buildIntegrator()), - bpIntegrator(FilterModelConfig8580::getInstance()->buildIntegrator()) + Filter(*FilterModelConfig8580::getInstance()), + hpIntegrator(*FilterModelConfig8580::getInstance()), + bpIntegrator(*FilterModelConfig8580::getInstance()) { - setFilterCurve(cp); - input(0); + setFilterCurve(0.5); } - ~Filter8580(); + ~Filter8580() override; - unsigned short clock(int voice1, int voice2, int voice3) override; - - void input(int sample) override { ve = (sample * voiceScaleS11 * 3 >> 11) + mixer[0][0]; } + unsigned short clock(int v1, int v2, int v3) override; /** * Set filter curve type based on single parameter. @@ -344,40 +314,4 @@ public: } // namespace reSIDfp -#if RESID_INLINING || defined(FILTER8580_CPP) - -namespace reSIDfp -{ - -RESID_INLINE -unsigned short Filter8580::clock(int voice1, int voice2, int voice3) -{ - voice1 = (voice1 * voiceScaleS11 >> 15) + voiceDC; - voice2 = (voice2 * voiceScaleS11 >> 15) + voiceDC; - // Voice 3 is silenced by voice3off if it is not routed through the filter. - voice3 = (filt3 || !voice3off) ? (voice3 * voiceScaleS11 >> 15) + voiceDC : 0; - - int Vi = 0; - int Vo = 0; - - (filt1 ? Vi : Vo) += voice1; - (filt2 ? Vi : Vo) += voice2; - (filt3 ? Vi : Vo) += voice3; - (filtE ? Vi : Vo) += ve; - - Vhp = currentSummer[currentResonance[Vbp] + Vlp + Vi]; - Vbp = hpIntegrator->solve(Vhp); - Vlp = bpIntegrator->solve(Vbp); - - if (lp) Vo += Vlp; - if (bp) Vo += Vbp; - if (hp) Vo += Vhp; - - return currentGain[currentMixer[Vo]]; -} - -} // namespace reSIDfp - -#endif - #endif diff --git a/src/sound/resid-fp/FilterModelConfig.cpp b/src/sound/resid-fp/FilterModelConfig.cpp index cd4b20400..2ab459164 100644 --- a/src/sound/resid-fp/FilterModelConfig.cpp +++ b/src/sound/resid-fp/FilterModelConfig.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2022 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -29,7 +29,6 @@ namespace reSIDfp FilterModelConfig::FilterModelConfig( double vvr, - double vdv, double c, double vdd, double vth, @@ -37,21 +36,19 @@ FilterModelConfig::FilterModelConfig( const Spline::Point *opamp_voltage, int opamp_size ) : - voice_voltage_range(vvr), - voice_DC_voltage(vdv), C(c), Vdd(vdd), Vth(vth), - Ut(26.0e-3), - uCox(ucox), Vddt(Vdd - Vth), vmin(opamp_voltage[0].x), vmax(std::max(Vddt, opamp_voltage[0].y)), denorm(vmax - vmin), norm(1.0 / denorm), N16(norm * ((1 << 16) - 1)), - currFactorCoeff(denorm * (uCox / 2. * 1.0e-6 / C)) + voice_voltage_range(vvr) { + setUCox(ucox); + // Convert op-amp voltage transfer to 16 bit values. std::vector scaled_voltage(opamp_size); @@ -79,4 +76,29 @@ FilterModelConfig::FilterModelConfig( } } +FilterModelConfig::~FilterModelConfig() +{ + for (int i = 0; i < 8; i++) + { + delete [] mixer[i]; + } + + for (int i = 0; i < 5; i++) + { + delete [] summer[i]; + } + + for (int i = 0; i < 16; i++) + { + delete [] volume[i]; + delete [] resonance[i]; + } +} + +void FilterModelConfig::setUCox(double new_uCox) +{ + uCox = new_uCox; + currFactorCoeff = denorm * (uCox / 2. * 1.0e-6 / C); +} + } // namespace reSIDfp diff --git a/src/sound/resid-fp/FilterModelConfig.h b/src/sound/resid-fp/FilterModelConfig.h index 9e557d363..1d37a8bf3 100644 --- a/src/sound/resid-fp/FilterModelConfig.h +++ b/src/sound/resid-fp/FilterModelConfig.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2023 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -24,8 +24,10 @@ #define FILTERMODELCONFIG_H #include +#include #include +#include "OpAmp.h" #include "Spline.h" #include "sidcxx11.h" @@ -35,20 +37,46 @@ namespace reSIDfp class FilterModelConfig { -protected: - const double voice_voltage_range; - const double voice_DC_voltage; +private: + /* + * Hack to add quick dither when converting values from float to int + * and avoid quantization noise. + * Hopefully this can be removed the day we move all the analog part + * processing to floats. + * + * Not sure about the effect of using such small buffer of numbers + * since the random sequence repeats every 1024 values but for + * now it seems to do the job. + */ + class Randomnoise + { + private: + double buffer[1024]; + mutable int index = 0; + public: + Randomnoise() + { + std::uniform_real_distribution unif(0., 1.); + std::default_random_engine re; + for (int i=0; i<1024; i++) + buffer[i] = unif(re); + } + double getNoise() const { index = (index + 1) & 0x3ff; return buffer[index]; } + }; +protected: /// Capacitor value. const double C; /// Transistor parameters. //@{ - const double Vdd; + /// Thermal voltage: Ut = kT/q = 8.61734315e-5*T ~ 26mV + static constexpr double Ut = 26.0e-3; + + const double Vdd; ///< Positive supply voltage const double Vth; ///< Threshold voltage - const double Ut; ///< Thermal voltage: Ut = kT/q = 8.61734315e-5*T ~ 26mV - const double uCox; ///< Transconductance coefficient: u*Cox const double Vddt; ///< Vdd - Vth + double uCox; ///< Transconductance coefficient: u*Cox //@} // Derived stuff @@ -58,38 +86,46 @@ protected: /// Fixed point scaling for 16 bit op-amp output. const double N16; + const double voice_voltage_range; + /// Current factor coefficient for op-amp integrators. - const double currFactorCoeff; + double currFactorCoeff; /// Lookup tables for gain and summer op-amps in output stage / filter. //@{ unsigned short* mixer[8]; //-V730_NOINIT this is initialized in the derived class constructor unsigned short* summer[5]; //-V730_NOINIT this is initialized in the derived class constructor - unsigned short* gain_vol[16]; //-V730_NOINIT this is initialized in the derived class constructor - unsigned short* gain_res[16]; //-V730_NOINIT this is initialized in the derived class constructor + unsigned short* volume[16]; //-V730_NOINIT this is initialized in the derived class constructor + unsigned short* resonance[16]; //-V730_NOINIT this is initialized in the derived class constructor //@} /// Reverse op-amp transfer function. unsigned short opamp_rev[1 << 16]; //-V730_NOINIT this is initialized in the derived class constructor private: - FilterModelConfig (const FilterModelConfig&) DELETE; - FilterModelConfig& operator= (const FilterModelConfig&) DELETE; + Randomnoise rnd; + +private: + FilterModelConfig(const FilterModelConfig&) = delete; + FilterModelConfig& operator= (const FilterModelConfig&) = delete; + + inline double getVoiceVoltage(float value, unsigned int env) const + { + return value * voice_voltage_range + getVoiceDC(env); + } protected: /** * @param vvr voice voltage range - * @param vdv voice DC voltage * @param c capacitor value - * @param vdd Vdd + * @param vdd Vdd supply voltage * @param vth threshold voltage * @param ucox u*Cox - * @param ominv opamp min voltage - * @param omaxv opamp max voltage + * @param opamp_voltage opamp voltage array + * @param opamp_size opamp voltage array size */ FilterModelConfig( double vvr, - double vdv, double c, double vdd, double vth, @@ -98,52 +134,139 @@ protected: int opamp_size ); - ~FilterModelConfig() + ~FilterModelConfig(); + + void setUCox(double new_uCox); + + virtual double getVoiceDC(unsigned int env) const = 0; + + /** + * The filter summer operates at n ~ 1, and has 5 fundamentally different + * input configurations (2 - 6 input "resistors"). + * + * Note that all "on" transistors are modeled as one. This is not + * entirely accurate, since the input for each transistor is different, + * and transistors are not linear components. However modeling all + * transistors separately would be extremely costly. + */ + inline void buildSummerTable(const OpAmp& opampModel) { - for (int i = 0; i < 8; i++) - { - delete [] mixer[i]; - } + const double r_N16 = 1. / N16; for (int i = 0; i < 5; i++) { - delete [] summer[i]; - } + const int idiv = 2 + i; // 2 - 6 input "resistors". + const int size = idiv << 16; + const double n = idiv; + const double r_idiv = 1. / idiv; + opampModel.reset(); + summer[i] = new unsigned short[size]; - for (int i = 0; i < 16; i++) + for (int vi = 0; vi < size; vi++) + { + const double vin = vmin + vi * r_N16 * r_idiv; /* vmin .. vmax */ + summer[i][vi] = getNormalizedValue(opampModel.solve(n, vin)); + } + } + } + + /** + * The audio mixer operates at n ~ 8/6 (6581) or 8/5 (8580), + * and has 8 fundamentally different input configurations + * (0 - 7 input "resistors"). + * + * All "on", transistors are modeled as one - see comments above for + * the filter summer. + */ + inline void buildMixerTable(const OpAmp& opampModel, double nRatio) + { + const double r_N16 = 1. / N16; + + for (int i = 0; i < 8; i++) { - delete [] gain_vol[i]; - delete [] gain_res[i]; + const int idiv = (i == 0) ? 1 : i; + const int size = (i == 0) ? 1 : i << 16; + const double n = i * nRatio; + const double r_idiv = 1. / idiv; + opampModel.reset(); + mixer[i] = new unsigned short[size]; + + for (int vi = 0; vi < size; vi++) + { + const double vin = vmin + vi * r_N16 * r_idiv; /* vmin .. vmax */ + mixer[i][vi] = getNormalizedValue(opampModel.solve(n, vin)); + } + } + } + + /** + * 4 bit "resistor" ladders in the audio output gain + * necessitate 16 gain tables. + * From die photographs of the volume "resistor" ladders + * it follows that gain ~ vol/12 (6581) or vol/16 (8580) + * (assuming ideal op-amps and ideal "resistors"). + */ + inline void buildVolumeTable(const OpAmp& opampModel, double nDivisor) + { + const double r_N16 = 1. / N16; + + for (int n8 = 0; n8 < 16; n8++) + { + const int size = 1 << 16; + const double n = n8 / nDivisor; + opampModel.reset(); + volume[n8] = new unsigned short[size]; + + for (int vi = 0; vi < size; vi++) + { + const double vin = vmin + vi * r_N16; /* vmin .. vmax */ + volume[n8][vi] = getNormalizedValue(opampModel.solve(n, vin)); + } + } + } + + /** + * 4 bit "resistor" ladders in the bandpass resonance gain + * necessitate 16 gain tables. + * From die photographs of the bandpass "resistor" ladders + * it follows that 1/Q ~ ~res/8 (6581) or 2^((4 - res)/8) (8580) + * (assuming ideal op-amps and ideal "resistors"). + */ + inline void buildResonanceTable(const OpAmp& opampModel, const double resonance_n[16]) + { + const double r_N16 = 1. / N16; + + for (int n8 = 0; n8 < 16; n8++) + { + const int size = 1 << 16; + opampModel.reset(); + resonance[n8] = new unsigned short[size]; + + for (int vi = 0; vi < size; vi++) + { + const double vin = vmin + vi * r_N16; /* vmin .. vmax */ + resonance[n8][vi] = getNormalizedValue(opampModel.solve(resonance_n[n8], vin)); + } } } public: - unsigned short** getGainVol() { return gain_vol; } - unsigned short** getGainRes() { return gain_res; } + unsigned short** getVolume() { return volume; } + unsigned short** getResonance() { return resonance; } unsigned short** getSummer() { return summer; } unsigned short** getMixer() { return mixer; } - /** - * The digital range of one voice is 20 bits; create a scaling term - * for multiplication which fits in 11 bits. - */ - int getVoiceScaleS11() const { return static_cast((norm * ((1 << 11) - 1)) * voice_voltage_range); } - - /** - * The "zero" output level of the voices. - */ - int getNormalizedVoiceDC() const { return static_cast(N16 * (voice_DC_voltage - vmin)); } - inline unsigned short getOpampRev(int i) const { return opamp_rev[i]; } inline double getVddt() const { return Vddt; } inline double getVth() const { return Vth; } // helper functions + inline unsigned short getNormalizedValue(double value) const { const double tmp = N16 * (value - vmin); - assert(tmp > -0.5 && tmp < 65535.5); - return static_cast(tmp + 0.5); + assert(tmp >= 0. && tmp <= 65535.); + return static_cast(tmp + rnd.getNoise()); } inline unsigned short getNormalizedCurrentFactor(double wl) const @@ -153,11 +276,17 @@ public: return static_cast(tmp + 0.5); } - inline unsigned short getNVmin() const { + inline unsigned short getNVmin() const + { const double tmp = N16 * vmin; assert(tmp > -0.5 && tmp < 65535.5); return static_cast(tmp + 0.5); } + + inline int getNormalizedVoice(float value, unsigned int env) const + { + return static_cast(getNormalizedValue(getVoiceVoltage(value, env))); + } }; } // namespace reSIDfp diff --git a/src/sound/resid-fp/FilterModelConfig6581.cpp b/src/sound/resid-fp/FilterModelConfig6581.cpp index 143b9e91c..fcbf32a46 100644 --- a/src/sound/resid-fp/FilterModelConfig6581.cpp +++ b/src/sound/resid-fp/FilterModelConfig6581.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2023 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2010 Dag Lem * @@ -22,28 +22,20 @@ #include "FilterModelConfig6581.h" -#include - #include "Integrator6581.h" #include "OpAmp.h" +#include "sidcxx11.h" + +#include +#include +#include +#include + namespace reSIDfp { -#ifndef HAVE_CXX11 -/** - * Compute log(1+x) without losing precision for small values of x - * - * @note when compiling with -ffastm-math the compiler will - * optimize the expression away leaving a plain log(1. + x) - */ -inline double log1p(double x) -{ - return log(1. + x) - (((1. + x) - 1.) - x) / (1. + x); -} -#endif - -const unsigned int OPAMP_SIZE = 33; +constexpr unsigned int OPAMP_SIZE = 33; /** * This is the SID 6581 op-amp voltage transfer function, measured on @@ -51,7 +43,7 @@ const unsigned int OPAMP_SIZE = 33; * All measured chips have op-amps with output voltages (and thus input * voltages) within the range of 0.81V - 10.31V. */ -const Spline::Point opamp_voltage[OPAMP_SIZE] = +constexpr Spline::Point opamp_voltage[OPAMP_SIZE] = { { 0.81, 10.31 }, // Approximate start of actual range { 2.40, 10.31 }, @@ -90,8 +82,12 @@ const Spline::Point opamp_voltage[OPAMP_SIZE] = std::unique_ptr FilterModelConfig6581::instance(nullptr); +std::mutex Instance6581_Lock; + FilterModelConfig6581* FilterModelConfig6581::getInstance() { + std::lock_guard lock(Instance6581_Lock); + if (!instance.get()) { instance.reset(new FilterModelConfig6581()); @@ -100,14 +96,32 @@ FilterModelConfig6581* FilterModelConfig6581::getInstance() return instance.get(); } +void FilterModelConfig6581::setFilterRange(double adjustment) +{ + // clamp into allowed range +#ifdef HAVE_CXX17 + adjustment = std::clamp(adjustment, 0.0, 1.0); +#else + adjustment = std::max(std::min(adjustment, 1.0), 0.); +#endif + + // Get the new uCox value, in the range [1,40] + const double new_uCox = (1. + 39. * adjustment) * 1e-6; + + // Ignore small changes + if (std::abs(uCox - new_uCox) < 1e-12) + return; + + setUCox(new_uCox); +} + FilterModelConfig6581::FilterModelConfig6581() : FilterModelConfig( - 1.5, // voice voltage range - 5.075, // voice DC voltage - 470e-12, // capacitor value - 12.18, // Vdd - 1.31, // Vth - 20e-6, // uCox + 1.5, // voice voltage range FIXME should theoretically be ~3,571V + 470e-12, // capacitor value + 12. * VOLTAGE_SKEW, // Vdd + 1.31, // Vth + 20e-6, // uCox opamp_voltage, OPAMP_SIZE ), @@ -119,190 +133,144 @@ FilterModelConfig6581::FilterModelConfig6581() : { dac.kinkedDac(MOS6581); - // Create lookup tables for gains / summers. - -#ifndef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - -// #pragma omp parallel sections { -// #pragma omp section + Dac envDac(8); + envDac.kinkedDac(MOS6581); + for(int i=0; i<256; i++) { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - // The filter summer operates at n ~ 1, and has 5 fundamentally different - // input configurations (2 - 6 input "resistors"). - // - // Note that all "on" transistors are modeled as one. This is not - // entirely accurate, since the input for each transistor is different, - // and transistors are not linear components. However modeling all - // transistors separately would be extremely costly. - for (int i = 0; i < 5; i++) - { - const int idiv = 2 + i; // 2 - 6 input "resistors". - const int size = idiv << 16; - const double n = idiv; - opampModel.reset(); - summer[i] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16 / idiv; /* vmin .. vmax */ - summer[i][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } - -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - // The audio mixer operates at n ~ 8/6, and has 8 fundamentally different - // input configurations (0 - 7 input "resistors"). - // - // All "on", transistors are modeled as one - see comments above for - // the filter summer. - for (int i = 0; i < 8; i++) - { - const int idiv = (i == 0) ? 1 : i; - const int size = (i == 0) ? 1 : i << 16; - const double n = i * 8.0 / 6.0; - opampModel.reset(); - mixer[i] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16 / idiv; /* vmin .. vmax */ - mixer[i][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } - -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - // 4 bit "resistor" ladders in the audio output gain - // necessitate 16 gain tables. - // From die photographs of the volume "resistor" ladders - // it follows that gain ~ vol/12 (assuming ideal - // op-amps and ideal "resistors"). - for (int n8 = 0; n8 < 16; n8++) - { - const int size = 1 << 16; - const double n = n8 / 12.0; - opampModel.reset(); - gain_vol[n8] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16; /* vmin .. vmax */ - gain_vol[n8][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } - -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - // 4 bit "resistor" ladders in the bandpass resonance gain - // necessitate 16 gain tables. - // From die photographs of the bandpass "resistor" ladders - // it follows that 1/Q ~ ~res/8 (assuming ideal - // op-amps and ideal "resistors"). - for (int n8 = 0; n8 < 16; n8++) - { - const int size = 1 << 16; - const double n = (~n8 & 0xf) / 8.0; - opampModel.reset(); - gain_res[n8] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16; /* vmin .. vmax */ - gain_res[n8][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } - -// #pragma omp section - { - const double nVddt = N16 * (Vddt - vmin); - - for (unsigned int i = 0; i < (1 << 16); i++) - { - // The table index is right-shifted 16 times in order to fit in - // 16 bits; the argument to sqrt is thus multiplied by (1 << 16). - const double tmp = nVddt - sqrt(static_cast(i << 16)); - assert(tmp > -0.5 && tmp < 65535.5); - vcr_nVg[i] = static_cast(tmp + 0.5); - } - } - -// #pragma omp section - { - // EKV model: - // - // Ids = Is * (if - ir) - // Is = (2 * u*Cox * Ut^2)/k * W/L - // if = ln^2(1 + e^((k*(Vg - Vt) - Vs)/(2*Ut)) - // ir = ln^2(1 + e^((k*(Vg - Vt) - Vd)/(2*Ut)) - - // moderate inversion characteristic current - const double Is = (2. * uCox * Ut * Ut) * WL_vcr; - - // Normalized current factor for 1 cycle at 1MHz. - const double N15 = norm * ((1 << 15) - 1); - const double n_Is = N15 * 1.0e-6 / C * Is; - - // kVgt_Vx = k*(Vg - Vt) - Vx - // I.e. if k != 1.0, Vg must be scaled accordingly. - for (int kVgt_Vx = 0; kVgt_Vx < (1 << 16); kVgt_Vx++) - { - const double log_term = log1p(exp((kVgt_Vx / N16) / (2. * Ut))); - // Scaled by m*2^15 - const double tmp = n_Is * log_term * log_term; - assert(tmp > -0.5 && tmp < 65535.5); - vcr_n_Ids_term[kVgt_Vx] = static_cast(tmp + 0.5); - } + const double envI = envDac.getOutput(i); + voiceDC[i] = 5. * VOLTAGE_SKEW + (0.2143 * envI); } } + + // Create lookup tables for gains / summers. + + // + // We spawn six threads to calculate these tables in parallel + // + auto filterSummer = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildSummerTable(opampModel); + }; + + auto filterMixer = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildMixerTable(opampModel, 8.0 / 6.0); + }; + + auto filterGain = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildVolumeTable(opampModel, 12.0); + }; + + auto filterResonance = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + // build temp n table + double resonance_n[16]; + for (int n8 = 0; n8 < 16; n8++) + { + resonance_n[n8] = (~n8 & 0xf) / 8.0; + } + + buildResonanceTable(opampModel, resonance_n); + }; + + auto filterVcrVg = [this] + { + const double nVddt = N16 * (Vddt - vmin); + + for (unsigned int i = 0; i < (1 << 16); i++) + { + // The table index is right-shifted 16 times in order to fit in + // 16 bits; the argument to sqrt is thus multiplied by (1 << 16). + const double tmp = nVddt - std::sqrt(static_cast(i << 16)); + assert(tmp > -0.5 && tmp < 65535.5); + vcr_nVg[i] = static_cast(tmp + 0.5); + } + }; + + auto filterVcrIds = [this] + { + // EKV model: + // + // Ids = Is * (if - ir) + // Is = (2 * u*Cox * Ut^2)/k * W/L + // if = ln^2(1 + e^((k*(Vg - Vt) - Vs)/(2*Ut)) + // ir = ln^2(1 + e^((k*(Vg - Vt) - Vd)/(2*Ut)) + + // moderate inversion characteristic current + // will be multiplied by uCox later + const double Is = (2. * Ut * Ut) * WL_vcr; + + // Normalized current factor for 1 cycle at 1MHz. + const double N15 = norm * ((1 << 15) - 1); + const double n_Is = N15 * 1.0e-6 / C * Is; + + // kVgt_Vx = k*(Vg - Vt) - Vx + // I.e. if k != 1.0, Vg must be scaled accordingly. + const double r_N16_2Ut = 1.0 / (N16 * 2.0 * Ut); + for (int i = 0; i < (1 << 16); i++) + { + const int kVgt_Vx = i - (1 << 15); + const double log_term = std::log1p(std::exp(kVgt_Vx * r_N16_2Ut)); + // Scaled by m*2^15 + vcr_n_Ids_term[i] = n_Is * log_term * log_term; + } + }; + +#if defined(HAVE_CXX20) && defined(__cpp_lib_jthread) + using sidThread = std::jthread; +#else + using sidThread = std::thread; +#endif + + sidThread thdSummer(filterSummer); + sidThread thdMixer(filterMixer); + sidThread thdGain(filterGain); + sidThread thdResonance(filterResonance); + sidThread thdVcrVg(filterVcrVg); + sidThread thdVcrIds(filterVcrIds); + +#if !defined(HAVE_CXX20) || !defined(__cpp_lib_jthread) + thdSummer.join(); + thdMixer.join(); + thdGain.join(); + thdResonance.join(); + thdVcrVg.join(); + thdVcrIds.join(); +#endif } unsigned short* FilterModelConfig6581::getDAC(double adjustment) const @@ -314,15 +282,10 @@ unsigned short* FilterModelConfig6581::getDAC(double adjustment) const for (unsigned int i = 0; i < (1 << DAC_BITS); i++) { const double fcd = dac.getOutput(i); - f0_dac[i] = getNormalizedValue(dac_zero + fcd * dac_scale / (1 << DAC_BITS)); + f0_dac[i] = getNormalizedValue(dac_zero + fcd * dac_scale); } return f0_dac; } -std::unique_ptr FilterModelConfig6581::buildIntegrator() -{ - return MAKE_UNIQUE(Integrator6581, this, WL_snake); -} - } // namespace reSIDfp diff --git a/src/sound/resid-fp/FilterModelConfig6581.h b/src/sound/resid-fp/FilterModelConfig6581.h index 06fcc5ce8..75a52dadb 100644 --- a/src/sound/resid-fp/FilterModelConfig6581.h +++ b/src/sound/resid-fp/FilterModelConfig6581.h @@ -41,17 +41,18 @@ class Integrator6581; */ class FilterModelConfig6581 final : public FilterModelConfig { -private: - static const unsigned int DAC_BITS = 11; - private: static std::unique_ptr instance; // This allows access to the private constructor -#ifdef HAVE_CXX11 friend std::unique_ptr::deleter_type; -#else - friend class std::auto_ptr; -#endif + +private: + static constexpr unsigned int DAC_BITS = 11; + + /** + * Power bricks generate voltages slightly out of spec + */ + static constexpr double VOLTAGE_SKEW = 1.015; /// Transistor parameters. //@{ @@ -68,21 +69,36 @@ private: /// DAC lookup table Dac dac; - /// VCR - 6581 only. + /// Voltage Controlled Resistors //@{ unsigned short vcr_nVg[1 << 16]; - unsigned short vcr_n_Ids_term[1 << 16]; + double vcr_n_Ids_term[1 << 16]; //@} + // Voice DC offset LUT + double voiceDC[256]; + private: double getDacZero(double adjustment) const { return dac_zero + (1. - adjustment); } FilterModelConfig6581(); - ~FilterModelConfig6581() DEFAULT; + ~FilterModelConfig6581() = default; + +protected: + /** + * On 6581 the DC offset varies between ~5.0V and ~5.214V depending on + * the envelope value. + */ + inline double getVoiceDC(unsigned int env) const override + { + return voiceDC[env]; + } public: static FilterModelConfig6581* getInstance(); + void setFilterRange(double adjustment); + /** * Construct an 11 bit cutoff frequency DAC output voltage table. * Ownership is transferred to the requester which becomes responsible @@ -93,17 +109,17 @@ public: */ unsigned short* getDAC(double adjustment) const; - /** - * Construct an integrator solver. - * - * @return the integrator - */ - std::unique_ptr buildIntegrator(); + inline double getWL_snake() const { return WL_snake; } inline unsigned short getVcr_nVg(int i) const { return vcr_nVg[i]; } - inline unsigned short getVcr_n_Ids_term(int i) const { return vcr_n_Ids_term[i]; } + inline unsigned short getVcr_n_Ids_term(int i) const + { + const double tmp = vcr_n_Ids_term[i] * uCox; + assert(tmp > -0.5 && tmp < 65535.5); + return static_cast(tmp + 0.5); + } // only used if SLOPE_FACTOR is defined - inline double getUt() const { return Ut; } + inline constexpr double getUt() const { return Ut; } inline double getN16() const { return N16; } }; diff --git a/src/sound/resid-fp/FilterModelConfig8580.cpp b/src/sound/resid-fp/FilterModelConfig8580.cpp index e838a366c..a0a0c9ad8 100644 --- a/src/sound/resid-fp/FilterModelConfig8580.cpp +++ b/src/sound/resid-fp/FilterModelConfig8580.cpp @@ -25,6 +25,10 @@ #include "Integrator8580.h" #include "OpAmp.h" +#include "sidcxx11.h" + +#include +#include namespace reSIDfp { @@ -57,7 +61,7 @@ namespace reSIDfp * E Rf|R2 RC * F Rf|R3 RC */ -const double resGain[16] = +constexpr double resGain[16] = { 1.4/1.0, // Rf/Ri 1.4 ((1.4*15.3)/(1.4+15.3))/1.0, // (Rf|R1)/Ri 1.28263 @@ -77,13 +81,13 @@ const double resGain[16] = ((1.4*4.7)/(1.4+4.7))/2.8, // (Rf|R3)/RC 0.385246 }; -const unsigned int OPAMP_SIZE = 21; +constexpr unsigned int OPAMP_SIZE = 21; /** * This is the SID 8580 op-amp voltage transfer function, measured on * CAP1B/CAP1A on a chip marked CSG 8580R5 1690 25. */ -const Spline::Point opamp_voltage[OPAMP_SIZE] = +constexpr Spline::Point opamp_voltage[OPAMP_SIZE] = { { 1.30, 8.91 }, // Approximate start of actual range { 4.76, 8.91 }, @@ -110,8 +114,12 @@ const Spline::Point opamp_voltage[OPAMP_SIZE] = std::unique_ptr FilterModelConfig8580::instance(nullptr); +std::mutex Instance8580_Lock; + FilterModelConfig8580* FilterModelConfig8580::getInstance() { + std::lock_guard lock(Instance8580_Lock); + if (!instance.get()) { instance.reset(new FilterModelConfig8580()); @@ -122,161 +130,89 @@ FilterModelConfig8580* FilterModelConfig8580::getInstance() FilterModelConfig8580::FilterModelConfig8580() : FilterModelConfig( - 0.30, // voice voltage range FIXME measure - 4.84, // voice DC voltage FIXME measure - 22e-9, // capacitor value - 9.09, // Vdd - 0.80, // Vth - 100e-6, // uCox + 0.24, // voice voltage range FIXME should theoretically be ~0,474V + 22e-9, // capacitor value + 9. * VOLTAGE_SKEW, // Vdd + 0.80, // Vth + 100e-6, // uCox opamp_voltage, OPAMP_SIZE ) { // Create lookup tables for gains / summers. -#ifndef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif -// #pragma omp parallel sections + // + // We spawn four threads to calculate these tables in parallel + // + auto filterSummer = [this] { -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildSummerTable(opampModel); + }; + + auto filterMixer = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildMixerTable(opampModel, 8.0 / 5.0); + }; + + auto filterGain = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildVolumeTable(opampModel, 16.0); + }; + + auto filterResonance = [this] + { + OpAmp opampModel( + std::vector( + std::begin(opamp_voltage), + std::end(opamp_voltage)), + Vddt, + vmin, + vmax); + + buildResonanceTable(opampModel, resGain); + }; + +#if defined(HAVE_CXX20) && defined(__cpp_lib_jthread) + using sidThread = std::jthread; +#else + using sidThread = std::thread; #endif - // The filter summer operates at n ~ 1, and has 5 fundamentally different - // input configurations (2 - 6 input "resistors"). - // - // Note that all "on" transistors are modeled as one. This is not - // entirely accurate, since the input for each transistor is different, - // and transistors are not linear components. However modeling all - // transistors separately would be extremely costly. - for (int i = 0; i < 5; i++) - { - const int idiv = 2 + i; // 2 - 6 input "resistors". - const int size = idiv << 16; - const double n = idiv; - opampModel.reset(); - summer[i] = new unsigned short[size]; - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16 / idiv; /* vmin .. vmax */ - summer[i][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } + sidThread thdSummer(filterSummer); + sidThread thdMixer(filterMixer); + sidThread thdGain(filterGain); + sidThread thdResonance(filterResonance); -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); +#if !defined(HAVE_CXX20) || !defined(__cpp_lib_jthread) + thdSummer.join(); + thdMixer.join(); + thdGain.join(); + thdResonance.join(); #endif - // The audio mixer operates at n ~ 8/5, and has 8 fundamentally different - // input configurations (0 - 7 input "resistors"). - // - // All "on", transistors are modeled as one - see comments above for - // the filter summer. - for (int i = 0; i < 8; i++) - { - const int idiv = (i == 0) ? 1 : i; - const int size = (i == 0) ? 1 : i << 16; - const double n = i * 8.0 / 5.0; - opampModel.reset(); - mixer[i] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16 / idiv; /* vmin .. vmax */ - mixer[i][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } - -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - // 4 bit "resistor" ladders in the audio output gain - // necessitate 16 gain tables. - // From die photographs of the volume "resistor" ladders - // it follows that gain ~ vol/16 (assuming ideal - // op-amps and ideal "resistors"). - for (int n8 = 0; n8 < 16; n8++) - { - const int size = 1 << 16; - const double n = n8 / 16.0; - opampModel.reset(); - gain_vol[n8] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16; /* vmin .. vmax */ - gain_vol[n8][vi] = getNormalizedValue(opampModel.solve(n, vin)); - } - } - } - -// #pragma omp section - { -#ifdef _OPENMP - OpAmp opampModel( - std::vector( - std::begin(opamp_voltage), - std::end(opamp_voltage)), - Vddt, - vmin, - vmax); -#endif - // 4 bit "resistor" ladders in the bandpass resonance gain - // necessitate 16 gain tables. - // From die photographs of the bandpass "resistor" ladders - // it follows that 1/Q ~ 2^((4 - res)/8) (assuming ideal - // op-amps and ideal "resistors"). - for (int n8 = 0; n8 < 16; n8++) - { - const int size = 1 << 16; - opampModel.reset(); - gain_res[n8] = new unsigned short[size]; - - for (int vi = 0; vi < size; vi++) - { - const double vin = vmin + vi / N16; /* vmin .. vmax */ - gain_res[n8][vi] = getNormalizedValue(opampModel.solve(resGain[n8], vin)); - } - } - } - } -} - -std::unique_ptr FilterModelConfig8580::buildIntegrator() -{ - return MAKE_UNIQUE(Integrator8580, this); } } // namespace reSIDfp diff --git a/src/sound/resid-fp/FilterModelConfig8580.h b/src/sound/resid-fp/FilterModelConfig8580.h index 509171bc3..72a055929 100644 --- a/src/sound/resid-fp/FilterModelConfig8580.h +++ b/src/sound/resid-fp/FilterModelConfig8580.h @@ -42,25 +42,30 @@ class FilterModelConfig8580 final : public FilterModelConfig private: static std::unique_ptr instance; // This allows access to the private constructor -#ifdef HAVE_CXX11 friend std::unique_ptr::deleter_type; -#else - friend class std::auto_ptr; -#endif + +private: + /** + * Reference voltage generated from Vcc by a voltage divider + */ + static constexpr double Vref = 4.75; + + /** + * Power bricks generate voltages slightly out of spec + */ + static constexpr double VOLTAGE_SKEW = 1.01; private: FilterModelConfig8580(); - ~FilterModelConfig8580() DEFAULT; + ~FilterModelConfig8580() = default; + +protected: + inline double getVoiceDC(unsigned int) const override { return getVref(); } public: static FilterModelConfig8580* getInstance(); - /** - * Construct an integrator solver. - * - * @return the integrator - */ - std::unique_ptr buildIntegrator(); + inline constexpr double getVref() const { return Vref * VOLTAGE_SKEW; } }; } // namespace reSIDfp diff --git a/src/sound/resid-fp/Integrator.h b/src/sound/resid-fp/Integrator.h new file mode 100644 index 000000000..e8b5ec0b7 --- /dev/null +++ b/src/sound/resid-fp/Integrator.h @@ -0,0 +1,47 @@ +/* + * This file is part of libsidplayfp, a SID player engine. + * + * Copyright 2011-2024 Leandro Nini + * Copyright 2007-2010 Antti Lankila + * Copyright 2004, 2010 Dag Lem + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef INTEGRATOR_H +#define INTEGRATOR_H + +namespace reSIDfp +{ + +class Integrator +{ +protected: + mutable int vx; + mutable int vc; + + Integrator() : + vx(0), + vc(0) {} + +public: + virtual int solve(int vi) const = 0; + + virtual ~Integrator() = default; +}; + +} // namespace reSIDfp + +#endif diff --git a/src/sound/resid-fp/Integrator6581.cpp b/src/sound/resid-fp/Integrator6581.cpp index 490be9b5c..0a48f5c49 100644 --- a/src/sound/resid-fp/Integrator6581.cpp +++ b/src/sound/resid-fp/Integrator6581.cpp @@ -18,8 +18,80 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define INTEGRATOR_CPP - #include "Integrator6581.h" -// This is needed when compiling with --disable-inline +#ifdef SLOPE_FACTOR +# include +# include "sidcxx11.h" +#endif + +namespace reSIDfp +{ + +int Integrator6581::solve(int vi) const +{ + // Make sure Vgst>0 so we're not in subthreshold mode + assert(vx < nVddt); + + // Check that transistor is actually in triode mode + // Vds < Vgs - Vth + assert(vi < nVddt); + + // "Snake" voltages for triode mode calculation. + const unsigned int Vgst = nVddt - vx; + const unsigned int Vgdt = nVddt - vi; + + const unsigned int Vgst_2 = Vgst * Vgst; + const unsigned int Vgdt_2 = Vgdt * Vgdt; + + // "Snake" current, scaled by (1/m)*2^13*m*2^16*m*2^16*2^-15 = m*2^30 + const int n_I_snake = fmc.getNormalizedCurrentFactor(wlSnake) * (static_cast(Vgst_2 - Vgdt_2) >> 15); + + // VCR gate voltage. // Scaled by m*2^16 + // Vg = Vddt - sqrt(((Vddt - Vw)^2 + Vgdt^2)/2) + const int nVg = static_cast(fmc.getVcr_nVg((nVddt_Vw_2 + (Vgdt_2 >> 1)) >> 16)); +#ifdef SLOPE_FACTOR + const double nVp = static_cast(nVg - nVt) / n; // Pinch-off voltage + const int kVgt = static_cast(nVp + 0.5) - nVmin; +#else + const int kVgt = (nVg - nVt) - nVmin; +#endif + + // VCR voltages for EKV model table lookup. + const int kVgt_Vs = (kVgt - vx) + (1 << 15); + assert((kVgt_Vs >= 0) && (kVgt_Vs < (1 << 16))); + const int kVgt_Vd = (kVgt - vi) + (1 << 15); + assert((kVgt_Vd >= 0) && (kVgt_Vd < (1 << 16))); + + // VCR current, scaled by m*2^15*2^15 = m*2^30 + const unsigned int If = static_cast(fmc.getVcr_n_Ids_term(kVgt_Vs)) << 15; + const unsigned int Ir = static_cast(fmc.getVcr_n_Ids_term(kVgt_Vd)) << 15; +#ifdef SLOPE_FACTOR + const double iVcr = static_cast(If - Ir); + const int n_I_vcr = static_cast(iVcr * n); +#else + const int n_I_vcr = If - Ir; +#endif + +#ifdef SLOPE_FACTOR + // estimate new slope factor based on gate voltage + constexpr double gamma = 1.0; // body effect factor + constexpr double phi = 0.8; // bulk Fermi potential + const double Vp = nVp / fmc.getN16(); + n = 1. + (gamma / (2. * std::sqrt(Vp + phi + 4. * fmc.getUt()))); + assert((n > 1.2) && (n < 1.8)); +#endif + + // Change in capacitor charge. + vc += n_I_snake + n_I_vcr; + + // vx = g(vc) + const int tmp = (vc >> 15) + (1 << 15); + assert(tmp < (1 << 16)); + vx = fmc.getOpampRev(tmp); + + // Return vo. + return vx - (vc >> 14); +} + +} // namespace reSIDfp diff --git a/src/sound/resid-fp/Integrator6581.h b/src/sound/resid-fp/Integrator6581.h index 5bdeca37d..71db37342 100644 --- a/src/sound/resid-fp/Integrator6581.h +++ b/src/sound/resid-fp/Integrator6581.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2022 Leandro Nini + * Copyright 2011-2023 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004, 2010 Dag Lem * @@ -23,6 +23,7 @@ #ifndef INTEGRATOR6581_H #define INTEGRATOR6581_H +#include "Integrator.h" #include "FilterModelConfig6581.h" #include @@ -33,10 +34,6 @@ // actually produces worse results, needs investigation //#define SLOPE_FACTOR -#ifdef SLOPE_FACTOR -# include -#endif - #include "siddefs-fp.h" namespace reSIDfp @@ -164,12 +161,10 @@ namespace reSIDfp * * Vg = nVddt - sqrt(((nVddt - vi)^2 + (nVddt - Vw)^2)/2) */ -class Integrator6581 +class Integrator6581 : public Integrator { private: - unsigned int nVddt_Vw_2; - mutable int vx; - mutable int vc; + const double wlSnake; #ifdef SLOPE_FACTOR // Slope factor n = 1/k @@ -177,109 +172,32 @@ private: // k = Cox/(Cox+Cdep) ~ 0.7 (depends on gate voltage) mutable double n; #endif + + unsigned int nVddt_Vw_2; + const unsigned short nVddt; const unsigned short nVt; const unsigned short nVmin; - const unsigned short nSnake; - const FilterModelConfig6581* fmc; + FilterModelConfig6581& fmc; public: - Integrator6581(const FilterModelConfig6581* fmc, - double WL_snake) : - nVddt_Vw_2(0), - vx(0), - vc(0), + Integrator6581(FilterModelConfig6581& fmc) : + wlSnake(fmc.getWL_snake()), #ifdef SLOPE_FACTOR n(1.4), #endif - nVddt(fmc->getNormalizedValue(fmc->getVddt())), - nVt(fmc->getNormalizedValue(fmc->getVth())), - nVmin(fmc->getNVmin()), - nSnake(fmc->getNormalizedCurrentFactor(WL_snake)), + nVddt_Vw_2(0), + nVddt(fmc.getNormalizedValue(fmc.getVddt())), + nVt(fmc.getNormalizedValue(fmc.getVth())), + nVmin(fmc.getNVmin()), fmc(fmc) {} void setVw(unsigned short Vw) { nVddt_Vw_2 = ((nVddt - Vw) * (nVddt - Vw)) >> 1; } - int solve(int vi) const; + int solve(int vi) const override; }; } // namespace reSIDfp -#if RESID_INLINING || defined(INTEGRATOR_CPP) - -namespace reSIDfp -{ - -RESID_INLINE -int Integrator6581::solve(int vi) const -{ - // Make sure Vgst>0 so we're not in subthreshold mode - assert(vx < nVddt); - - // Check that transistor is actually in triode mode - // Vds < Vgs - Vth - assert(vi < nVddt); - - // "Snake" voltages for triode mode calculation. - const unsigned int Vgst = nVddt - vx; - const unsigned int Vgdt = nVddt - vi; - - const unsigned int Vgst_2 = Vgst * Vgst; - const unsigned int Vgdt_2 = Vgdt * Vgdt; - - // "Snake" current, scaled by (1/m)*2^13*m*2^16*m*2^16*2^-15 = m*2^30 - const int n_I_snake = nSnake * (static_cast(Vgst_2 - Vgdt_2) >> 15); - - // VCR gate voltage. // Scaled by m*2^16 - // Vg = Vddt - sqrt(((Vddt - Vw)^2 + Vgdt^2)/2) - const int nVg = static_cast(fmc->getVcr_nVg((nVddt_Vw_2 + (Vgdt_2 >> 1)) >> 16)); -#ifdef SLOPE_FACTOR - const double nVp = static_cast(nVg - nVt) / n; // Pinch-off voltage - const int kVgt = static_cast(nVp + 0.5) - nVmin; -#else - const int kVgt = (nVg - nVt) - nVmin; -#endif - - // VCR voltages for EKV model table lookup. - const int kVgt_Vs = (vx < kVgt) ? kVgt - vx : 0; - assert(kVgt_Vs < (1 << 16)); - const int kVgt_Vd = (vi < kVgt) ? kVgt - vi : 0; - assert(kVgt_Vd < (1 << 16)); - - // VCR current, scaled by m*2^15*2^15 = m*2^30 - const unsigned int If = static_cast(fmc->getVcr_n_Ids_term(kVgt_Vs)) << 15; - const unsigned int Ir = static_cast(fmc->getVcr_n_Ids_term(kVgt_Vd)) << 15; -#ifdef SLOPE_FACTOR - const double iVcr = static_cast(If - Ir); - const int n_I_vcr = static_cast(iVcr * n); -#else - const int n_I_vcr = If - Ir; -#endif - -#ifdef SLOPE_FACTOR - // estimate new slope factor based on gate voltage - const double gamma = 1.0; // body effect factor - const double phi = 0.8; // bulk Fermi potential - const double Vp = nVp / fmc->getN16(); - n = 1. + (gamma / (2. * sqrt(Vp + phi + 4. * fmc->getUt()))); - assert((n > 1.2) && (n < 1.8)); -#endif - - // Change in capacitor charge. - vc += n_I_snake + n_I_vcr; - - // vx = g(vc) - const int tmp = (vc >> 15) + (1 << 15); - assert(tmp < (1 << 16)); - vx = fmc->getOpampRev(tmp); - - // Return vo. - return vx - (vc >> 14); -} - -} // namespace reSIDfp - -#endif - #endif diff --git a/src/sound/resid-fp/Integrator8580.cpp b/src/sound/resid-fp/Integrator8580.cpp index 6fba9521b..762442d92 100644 --- a/src/sound/resid-fp/Integrator8580.cpp +++ b/src/sound/resid-fp/Integrator8580.cpp @@ -18,8 +18,36 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define INTEGRATOR8580_CPP - #include "Integrator8580.h" -// This is needed when compiling with --disable-inline +namespace reSIDfp +{ + +int Integrator8580::solve(int vi) const +{ + // Make sure we're not in subthreshold mode + assert(vx < nVgt); + + // DAC voltages + const unsigned int Vgst = nVgt - vx; + const unsigned int Vgdt = (vi < nVgt) ? nVgt - vi : 0; // triode/saturation mode + + const unsigned int Vgst_2 = Vgst * Vgst; + const unsigned int Vgdt_2 = Vgdt * Vgdt; + + // DAC current, scaled by (1/m)*2^13*m*2^16*m*2^16*2^-15 = m*2^30 + const int n_I_dac = n_dac * (static_cast(Vgst_2 - Vgdt_2) >> 15); + + // Change in capacitor charge. + vc += n_I_dac; + + // vx = g(vc) + const int tmp = (vc >> 15) + (1 << 15); + assert(tmp < (1 << 16)); + vx = fmc.getOpampRev(tmp); + + // Return vo. + return vx - (vc >> 14); +} + +} // namespace reSIDfp diff --git a/src/sound/resid-fp/Integrator8580.h b/src/sound/resid-fp/Integrator8580.h index db9e46b05..857d22ca2 100644 --- a/src/sound/resid-fp/Integrator8580.h +++ b/src/sound/resid-fp/Integrator8580.h @@ -23,6 +23,7 @@ #ifndef INTEGRATOR8580_H #define INTEGRATOR8580_H +#include "Integrator.h" #include "FilterModelConfig8580.h" #include @@ -51,21 +52,16 @@ namespace reSIDfp * * Rfc gate voltage is generated by an OP Amp and depends on chip temperature. */ -class Integrator8580 +class Integrator8580 : public Integrator { private: - mutable int vx; - mutable int vc; - unsigned short nVgt; unsigned short n_dac; - const FilterModelConfig8580* fmc; + FilterModelConfig8580& fmc; public: - Integrator8580(const FilterModelConfig8580* fmc) : - vx(0), - vc(0), + Integrator8580(FilterModelConfig8580& fmc) : fmc(fmc) { setV(1.5); @@ -78,7 +74,7 @@ public: { // Normalized current factor, 1 cycle at 1MHz. // Fit in 5 bits. - n_dac = fmc->getNormalizedCurrentFactor(wl); + n_dac = fmc.getNormalizedCurrentFactor(wl); } /** @@ -87,56 +83,19 @@ public: void setV(double v) { // Gate voltage is controlled by the switched capacitor voltage divider - // Ua = Ue * v = 4.76v 1 1.0 && v < 2.0); - const double Vg = 4.76 * v; - const double Vgt = Vg - fmc->getVth(); + const double Vg = fmc.getVref() * v; + const double Vgt = Vg - fmc.getVth(); // Vg - Vth, normalized so that translated values can be subtracted: // Vgt - x = (Vgt - t) - (x - t) - nVgt = fmc->getNormalizedValue(Vgt); + nVgt = fmc.getNormalizedValue(Vgt); } - int solve(int vi) const; + int solve(int vi) const override; }; } // namespace reSIDfp -#if RESID_INLINING || defined(INTEGRATOR8580_CPP) - -namespace reSIDfp -{ - -RESID_INLINE -int Integrator8580::solve(int vi) const -{ - // Make sure we're not in subthreshold mode - assert(vx < nVgt); - - // DAC voltages - const unsigned int Vgst = nVgt - vx; - const unsigned int Vgdt = (vi < nVgt) ? nVgt - vi : 0; // triode/saturation mode - - const unsigned int Vgst_2 = Vgst * Vgst; - const unsigned int Vgdt_2 = Vgdt * Vgdt; - - // DAC current, scaled by (1/m)*2^13*m*2^16*m*2^16*2^-15 = m*2^30 - const int n_I_dac = n_dac * (static_cast(Vgst_2 - Vgdt_2) >> 15); - - // Change in capacitor charge. - vc += n_I_dac; - - // vx = g(vc) - const int tmp = (vc >> 15) + (1 << 15); - assert(tmp < (1 << 16)); - vx = fmc->getOpampRev(tmp); - - // Return vo. - return vx - (vc >> 14); -} - -} // namespace reSIDfp - -#endif - #endif diff --git a/src/sound/resid-fp/OpAmp.cpp b/src/sound/resid-fp/OpAmp.cpp index b26b2efcb..ed4f2700c 100644 --- a/src/sound/resid-fp/OpAmp.cpp +++ b/src/sound/resid-fp/OpAmp.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2015 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify @@ -28,7 +28,7 @@ namespace reSIDfp { -const double EPSILON = 1e-8; +constexpr double EPSILON = 1e-8; double OpAmp::solve(double n, double vi) const { @@ -48,7 +48,7 @@ double OpAmp::solve(double n, double vi) const // Calculate f and df. - Spline::Point out = opamp->evaluate(x); + Spline::Point out = opamp.evaluate(x); const double vo = out.x; const double dvo = out.y; @@ -64,9 +64,9 @@ double OpAmp::solve(double n, double vi) const // Newton-Raphson step: xk1 = xk - f(xk)/f'(xk) x -= f / df; - if (unlikely(fabs(x - xk) < EPSILON)) + if (unlikely(std::fabs(x - xk) < EPSILON)) { - out = opamp->evaluate(x); + out = opamp.evaluate(x); return out.x; } diff --git a/src/sound/resid-fp/OpAmp.h b/src/sound/resid-fp/OpAmp.h index f048b1845..ec9d68cbb 100644 --- a/src/sound/resid-fp/OpAmp.h +++ b/src/sound/resid-fp/OpAmp.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2023 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004,2010 Dag Lem * @@ -23,7 +23,6 @@ #ifndef OPAMP_H #define OPAMP_H -#include #include #include "Spline.h" @@ -72,13 +71,13 @@ class OpAmp { private: /// Current root position (cached as guess to speed up next iteration) - mutable double x; + mutable double x = 0.; const double Vddt; const double vmin; const double vmax; - std::unique_ptr const opamp; + Spline opamp; public: /** @@ -89,14 +88,13 @@ public: * @param vmin * @param vmax */ - OpAmp(const std::vector &opamp, double Vddt, + OpAmp(const std::vector &opamp_voltages, double Vddt, double vmin, double vmax ) : - x(0.), Vddt(Vddt), vmin(vmin), vmax(vmax), - opamp(new Spline(opamp)) {} + opamp(opamp_voltages) {} /** * Reset root position diff --git a/src/sound/resid-fp/SID.cpp b/src/sound/resid-fp/SID.cpp index 840d264e2..5b5506bc3 100644 --- a/src/sound/resid-fp/SID.cpp +++ b/src/sound/resid-fp/SID.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2016 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem * @@ -26,11 +26,12 @@ #include +#include "sidcxx11.h" + #include "array.h" #include "Dac.h" #include "Filter6581.h" #include "Filter8580.h" -#include "Potentiometer.h" #include "WaveformCalculator.h" #include "resample/TwoPassSincResampler.h" #include "resample/ZeroOrderResampler.h" @@ -38,8 +39,8 @@ namespace reSIDfp { -const unsigned int ENV_DAC_BITS = 8; -const unsigned int OSC_DAC_BITS = 12; +constexpr unsigned int ENV_DAC_BITS = 8; +constexpr unsigned int OSC_DAC_BITS = 12; /** * The waveform D/A converter introduces a DC offset in the signal @@ -106,8 +107,8 @@ const unsigned int OSC_DAC_BITS = 12; * On my 6581R4AR has 0x3A as the only value giving the same output level as 1.prg */ //@{ -unsigned int constexpr OFFSET_6581 = 0x380; -unsigned int constexpr OFFSET_8580 = 0x9c0; +constexpr unsigned int OFFSET_6581 = 0x380; +constexpr unsigned int OFFSET_8580 = 0x9c0; //@} /** @@ -128,31 +129,24 @@ unsigned int constexpr OFFSET_8580 = 0x9c0; * [2]: http://noname.c64.org/csdb/forums/?roomid=11&topicid=29025&showallposts=1 */ //@{ -int constexpr BUS_TTL_6581 = 0x01d00; -int constexpr BUS_TTL_8580 = 0xa2000; +constexpr int BUS_TTL_6581 = 0x01d00; +constexpr int BUS_TTL_8580 = 0xa2000; //@} SID::SID() : filter6581(new Filter6581()), filter8580(new Filter8580()), - externalFilter(new ExternalFilter()), resampler(nullptr), - potX(new Potentiometer()), - potY(new Potentiometer()) + cws(AVERAGE) { - voice[0].reset(new Voice()); - voice[1].reset(new Voice()); - voice[2].reset(new Voice()); - - muted[0] = muted[1] = muted[2] = false; - + setChipModel(MOS6581); reset(); - setChipModel(MOS8580); } SID::~SID() { - // Needed to delete auto_ptr with complete type + delete filter6581; + delete filter8580; } void SID::setFilter6581Curve(double filterCurve) @@ -160,6 +154,11 @@ void SID::setFilter6581Curve(double filterCurve) filter6581->setFilterCurve(filterCurve); } +void SID::setFilter6581Range(double adjustment) +{ + filter6581->setFilterRange(adjustment); +} + void SID::setFilter8580Curve(double filterCurve) { filter8580->setFilterCurve(filterCurve); @@ -178,7 +177,7 @@ void SID::voiceSync(bool sync) // Synchronize the 3 waveform generators. for (int i = 0; i < 3; i++) { - voice[i]->wave()->synchronize(voice[(i + 1) % 3]->wave(), voice[(i + 2) % 3]->wave()); + voice[i].wave()->synchronize(voice[(i + 1) % 3].wave(), voice[(i + 2) % 3].wave()); } } @@ -187,10 +186,10 @@ void SID::voiceSync(bool sync) for (int i = 0; i < 3; i++) { - WaveformGenerator* const wave = voice[i]->wave(); + WaveformGenerator* const wave = voice[i].wave(); const unsigned int freq = wave->readFreq(); - if (wave->readTest() || freq == 0 || !voice[(i + 1) % 3]->wave()->readSync()) + if (wave->readTest() || freq == 0 || !voice[(i + 1) % 3].wave()->readSync()) { continue; } @@ -210,12 +209,14 @@ void SID::setChipModel(ChipModel model) switch (model) { case MOS6581: - filter = filter6581.get(); + filter = filter6581; + scaleFactor = 3; modelTTL = BUS_TTL_6581; break; case MOS8580: - filter = filter8580.get(); + filter = filter8580; + scaleFactor = 5; modelTTL = BUS_TTL_8580; break; @@ -227,7 +228,7 @@ void SID::setChipModel(ChipModel model) // calculate waveform-related tables matrix_t* wavetables = WaveformCalculator::getInstance()->getWaveTable(); - matrix_t* pulldowntables = WaveformCalculator::getInstance()->buildPulldownTable(model); + matrix_t* pulldowntables = WaveformCalculator::getInstance()->buildPulldownTable(model, cws); // calculate envelope DAC table { @@ -247,7 +248,8 @@ void SID::setChipModel(ChipModel model) Dac dacBuilder(OSC_DAC_BITS); dacBuilder.kinkedDac(model); - const double offset = dacBuilder.getOutput(is6581 ? OFFSET_6581 : OFFSET_8580); + //const double offset = dacBuilder.getOutput(is6581 ? OFFSET_6581 : OFFSET_8580); + const double offset = dacBuilder.getOutput(0x7ff); for (unsigned int i = 0; i < (1 << OSC_DAC_BITS); i++) { @@ -259,11 +261,35 @@ void SID::setChipModel(ChipModel model) // set voice tables for (int i = 0; i < 3; i++) { - voice[i]->setEnvDAC(envDAC); - voice[i]->setWavDAC(oscDAC); - voice[i]->wave()->setModel(is6581); - voice[i]->wave()->setWaveformModels(wavetables); - voice[i]->wave()->setPulldownModels(pulldowntables); + voice[i].setEnvDAC(envDAC); + voice[i].setWavDAC(oscDAC); + voice[i].wave()->setModel(is6581); + voice[i].wave()->setWaveformModels(wavetables); + voice[i].wave()->setPulldownModels(pulldowntables); + } +} + +void SID::setCombinedWaveforms(CombinedWaveforms cws) +{ + switch (cws) + { + case AVERAGE: + case WEAK: + case STRONG: + break; + + default: + throw SIDError("Unknown combined waveforms type"); + } + + this->cws = cws; + + // rebuild waveform-related tables + matrix_t* pulldowntables = WaveformCalculator::getInstance()->buildPulldownTable(model, cws); + + for (int i = 0; i < 3; i++) + { + voice[i].wave()->setPulldownModels(pulldowntables); } } @@ -271,12 +297,12 @@ void SID::reset() { for (int i = 0; i < 3; i++) { - voice[i]->reset(); + voice[i].reset(); } filter6581->reset(); filter8580->reset(); - externalFilter->reset(); + externalFilter.reset(); if (resampler.get()) { @@ -299,22 +325,22 @@ unsigned char SID::read(int offset) switch (offset) { case 0x19: // X value of paddle - busValue = potX->readPOT(); + busValue = potX.readPOT(); busValueTtl = modelTTL; break; case 0x1a: // Y value of paddle - busValue = potY->readPOT(); + busValue = potY.readPOT(); busValueTtl = modelTTL; break; case 0x1b: // Voice #3 waveform output - busValue = voice[2]->wave()->readOSC(); + busValue = voice[2].wave()->readOSC(); busValueTtl = modelTTL; break; case 0x1c: // Voice #3 ADSR output - busValue = voice[2]->envelope()->readENV(); + busValue = voice[2].envelope()->readENV(); busValueTtl = modelTTL; break; @@ -337,87 +363,87 @@ void SID::write(int offset, unsigned char value) switch (offset) { case 0x00: // Voice #1 frequency (Low-byte) - voice[0]->wave()->writeFREQ_LO(value); + voice[0].wave()->writeFREQ_LO(value); break; case 0x01: // Voice #1 frequency (High-byte) - voice[0]->wave()->writeFREQ_HI(value); + voice[0].wave()->writeFREQ_HI(value); break; case 0x02: // Voice #1 pulse width (Low-byte) - voice[0]->wave()->writePW_LO(value); + voice[0].wave()->writePW_LO(value); break; case 0x03: // Voice #1 pulse width (bits #8-#15) - voice[0]->wave()->writePW_HI(value); + voice[0].wave()->writePW_HI(value); break; case 0x04: // Voice #1 control register - voice[0]->writeCONTROL_REG(muted[0] ? 0 : value); + voice[0].writeCONTROL_REG(value); break; case 0x05: // Voice #1 Attack and Decay length - voice[0]->envelope()->writeATTACK_DECAY(value); + voice[0].envelope()->writeATTACK_DECAY(value); break; case 0x06: // Voice #1 Sustain volume and Release length - voice[0]->envelope()->writeSUSTAIN_RELEASE(value); + voice[0].envelope()->writeSUSTAIN_RELEASE(value); break; case 0x07: // Voice #2 frequency (Low-byte) - voice[1]->wave()->writeFREQ_LO(value); + voice[1].wave()->writeFREQ_LO(value); break; case 0x08: // Voice #2 frequency (High-byte) - voice[1]->wave()->writeFREQ_HI(value); + voice[1].wave()->writeFREQ_HI(value); break; case 0x09: // Voice #2 pulse width (Low-byte) - voice[1]->wave()->writePW_LO(value); + voice[1].wave()->writePW_LO(value); break; case 0x0a: // Voice #2 pulse width (bits #8-#15) - voice[1]->wave()->writePW_HI(value); + voice[1].wave()->writePW_HI(value); break; case 0x0b: // Voice #2 control register - voice[1]->writeCONTROL_REG(muted[1] ? 0 : value); + voice[1].writeCONTROL_REG(value); break; case 0x0c: // Voice #2 Attack and Decay length - voice[1]->envelope()->writeATTACK_DECAY(value); + voice[1].envelope()->writeATTACK_DECAY(value); break; case 0x0d: // Voice #2 Sustain volume and Release length - voice[1]->envelope()->writeSUSTAIN_RELEASE(value); + voice[1].envelope()->writeSUSTAIN_RELEASE(value); break; case 0x0e: // Voice #3 frequency (Low-byte) - voice[2]->wave()->writeFREQ_LO(value); + voice[2].wave()->writeFREQ_LO(value); break; case 0x0f: // Voice #3 frequency (High-byte) - voice[2]->wave()->writeFREQ_HI(value); + voice[2].wave()->writeFREQ_HI(value); break; case 0x10: // Voice #3 pulse width (Low-byte) - voice[2]->wave()->writePW_LO(value); + voice[2].wave()->writePW_LO(value); break; case 0x11: // Voice #3 pulse width (bits #8-#15) - voice[2]->wave()->writePW_HI(value); + voice[2].wave()->writePW_HI(value); break; case 0x12: // Voice #3 control register - voice[2]->writeCONTROL_REG(muted[2] ? 0 : value); + voice[2].writeCONTROL_REG(value); break; case 0x13: // Voice #3 Attack and Decay length - voice[2]->envelope()->writeATTACK_DECAY(value); + voice[2].envelope()->writeATTACK_DECAY(value); break; case 0x14: // Voice #3 Sustain volume and Release length - voice[2]->envelope()->writeSUSTAIN_RELEASE(value); + voice[2].envelope()->writeSUSTAIN_RELEASE(value); break; case 0x15: // Filter cut off frequency (bits #0-#2) @@ -448,9 +474,9 @@ void SID::write(int offset, unsigned char value) voiceSync(false); } -void SID::setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency) +void SID::setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency) { - externalFilter->setClockFrequency(clockFrequency); + externalFilter.setClockFrequency(clockFrequency); switch (method) { @@ -459,7 +485,7 @@ void SID::setSamplingParameters(double clockFrequency, SamplingMethod method, do break; case RESAMPLE: - resampler.reset(TwoPassSincResampler::create(clockFrequency, samplingFrequency, highestAccurateFrequency)); + resampler.reset(TwoPassSincResampler::create(clockFrequency, samplingFrequency)); break; default: @@ -480,16 +506,16 @@ void SID::clockSilent(unsigned int cycles) for (int i = 0; i < delta_t; i++) { // clock waveform generators (can affect OSC3) - voice[0]->wave()->clock(); - voice[1]->wave()->clock(); - voice[2]->wave()->clock(); + voice[0].wave()->clock(); + voice[1].wave()->clock(); + voice[2].wave()->clock(); - voice[0]->wave()->output(voice[2]->wave()); - voice[1]->wave()->output(voice[0]->wave()); - voice[2]->wave()->output(voice[1]->wave()); + voice[0].wave()->output(voice[2].wave()); + voice[1].wave()->output(voice[0].wave()); + voice[2].wave()->output(voice[1].wave()); // clock ENV3 only - voice[2]->envelope()->clock(); + voice[2].envelope()->clock(); } cycles -= delta_t; diff --git a/src/sound/resid-fp/Spline.cpp b/src/sound/resid-fp/Spline.cpp index 50d55fef1..273fea032 100644 --- a/src/sound/resid-fp/Spline.cpp +++ b/src/sound/resid-fp/Spline.cpp @@ -92,11 +92,11 @@ Spline::Point Spline::evaluate(double x) const { if ((x < c->x1) || (x > c->x2)) { - for (size_t i = 0; i < params.size(); i++) + for (const auto & param : params) { - if (x <= params[i].x2) + if (x <= param.x2) { - c = ¶ms[i]; + c = ¶m; break; } } diff --git a/src/sound/resid-fp/Spline.h b/src/sound/resid-fp/Spline.h index 6cc2b1edc..c3ef1637b 100644 --- a/src/sound/resid-fp/Spline.h +++ b/src/sound/resid-fp/Spline.h @@ -38,14 +38,14 @@ namespace reSIDfp class Spline { public: - typedef struct + using Point = struct { double x; double y; - } Point; + }; private: - typedef struct + using Param = struct { double x1; double x2; @@ -53,9 +53,9 @@ private: double b; double c; double d; - } Param; + }; - typedef std::vector ParamVector; + using ParamVector = std::vector; private: /// Interpolation parameters diff --git a/src/sound/resid-fp/Voice.h b/src/sound/resid-fp/Voice.h index fc7ed41b7..0fb708b1e 100644 --- a/src/sound/resid-fp/Voice.h +++ b/src/sound/resid-fp/Voice.h @@ -23,14 +23,10 @@ #ifndef VOICE_H #define VOICE_H -#include - #include "siddefs-fp.h" #include "WaveformGenerator.h" #include "EnvelopeGenerator.h" -#include "sidcxx11.h" - namespace reSIDfp { @@ -40,9 +36,9 @@ namespace reSIDfp class Voice { private: - std::unique_ptr const waveformGenerator; + WaveformGenerator waveformGenerator; - std::unique_ptr const envelopeGenerator; + EnvelopeGenerator envelopeGenerator; /// The DAC LUT for analog waveform output float* wavDAC; //-V730_NOINIT this is initialized in the SID constructor @@ -67,23 +63,16 @@ public: * @return the voice analog output */ RESID_INLINE - int output(const WaveformGenerator* ringModulator) const + float output(const WaveformGenerator* ringModulator) { - unsigned int const wav = waveformGenerator->output(ringModulator); - unsigned int const env = envelopeGenerator->output(); + unsigned int const wav = waveformGenerator.output(ringModulator); + unsigned int const env = envelopeGenerator.output(); // DAC imperfections are emulated by using the digital output // as an index into a DAC lookup table. - return static_cast(wavDAC[wav] * envDAC[env]); + return wavDAC[wav] * envDAC[env]; } - /** - * Constructor. - */ - Voice() : - waveformGenerator(new WaveformGenerator()), - envelopeGenerator(new EnvelopeGenerator()) {} - /** * Set the analog DAC emulation for waveform generator. * Must be called before any operation. @@ -100,9 +89,9 @@ public: */ void setEnvDAC(float* dac) { envDAC = dac; } - WaveformGenerator* wave() const { return waveformGenerator.get(); } + WaveformGenerator* wave() { return &waveformGenerator; } - EnvelopeGenerator* envelope() const { return envelopeGenerator.get(); } + EnvelopeGenerator* envelope() { return &envelopeGenerator; } /** * Write control register. @@ -111,8 +100,8 @@ public: */ void writeCONTROL_REG(unsigned char control) { - waveformGenerator->writeCONTROL_REG(control); - envelopeGenerator->writeCONTROL_REG(control); + waveformGenerator.writeCONTROL_REG(control); + envelopeGenerator.writeCONTROL_REG(control); } /** @@ -120,8 +109,8 @@ public: */ void reset() { - waveformGenerator->reset(); - envelopeGenerator->reset(); + waveformGenerator.reset(); + envelopeGenerator.reset(); } }; diff --git a/src/sound/resid-fp/WaveformCalculator.cpp b/src/sound/resid-fp/WaveformCalculator.cpp index 74a93cce5..7e167bb18 100644 --- a/src/sound/resid-fp/WaveformCalculator.cpp +++ b/src/sound/resid-fp/WaveformCalculator.cpp @@ -21,66 +21,154 @@ #include "WaveformCalculator.h" +#include "sidcxx11.h" + +#include +#include #include namespace reSIDfp { +/** + * Combined waveform model parameters. + */ +using distance_t = float (*)(float, int); + +using CombinedWaveformConfig = struct +{ + distance_t distFunc; + float threshold; + float topbit; + float pulsestrength; + float distance1; + float distance2; +}; + +using cw_cache_t = std::map; + +cw_cache_t PULLDOWN_CACHE; + +std::mutex PULLDOWN_CACHE_Lock; + WaveformCalculator* WaveformCalculator::getInstance() { static WaveformCalculator instance; return &instance; } -/** - * Parameters derived with the Monte Carlo method based on - * samplings by kevtris. Code and data available in the project repository [1]. - * - * The score here reported is the acoustic error - * calculated XORing the estimated and the sampled values. - * In parentheses the number of mispredicted bits. - * - * [1] https://github.com/libsidplayfp/combined-waveforms - */ -const CombinedWaveformConfig config[2][5] = -{ - { /* kevtris chip G (6581 R2) */ - {0.862147212f, 0.f, 10.8962431f, 2.50848103f }, // TS error 1941 (327/28672) - {0.932746708f, 2.07508397f, 1.03668225f, 1.14876997f }, // PT error 5992 (126/32768) - {0.860927045f, 2.43506575f, 0.908603609f, 1.07907593f }, // PS error 3693 (521/28672) - {0.741343081f, 0.0452554375f, 1.1439606f, 1.05711341f }, // PTS error 338 ( 29/28672) - {0.96f, 2.5f, 1.1f, 1.2f }, // NP guessed - }, - { /* kevtris chip V (8580 R5) */ - {0.715788841f, 0.f, 1.32999945f, 2.2172699f }, // TS error 928 (135/32768) - {0.93500334f, 1.05977178f, 1.08629429f, 1.43518543f }, // PT error 7991 (212/32768) - {0.920648575f, 0.943601072f, 1.13034654f, 1.41881108f }, // PS error 12566 (394/32768) - {0.90921098f, 0.979807794f, 0.942194462f, 1.40958893f }, // PTS error 2092 ( 60/32768) - {0.95f, 1.15f, 1.f, 1.45f }, // NP guessed - }, -}; - -typedef float (*distance_t)(float, int); - // Distance functions static float exponentialDistance(float distance, int i) { return pow(distance, -i); } -#if 0 MAYBE_UNUSED static float linearDistance(float distance, int i) { return 1.f / (1.f + i * distance); } -#endif -#if 0 -MAYBE_UNUSED static float quadraticDistance(float distance, int i) +static float quadraticDistance(float distance, int i) { return 1.f / (1.f + (i*i) * distance); } -#endif + +/** + * Parameters derived with the Monte Carlo method based on + * samplings from real machines. + * Code and data available in the project repository [1]. + * Sampling program made by Dag Lem [2]. + * + * The score here reported is the acoustic error + * calculated XORing the estimated and the sampled values. + * In parentheses the number of mispredicted bits. + * + * [1] https://github.com/libsidplayfp/combined-waveforms + * [2] https://github.com/daglem/reDIP-SID/blob/master/research/combsample.d64 + */ +const CombinedWaveformConfig configAverage[2][5] = +{ + { /* 6581 R3 0486S sampled by Trurl */ + // TS error 3555 (324/32768) [RMS: 73.98] + { exponentialDistance, 0.877322257f, 1.11349654f, 0.f, 2.14537621f, 9.08618164f }, + // PT error 4590 (124/32768) [RMS: 68.90] + { linearDistance, 0.941692829f, 1.f, 1.80072665f, 0.033124879f, 0.232303441f }, + // PS error 19352 (763/32768) [RMS: 96.91] + { linearDistance, 1.66494179f, 1.03760982f, 5.62705326f, 0.291590303f, 0.283631504f }, + // PTS error 5068 ( 94/32768) [RMS: 41.69] + { linearDistance, 1.09762526f, 0.975265801f, 1.52196741f, 0.151528224f, 0.841949463f }, + // NP guessed + { exponentialDistance, 0.96f, 1.f, 2.5f, 1.1f, 1.2f }, + }, + { /* 8580 R5 1088 sampled by reFX-Mike */ + // TS error 10660 (353/32768) [RMS: 58.34] + { exponentialDistance, 0.853578329f, 1.09615636f, 0.f, 1.8819375f, 6.80794907f }, + // PT error 10635 (289/32768) [RMS: 108.81] + { exponentialDistance, 0.929835618f, 1.f, 1.12836814f, 1.10453653f, 1.48065746f }, + // PS error 12255 (554/32768) [RMS: 102.27] + { quadraticDistance, 0.911938608f, 0.996440411f, 1.2278074f, 0.000117214302f, 0.18948476f }, + // PTS error 6913 (127/32768) [RMS: 55.80] + { exponentialDistance, 0.938004673f, 1.04827631f, 1.21178246f, 0.915959001f, 1.42698038f }, + // NP guessed + { exponentialDistance, 0.95f, 1.f, 1.15f, 1.f, 1.45f }, + }, +}; + +const CombinedWaveformConfig configWeak[2][5] = +{ + { /* 6581 R2 4383 sampled by ltx128 */ + // TS error 1474 (198/32768) [RMS: 62.81] + { exponentialDistance, 0.892563999f, 1.11905622f, 0.f, 2.21876144f, 9.63837719f }, + // PT error 612 (102/32768) [RMS: 43.71] + { linearDistance, 1.01262534f, 1.f, 2.46070528f, 0.0537485816f, 0.0986242667f }, + // PS error 8135 (575/32768) [RMS: 75.10] + { linearDistance, 2.14896345f, 1.0216713f, 10.5400085f, 0.244498149f, 0.126134038f }, + // PTS error 2489 (60/32768) [RMS: 24.41] + { linearDistance, 1.22330308f, 0.933797896f, 2.83245254f, 0.0615176819f, 0.323831677f }, + // NP guessed + { exponentialDistance, 0.96f, 1.f, 2.5f, 1.1f, 1.2f }, + }, + { /* 8580 R5 4887 sampled by reFX-Mike */ + // TS error 741 (76/32768) [RMS: 53.74] + { exponentialDistance, 0.812351167f, 1.1727736f, 0.f, 1.87459648f, 2.31578159f }, + // PT error 7199 (192/32768) [RMS: 88.43] + { exponentialDistance, 0.917997837f, 1.f, 1.01248944f, 1.05761552f, 1.37529826f }, + // PS error 9856 (332/32768) [RMS: 86.29] + { quadraticDistance, 0.968754232f, 1.00669801f, 1.29909098f, 0.00962483883f, 0.146850556f }, + // PTS error 4809 (60/32768) [RMS: 45.37] + { exponentialDistance, 0.941834152f, 1.06401193f, 0.991132736f, 0.995310068f, 1.41105855f }, + // NP guessed + { exponentialDistance, 0.95f, 1.f, 1.15f, 1.f, 1.45f }, + }, +}; + +const CombinedWaveformConfig configStrong[2][5] = +{ + { /* 6581 R2 0384 sampled by Trurl */ + // TS error 20337 (1579/32768) [RMS: 88.57] + { exponentialDistance, 0.000637792516f, 1.56725872f, 0.f, 0.00036806846f, 1.51800942f }, + // PT error 5190 (238/32768) [RMS: 83.54] + { linearDistance, 0.924780309f, 1.f, 1.96809769f, 0.0888123438f, 0.234606609f }, + // PS error 31015 (2181/32768) [RMS: 114.99] + { linearDistance, 1.2328074f, 0.73079139f, 3.9719491f, 0.00156516861f, 0.314677745f }, + // PTS error 9874 (201/32768) [RMS: 52.30] + { linearDistance, 1.08558261f, 0.857638359f, 1.52781796f, 0.152927235f, 1.02657032f }, + // NP guessed + { exponentialDistance, 0.96f, 1.f, 2.5f, 1.1f, 1.2f }, + }, + { /* 8580 R5 1489 sampled by reFX-Mike */ + // TS error 4837 (388/32768) [RMS: 76.07] + { exponentialDistance, 0.89762634f, 56.7594185f, 0.f, 7.68995237f, 12.0754194f }, + // PT error 9266 (508/32768) [RMS: 127.83] + { exponentialDistance, 0.87147671f, 1.f, 1.44887495f, 1.05899632f, 1.43786001f }, + // PS error 13168 (718/32768) [RMS: 123.35] + { quadraticDistance, 0.89255774f, 1.2253896f, 1.75615835f, 0.0245045591f, 0.12982437f }, + // PTS error 6702 (300/32768) [RMS: 71.01] + { linearDistance, 0.91124934f, 0.963609755f, 0.909965038f, 1.07445884f, 1.82399702f }, + // NP guessed + { exponentialDistance, 0.95f, 1.f, 1.15f, 1.f, 1.45f }, + }, +}; /// Calculate triangle waveform static unsigned int triXor(unsigned int val) @@ -96,15 +184,17 @@ static unsigned int triXor(unsigned int val) * @param threshold * @param accumulator the high bits of the accumulator value */ -short calculatePulldown(float distancetable[], float pulsestrength, float threshold, unsigned int accumulator) +short calculatePulldown(float distancetable[], float topbit, float pulsestrength, float threshold, unsigned int accumulator) { - unsigned char bit[12]; + float bit[12]; for (unsigned int i = 0; i < 12; i++) { - bit[i] = (accumulator & (1u << i)) != 0 ? 1 : 0; + bit[i] = (accumulator & (1u << i)) != 0 ? 1.f : 0.f; } + bit[11] *= topbit; + float pulldown[12]; for (int sb = 0; sb < 12; sb++) @@ -117,7 +207,7 @@ short calculatePulldown(float distancetable[], float pulsestrength, float thresh if (cb == sb) continue; const float weight = distancetable[sb - cb + 12]; - avg += static_cast(1 - bit[cb]) * weight; + avg += (1.f - bit[cb]) * weight; n += weight; } @@ -131,7 +221,7 @@ short calculatePulldown(float distancetable[], float pulsestrength, float thresh for (unsigned int i = 0; i < 12; i++) { - const float bitValue = bit[i] != 0 ? 1.f - pulldown[i] : 0.f; + const float bitValue = bit[i] > 0.f ? 1.f - pulldown[i] : 0.f; if (bitValue > threshold) { value |= 1u << i; @@ -157,9 +247,26 @@ WaveformCalculator::WaveformCalculator() : } } -matrix_t* WaveformCalculator::buildPulldownTable(ChipModel model) +matrix_t* WaveformCalculator::buildPulldownTable(ChipModel model, CombinedWaveforms cws) { - const CombinedWaveformConfig* cfgArray = config[model == MOS6581 ? 0 : 1]; + std::lock_guard lock(PULLDOWN_CACHE_Lock); + + const int modelIdx = model == MOS6581 ? 0 : 1; + const CombinedWaveformConfig* cfgArray; + + switch (cws) + { + default: + case AVERAGE: + cfgArray = configAverage[modelIdx]; + break; + case WEAK: + cfgArray = configWeak[modelIdx]; + break; + case STRONG: + cfgArray = configStrong[modelIdx]; + break; + } cw_cache_t::iterator lb = PULLDOWN_CACHE.lower_bound(cfgArray); @@ -174,7 +281,7 @@ matrix_t* WaveformCalculator::buildPulldownTable(ChipModel model) { const CombinedWaveformConfig& cfg = cfgArray[wav]; - const distance_t distFunc = exponentialDistance; + const distance_t distFunc = cfg.distFunc; float distancetable[12 * 2 + 1]; distancetable[12] = 1.f; @@ -186,14 +293,11 @@ matrix_t* WaveformCalculator::buildPulldownTable(ChipModel model) for (unsigned int idx = 0; idx < (1u << 12); idx++) { - pdTable[wav][idx] = calculatePulldown(distancetable, cfg.pulsestrength, cfg.threshold, idx); + pdTable[wav][idx] = calculatePulldown(distancetable, cfg.topbit, cfg.pulsestrength, cfg.threshold, idx); } } -#ifdef HAVE_CXX11 + return &(PULLDOWN_CACHE.emplace_hint(lb, cw_cache_t::value_type(cfgArray, pdTable))->second); -#else - return &(PULLDOWN_CACHE.insert(lb, cw_cache_t::value_type(cfgArray, pdTable))->second); -#endif } } // namespace reSIDfp diff --git a/src/sound/resid-fp/WaveformCalculator.h b/src/sound/resid-fp/WaveformCalculator.h index 4ad677274..f6db00c7d 100644 --- a/src/sound/resid-fp/WaveformCalculator.h +++ b/src/sound/resid-fp/WaveformCalculator.h @@ -22,46 +22,33 @@ #ifndef WAVEFORMCALCULATOR_h #define WAVEFORMCALCULATOR_h -#include - #include "array.h" -#include "sidcxx11.h" + #include "siddefs-fp.h" namespace reSIDfp { -/** - * Combined waveform model parameters. - */ -typedef struct -{ - float threshold; - float pulsestrength; - float distance1; - float distance2; -} CombinedWaveformConfig; - /** * Combined waveform calculator for WaveformGenerator. * By combining waveforms, the bits of each waveform are effectively short - * circuited. A zero bit in one waveform will result in a zero output bit - * (thus the infamous claim that the waveforms are AND'ed). + * circuited, a zero bit in one waveform will result in a zero output bit, + * thus the claim that the waveforms are AND'ed. * However, a zero bit in one waveform may also affect the neighboring bits * in the output. * * Example: - * + * * 1 1 * Bit # 1 0 9 8 7 6 5 4 3 2 1 0 * ----------------------- * Sawtooth 0 0 0 1 1 1 1 1 1 0 0 0 - * + * * Triangle 0 0 1 1 1 1 1 1 0 0 0 0 - * + * * AND 0 0 0 1 1 1 1 1 0 0 0 0 - * + * * Output 0 0 0 0 1 1 1 0 0 0 0 0 * * @@ -98,14 +85,9 @@ typedef struct */ class WaveformCalculator { -private: - typedef std::map cw_cache_t; - private: matrix_t wftable; - cw_cache_t PULLDOWN_CACHE; - private: WaveformCalculator(); @@ -126,9 +108,10 @@ public: * Build pulldown table for use by WaveformGenerator. * * @param model Chip model to use + * @param cws strength of combined waveforms * @return Pulldown table */ - matrix_t* buildPulldownTable(ChipModel model); + matrix_t* buildPulldownTable(ChipModel model, CombinedWaveforms cws); }; } // namespace reSIDfp diff --git a/src/sound/resid-fp/WaveformGenerator.cpp b/src/sound/resid-fp/WaveformGenerator.cpp index 4c7a55b3d..be0738bba 100644 --- a/src/sound/resid-fp/WaveformGenerator.cpp +++ b/src/sound/resid-fp/WaveformGenerator.cpp @@ -40,13 +40,13 @@ namespace reSIDfp * and [VICE Bug #1128](http://sourceforge.net/p/vice-emu/bugs/1128/) */ // ~95ms -const unsigned int FLOATING_OUTPUT_TTL_6581R3 = 54000; -const unsigned int FLOATING_OUTPUT_FADE_6581R3 = 1400; +constexpr unsigned int FLOATING_OUTPUT_TTL_6581R3 = 54000; +constexpr unsigned int FLOATING_OUTPUT_FADE_6581R3 = 1400; // ~1s -//const unsigned int FLOATING_OUTPUT_TTL_6581R4 = 1000000; +constexpr unsigned int FLOATING_OUTPUT_TTL_6581R4 = 1000000; // ~1s -const unsigned int FLOATING_OUTPUT_TTL_8580R5 = 800000; -const unsigned int FLOATING_OUTPUT_FADE_8580R5 = 50000; +constexpr unsigned int FLOATING_OUTPUT_TTL_8580R5 = 800000; +constexpr unsigned int FLOATING_OUTPUT_FADE_8580R5 = 50000; /** * Number of cycles after which the shift register is reset @@ -58,15 +58,15 @@ const unsigned int FLOATING_OUTPUT_FADE_8580R5 = 50000; * only the big difference between the old and new models. */ // ~210ms -const unsigned int SHIFT_REGISTER_RESET_6581R3 = 50000; -const unsigned int SHIFT_REGISTER_FADE_6581R3 = 15000; +constexpr unsigned int SHIFT_REGISTER_RESET_6581R3 = 50000; +constexpr unsigned int SHIFT_REGISTER_FADE_6581R3 = 15000; // ~2.15s -//const unsigned int SHIFT_REGISTER_RESET_6581R4 = 2150000; +constexpr unsigned int SHIFT_REGISTER_RESET_6581R4 = 2150000; // ~2.8s -const unsigned int SHIFT_REGISTER_RESET_8580R5 = 986000; -const unsigned int SHIFT_REGISTER_FADE_8580R5 = 314300; +constexpr unsigned int SHIFT_REGISTER_RESET_8580R5 = 986000; +constexpr unsigned int SHIFT_REGISTER_FADE_8580R5 = 314300; -const unsigned int shift_mask = +constexpr unsigned int shift_mask = ~( (1u << 2) | // Bit 20 (1u << 4) | // Bit 18 @@ -107,15 +107,100 @@ const unsigned int shift_mask = * -----+-------+--------------+-------------- * phi1 | 1 | X --> X | A --> A <- shift phase 2 * phi2 | 1 | X <-> X | A <-> A + * + * + * Normal cycles + * ------------- + * Normally, when noise is selected along with another waveform, + * c1 and c2 are closed and the output bits pull down the corresponding + * shift register bits. + * + * noi_out_x noi_out_x+1 + * ^ ^ + * | | + * +-------------+ +-------------+ + * | | | | + * +---o<|---+ | +---o<|---+ | + * | | | | | | + * c2 | c1 | | c2 | c1 | | + * | | | | | | + * >---/---+---|>o---+ +---/---+---|>o---+ +---/---> + * LC LC LC + * + * + * Shift phase 1 + * ------------- + * During shift phase 1 c1 and c2 are open, the SR bits are floating + * and will be driven by the output of combined waveforms, + * or slowly turn high. + * + * noi_out_x noi_out_x+1 + * ^ ^ + * | | + * +-------------+ +-------------+ + * | | | | + * +---o<|---+ | +---o<|---+ | + * | | | | | | + * c2 / c1 / | c2 / c1 / | + * | | | | | | + * >-------+---|>o---+ +-------+---|>o---+ +-------> + * LC LC LC + * + * + * Shift phase 2 (phi1) + * -------------------- + * During the first half cycle of shift phase 2 c1 is closed + * so the value from of noi_out_x-1 enters the bit. + * + * noi_out_x noi_out_x+1 + * ^ ^ + * | | + * +-------------+ +-------------+ + * | | | | + * +---o<|---+ | +---o<|---+ | + * | | | | | | + * c2 / c1 | | c2 / c1 | | + * | | | | | | + * >---/---+---|>o---+ +---/---+---|>o---+ +---/---> + * LC LC LC + * + * + * Shift phase 2 (phi2) + * -------------------- + * On the second half of shift phase 2 c2 closes and + * we're back to normal cycles. */ inline bool do_writeback(unsigned int waveform_old, unsigned int waveform_new, bool is6581) { // no writeback without combined waveforms - if (waveform_new <= 8) - return false; + if (waveform_old <= 8) - return false; // fixes SID/noisewriteback/noise_writeback_test2-{old,new} + // fixes SID/noisewriteback/noise_writeback_test2-{old,new} + return false; + + if (waveform_new < 8) + return false; + + if ((waveform_new == 8) + // breaks noise_writeback_check_F_to_8_old + // but fixes simple and scan + && (waveform_old != 0xf)) + { + // fixes + // noise_writeback_check_9_to_8_old + // noise_writeback_check_A_to_8_old + // noise_writeback_check_B_to_8_old + // noise_writeback_check_D_to_8_old + // noise_writeback_check_E_to_8_old + // noise_writeback_check_F_to_8_old + // noise_writeback_check_9_to_8_new + // noise_writeback_check_A_to_8_new + // noise_writeback_check_D_to_8_new + // noise_writeback_check_E_to_8_new + // noise_writeback_test1-{old,new} + return false; + } // What's happening here? if (is6581 && @@ -190,8 +275,16 @@ void WaveformGenerator::write_shift_register() { if (unlikely(waveform > 0x8)) { +#if 0 + // FIXME this breaks SID/wf12nsr/wf12nsr if (waveform == 0xc) - return; // breaks SID/wf12nsr/wf12nsr + // fixes + // noise_writeback_check_8_to_C_old + // noise_writeback_check_9_to_C_old + // noise_writeback_check_A_to_C_old + // noise_writeback_check_C_to_C_old + return; +#endif // Write changes to the shift register output caused by combined waveforms // back into the shift register. diff --git a/src/sound/resid-fp/WaveformGenerator.h b/src/sound/resid-fp/WaveformGenerator.h index adca6c228..7bbccbc80 100644 --- a/src/sound/resid-fp/WaveformGenerator.h +++ b/src/sound/resid-fp/WaveformGenerator.h @@ -93,64 +93,64 @@ namespace reSIDfp class WaveformGenerator { private: - matrix_t* model_wave; - matrix_t* model_pulldown; + matrix_t* model_wave = nullptr; + matrix_t* model_pulldown = nullptr; - short* wave; - short* pulldown; + short* wave = nullptr; + short* pulldown = nullptr; // PWout = (PWn/40.95)% - unsigned int pw; + unsigned int pw = 0; - unsigned int shift_register; + unsigned int shift_register = 0; /// Shift register is latched when transitioning to shift phase 1. - unsigned int shift_latch; + unsigned int shift_latch = 0; /// Emulation of pipeline causing bit 19 to clock the shift register. - int shift_pipeline; + int shift_pipeline = 0; - unsigned int ring_msb_mask; - unsigned int no_noise; - unsigned int noise_output; - unsigned int no_noise_or_noise_output; - unsigned int no_pulse; - unsigned int pulse_output; + unsigned int ring_msb_mask = 0; + unsigned int no_noise = 0; + unsigned int noise_output = 0; + unsigned int no_noise_or_noise_output = 0; + unsigned int no_pulse = 0; + unsigned int pulse_output = 0; /// The control register right-shifted 4 bits; used for output function table lookup. - unsigned int waveform; + unsigned int waveform = 0; - unsigned int waveform_output; + unsigned int waveform_output = 0; /// Current accumulator value. - unsigned int accumulator; + unsigned int accumulator = 0x555555; // Accumulator's even bits are high on powerup // Fout = (Fn*Fclk/16777216)Hz - unsigned int freq; + unsigned int freq = 0; /// 8580 tri/saw pipeline - unsigned int tri_saw_pipeline; + unsigned int tri_saw_pipeline = 0x555; /// The OSC3 value - unsigned int osc3; + unsigned int osc3 = 0; /// Remaining time to fully reset shift register. - unsigned int shift_register_reset; + unsigned int shift_register_reset = 0; // The wave signal TTL when no waveform is selected. - unsigned int floating_output_ttl; + unsigned int floating_output_ttl = 0; /// The control register bits. Gate is handled by EnvelopeGenerator. //@{ - bool test; - bool sync; + bool test = false; + bool sync = false; //@} /// Test bit is latched at phi2 for the noise XOR. bool test_or_reset; /// Tell whether the accumulator MSB was set high on this cycle. - bool msb_rising; + bool msb_rising = false; bool is6581; //-V730_NOINIT this is initialized in the SID constructor @@ -160,7 +160,7 @@ private: void write_shift_register(); void set_noise_output(); - + void set_no_noise_or_noise_output(); void waveBitfade(); @@ -194,35 +194,6 @@ public: */ void synchronize(WaveformGenerator* syncDest, const WaveformGenerator* syncSource) const; - /** - * Constructor. - */ - WaveformGenerator() : - model_wave(nullptr), - model_pulldown(nullptr), - wave(nullptr), - pulldown(nullptr), - pw(0), - shift_register(0), - shift_pipeline(0), - ring_msb_mask(0), - no_noise(0), - noise_output(0), - no_noise_or_noise_output(0), - no_pulse(0), - pulse_output(0), - waveform(0), - waveform_output(0), - accumulator(0x555555), // Accumulator's even bits are high on powerup - freq(0), - tri_saw_pipeline(0x555), - osc3(0), - shift_register_reset(0), - floating_output_ttl(0), - test(false), - sync(false), - msb_rising(false) {} - /** * Write FREQ LO register. * @@ -397,13 +368,13 @@ unsigned int WaveformGenerator::output(const WaveformGenerator* ringModulator) { osc3 = waveform_output; } - // In the 6581 the top bit of the accumulator may be driven low by combined waveforms // when the sawtooth is selected - if (is6581 - && (waveform & 0x2) - && ((waveform_output & 0x800) == 0)) + if (is6581 && (waveform & 0x2) && ((waveform_output & 0x800) == 0)) + { + msb_rising = 0; accumulator &= 0x7fffff; + } write_shift_register(); } diff --git a/src/sound/resid-fp/array.h b/src/sound/resid-fp/array.h index a0d390966..58c4617ae 100644 --- a/src/sound/resid-fp/array.h +++ b/src/sound/resid-fp/array.h @@ -26,9 +26,7 @@ # include "config.h" #endif -#ifdef HAVE_CXX11 -# include -#endif +#include /** * Counter. @@ -36,11 +34,7 @@ class counter { private: -#ifndef HAVE_CXX11 - volatile unsigned int c; -#else std::atomic c; -#endif public: counter() : c(1) {} @@ -81,6 +75,6 @@ public: T const* operator[](unsigned int a) const { return &data[a * y]; } }; -typedef matrix matrix_t; +using matrix_t = matrix; #endif diff --git a/src/sound/resid-fp/config.h b/src/sound/resid-fp/config.h index 0eeba8dee..399003a55 100644 --- a/src/sound/resid-fp/config.h +++ b/src/sound/resid-fp/config.h @@ -1 +1 @@ -#define HAVE_CXX14 +#define HAVE_CXX17 diff --git a/src/sound/resid-fp/resample/Resampler.h b/src/sound/resid-fp/resample/Resampler.h index 904f65458..293fda6ce 100644 --- a/src/sound/resid-fp/resample/Resampler.h +++ b/src/sound/resid-fp/resample/Resampler.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2020 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify @@ -23,6 +23,7 @@ #define RESAMPLER_H #include +#include #include "../sidcxx11.h" @@ -37,28 +38,45 @@ namespace reSIDfp */ class Resampler { -protected: - inline short softClip(int x) const +private: + template + static inline int clipper(int x) { + assert(x >= 0); constexpr int threshold = 28000; if (likely(x < threshold)) return x; - constexpr double t = threshold / 32768.; + constexpr double max_val = static_cast(m); + constexpr double t = threshold / max_val; constexpr double a = 1. - t; constexpr double b = 1. / a; - double value = static_cast(x - threshold) / 32768.; - value = t + a * tanh(b * value); - return static_cast(value * 32768.); + double value = static_cast(x - threshold) / max_val; + value = t + a * std::tanh(b * value); + return static_cast(value * max_val); } + /* + * Soft Clipping implementation, splitted for test. + */ + static inline int softClipImpl(int x) + { + return x < 0 ? -clipper<32768>(-x) : clipper<32767>(x); + } + +protected: + /* + * Soft Clipping into 16 bit range [-32768,32767] + */ + static inline short softClip(int x) { return static_cast(softClipImpl(x)); } + virtual int output() const = 0; Resampler() {} public: - virtual ~Resampler() {} + virtual ~Resampler() = default; /** * Input a sample into resampler. Output "true" when resampler is ready with new sample. @@ -73,9 +91,10 @@ public: * * @return resampled sample */ - short getOutput() const + inline short getOutput(int scaleFactor) const { - return softClip(output()); + const int out = (scaleFactor * output()) / 2; + return softClip(out); } virtual void reset() = 0; diff --git a/src/sound/resid-fp/resample/SincResampler.cpp b/src/sound/resid-fp/resample/SincResampler.cpp index df7d8af83..14ae13752 100644 --- a/src/sound/resid-fp/resample/SincResampler.cpp +++ b/src/sound/resid-fp/resample/SincResampler.cpp @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2020 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem * @@ -22,11 +22,16 @@ #include "SincResampler.h" +#ifdef HAVE_CXX20 +# include +#endif + +#include +#include #include #include #include -#include -#include +#include #include "../siddefs-fp.h" @@ -34,10 +39,8 @@ # include "config.h" #endif -#ifdef HAVE_EMMINTRIN_H -# include -#elif defined HAVE_MMINTRIN_H -# include +#ifdef HAVE_SMMINTRIN_H +# include #elif defined(HAVE_ARM_NEON_H) # include #endif @@ -45,15 +48,10 @@ namespace reSIDfp { -typedef std::map fir_cache_t; - -/// Cache for the expensive FIR table computation results. -fir_cache_t FIR_CACHE; - /// Maximum error acceptable in I0 is 1e-6, or ~96 dB. -const double I0E = 1e-6; +constexpr double I0E = 1e-6; -const int BITS = 16; +constexpr int BITS = 16; /** * Compute the 0th order modified Bessel function of the first kind. @@ -90,7 +88,7 @@ double I0(double x) * @param bLength length of the sinc buffer * @return convolved result */ -int convolve(const short* a, const short* b, int bLength) +int convolve(const int* a, const short* b, int bLength) { #ifdef HAVE_EMMINTRIN_H int out = 0; @@ -102,7 +100,7 @@ int convolve(const short* a, const short* b, int bLength) { if (offset) { - const int l = (0x10 - offset)/2; + const int l = (0x10 - offset) / 2; for (int i = 0; i < l; i++) { @@ -208,9 +206,9 @@ int convolve(const short* a, const short* b, int bLength) bLength &= 3; #else int32x4_t acc = vdupq_n_s32(0); - + const int n = bLength / 4; - + for (int i = 0; i < n; i++) { const int16x4_t h_vec = vld1_s16(a); @@ -219,12 +217,12 @@ int convolve(const short* a, const short* b, int bLength) a += 4; b += 4; } - + int out = vgetq_lane_s32(acc, 0) + vgetq_lane_s32(acc, 1) + vgetq_lane_s32(acc, 2) + vgetq_lane_s32(acc, 3); - + bLength &= 3; #endif #else @@ -233,7 +231,7 @@ int convolve(const short* a, const short* b, int bLength) for (int i = 0; i < bLength; i++) { - out += *a++ * *b++; + out += a[i] * static_cast(b[i]); } return (out + (1 << 14)) >> 15; @@ -265,17 +263,27 @@ int SincResampler::fir(int subcycle) return v1 + (firTableOffset * (v2 - v1) >> 10); } -SincResampler::SincResampler(double clockFrequency, double samplingFrequency, double highestAccurateFrequency) : - sampleIndex(0), - cyclesPerSample(static_cast(clockFrequency / samplingFrequency * 1024.)), - sampleOffset(0), - outputValue(0) +SincResampler::SincResampler( + double clockFrequency, + double samplingFrequency, + double highestAccurateFrequency) : + cyclesPerSample(static_cast(clockFrequency / samplingFrequency * 1024.)) { +#if defined(HAVE_CXX20) && defined(__cpp_lib_constexpr_cmath) + constexpr double PI = std::numbers::pi; +#else +# ifdef M_PI + constexpr double PI = M_PI; +#else + constexpr double PI = 3.14159265358979323846; +# endif +#endif + // 16 bits -> -96dB stopband attenuation. - const double A = -20. * log10(1.0 / (1 << BITS)); + const double A = -20. * std::log10(1.0 / (1 << BITS)); // A fraction of the bandwidth is allocated to the transition band, which we double // because we design the filter to transition halfway at nyquist. - const double dw = (1. - 2.*highestAccurateFrequency / samplingFrequency) * M_PI * 2.; + const double dw = (1. - 2.*highestAccurateFrequency / samplingFrequency) * PI * 2.; // For calculation of beta and N see the reference for the kaiserord // function in the MATLAB Signal Processing Toolbox: @@ -283,6 +291,7 @@ SincResampler::SincResampler(double clockFrequency, double samplingFrequency, do const double beta = 0.1102 * (A - 8.7); const double I0beta = I0(beta); const double cyclesPerSampleD = clockFrequency / samplingFrequency; + const double inv_cyclesPerSampleD = samplingFrequency / clockFrequency; { // The filter order will maximally be 124 with the current constraints. @@ -302,40 +311,22 @@ SincResampler::SincResampler(double clockFrequency, double samplingFrequency, do assert(firN < RINGSIZE); // Error is bounded by err < 1.234 / L^2, so L = sqrt(1.234 / (2^-16)) = sqrt(1.234 * 2^16). - firRES = static_cast(ceil(sqrt(1.234 * (1 << BITS)) / cyclesPerSampleD)); + firRES = static_cast(std::ceil(std::sqrt(1.234 * (1 << BITS)) * inv_cyclesPerSampleD)); // firN*firRES represent the total resolution of the sinc sampling. JOS // recommends a length of 2^BITS, but we don't quite use that good a filter. // The filter test program indicates that the filter performs well, though. } - // Create the map key - std::ostringstream o; - o << firN << "," << firRES << "," << cyclesPerSampleD; - const std::string firKey = o.str(); - fir_cache_t::iterator lb = FIR_CACHE.lower_bound(firKey); - - // The FIR computation is expensive and we set sampling parameters often, but - // from a very small set of choices. Thus, caching is used to speed initialization. - if (lb != FIR_CACHE.end() && !(FIR_CACHE.key_comp()(firKey, lb->first))) - { - firTable = &(lb->second); - } - else { // Allocate memory for FIR tables. - matrix_t tempTable(firRES, firN); -#ifdef HAVE_CXX11 - firTable = &(FIR_CACHE.emplace_hint(lb, fir_cache_t::value_type(firKey, tempTable))->second); -#else - firTable = &(FIR_CACHE.insert(lb, fir_cache_t::value_type(firKey, tempTable))->second); -#endif + firTable = new matrix_t(firRES, firN); // The cutoff frequency is midway through the transition band, in effect the same as nyquist. - const double wc = M_PI; + const double wc = PI; // Calculate the sinc tables. - const double scale = 32768.0 * wc / cyclesPerSampleD / M_PI; + const double scale = 32768.0 * wc * inv_cyclesPerSampleD / PI; // we're not interested in the fractional part // so use int division before converting to double @@ -351,10 +342,10 @@ SincResampler::SincResampler(double clockFrequency, double samplingFrequency, do const double x = j - jPhase; const double xt = x / firN_2; - const double kaiserXt = fabs(xt) < 1. ? I0(beta * sqrt(1. - xt * xt)) / I0beta : 0.; + const double kaiserXt = std::fabs(xt) < 1. ? I0(beta * std::sqrt(1. - xt * xt)) / I0beta : 0.; - const double wt = wc * x / cyclesPerSampleD; - const double sincWt = fabs(wt) >= 1e-8 ? sin(wt) / wt : 1.; + const double wt = wc * x * inv_cyclesPerSampleD; + const double sincWt = std::fabs(wt) >= 1e-8 ? std::sin(wt) / wt : 1.; (*firTable)[i][j] = static_cast(scale * sincWt * kaiserXt); } @@ -362,18 +353,16 @@ SincResampler::SincResampler(double clockFrequency, double samplingFrequency, do } } +SincResampler::~SincResampler() +{ + delete firTable; +} + bool SincResampler::input(int input) { bool ready = false; - /* - * Clip the input as it may overflow the 16 bit range. - * - * Approximate measured input ranges: - * 6581: [-24262,+25080] (Kawasaki_Synthesizer_Demo) - * 8580: [-21514,+35232] (64_Forever, Drum_Fool) - */ - sample[sampleIndex] = sample[sampleIndex + RINGSIZE] = softClip(input); + sample[sampleIndex] = sample[sampleIndex + RINGSIZE] = input; sampleIndex = (sampleIndex + 1) & (RINGSIZE - 1); if (sampleOffset < 1024) @@ -390,7 +379,7 @@ bool SincResampler::input(int input) void SincResampler::reset() { - memset(sample, 0, sizeof(sample)); + std::fill(std::begin(sample), std::end(sample), 0); sampleOffset = 0; } diff --git a/src/sound/resid-fp/resample/SincResampler.h b/src/sound/resid-fp/resample/SincResampler.h index 7502d96fd..c3228171f 100644 --- a/src/sound/resid-fp/resample/SincResampler.h +++ b/src/sound/resid-fp/resample/SincResampler.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2013 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem * @@ -25,13 +25,8 @@ #include "Resampler.h" -#include -#include - #include "../array.h" -#include "../sidcxx11.h" - namespace reSIDfp { @@ -54,13 +49,13 @@ class SincResampler final : public Resampler { private: /// Size of the ring buffer, must be a power of 2 - static const int RINGSIZE = 2048; + static constexpr int RINGSIZE = 2048; private: /// Table of the fir filter coefficients matrix_t* firTable; - int sampleIndex; + int sampleIndex = 0; /// Filter resolution int firRES; @@ -70,11 +65,11 @@ private: const int cyclesPerSample; - int sampleOffset; + int sampleOffset = 0; - int outputValue; + int outputValue = 0; - short sample[RINGSIZE * 2]; + int sample[RINGSIZE * 2]; private: int fir(int subcycle); @@ -82,25 +77,25 @@ private: public: /** * Use a clock freqency of 985248Hz for PAL C64, 1022730Hz for NTSC C64. - * The default end of passband frequency is pass_freq = 0.9*sample_freq/2 - * for sample frequencies up to ~ 44.1kHz, and 20kHz for higher sample frequencies. * - * For resampling, the ratio between the clock frequency and the sample frequency - * is limited as follows: 125*clock_freq/sample_freq < 16384 + * For resampling, the ratio between the clock frequency + * and the sample frequency is limited as follows: + * 125*clock_freq/sample_freq < 16384 + * * E.g. provided a clock frequency of ~ 1MHz, the sample frequency * can not be set lower than ~ 8kHz. - * A lower sample frequency would make the resampling code overfill its 16k sample ring buffer. - * - * The end of passband frequency is also limited: pass_freq <= 0.9*sample_freq/2 - * - * E.g. for a 44.1kHz sampling rate the end of passband frequency is limited - * to slightly below 20kHz. This constraint ensures that the FIR table is not overfilled. + * A lower sample frequency would make the resampling code overfill + * its 16k sample ring buffer. * * @param clockFrequency System clock frequency at Hz * @param samplingFrequency Desired output sampling rate - * @param highestAccurateFrequency + * @param highestAccurateFrequency passband frequency limit */ - SincResampler(double clockFrequency, double samplingFrequency, double highestAccurateFrequency); + SincResampler( + double clockFrequency, + double samplingFrequency, + double highestAccurateFrequency); + ~SincResampler() override; bool input(int input) override; diff --git a/src/sound/resid-fp/resample/TwoPassSincResampler.h b/src/sound/resid-fp/resample/TwoPassSincResampler.h index 81659193a..7ba28ea8e 100644 --- a/src/sound/resid-fp/resample/TwoPassSincResampler.h +++ b/src/sound/resid-fp/resample/TwoPassSincResampler.h @@ -51,14 +51,25 @@ private: public: // Named constructor - static TwoPassSincResampler* create(double clockFrequency, double samplingFrequency, double highestAccurateFrequency) + static TwoPassSincResampler* create(double clockFrequency, double samplingFrequency) { - // Calculation according to Laurent Ganier. It evaluates to about 120 kHz at typical settings. + // Set the passband frequency slightly below half sampling frequency + // pass_freq <= 0.9*sample_freq/2 + // + // This constraint ensures that the FIR table is not overfilled. + // For higher sampling frequencies we're fine with 20KHz + const double halfFreq = (samplingFrequency > 44000.) + ? 20000. : samplingFrequency * 0.45; + + // Calculation according to Laurent Ganier. + // It evaluates to about 120 kHz at typical settings. // Some testing around the chosen value seems to confirm that this does work. - double const intermediateFrequency = 2. * highestAccurateFrequency - + sqrt(2. * highestAccurateFrequency * clockFrequency - * (samplingFrequency - 2. * highestAccurateFrequency) / samplingFrequency); - return new TwoPassSincResampler(clockFrequency, samplingFrequency, highestAccurateFrequency, intermediateFrequency); + double const intermediateFrequency = 2. * halfFreq + + std::sqrt(2. * halfFreq * clockFrequency + * (samplingFrequency - 2. * halfFreq) / samplingFrequency); + + return new TwoPassSincResampler( + clockFrequency, samplingFrequency, halfFreq, intermediateFrequency); } bool input(int sample) override diff --git a/src/sound/resid-fp/resample/test.cpp b/src/sound/resid-fp/resample/test.cpp index b229e9e4d..d84e641d2 100644 --- a/src/sound/resid-fp/resample/test.cpp +++ b/src/sound/resid-fp/resample/test.cpp @@ -35,6 +35,10 @@ # define unique_ptr auto_ptr #endif +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + /** * Simple sin waveform in, power output measurement function. * It would be far better to use FFT. @@ -57,7 +61,7 @@ int main(int, const char*[]) for (int j = 0; j < RINGSIZE; j ++) { - int signal = static_cast(32768.0 * sin(k++ * omega) * sqrt(2)); + int signal = static_cast(32768.0 * std::sin(k++ * omega) * sqrt(2)); r->input(signal); } @@ -67,7 +71,7 @@ int main(int, const char*[]) /* Now, during measurement stage, put 100 cycles of waveform through filter. */ for (int j = 0; j < 100000; j ++) { - int signal = static_cast(32768.0 * sin(k++ * omega) * sqrt(2)); + int signal = static_cast(32768.0 * std::sin(k++ * omega) * std::sqrt(2)); if (r->input(signal)) { @@ -77,7 +81,7 @@ int main(int, const char*[]) } } - results.insert(std::make_pair(freq, 10 * log10(pwr / n))); + results.insert(std::make_pair(freq, 10 * std::log10(pwr / n))); } clock_t end = clock(); diff --git a/src/sound/resid-fp/sid.h b/src/sound/resid-fp/sid.h index 05ad83c3b..ef3dc71b3 100644 --- a/src/sound/resid-fp/sid.h +++ b/src/sound/resid-fp/sid.h @@ -1,7 +1,7 @@ /* * This file is part of libsidplayfp, a SID player engine. * - * Copyright 2011-2016 Leandro Nini + * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2004 Dag Lem * @@ -26,6 +26,9 @@ #include #include "siddefs-fp.h" +#include "ExternalFilter.h" +#include "Potentiometer.h" +#include "Voice.h" #include "sidcxx11.h" @@ -35,9 +38,6 @@ namespace reSIDfp class Filter; class Filter6581; class Filter8580; -class ExternalFilter; -class Potentiometer; -class Voice; class Resampler; /** @@ -64,28 +64,31 @@ private: Filter* filter; /// Filter used, if model is set to 6581 - std::unique_ptr const filter6581; + Filter6581* const filter6581; /// Filter used, if model is set to 8580 - std::unique_ptr const filter8580; + Filter8580* const filter8580; + + /// Resampler used by audio generation code. + std::unique_ptr resampler; /** * External filter that provides high-pass and low-pass filtering * to adjust sound tone slightly. */ - std::unique_ptr const externalFilter; - - /// Resampler used by audio generation code. - std::unique_ptr resampler; + ExternalFilter externalFilter; /// Paddle X register support - std::unique_ptr const potX; + Potentiometer potX; /// Paddle Y register support - std::unique_ptr const potY; + Potentiometer potY; /// SID voices - std::unique_ptr voice[3]; + Voice voice[3]; + + /// Used to amplify the output by x/2 to get an adequate playback volume + int scaleFactor; /// Time to live for the last written value int busValueTtl; @@ -99,12 +102,12 @@ private: /// Currently active chip model. ChipModel model; + /// Currently selected combined waveforms strength. + CombinedWaveforms cws; + /// Last written value unsigned char busValue; - /// Flags for muted channels - bool muted[3]; - /** * Emulated nonlinearity of the envelope DAC. * @@ -132,7 +135,7 @@ private: * * @return the output sample */ - int output() const; + int output(); /** * Calculate the numebr of cycles according to current parameters @@ -159,6 +162,14 @@ public: */ ChipModel getChipModel() const { return model; } + /** + * Set combined waveforms strength. + * + * @param cws strength of combined waveforms + * @throw SIDError + */ + void setCombinedWaveforms(CombinedWaveforms cws); + /** * SID reset. */ @@ -204,14 +215,6 @@ public: */ void write(int offset, unsigned char value); - /** - * SID voice muting. - * - * @param channel channel to modify - * @param enable is muted? - */ - void mute(int channel, bool enable) { muted[channel] = enable; } - /** * Setting of SID sampling parameters. * @@ -237,7 +240,11 @@ public: * @param highestAccurateFrequency * @throw SIDError */ - void setSamplingParameters(double clockFrequency, SamplingMethod method, double samplingFrequency, double highestAccurateFrequency); + void setSamplingParameters( + double clockFrequency, + SamplingMethod method, + double samplingFrequency + ); /** * Clock SID forward using chosen output sampling algorithm. @@ -267,6 +274,13 @@ public: */ void setFilter6581Curve(double filterCurve); + /** + * Set filter range parameter for 6581 model + * + * @see Filter6581::setFilterRange(double) + */ + void setFilter6581Range ( double adjustment ); + /** * Set filter curve parameter for 8580 model. * @@ -312,13 +326,22 @@ void SID::ageBusValue(unsigned int n) } RESID_INLINE -int SID::output() const +int SID::output() { - const int v1 = voice[0]->output(voice[2]->wave()); - const int v2 = voice[1]->output(voice[0]->wave()); - const int v3 = voice[2]->output(voice[1]->wave()); + const float o1 = voice[0].output(voice[2].wave()); + const float o2 = voice[1].output(voice[0].wave()); + const float o3 = voice[2].output(voice[1].wave()); - return externalFilter->clock(filter->clock(v1, v2, v3)); + const unsigned int env1 = voice[0].envelope()->output(); + const unsigned int env2 = voice[1].envelope()->output(); + const unsigned int env3 = voice[2].envelope()->output(); + + const int v1 = filter->getNormalizedVoice(o1, env1); + const int v2 = filter->getNormalizedVoice(o2, env2); + const int v3 = filter->getNormalizedVoice(o3, env3); + + const int input = static_cast(filter->clock(v1, v2, v3)); + return externalFilter.clock(input); } @@ -337,18 +360,18 @@ int SID::clock(unsigned int cycles, short* buf) for (unsigned int i = 0; i < delta_t; i++) { // clock waveform generators - voice[0]->wave()->clock(); - voice[1]->wave()->clock(); - voice[2]->wave()->clock(); + voice[0].wave()->clock(); + voice[1].wave()->clock(); + voice[2].wave()->clock(); // clock envelope generators - voice[0]->envelope()->clock(); - voice[1]->envelope()->clock(); - voice[2]->envelope()->clock(); + voice[0].envelope()->clock(); + voice[1].envelope()->clock(); + voice[2].envelope()->clock(); if (unlikely(resampler->input(output()))) { - buf[s++] = resampler->getOutput(); + buf[s++] = resampler->getOutput(scaleFactor); } } diff --git a/src/sound/resid-fp/siddefs-fp.h b/src/sound/resid-fp/siddefs-fp.h index 7061e3a85..22e40f4fb 100644 --- a/src/sound/resid-fp/siddefs-fp.h +++ b/src/sound/resid-fp/siddefs-fp.h @@ -24,10 +24,10 @@ #define RESID_BRANCH_HINTS true // Compiler specifics. +#ifndef _MSC_VER #define HAVE_BUILTIN_EXPECT true - -#ifndef M_PI -# define M_PI 3.14159265358979323846 +#else +#define HAVE_BUILTIN_EXPECT false #endif // Branch prediction macros, lifted off the Linux kernel. @@ -43,6 +43,8 @@ namespace reSIDfp { typedef enum { MOS6581=1, MOS8580 } ChipModel; +typedef enum { AVERAGE=1, WEAK, STRONG } CombinedWaveforms; + typedef enum { DECIMATE=1, RESAMPLE } SamplingMethod; } diff --git a/src/sound/resid-fp/siddefs-fp.h.in b/src/sound/resid-fp/siddefs-fp.h.in index 4c31ffb46..dfe543db5 100644 --- a/src/sound/resid-fp/siddefs-fp.h.in +++ b/src/sound/resid-fp/siddefs-fp.h.in @@ -26,10 +26,6 @@ // Compiler specifics. #define HAVE_BUILTIN_EXPECT @HAVE_BUILTIN_EXPECT@ -#ifndef M_PI -# define M_PI 3.14159265358979323846 -#endif - // Branch prediction macros, lifted off the Linux kernel. #if RESID_BRANCH_HINTS && HAVE_BUILTIN_EXPECT # define likely(x) __builtin_expect(!!(x), 1) @@ -43,6 +39,8 @@ namespace reSIDfp { typedef enum { MOS6581=1, MOS8580 } ChipModel; +typedef enum { AVERAGE=1, WEAK, STRONG } CombinedWaveforms; + typedef enum { DECIMATE=1, RESAMPLE } SamplingMethod; } diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index ae87ce870..e92830f67 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -43,73 +43,73 @@ static const struct { } ac97_codecs[] = { // clang-format off { - .device = &ad1881_device, - .min_rate = 7000, - .max_rate = 48000, - .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, - .reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */ - .extid_flags = AC97_VRA, - .pcsr_mask = 0xbf, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x74, 0x0000, 0xff07}, {0, 0x76, 0x0404, 0xdde5}, {0, 0x78, 48000, 0x0000}, {0, 0x7a, 48000, 0x0000}, {0}} + .device = &ad1881_device, + .min_rate = 7000, + .max_rate = 48000, + .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, + .reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */ + .extid_flags = AC97_VRA, + .pcsr_mask = 0xbf, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x74, 0x0000, 0xff07}, {0, 0x76, 0x0404, 0xdde5}, {0, 0x78, 48000, 0x0000}, {0, 0x7a, 48000, 0x0000}, {0}} }, { - .device = &ak4540_device, - .misc_flags = AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .pcsr_mask = 0x1f + .device = &ak4540_device, + .misc_flags = AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .pcsr_mask = 0x1f }, { - .device = &alc100_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, - .reset_flags = (22 << AC97_3D_SHIFT), - .extid_flags = AC97_AMAP, - .pcsr_mask = 0xbf + .device = &alc100_device, + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, + .reset_flags = (22 << AC97_3D_SHIFT), + .extid_flags = AC97_AMAP, + .pcsr_mask = 0xbf }, { - .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}} + .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}} }, { - .device = &cs4297a_device, - .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT), - .extid_flags = AC97_AMAP, - .pcsr_mask = 0xff, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5e, 0x0000, 0x01b0}, {0, 0x60, 0x0023, 0x0001}, {0, 0x68, 0x0000, 0xdfff}, {0}} + .device = &cs4297a_device, + .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT), + .extid_flags = AC97_AMAP, + .pcsr_mask = 0xff, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5e, 0x0000, 0x01b0}, {0, 0x60, 0x0023, 0x0001}, {0, 0x68, 0x0000, 0xdfff}, {0}} }, { - .device = &stac9708_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = AC97_SDAC, - .pcsr_mask = 0xff, - .eascr_mask = 0x02, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x6c, 0x0000, 0x0003}, {0, 0x74, 0x0000, 0x0003}, {0}} + .device = &stac9708_device, + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, + .extid_flags = AC97_SDAC, + .pcsr_mask = 0xff, + .eascr_mask = 0x02, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x6c, 0x0000, 0x0003}, {0, 0x74, 0x0000, 0x0003}, {0}} }, { - .device = &stac9721_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = AC97_AMAP, - .pcsr_mask = 0xff, - .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x6c, 0x0000, 0x0000}, {0, 0x6e, 0x0000, 0x0003}, {0, 0x70, 0x0000, 0xffff}, {0, 0x72, 0x0000, 0x0006}, {0, 0x74, 0x0000, 0x0003}, {0, 0x76, 0x0000, 0xffff}, {0, 0x78, 0x0000, 0x3802}, {0}} + .device = &stac9721_device, + .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, + .extid_flags = AC97_AMAP, + .pcsr_mask = 0xff, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x6c, 0x0000, 0x0000}, {0, 0x6e, 0x0000, 0x0003}, {0, 0x70, 0x0000, 0xffff}, {0, 0x72, 0x0000, 0x0006}, {0, 0x74, 0x0000, 0x0003}, {0, 0x76, 0x0000, 0xffff}, {0, 0x78, 0x0000, 0x3802}, {0}} }, { - .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 = &tr28023_device, + .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_POP | AC97_MS | AC97_LPBK, + .reset_flags = 0, + .extid_flags = 0, + .pcsr_mask = 0x3f }, { - .device = &wm9701a_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, - .reset_flags = AC97_DAC_18B | AC97_ADC_18B, - .extid_flags = 0, - .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 }; @@ -577,8 +577,7 @@ ac97_codec_getrate(void *priv, uint8_t reg) static void * ac97_codec_init(const device_t *info) { - ac97_codec_t *dev = malloc(sizeof(ac97_codec_t)); - memset(dev, 0, sizeof(ac97_codec_t)); + ac97_codec_t *dev = calloc(1, sizeof(ac97_codec_t)); for (; dev->model < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])); dev->model++) { if (ac97_codecs[dev->model].device->local == info->local) @@ -661,7 +660,7 @@ const device_t ad1881_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -675,7 +674,7 @@ const device_t ak4540_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -689,7 +688,7 @@ const device_t alc100_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -703,7 +702,7 @@ const device_t cs4297_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -717,7 +716,7 @@ const device_t cs4297a_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -731,7 +730,7 @@ const device_t stac9708_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -745,7 +744,7 @@ const device_t stac9721_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -759,7 +758,7 @@ const device_t tr28023_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -773,7 +772,7 @@ const device_t wm9701a_device = { .init = ac97_codec_init, .close = ac97_codec_close, .reset = ac97_codec_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index ceac42387..8c1e45c40 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -787,8 +787,7 @@ ac97_via_speed_changed(void *priv) static void * ac97_via_init(UNUSED(const device_t *info)) { - ac97_via_t *dev = malloc(sizeof(ac97_via_t)); - memset(dev, 0, sizeof(ac97_via_t)); + ac97_via_t *dev = calloc(1, sizeof(ac97_via_t)); ac97_via_log("AC97 VIA: init()\n"); @@ -839,7 +838,7 @@ const device_t ac97_via_device = { .init = ac97_via_init, .close = ac97_via_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = ac97_via_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 4b7941959..87755a96c 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -16,7 +16,7 @@ * * Copyright 2008-2020 Sarah Walker. * Copyright 2018-2020 TheCollector1995. - * Copyright 2021-2022 RichardG. + * Copyright 2021-2025 RichardG. */ #include #include @@ -33,6 +33,7 @@ #include <86box/plat_fallthrough.h> #define CS4231 0x80 +#define CS4232 0x02 #define CS4236 0x03 static int ad1848_vols_7bits[128]; @@ -57,10 +58,10 @@ ad1848_setdma(ad1848_t *ad1848, int newdma) void ad1848_updatevolmask(ad1848_t *ad1848) { - if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->xregs[4] & 0x10) || ad1848->wten)) - ad1848->wave_vol_mask = 0x3f; - else + if ((ad1848->type == AD1848_TYPE_CS4236B) && !(ad1848->xregs[4] & 0x10) && !ad1848->wten) ad1848->wave_vol_mask = 0x7f; + else + ad1848->wave_vol_mask = 0x3f; } static double @@ -106,8 +107,8 @@ ad1848_updatefreq(ad1848_t *ad1848) { double freq; - if (ad1848->type >= AD1848_TYPE_CS4235) { - if (ad1848->xregs[11] & 0x20) { + if (ad1848->type >= AD1848_TYPE_CS4232) { + if (ad1848->xregs[11] & 0x20) { /* CS4236B+ only */ freq = 16934400.0; switch (ad1848->xregs[13]) { default: @@ -166,6 +167,7 @@ ad1848_read(uint16_t addr, void *priv) { ad1848_t *ad1848 = (ad1848_t *) priv; uint8_t ret = 0xff; + uint8_t temp = 0; switch (addr & 3) { case 0: /* Index */ @@ -182,7 +184,7 @@ ad1848_read(uint16_t addr, void *priv) case 18: case 19: - if (ad1848->type >= AD1848_TYPE_CS4235) { + if (ad1848->type >= AD1848_TYPE_CS4236B) { if ((ad1848->xregs[4] & 0x14) == 0x14) /* FM remapping */ ret = ad1848->xregs[ad1848->index - 12]; /* real FM volume on registers 6 and 7 */ else if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) /* wavetable remapping */ @@ -192,17 +194,41 @@ ad1848_read(uint16_t addr, void *priv) case 20: case 21: - /* Backdoor to the Control/RAM registers on CS4235. */ - if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) + /* Backdoor to the Control/RAM registers on CS4235+. */ + if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) ret = ad1848->cram_read(ad1848->index - 15, ad1848->cram_priv); break; case 23: - if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->regs[23] & 0x08)) { - if ((ad1848->xindex & 0xfe) == 0x00) /* remapped line volume */ - ret = ad1848->regs[18 + ad1848->xindex]; - else - ret = ad1848->xregs[ad1848->xindex]; + if ((ad1848->type >= AD1848_TYPE_CS4236B) && (ad1848->regs[23] & 0x08)) { + ret = ad1848->xregs[ad1848->xindex]; + switch (ad1848->xindex) { + case 0 ... 1: + /* Remapped line volume. */ + ret = ad1848->regs[18 + ad1848->xindex]; + break; + + case 23 ... 24: + case 29: + /* Backdoor to control indirect registers on CS4235+. */ + if (ad1848->type >= AD1848_TYPE_CS4235) { + temp = ad1848->cram_read(3, ad1848->cram_priv); + ad1848->cram_write(3, (ad1848->xindex == 23) ? 2 : ((ad1848->xindex == 24) ? 8 : 9), ad1848->cram_priv); + ret = ad1848->cram_read(4, ad1848->cram_priv); + ad1848->cram_write(3, temp, ad1848->cram_priv); + } + break; + + case 26 ... 28: + case 30: + /* Backdoor to control registers on CS4235+. */ + if (ad1848->type >= AD1848_TYPE_CS4235) + ret = ad1848->cram_read((ad1848->xindex == 30) ? 7 : (ad1848->xindex - 26), ad1848->cram_priv); + break; + + default: + break; + } } break; @@ -235,7 +261,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) ad1848->index = val & 0x1f; /* cs4231a extended mode enabled */ else ad1848->index = val & 0x0f; /* ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? */ - if (ad1848->type >= AD1848_TYPE_CS4235) + if (ad1848->type >= AD1848_TYPE_CS4236B) ad1848->regs[23] &= ~0x08; /* clear XRAE */ ad1848->trd = val & 0x20; ad1848->mce = val & 0x40; @@ -244,7 +270,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 1: switch (ad1848->index) { case 10: - if (ad1848->type < AD1848_TYPE_CS4235) + if (ad1848->type < AD1848_TYPE_CS4232) break; fallthrough; @@ -272,47 +298,53 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) return; case 12: - if (ad1848->type != AD1848_TYPE_DEFAULT) - ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80; + if (ad1848->type >= AD1848_TYPE_CS4248) { + ad1848->regs[12] = 0x80 | (val & 0x70) | (ad1848->regs[12] & 0x0f); + if ((ad1848->type >= AD1848_TYPE_CS4231) && (ad1848->type < AD1848_TYPE_CS4235)) { + if (val & 0x40) + ad1848->fmt_mask |= 0x80; + else + ad1848->fmt_mask &= ~0x80; + } + } return; case 14: ad1848->count = ad1848->regs[15] | (val << 8); break; - case 17: - /* Enable additional data formats on modes 2 and 3 where supported. */ - if ((ad1848->type == AD1848_TYPE_CS4231) || (ad1848->type == AD1848_TYPE_CS4236)) - ad1848->fmt_mask = (val & 0x40) ? 0xf0 : 0x70; - break; - case 18: case 19: - if (ad1848->type >= AD1848_TYPE_CS4235) { - if ((ad1848->xregs[4] & 0x14) == 0x14) { /* FM remapping */ - ad1848->xregs[ad1848->index - 12] = val; /* real FM volume on extended registers 6 and 7 */ - temp = 1; + if (ad1848->type >= AD1848_TYPE_CS4236B) { + if (ad1848->type >= AD1848_TYPE_CS4235) { + if (ad1848->xregs[18] & 0x20) /* AUX1 remapping */ + ad1848->regs[ad1848->index & 3] = val; /* also controls AUX1 on registers 2 and 3 */ + } else { + if ((ad1848->xregs[4] & 0x14) == 0x14) { /* FM remapping */ + ad1848->xregs[6 | (ad1848->index & 1)] = val; /* real FM volume on extended registers 6 and 7 */ + temp = 1; - if (ad1848->index == 18) { - if (val & 0x80) - ad1848->fm_vol_l = 0; - else - ad1848->fm_vol_l = ad1848_vols_7bits[val & 0x3f]; - } else { - if (val & 0x80) - ad1848->fm_vol_r = 0; - else - ad1848->fm_vol_r = ad1848_vols_7bits[val & 0x3f]; + if (ad1848->index == 18) { + if (val & 0x80) + ad1848->fm_vol_l = 0; + else + ad1848->fm_vol_l = ad1848_vols_7bits[val & 0x3f]; + } else { + if (val & 0x80) + ad1848->fm_vol_r = 0; + else + ad1848->fm_vol_r = ad1848_vols_7bits[val & 0x3f]; + } + } + if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) { /* wavetable remapping */ + ad1848->xregs[16 | (ad1848->index & 1)] = val; /* real wavetable volume on extended registers 16 and 17 */ + temp = 1; } - } - if (ad1848->wten && !(ad1848->xregs[4] & 0x08)) { /* wavetable remapping */ - ad1848->xregs[ad1848->index - 2] = val; /* real wavetable volume on extended registers 16 and 17 */ - temp = 1; - } - /* Stop here if any remapping is enabled. */ - if (temp) - return; + /* Stop here if any remapping is enabled. */ + if (temp) + return; + } /* HACK: the Windows 9x driver's "Synth" control writes to this register with no remapping, even if internal FM is enabled. */ @@ -332,8 +364,8 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 20: case 21: - /* Backdoor to the Control/RAM registers on CS4235. */ - if ((ad1848->type == AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) { + /* Backdoor to the Control/RAM registers on CS4235+. */ + if ((ad1848->type >= AD1848_TYPE_CS4235) && (ad1848->xregs[18] & 0x80)) { ad1848->cram_write(ad1848->index - 15, val, ad1848->cram_priv); val = ad1848->regs[ad1848->index]; } @@ -344,17 +376,19 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) break; case 23: - if ((ad1848->type >= AD1848_TYPE_CS4235) && ((ad1848->regs[12] & 0x60) == 0x60)) { + if ((ad1848->type >= AD1848_TYPE_CS4236B) && ((ad1848->regs[12] & 0x60) == 0x60)) { if (!(ad1848->regs[23] & 0x08)) { /* existing (not new) XRAE is clear */ ad1848->xindex = ((val & 0x04) << 2) | (val >> 4); break; } switch (ad1848->xindex) { - case 0: - case 1: /* remapped line volume */ - ad1848->regs[18 + ad1848->xindex] = val; - return; + case 0 ... 1: + if (ad1848->type < AD1848_TYPE_CS4235) { + /* Remapped line volume. */ + ad1848->regs[18 | ad1848->xindex] = val; + } + break; case 6: if (val & 0x80) @@ -375,9 +409,27 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) updatefreq = 1; break; + case 23 ... 24: + case 29: + /* Backdoor to control indirect registers on CS4235+. */ + if (ad1848->type >= AD1848_TYPE_CS4235) { + temp = ad1848->cram_read(3, ad1848->cram_priv); + ad1848->cram_write(3, (ad1848->xindex == 23) ? 2 : ((ad1848->xindex == 24) ? 8 : 9), ad1848->cram_priv); + ad1848->cram_write(4, val, ad1848->cram_priv); + ad1848->cram_write(3, temp, ad1848->cram_priv); + } + break; + case 25: return; + case 26 ... 28: + case 30: + /* Backdoor to control registers on CS4235+. */ + if (ad1848->type >= AD1848_TYPE_CS4235) + ad1848->cram_write((ad1848->xindex == 30) ? 7 : (ad1848->xindex - 26), val, ad1848->cram_priv); + break; + default: break; } @@ -401,7 +453,11 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 25: return; case 27: - if (ad1848->type != AD1848_TYPE_DEFAULT) + if ((ad1848->type != AD1848_TYPE_CS4232) && (ad1848->type != AD1848_TYPE_CS4236)) + return; + break; + case 29: + if ((ad1848->type != AD1848_TYPE_CS4232) && (ad1848->type != AD1848_TYPE_CS4236)) return; break; @@ -456,17 +512,13 @@ ad1848_process_mulaw(uint8_t byte) { byte = ~byte; int temp = (((byte & 0x0f) << 3) + 0x84); - int16_t dec; temp <<= ((byte & 0x70) >> 4); temp = (byte & 0x80) ? (0x84 - temp) : (temp - 0x84); if (temp > 32767) - dec = 32767; + return 32767; else if (temp < -32768) - dec = -32768; - else - dec = (int16_t) temp; - - return dec; + return -32768; + return (int16_t) temp; } static int16_t @@ -489,8 +541,7 @@ ad1848_process_alaw(uint8_t byte) dec |= 0x108; break; } - dec = (byte & 0x80) ? dec : -dec; - return (int16_t) dec; + return (int16_t) ((byte & 0x80) ? dec : -dec); } static uint32_t @@ -704,10 +755,7 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->regs[8] = 0; ad1848->regs[9] = 0x08; ad1848->regs[10] = ad1848->regs[11] = 0; - if ((type == AD1848_TYPE_CS4248) || (type == AD1848_TYPE_CS4231) || (type >= AD1848_TYPE_CS4235)) - ad1848->regs[12] = 0x8a; - else - ad1848->regs[12] = 0xa; + ad1848->regs[12] = (type >= AD1848_TYPE_CS4248) ? 0x8a : 0xa; ad1848->regs[13] = 0; ad1848->regs[14] = ad1848->regs[15] = 0; @@ -719,27 +767,30 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->regs[25] = CS4231; ad1848->regs[26] = 0x80; ad1848->regs[29] = 0x80; - } else if (type >= AD1848_TYPE_CS4235) { + } else if (type >= AD1848_TYPE_CS4232) { ad1848->regs[16] = ad1848->regs[17] = 0; ad1848->regs[18] = ad1848->regs[19] = 0; ad1848->regs[20] = ad1848->regs[21] = 0; ad1848->regs[22] = ad1848->regs[23] = 0; ad1848->regs[24] = 0; - ad1848->regs[25] = CS4236; + ad1848->regs[25] = (type == AD1848_TYPE_CS4232) ? CS4232 : CS4236; ad1848->regs[26] = 0xa0; ad1848->regs[27] = ad1848->regs[29] = 0; ad1848->regs[30] = ad1848->regs[31] = 0; - ad1848->xregs[0] = ad1848->xregs[1] = 0xe8; - ad1848->xregs[2] = ad1848->xregs[3] = 0xcf; - ad1848->xregs[4] = 0x84; - ad1848->xregs[5] = 0; - ad1848->xregs[6] = ad1848->xregs[7] = 0x80; - ad1848->xregs[8] = ad1848->xregs[9] = 0; - ad1848->xregs[10] = 0x3f; - ad1848->xregs[11] = 0xc0; - ad1848->xregs[14] = ad1848->xregs[15] = 0; - ad1848->xregs[16] = ad1848->xregs[17] = 0; + if (type >= AD1848_TYPE_CS4236B) { + if (type < AD1848_TYPE_CS4235) + ad1848->xregs[0] = ad1848->xregs[1] = 0xe8; + ad1848->xregs[2] = ad1848->xregs[3] = 0xcf; + ad1848->xregs[4] = 0x84; + ad1848->xregs[5] = 0; + ad1848->xregs[6] = ad1848->xregs[7] = 0x80; + ad1848->xregs[8] = ad1848->xregs[9] = 0; + ad1848->xregs[10] = 0x3f; + ad1848->xregs[11] = 0xc0; + ad1848->xregs[14] = ad1848->xregs[15] = 0; + ad1848->xregs[16] = ad1848->xregs[17] = 0; + } } ad1848_updatefreq(ad1848); @@ -747,7 +798,7 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->out_l = ad1848->out_r = 0; ad1848->fm_vol_l = ad1848->fm_vol_r = 65536; ad1848_updatevolmask(ad1848); - if (type == AD1848_TYPE_CS4235) + if (type >= AD1848_TYPE_CS4235) ad1848->fmt_mask = 0x50; else ad1848->fmt_mask = 0x70; diff --git a/src/sound/snd_adlib.c b/src/sound/snd_adlib.c index f5eae9b93..1f307596c 100644 --- a/src/sound/snd_adlib.c +++ b/src/sound/snd_adlib.c @@ -103,8 +103,7 @@ adlib_mca_feedb(void *priv) void * adlib_init(UNUSED(const device_t *info)) { - adlib_t *adlib = malloc(sizeof(adlib_t)); - memset(adlib, 0, sizeof(adlib_t)); + adlib_t *adlib = calloc(1, sizeof(adlib_t)); adlib_log("adlib_init\n"); fm_driver_get(FM_YM3812, &adlib->opl); @@ -151,7 +150,7 @@ const device_t adlib_device = { .init = adlib_init, .close = adlib_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -165,7 +164,7 @@ const device_t adlib_mca_device = { .init = adlib_mca_init, .close = adlib_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 488dcb8a6..360da3fec 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -791,8 +791,8 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv) adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { - adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; - adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; + adgold_buffer[c] = ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4; + adgold_buffer[c + 1] = ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4; } if (adgold->surround_enabled) @@ -904,7 +904,6 @@ adgold_get_music_buffer(int32_t *buffer, int len, void *priv) int c; const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv); - adgold_update(adgold); for (c = 0; c < len * 2; c += 2) { adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2; @@ -1067,8 +1066,7 @@ adgold_init(UNUSED(const device_t *info)) FILE *fp; int c; double out; - adgold_t *adgold = malloc(sizeof(adgold_t)); - memset(adgold, 0, sizeof(adgold_t)); + adgold_t *adgold = calloc(1, sizeof(adgold_t)); adgold->dma = device_get_config_int("dma"); adgold->irq = device_get_config_int("irq"); @@ -1194,73 +1192,69 @@ adgold_close(void *priv) static const device_config_t adgold_config[] = { // clang-format off { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "Low DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .name = "dma", + .description = "Low DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "gameport", - .description = "Enable Game port", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "surround", - .description = "Surround module", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "surround", + .description = "Surround module", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1274,7 +1268,7 @@ const device_t adgold_device = { .init = adgold_init, .close = adgold_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = adgold_config diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index f8c14e06f..f8a6e4153 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1,22 +1,24 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Ensoniq AudioPCI family emulation. + * Ensoniq AudioPCI family emulation. * + * Authors: Sarah Walker, + * RichardG, + * Miran Grca, + * Jasmine Iwanek, + * Cacodemon345 * - * - * Authors: Sarah Walker, - * RichardG, - * Miran Grca, - * - * Copyright 2008-2021 Sarah Walker. - * Copyright 2021-2024 RichardG. - * Copyright 2021 Miran Grca. + * Copyright 2008-2021 Sarah Walker. + * Copyright 2021-2024 RichardG. + * Copyright 2021 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. + * Copyright 2024-2025 Cacodemon345. */ #include #include @@ -39,14 +41,15 @@ #include <86box/sound.h> #include <86box/timer.h> #include <86box/plat_unused.h> +#include <86box/snd_akm4531.h> #define N 16 -#define ES1371_NCoef 91 +#define ES137x_NCoef 91 -static float low_fir_es1371_coef[ES1371_NCoef]; +static float low_fir_es137x_coef[ES137x_NCoef]; -typedef struct es1371_t { +typedef struct es137x_t { uint8_t pci_command; uint8_t pci_serr; @@ -111,6 +114,9 @@ typedef struct es1371_t { int16_t out_l; int16_t out_r; + int16_t prev_out_l; + int16_t prev_out_r; + int32_t vol_l; int32_t vol_r; } dac[2], adc; @@ -130,14 +136,40 @@ typedef struct es1371_t { uint8_t pci_slot; int pos; - int16_t buffer[SOUNDBUFLEN * 2]; + int16_t buffer[WTBUFLEN * 2]; uint32_t type; -} es1371_t; -#define AUDIOPCI_ES1371 0x13710200 -#define AUDIOPCI_ES1373 0x13710400 -#define AUDIOPCI_CT5880 0x58800400 + akm4531_t akm_codec; + + uint32_t calc_sample_rate; + uint32_t calc_sample_rate_synth; + + double interp_factor; + uint32_t interp_step; + + double interp_factor_synth; + uint32_t interp_step_synth; + + uint32_t step_pcm; + uint32_t step_synth; +} es137x_t; + +static const double akm4531_att_2dbstep_5bits[] = { + // clang-format off + 25.0, 32.0, 41.0, 51.0, 65.0, 82.0, 103.0, 130.0, + 164.0, 206.0, 260.0, 327.0, 412.0, 519.0, 653.0, 822.0, + 1036.0, 1304.0, 1641.0, 2067.0, 2602.0, 3276.0, 4125.0, 5192.0, + 6537.0, 8230.0, 10362.0, 13044.0, 16422.0, 20674.0, 26027.0, 32767.0 + // clang-format on +}; + +static double akm4531_gain_2dbstep_5bits[0x20]; + +#define AUDIOPCI_ES1370 0x50000000 +#define AUDIOPCI_ES1371 0x13710200 +#define AUDIOPCI_ES1373 0x13710400 +#define AUDIOPCI_CT5880 0x58800400 #define LEGACY_SB_ADDR (1 << 29) #define LEGACY_SSCAPE_ADDR_SHIFT 27 @@ -204,8 +236,8 @@ typedef struct es1371_t { #define FORMAT_MONO_16 2 #define FORMAT_STEREO_16 3 -static void es1371_fetch(es1371_t *dev, int dac_nr); -static void update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl); +static void es137x_fetch(es137x_t *dev, int dac_nr); +static void update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl); #ifdef ENABLE_AUDIOPCI_LOG int audiopci_do_log = ENABLE_AUDIOPCI_LOG; @@ -226,7 +258,7 @@ audiopci_log(const char *fmt, ...) #endif static void -es1371_update_irqs(es1371_t *dev) +es137x_update_irqs(es137x_t *dev) { int irq = 0; @@ -257,63 +289,63 @@ es1371_update_irqs(es1371_t *dev) } static void -es1371_update_tx_irq(es1371_t *dev) +es137x_update_tx_irq(es137x_t *dev) { dev->uart_status &= ~UART_STATUS_TXINT; if (((dev->uart_ctrl & UART_CTRL_TXINTEN) == 0x20) && (dev->uart_status & UART_STATUS_TXRDY)) dev->uart_status |= UART_STATUS_TXINT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); } static void -es1371_set_tx_irq(es1371_t *dev, int set) +es137x_set_tx_irq(es137x_t *dev, int set) { dev->uart_status &= ~UART_STATUS_TXRDY; if (set) dev->uart_status |= UART_STATUS_TXRDY; - es1371_update_tx_irq(dev); + es137x_update_tx_irq(dev); } static void -es1371_update_rx_irq(es1371_t *dev) +es137x_update_rx_irq(es137x_t *dev) { dev->uart_status &= ~UART_STATUS_RXINT; if ((dev->uart_ctrl & UART_CTRL_RXINTEN) && (dev->uart_status & UART_STATUS_RXRDY)) dev->uart_status |= UART_STATUS_RXINT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); } static void -es1371_set_rx_irq(es1371_t *dev, int set) +es137x_set_rx_irq(es137x_t *dev, int set) { dev->uart_status &= ~UART_STATUS_RXRDY; if (set) dev->uart_status |= UART_STATUS_RXRDY; - es1371_update_rx_irq(dev); + es137x_update_rx_irq(dev); } static void -es1371_scan_fifo(es1371_t *dev) +es137x_scan_fifo(es137x_t *dev) { if (dev->read_fifo_pos != dev->write_fifo_pos) { dev->uart_data = dev->uart_fifo[dev->read_fifo_pos]; dev->read_fifo_pos = (dev->read_fifo_pos + 1) & 7; - es1371_set_rx_irq(dev, 1); + es137x_set_rx_irq(dev, 1); } else - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); } static void -es1371_write_fifo(es1371_t *dev, uint8_t val) +es137x_write_fifo(es137x_t *dev, uint8_t val) { if (dev->write_fifo_pos < 8) { dev->uart_fifo[dev->write_fifo_pos] = val | UART_FIFO_BYTE_VALID; @@ -322,27 +354,91 @@ es1371_write_fifo(es1371_t *dev, uint8_t val) } static void -es1371_reset_fifo(es1371_t *dev) +es137x_reset_fifo(es137x_t *dev) { for (uint8_t i = 0; i < 8; i++) dev->uart_fifo[i] = 0x00000000; dev->read_fifo_pos = dev->write_fifo_pos = 0; - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); } static void -es1371_reset(void *priv) +akm4531_reset(es137x_t *dev) { - es1371_t *dev = (es1371_t *) priv; + akm4531_t *codec = &dev->akm_codec; + + memset(codec->registers, 0, sizeof(codec->registers)); + + codec->registers[0] = 0x80; + codec->registers[1] = 0x80; + + for (int i = 0x02; i <= 0x0E; i++) { + codec->registers[i] = 0b10000110; + } + + codec->registers[0xf] = 0x80; + + codec->registers[0x17] = 0x3; + codec->registers[0x16] = 0x3; +} + +static double +lerp(double v0, double v1, double t) +{ + return (1. - t) * v0 + t * v1; +} + +static void +es1370_calc_sample_rate(es137x_t *dev) +{ + if (dev->type != AUDIOPCI_ES1370) + return; + + dev->calc_sample_rate = 1411200 / (((dev->int_ctrl >> 16) & 0x1fff) + 2); + + // audiopci_log("ES1370 calc sample rate %u\n", dev->calc_sample_rate); + + dev->interp_factor = 1.0; + dev->interp_step = 1; + + if (dev->calc_sample_rate >= 44100 || dev->calc_sample_rate < 11025) { + dev->interp_factor = 1.0; + dev->interp_step = 1; + dev->calc_sample_rate = 44100; + } + if (dev->calc_sample_rate == 22050) { + dev->interp_factor = 0.5; + dev->interp_step = 2; + } + if (dev->calc_sample_rate == 11025) { + dev->interp_factor = 0.25; + dev->interp_step = 4; + } + if ((((dev->int_ctrl >> 16) & 0x1fff) + 2) == 256) { + /* 5512.5 Hz */ + dev->interp_factor = 0.125; + dev->interp_step = 8; + dev->calc_sample_rate = 5512; + } + + dev->calc_sample_rate_synth = 44100 / (1 << (((dev->int_ctrl >> 12) & 3) ^ 3)); + dev->interp_factor_synth = 1. / (double) ((1 << ((dev->int_ctrl >> 12) & 3) ^ 3)); + dev->interp_step_synth = (1 << (((dev->int_ctrl >> 12) & 3) ^ 3)); +} + +static void +es137x_reset(void *priv) +{ + es137x_t *dev = (es137x_t *) priv; nmi = 0; /* Default subsystem ID. */ - dev->subsys_lock = 0x00; - *((uint16_t *) &dev->subsys_id[0]) = 0x1274; - *((uint16_t *) &dev->subsys_id[2]) = 0x1371; + dev->subsys_lock = 0x00; + *((uint16_t *) &dev->subsys_id[0]) = (dev->type == AUDIOPCI_ES1370) ? 0x4942 : 0x1274; + *((uint16_t *) &dev->subsys_id[2]) = (dev->type == AUDIOPCI_ES1370) ? 0x4c4c : 0x1371; /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ @@ -350,11 +446,13 @@ es1371_reset(void *priv) /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type == AUDIOPCI_ES1370) + dev->int_status = 0x00000060; + else if (dev->type == AUDIOPCI_CT5880) dev->int_status = 0x52080ec0; - else if (dev->type >= AUDIOPCI_ES1373) + else if (dev->type == AUDIOPCI_ES1373) dev->int_status = 0x7f080ec0; - else + else /* AUDIOPCI_ES1371 */ dev->int_status = 0x7ffffec0; /* UART Status Register, Address 09H @@ -441,17 +539,20 @@ es1371_reset(void *priv) dev->uart_fifo[i] = 0xffff0000; /* Reset the UART TX. */ - es1371_set_tx_irq(dev, 0); + es137x_set_tx_irq(dev, 0); /* Reset the UART (RX) FIFO. */ - es1371_reset_fifo(dev); + es137x_reset_fifo(dev); /* Update interrupts to ensure they're all correctly cleared. */ - es1371_update_irqs(dev); + es137x_update_irqs(dev); + + /* Reset the codec. */ + akm4531_reset(dev); } static uint32_t -es1371_read_frame_reg(es1371_t *dev, int frame, int page) +es137x_read_frame_reg(es137x_t *dev, int frame, int page) { uint32_t ret = 0xffffffff; @@ -559,7 +660,7 @@ es1371_read_frame_reg(es1371_t *dev, int frame, int page) } static void -es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) +es137x_write_frame_reg(es137x_t *dev, int frame, int page, uint32_t val) { switch (frame) { case 0x30: @@ -666,9 +767,9 @@ es1371_write_frame_reg(es1371_t *dev, int frame, int page, uint32_t val) } static uint8_t -es1371_inb(uint16_t port, void *priv) +es137x_inb(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint8_t ret = 0xff; switch (port & 0x3f) { @@ -685,7 +786,7 @@ es1371_inb(uint16_t port, void *priv) break; case 0x03: ret = dev->int_ctrl >> 24; - if (dev->type < AUDIOPCI_ES1373) + if (dev->type == AUDIOPCI_ES1371) ret |= 0xfc; break; @@ -713,7 +814,7 @@ es1371_inb(uint16_t port, void *priv) Addressable as byte only */ case 0x08: ret = dev->uart_data; - es1371_set_rx_irq(dev, 0); + es137x_set_rx_irq(dev, 0); audiopci_log("[R] UART DATA = %02X\n", ret); break; @@ -758,19 +859,19 @@ es1371_inb(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus & 0xff; break; case 0x1d: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 8; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 16; break; case 0x1f: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 24; break; @@ -783,24 +884,29 @@ es1371_inb(uint16_t port, void *priv) ret = dev->si_cr >> 8; break; case 0x22: - ret = (dev->si_cr >> 16) | 0x80; + ret = dev->si_cr >> 16; + if (dev->type != AUDIOPCI_ES1370) + ret |= 0x80; break; case 0x23: - ret = 0xff; + if (dev->type == AUDIOPCI_ES1370) + ret = 0x00; + else + ret = 0xff; break; default: - audiopci_log("Bad es1371_inb: port=%04x\n", port); + audiopci_log("Bad es137x_inb: port=%04x\n", port); } - audiopci_log("es1371_inb: port=%04x ret=%02x\n", port, ret); + audiopci_log("es137x_inb: port=%04x ret=%02x\n", port, ret); return ret; } static uint16_t -es1371_inw(uint16_t port, void *priv) +es137x_inw(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint16_t ret = 0xffff; switch (port & 0x3e) { @@ -811,7 +917,7 @@ es1371_inw(uint16_t port, void *priv) break; case 0x02: ret = (dev->int_ctrl >> 16) & 0xff0f; - if (dev->type < AUDIOPCI_ES1373) + if (dev->type == AUDIOPCI_ES1371) ret |= 0xfc00; break; @@ -836,11 +942,11 @@ es1371_inw(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus & 0xffff; break; case 0x1e: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 16; break; @@ -850,7 +956,9 @@ es1371_inw(uint16_t port, void *priv) ret = dev->si_cr & 0xffff; break; case 0x22: - ret = (dev->si_cr >> 16) | 0xff80; + ret = dev->si_cr >> 16; + if (dev->type != AUDIOPCI_ES1370) + ret |= 0xff80; break; /* DAC1 Channel Sample Count Register, Address 24H @@ -884,36 +992,39 @@ es1371_inw(uint16_t port, void *priv) case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) & 0xffff; + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page) & 0xffff; break; case 0x32: case 0x36: case 0x3a: case 0x3e: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page) >> 16; break; default: break; } - audiopci_log("es1371_inw: port=%04x ret=%04x\n", port, ret); + audiopci_log("es137x_inw: port=%04x ret=%04x\n", port, ret); return ret; } static uint32_t -es1371_inl(uint16_t port, void *priv) +es137x_inl(uint16_t port, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t ret = 0xffffffff; + if ((dev->type == AUDIOPCI_ES1370) && (port & 0x3c) == 0x14) + port = 0x10; + switch (port & 0x3c) { /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: ret = dev->int_ctrl & 0xff0fffff; - if (ret < AUDIOPCI_ES1373) + if ((ret < AUDIOPCI_ES1373) && (ret != AUDIOPCI_ES1370)) ret |= 0xfc000000; break; @@ -940,6 +1051,8 @@ es1371_inl(uint16_t port, void *priv) /* CODEC Read Register, Address 14H Addressable as longword only */ case 0x14: + if (dev->type == AUDIOPCI_ES1370) + break; ret = dev->codec_ctrl | CODEC_READY; break; @@ -952,14 +1065,16 @@ es1371_inl(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus; break; /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - ret = dev->si_cr | 0xff800000; + ret = dev->si_cr; + if (dev->type != AUDIOPCI_ES1370) + ret |= 0xff800000; break; /* DAC1 Channel Sample Count Register, Address 24H @@ -984,24 +1099,24 @@ es1371_inl(uint16_t port, void *priv) case 0x34: case 0x38: case 0x3c: - ret = es1371_read_frame_reg(dev, port & 0x3c, dev->mem_page); + ret = es137x_read_frame_reg(dev, port & 0x3c, dev->mem_page); break; default: break; } - audiopci_log("es1371_inl: port=%04x ret=%08x\n", port, ret); + audiopci_log("es137x_inl: port=%04x ret=%08x\n", port, ret); return ret; } static void -es1371_outb(uint16_t port, uint8_t val, void *priv) +es137x_outb(uint16_t port, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; - audiopci_log("es1371_outb: port=%04x val=%02x\n", port, val); + audiopci_log("es137x_outb: port=%04x val=%02x\n", port, val); switch (port & 0x3f) { /* Interrupt/Chip Select Control Register, Address 00H @@ -1011,36 +1126,44 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + es137x_fetch(dev, 1); } + // audiopci_log("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffffff00) | val; break; case 0x01: dev->int_ctrl = (dev->int_ctrl & 0xffff00ff) | (val << 8); + es1370_calc_sample_rate(dev); break; case 0x02: dev->int_ctrl = (dev->int_ctrl & 0xff00ffff) | (val << 16); + es1370_calc_sample_rate(dev); break; case 0x03: dev->int_ctrl = (dev->int_ctrl & 0x00ffffff) | (val << 24); gameport_remap(dev->gameport, 0x200 | ((val & 0x03) << 3)); + es1370_calc_sample_rate(dev); break; /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only, but PCem implements byte access, which must be for a reason */ case 0x06: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; case 0x07: - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type == AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); break; @@ -1050,7 +1173,7 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) audiopci_log("MIDI data = %02x\n", val); /* TX does not use FIFO. */ midi_raw_out_byte(val); - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); break; /* UART Control Register, Address 09H @@ -1061,15 +1184,15 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) if ((val & 0x03) == 0x03) { /* Reset TX */ - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); /* Software reset */ - es1371_reset_fifo(dev); + es137x_reset_fifo(dev); } else { - es1371_set_tx_irq(dev, 1); + es137x_set_tx_irq(dev, 1); - es1371_update_tx_irq(dev); - es1371_update_rx_irq(dev); + es137x_update_tx_irq(dev); + es137x_update_rx_irq(dev); } break; @@ -1101,7 +1224,7 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) case 0x1b: old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x00ffffff) | (val << 24); - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1123,29 +1246,39 @@ es1371_outb(uint16_t port, uint8_t val, void *priv) /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - dev->si_cr = (dev->si_cr & 0xffffff00) | val; + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xffff00) | val; + else + dev->si_cr = (dev->si_cr & 0xffffff00) | val; break; case 0x21: - dev->si_cr = (dev->si_cr & 0xffff00ff) | (val << 8); + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xff00ff) | (val << 8); + else + dev->si_cr = (dev->si_cr & 0xffff00ff) | (val << 8); if (!(dev->si_cr & SI_P1_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + + es137x_update_irqs(dev); break; case 0x22: - dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xc0ffff) | ((val & 0x3f) << 16); + else + dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); break; default: - audiopci_log("Bad es1371_outb: port=%04x val=%02x\n", port, val); + audiopci_log("Bad es137x_outb: port=%04x val=%02x\n", port, val); } } static void -es1371_outw(uint16_t port, uint16_t val, void *priv) +es137x_outw(uint16_t port, uint16_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; switch (port & 0x3f) { @@ -1156,19 +1289,27 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) dev->dac[0].addr = dev->dac[0].addr_latch; dev->dac[0].buffer_pos = 0; dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dev->step_synth = dev->interp_step_synth; + es137x_fetch(dev, 0); } if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { dev->dac[1].addr = dev->dac[1].addr_latch; dev->dac[1].buffer_pos = 0; dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dev->step_pcm = dev->interp_step; + es137x_fetch(dev, 1); } + // audiopci_log("INTCTRL 0x%02X\n", val & 0xff); dev->int_ctrl = (dev->int_ctrl & 0xffff0000) | val; break; case 0x02: dev->int_ctrl = (dev->int_ctrl & 0x0000ffff) | (val << 16); gameport_remap(dev->gameport, 0x200 | ((val & 0x0300) >> 5)); + es1370_calc_sample_rate(dev); break; /* Memory Page Register, Address 0CH @@ -1179,6 +1320,17 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) case 0x0e: break; + /* CODEC Write Register, Address 10H + Addressable as word, longword */ + case 0x10: + if (dev->type != AUDIOPCI_ES1370) + break; + + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; + if ((val >> 8) == 0x16 && !(val & 1)) + akm4531_reset(dev); + break; + /* Legacy Control/Status Register, Address 18H Addressable as byte, word, longword */ case 0x18: @@ -1187,7 +1339,7 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) case 0x1a: old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val << 16); - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1203,15 +1355,22 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - dev->si_cr = (dev->si_cr & 0xffff0000) | val; + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xff0000) | val; + else + dev->si_cr = (dev->si_cr & 0xffff0000) | val; + if (!(dev->si_cr & SI_P1_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; case 0x22: - dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xc0ffff) | ((val & 0x3f) << 16); + else + dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1238,40 +1397,57 @@ es1371_outw(uint16_t port, uint16_t val, void *priv) } static void -es1371_outl(uint16_t port, uint32_t val, void *priv) +es137x_outl(uint16_t port, uint32_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t old_legacy_ctrl; - audiopci_log("es1371_outl: port=%04x val=%08x\n", port, val); + audiopci_log("es137x_outl: port=%04x val=%08x\n", port, val); switch (port & 0x3f) { /* Interrupt/Chip Select Control Register, Address 00H Addressable as byte, word, longword */ case 0x00: - if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { - dev->dac[0].addr = dev->dac[0].addr_latch; - dev->dac[0].buffer_pos = 0; - dev->dac[0].buffer_pos_end = 0; - es1371_fetch(dev, 0); + { + uint8_t dac1start = 0; + uint8_t dac2start = 0; + + if (!(dev->int_ctrl & INT_DAC1_EN) && (val & INT_DAC1_EN)) { + dev->dac[0].addr = dev->dac[0].addr_latch; + dev->dac[0].buffer_pos = 0; + dev->dac[0].buffer_pos_end = 0; + dev->dac[0].prev_out_l = 0; + dev->dac[0].prev_out_r = 0; + dac1start = 1; + es137x_fetch(dev, 0); + } + if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { + dev->dac[1].addr = dev->dac[1].addr_latch; + dev->dac[1].buffer_pos = 0; + dev->dac[1].buffer_pos_end = 0; + dev->dac[1].prev_out_l = 0; + dev->dac[1].prev_out_r = 0; + dac2start = 1; + es137x_fetch(dev, 1); + } + // audiopci_log("INTCTRL 0x%02X\n", val & 0xff); + dev->int_ctrl = val; + gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); + es1370_calc_sample_rate(dev); + if (dac1start) + dev->step_synth = dev->interp_step_synth; + if (dac2start) + dev->step_pcm = dev->interp_step; + break; } - if (!(dev->int_ctrl & INT_DAC2_EN) && (val & INT_DAC2_EN)) { - dev->dac[1].addr = dev->dac[1].addr_latch; - dev->dac[1].buffer_pos = 0; - dev->dac[1].buffer_pos_end = 0; - es1371_fetch(dev, 1); - } - dev->int_ctrl = val; - gameport_remap(dev->gameport, 0x200 | ((val & 0x03000000) >> 21)); - break; /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ case 0x04: audiopci_log("[W] STATUS = %08X\n", val); - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type == AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd208ffff) | (val & 0x2df70000); - else if (dev->type >= AUDIOPCI_ES1373) + else if (dev->type == AUDIOPCI_ES1373) dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; @@ -1284,6 +1460,12 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* Sample Rate Converter Interface Register, Address 10H Addressable as longword only */ case 0x10: + if (dev->type == AUDIOPCI_ES1370) { + dev->akm_codec.registers[(val >> 8) & 0xFF] = val & 0xFF; + if ((val >> 8) == 0x16 && !(val & 1)) + akm4531_reset(dev); + break; + } dev->sr_cir = val & 0xfff8ffff; /*Bits 16 to 18 are undefined*/ if (dev->sr_cir & SRC_RAM_WE) { dev->sr_ram[dev->sr_cir >> 25] = val & 0xffff; @@ -1334,6 +1516,8 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* CODEC Write Register, Address 14H Addressable as longword only */ case 0x14: + if (dev->type == AUDIOPCI_ES1370) + break; if (val & CODEC_READ) { dev->codec_ctrl &= 0x00ff0000; dev->codec_ctrl |= ac97_codec_readw(dev->codec, val >> 16); @@ -1354,7 +1538,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) old_legacy_ctrl = dev->legacy_ctrl; dev->legacy_ctrl = (dev->legacy_ctrl & 0x0000ffff) | (val & 0xffff0000); dev->legacy_ctrl |= LEGACY_INT; - es1371_update_irqs(dev); + es137x_update_irqs(dev); update_legacy(dev, old_legacy_ctrl); break; @@ -1367,12 +1551,15 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - dev->si_cr = (val & 0x007fffff) | 0xff800000; + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = val & 0x3fffff; + else + dev->si_cr = (val & 0x007fffff) | 0xff800000; if (!(dev->si_cr & SI_P1_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1397,7 +1584,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) case 0x34: case 0x38: case 0x3c: - es1371_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); + es137x_write_frame_reg(dev, port & 0x3c, dev->mem_page, val); break; default: @@ -1406,7 +1593,7 @@ es1371_outl(uint16_t port, uint32_t val, void *priv) } static void -capture_event(es1371_t *dev, int type, int rw, uint16_t port) +capture_event(es137x_t *dev, int type, int rw, uint16_t port) { dev->legacy_ctrl &= ~(LEGACY_EVENT_MASK | LEGACY_EVENT_ADDR_MASK); dev->legacy_ctrl |= type; @@ -1524,7 +1711,7 @@ capture_read_slave_dma(uint16_t port, void *priv) } static void -update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) +update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl) { if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { @@ -1713,10 +1900,106 @@ update_legacy(es1371_t *dev, uint32_t old_legacy_ctrl) } } +static uint8_t +es1370_pci_read(int func, int addr, void *priv) +{ + const es137x_t *dev = (es137x_t *) priv; + + if (func > 0) + return 0xff; + + if ((addr > 0x3f) && ((addr < 0xdc) || (addr > 0xe1))) + return 0x00; + + switch (addr) { + case 0x00: /* Vendor ID */ + return 0x74; /* Ensoniq */ + case 0x01: + return 0x12; + + case 0x02: /* Device ID */ + return dev->type >> 16; /* ES1370 */ + case 0x03: + return dev->type >> 24; + + case 0x04: /* Command TODO */ + return dev->pci_command; + case 0x05: + return dev->pci_serr; + + case 0x06: /* Status TODO */ + return 0x10; /* Supports ACPI */ + case 0x07: + return 0x00; + + case 0x08: /* Class Code & Revision ID */ + return dev->type >> 8; /* Revision ID - 0x00 is actual Ensoniq-branded ES1370 */ + case 0x09: + return 0x00; /* Multimedia audio device */ + case 0x0a: + return 0x01; + case 0x0b: + return 0x04; + +// case 0x0c: /* Cache Line Size TODO */ +// case 0x0d: /* Latency Timer TODO */ +// case 0x0e: /* Header Type TODO */ +// case 0x0f: /* BIST TODO */ + + case 0x10: /* Base Address TODO */ + return 0x01 | (dev->base_addr & 0xc0); /* memBaseAddr */ + case 0x11: + return dev->base_addr >> 8; + case 0x12: + return dev->base_addr >> 16; + case 0x13: + return dev->base_addr >> 24; + + case 0x2c ... 0x2f: + return dev->subsys_id[addr & 3]; /* Subsystem vendor ID */ + +#if 0 + case 0x34: // TODO + return 0xdc; /* Capabilites pointer */ +#endif + + case 0x3c: + return dev->int_line; + case 0x3d: + return 0x01; /* INTA */ + + case 0x3e: + return 0xc; /* Minimum grant */ + case 0x3f: + return 0x80; /* Maximum latency */ + +#if 0 + case 0xdc: + return 0x01; /* Capabilities identifier */ + case 0xdd: + return 0x00; /* Next item pointer */ + case 0xde: + return 0x31; /* Power management capabilities */ + case 0xdf: + return 0x6c; + + case 0xe0: + return dev->pmcsr & 0xff; + case 0xe1: + return dev->pmcsr >> 8; +#endif + + default: + break; + } + + return 0x00; +} + static uint8_t es1371_pci_read(int func, int addr, void *priv) { - const es1371_t *dev = (es1371_t *) priv; + const es137x_t *dev = (es137x_t *) priv; if (func > 0) return 0xff; @@ -1780,7 +2063,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x80; /* Maximum latency */ case 0x40: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) return dev->subsys_lock; break; @@ -1806,42 +2089,93 @@ es1371_pci_read(int func, int addr, void *priv) } static void -es1371_io_set(es1371_t *dev, int set) +es137x_io_set(es137x_t *dev, int set) { if (dev->pci_command & PCI_COMMAND_IO) { io_handler(set, dev->base_addr, 0x0040, - es1371_inb, es1371_inw, es1371_inl, - es1371_outb, es1371_outw, es1371_outl, dev); + es137x_inb, es137x_inw, es137x_inl, + es137x_outb, es137x_outw, es137x_outl, dev); } } static void -es1371_pci_write(int func, int addr, uint8_t val, void *priv) +es1370_pci_write(int func, int addr, uint8_t val, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; if (func) return; switch (addr) { case 0x04: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->pci_command = val & 0x05; - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); break; case 0x05: dev->pci_serr = val & 1; break; case 0x10: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); break; case 0x11: - es1371_io_set(dev, 0); + es137x_io_set(dev, 0); dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); - es1371_io_set(dev, 1); + es137x_io_set(dev, 1); + break; + case 0x12: + dev->base_addr = (dev->base_addr & 0xff00ffc0) | (val << 16); + break; + case 0x13: + dev->base_addr = (dev->base_addr & 0x00ffffc0) | (val << 24); + break; + + case 0x3c: + dev->int_line = val; + break; + + case 0xe0: + dev->pmcsr = (dev->pmcsr & 0xff00) | (val & 0x03); + break; + case 0xe1: + dev->pmcsr = (dev->pmcsr & 0x00ff) | ((val & 0x01) << 8); + break; + + default: + break; + } +} + +static void +es1371_pci_write(int func, int addr, uint8_t val, void *priv) +{ + es137x_t *dev = (es137x_t *) priv; + + if (func) + return; + + switch (addr) { + case 0x04: + es137x_io_set(dev, 0); + dev->pci_command = val & 0x05; + es137x_io_set(dev, 1); + break; + case 0x05: + dev->pci_serr = val & 1; + break; + + case 0x10: + es137x_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffffff00) | (val & 0xc0); + es137x_io_set(dev, 1); + break; + case 0x11: + es137x_io_set(dev, 0); + dev->base_addr = (dev->base_addr & 0xffff00c0) | (val << 8); + es137x_io_set(dev, 1); break; case 0x12: dev->base_addr = (dev->base_addr & 0xff00ffc0) | (val << 16); @@ -1860,7 +2194,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if (dev->type >= AUDIOPCI_ES1373) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) dev->subsys_lock = val; break; @@ -1877,7 +2211,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) } static void -es1371_fetch(es1371_t *dev, int dac_nr) +es137x_fetch(es137x_t *dev, int dac_nr) { if (dev->si_cr & (dac_nr ? SI_P2_PAUSE : SI_P1_PAUSE)) return; @@ -1981,8 +2315,8 @@ low_fir_es1371(int dac_nr, int i, float NewSample) read_pos = (pos + 15) & (127 & ~15); n_coef = (16 - pos) & 15; - while (n_coef < ES1371_NCoef) { - out += low_fir_es1371_coef[n_coef] * x[dac_nr][i][read_pos]; + while (n_coef < ES137x_NCoef) { + out += low_fir_es137x_coef[n_coef] * x[dac_nr][i][read_pos]; read_pos = (read_pos + 16) & (127 & ~15); n_coef += 16; } @@ -1997,13 +2331,13 @@ low_fir_es1371(int dac_nr, int i, float NewSample) } static void -es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) +es137x_next_sample_filtered(es137x_t *dev, int dac_nr, int out_idx) { int out_l; int out_r; if ((dev->dac[dac_nr].buffer_pos - dev->dac[dac_nr].buffer_pos_end) >= 0) - es1371_fetch(dev, dac_nr); + es137x_fetch(dev, dac_nr); out_l = dev->dac[dac_nr].buffer_l[dev->dac[dac_nr].buffer_pos & 63]; out_r = dev->dac[dac_nr].buffer_r[dev->dac[dac_nr].buffer_pos & 63]; @@ -2020,21 +2354,35 @@ es1371_next_sample_filtered(es1371_t *dev, int dac_nr, int out_idx) } static void -es1371_update(es1371_t *dev) +es137x_update(es137x_t *dev) { int32_t l; int32_t r; - l = (dev->dac[0].out_l * dev->dac[0].vol_l) >> 12; - l += ((dev->dac[1].out_l * dev->dac[1].vol_l) >> 12); - r = (dev->dac[0].out_r * dev->dac[0].vol_r) >> 12; - r += ((dev->dac[1].out_r * dev->dac[1].vol_r) >> 12); + if (dev->type == AUDIOPCI_ES1370) { + l = dev->dac[0].out_l * (((dev->akm_codec.registers[0x4] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x4] & 0x1f)]) / 32767.0); + r = dev->dac[0].out_r * (((dev->akm_codec.registers[0x5] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x5] & 0x1f)]) / 32767.0); - l >>= 1; - r >>= 1; + l += dev->dac[1].out_l * (((dev->akm_codec.registers[0x2] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x2] & 0x1f)]) / 32767.0); + r += dev->dac[1].out_r * (((dev->akm_codec.registers[0x3] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[0x3] & 0x1f)]) / 32767.0); - l = (((l * dev->pcm_vol_l) >> 15) * dev->master_vol_l) >> 15; - r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; + l >>= 1; + r >>= 1; + + l *= (((dev->akm_codec.registers[0x0] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[0x0] & 0x1f) ^ 0x1f]) / 32767.0); + r *= (((dev->akm_codec.registers[0x1] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[0x1] & 0x1f) ^ 0x1f]) / 32767.0); + } else { + l = (dev->dac[0].out_l * dev->dac[0].vol_l) >> 12; + l += ((dev->dac[1].out_l * dev->dac[1].vol_l) >> 12); + r = (dev->dac[0].out_r * dev->dac[0].vol_r) >> 12; + r += ((dev->dac[1].out_r * dev->dac[1].vol_r) >> 12); + + l >>= 1; + r >>= 1; + + l = (((l * dev->pcm_vol_l) >> 15) * dev->master_vol_l) >> 15; + r = (((r * dev->pcm_vol_r) >> 15) * dev->master_vol_r) >> 15; + } if (l < -32768) l = -32768; @@ -2045,16 +2393,16 @@ es1371_update(es1371_t *dev) else if (r > 32767) r = 32767; - for (; dev->pos < sound_pos_global; dev->pos++) { + for (; dev->pos < ((dev->type == AUDIOPCI_ES1370) ? wavetable_pos_global : sound_pos_global); dev->pos++) { dev->buffer[dev->pos * 2] = l; dev->buffer[dev->pos * 2 + 1] = r; } } static void -es1371_poll(void *priv) +es137x_poll(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; int frac; int idx; int samp1_l; @@ -2064,21 +2412,41 @@ es1371_poll(void *priv) timer_advance_u64(&dev->dac[1].timer, dev->dac[1].latch); - es1371_scan_fifo(dev); + es137x_scan_fifo(dev); - es1371_update(dev); + es137x_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) { - /* SRC bypass. */ - if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) - es1371_fetch(dev, 0); + if ((((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) && (dev->int_ctrl & INT_DAC1_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { + if ((dev->calc_sample_rate_synth != 44100) && (dev->type == AUDIOPCI_ES1370)) { + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0 && dev->step_synth >= dev->interp_step_synth) + es137x_fetch(dev, 0); - dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; - dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; - dev->dac[0].buffer_pos++; + if (dev->step_synth >= dev->interp_step_synth) { + dev->step_synth = 0; + } - goto dac0_count; + dev->dac[0].out_l = lerp(dev->dac[0].prev_out_l, dev->dac[0].buffer_l[(dev->dac[0].buffer_pos) & 63], (dev->step_synth + 1) * dev->interp_factor_synth); + dev->dac[0].out_r = lerp(dev->dac[0].prev_out_r, dev->dac[0].buffer_r[(dev->dac[0].buffer_pos) & 63], (dev->step_synth + 1) * dev->interp_factor_synth); + + dev->step_synth++; + if (dev->step_synth >= dev->interp_step_synth) { + dev->dac[0].prev_out_l = dev->dac[0].out_l; + dev->dac[0].prev_out_r = dev->dac[0].out_r; + dev->dac[0].buffer_pos++; + goto dac0_count; + } + } else { + /* SRC bypass. */ + if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0) + es137x_fetch(dev, 0); + + dev->dac[0].out_l = dev->dac[0].buffer_l[dev->dac[0].buffer_pos & 63]; + dev->dac[0].out_r = dev->dac[0].buffer_r[dev->dac[0].buffer_pos & 63]; + dev->dac[0].buffer_pos++; + + goto dac0_count; + } } else { frac = dev->dac[0].ac & 0x7fff; idx = dev->dac[0].ac >> 15; @@ -2092,14 +2460,14 @@ es1371_poll(void *priv) dev->dac[0].ac += dev->dac[0].vf; dev->dac[0].ac &= ((32 << 15) - 1); if ((dev->dac[0].ac >> (15 + 4)) != dev->dac[0].f_pos) { - es1371_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); + es137x_next_sample_filtered(dev, 0, dev->dac[0].f_pos ? 16 : 0); dev->dac[0].f_pos = (dev->dac[0].f_pos + 1) & 1; dac0_count: dev->dac[0].curr_samp_ct--; if (dev->dac[0].curr_samp_ct < 0) { dev->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(dev); + es137x_update_irqs(dev); dev->dac[0].curr_samp_ct = dev->dac[0].samp_ct; } } @@ -2107,16 +2475,36 @@ dac0_count: } if (dev->int_ctrl & INT_DAC2_EN) { - if ((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) { - /* SRC bypass. */ - if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) - es1371_fetch(dev, 1); + if ((((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) && (dev->int_ctrl & INT_DAC2_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { + if ((dev->calc_sample_rate != 44100) && (dev->type == AUDIOPCI_ES1370)) { + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0 && dev->step_pcm >= dev->interp_step) + es137x_fetch(dev, 1); - dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; - dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; - dev->dac[1].buffer_pos++; + if (dev->step_pcm >= dev->interp_step) { + dev->step_pcm = 0; + } - goto dac1_count; + dev->dac[1].out_l = lerp(dev->dac[1].prev_out_l, dev->dac[1].buffer_l[(dev->dac[1].buffer_pos) & 63], (dev->step_pcm + 1) * dev->interp_factor); + dev->dac[1].out_r = lerp(dev->dac[1].prev_out_r, dev->dac[1].buffer_r[(dev->dac[1].buffer_pos) & 63], (dev->step_pcm + 1) * dev->interp_factor); + + dev->step_pcm++; + if (dev->step_pcm >= dev->interp_step) { + dev->dac[1].prev_out_l = dev->dac[1].out_l; + dev->dac[1].prev_out_r = dev->dac[1].out_r; + dev->dac[1].buffer_pos++; + goto dac1_count; + } + } else { + /* SRC bypass. */ + if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0) + es137x_fetch(dev, 1); + + dev->dac[1].out_l = dev->dac[1].buffer_l[dev->dac[1].buffer_pos & 63]; + dev->dac[1].out_r = dev->dac[1].buffer_r[dev->dac[1].buffer_pos & 63]; + dev->dac[1].buffer_pos++; + + goto dac1_count; + } } else { frac = dev->dac[1].ac & 0x7fff; idx = dev->dac[1].ac >> 15; @@ -2130,14 +2518,14 @@ dac0_count: dev->dac[1].ac += dev->dac[1].vf; dev->dac[1].ac &= ((32 << 15) - 1); if ((dev->dac[1].ac >> (15 + 4)) != dev->dac[1].f_pos) { - es1371_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); + es137x_next_sample_filtered(dev, 1, dev->dac[1].f_pos ? 16 : 0); dev->dac[1].f_pos = (dev->dac[1].f_pos + 1) & 1; dac1_count: dev->dac[1].curr_samp_ct--; if (dev->dac[1].curr_samp_ct < 0) { dev->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(dev); + es137x_update_irqs(dev); dev->dac[1].curr_samp_ct = dev->dac[1].samp_ct; } } @@ -2146,11 +2534,11 @@ dac1_count: } static void -es1371_get_buffer(int32_t *buffer, int len, void *priv) +es137x_get_buffer(int32_t *buffer, int len, void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; - es1371_update(dev); + es137x_update(dev); for (int c = 0; c < len * 2; c++) buffer[c] += (dev->buffer[c] / 2); @@ -2158,10 +2546,22 @@ es1371_get_buffer(int32_t *buffer, int len, void *priv) dev->pos = 0; } +static void +es1370_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const es137x_t *dev = (es137x_t *) priv; + double c = 0.0; + double mastervol = ((dev->akm_codec.registers[channel] & 0x80) ? 0 : akm4531_att_2dbstep_5bits[(dev->akm_codec.registers[channel] & 0x1f) ^ 0x1f]) / 32767.0; + double cdvol = ((dev->akm_codec.registers[channel + 0x6] & 0x80) ? 0 : akm4531_gain_2dbstep_5bits[(dev->akm_codec.registers[channel + 0x6] & 0x1f)]) / 32767.0; + + c = *buffer * mastervol * cdvol; + *buffer = c; +} + static void es1371_filter_cd_audio(int channel, double *buffer, void *priv) { - const es1371_t *dev = (es1371_t *) priv; + const es137x_t *dev = (es137x_t *) priv; double c; int cd = channel ? dev->cd_vol_r : dev->cd_vol_l; int master = channel ? dev->master_vol_r : dev->master_vol_l; @@ -2177,49 +2577,49 @@ sinc(double x) } static void -generate_es1371_filter(void) +generate_es137x_filter(void) { /* Cutoff frequency = 1 / 32 */ float fC = 1.0 / 32.0; float gain; int n; - for (n = 0; n < ES1371_NCoef; n++) { + for (n = 0; n < ES137x_NCoef; n++) { /* Blackman window */ - double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (ES1371_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (ES1371_NCoef - 1))); + double w = 0.42 - (0.5 * cos((2.0 * n * M_PI) / (double) (ES137x_NCoef - 1))) + (0.08 * cos((4.0 * n * M_PI) / (double) (ES137x_NCoef - 1))); /* Sinc filter */ - double h = sinc(2.0 * fC * ((double) n - ((double) (ES1371_NCoef - 1) / 2.0))); + double h = sinc(2.0 * fC * ((double) n - ((double) (ES137x_NCoef - 1) / 2.0))); /* Create windowed-sinc filter */ - low_fir_es1371_coef[n] = w * h; + low_fir_es137x_coef[n] = w * h; } - low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; + low_fir_es137x_coef[(ES137x_NCoef - 1) / 2] = 1.0; gain = 0.0; - for (n = 0; n < ES1371_NCoef; n++) - gain += low_fir_es1371_coef[n] / (float) N; + for (n = 0; n < ES137x_NCoef; n++) + gain += low_fir_es137x_coef[n] / (float) N; gain /= 0.65; /* Normalise filter, to produce unity gain */ - for (n = 0; n < ES1371_NCoef; n++) - low_fir_es1371_coef[n] /= gain; + for (n = 0; n < ES137x_NCoef; n++) + low_fir_es137x_coef[n] /= gain; } static void -es1371_input_msg(void *priv, uint8_t *msg, uint32_t len) +es137x_input_msg(void *priv, uint8_t *msg, uint32_t len) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; for (uint32_t i = 0; i < len; i++) - es1371_write_fifo(dev, msg[i]); + es137x_write_fifo(dev, msg[i]); } static int -es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) +es137x_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; uint32_t i = -1; audiopci_log("Abort = %i\n", abort); @@ -2229,7 +2629,7 @@ es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) if (!abort) { for (i = 0; i < len; i++) { - es1371_write_fifo(dev, buffer[i]); + es137x_write_fifo(dev, buffer[i]); if (dev->uart_status & UART_STATUS_RXRDY) break; } @@ -2240,17 +2640,61 @@ es1371_input_sysex(void *priv, uint8_t *buffer, uint32_t len, int abort) return 7 - i; } +static void es137x_speed_changed(void *priv); + +static void * +es1370_init(const device_t *info) +{ + es137x_t *dev = calloc(1, sizeof(es137x_t)); + dev->type = info->local; + + if (device_get_config_int("receive_input")) + midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); + + wavetable_add_handler(es137x_get_buffer, dev); + sound_set_cd_audio_filter(es1370_filter_cd_audio, dev); + + dev->gameport = gameport_add(&gameport_pnp_device); + gameport_remap(dev->gameport, 0x200); + + pci_add_card((info->local & 1) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1370_pci_read, es1370_pci_write, dev, &dev->pci_slot); + + timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); + + generate_es137x_filter(); + + dev->dac[0].vol_l = 1 << 12; + dev->dac[0].vol_r = 1 << 12; + dev->dac[1].vol_l = 1 << 12; + dev->dac[1].vol_r = 1 << 12; + + dev->pcm_vol_l = 1 << 15; + dev->pcm_vol_r = 1 << 15; + dev->master_vol_l = 1 << 15; + dev->master_vol_r = 1 << 15; + + es137x_reset(dev); + + es137x_speed_changed(dev); + + for (int i = 0; i < 0x20; i++) { + double attn = (12.0 - (i * 2.0)); + akm4531_gain_2dbstep_5bits[i] = pow(10, attn / 10.) * 32767.0; + } + + return dev; +} + static void * es1371_init(const device_t *info) { - es1371_t *dev = malloc(sizeof(es1371_t)); - memset(dev, 0x00, sizeof(es1371_t)); + es137x_t *dev = calloc(1, sizeof(es137x_t)); dev->type = info->local & 0xffffff00; if (device_get_config_int("receive_input")) - midi_in_handler(1, es1371_input_msg, es1371_input_sysex, dev); + midi_in_handler(1, es137x_input_msg, es137x_input_sysex, dev); - sound_add_handler(es1371_get_buffer, dev); + sound_add_handler(es137x_get_buffer, dev); sound_set_cd_audio_filter(es1371_filter_cd_audio, dev); dev->gameport = gameport_add(&gameport_pnp_device); @@ -2258,9 +2702,9 @@ es1371_init(const device_t *info) pci_add_card((info->local & 1) ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, dev, &dev->pci_slot); - timer_add(&dev->dac[1].timer, es1371_poll, dev, 1); + timer_add(&dev->dac[1].timer, es137x_poll, dev, 1); - generate_es1371_filter(); + generate_es137x_filter(); ac97_codec = &dev->codec; ac97_codec_count = 1; @@ -2269,132 +2713,170 @@ es1371_init(const device_t *info) if (!(info->local & 1)) device_add(ac97_codec_get(device_get_config_int("codec"))); - es1371_reset(dev); + es137x_reset(dev); return dev; } static void -es1371_close(void *priv) +es137x_close(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; free(dev); } static void -es1371_speed_changed(void *priv) +es137x_speed_changed(void *priv) { - es1371_t *dev = (es1371_t *) priv; + es137x_t *dev = (es137x_t *) priv; - dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ)); + dev->dac[1].latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) ((dev->type == AUDIOPCI_ES1370) ? WT_FREQ : SOUND_FREQ))); } -static const device_config_t es1371_config[] = { - // clang-format off +static const device_config_t es1370_config[] = { + // clang-format off { - .name = "codec", - .description = "Codec", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "Asahi Kasei AK4540", - .value = AC97_CODEC_AK4540 - }, - { - .description = "TriTech TR28023 / Creative CT1297", - .value = AC97_CODEC_TR28023 - }, - { .description = "" } - }, - .default_int = AC97_CODEC_TR28023 - }, - { - .name = "receive_input", - .description = "Receive input (MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive input (MIDI)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on +}; + +static const device_config_t es1371_config[] = { + // clang-format off + { + .name = "codec", + .description = "Codec", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = AC97_CODEC_TR28023, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Asahi Kasei AK4540", .value = AC97_CODEC_AK4540 }, + { .description = "TriTech TR28023 / Creative CT1297", .value = AC97_CODEC_TR28023 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on }; static const device_config_t es1373_config[] = { - // clang-format off + // clang-format off { - .name = "codec", - .description = "Codec", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "Crystal CS4297A", - .value = AC97_CODEC_CS4297A - }, - { - .description = "SigmaTel STAC9721T", - .value = AC97_CODEC_STAC9721 - }, - { - .description = "TriTech TR28023 / Creative CT1297", - .value = AC97_CODEC_TR28023 - }, + .name = "codec", + .description = "Codec", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = AC97_CODEC_CS4297A, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Crystal CS4297A", .value = AC97_CODEC_CS4297A }, + { .description = "SigmaTel STAC9721T", .value = AC97_CODEC_STAC9721 }, + { .description = "TriTech TR28023 / Creative CT1297", .value = AC97_CODEC_TR28023 }, { .description = "" } }, - .default_int = AC97_CODEC_CS4297A + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t ct5880_config[] = { - // clang-format off + // clang-format off { - .name = "codec", - .description = "Codec", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "SigmaTel STAC9708T", - .value = AC97_CODEC_STAC9708 - }, - { - .description = "SigmaTel STAC9721T (stereo)", - .value = AC97_CODEC_STAC9721 - }, - { .description = "" } + .name = "codec", + .description = "Codec", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = AC97_CODEC_STAC9708, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "SigmaTel STAC9708T", .value = AC97_CODEC_STAC9708 }, + { .description = "SigmaTel STAC9721T (stereo)", .value = AC97_CODEC_STAC9721 }, + { .description = "TriTech TR28023 / Creative CT1297", .value = AC97_CODEC_TR28023 }, + { .description = "" } }, - .default_int = AC97_CODEC_STAC9708 + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on }; static const device_config_t es1371_onboard_config[] = { - // clang-format off + // clang-format off { - .name = "receive_input", - .description = "Receive input (MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on + // clang-format on +}; + +const device_t es1370_device = { + .name = "Ensoniq AudioPCI (ES1370)", + .internal_name = "es1370", + .flags = DEVICE_PCI, + .local = AUDIOPCI_ES1370, + .init = es1370_init, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, + .force_redraw = NULL, + .config = es1370_config }; const device_t es1371_device = { @@ -2403,10 +2885,10 @@ const device_t es1371_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1371, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, - { .available = NULL }, - .speed_changed = es1371_speed_changed, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_config }; @@ -2417,10 +2899,10 @@ const device_t es1371_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1371 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, - { .available = NULL }, - .speed_changed = es1371_speed_changed, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; @@ -2431,10 +2913,10 @@ const device_t es1373_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1373, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, - { .available = NULL }, - .speed_changed = es1371_speed_changed, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1373_config }; @@ -2445,10 +2927,10 @@ const device_t es1373_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_ES1373 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, - { .available = NULL }, - .speed_changed = es1371_speed_changed, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; @@ -2459,10 +2941,10 @@ const device_t ct5880_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_CT5880, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, - { .available = NULL }, - .speed_changed = es1371_speed_changed, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = ct5880_config }; @@ -2473,10 +2955,10 @@ const device_t ct5880_onboard_device = { .flags = DEVICE_PCI, .local = AUDIOPCI_CT5880 | 1, .init = es1371_init, - .close = es1371_close, - .reset = es1371_reset, - { .available = NULL }, - .speed_changed = es1371_speed_changed, + .close = es137x_close, + .reset = es137x_reset, + .available = NULL, + .speed_changed = es137x_speed_changed, .force_redraw = NULL, .config = es1371_onboard_config }; diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index 28ab2b7ac..76bf1b24f 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -974,8 +974,7 @@ azt_init(const device_t *info) int loaded_from_eeprom = 0; uint16_t addr_setting; uint8_t read_eeprom[AZTECH_EEPROM_SIZE]; - azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); - memset(azt2316a, 0, sizeof(azt2316a_t)); + azt2316a_t *azt2316a = calloc(1, sizeof(azt2316a_t)); azt2316a->type = info->local; @@ -1226,8 +1225,7 @@ azt_init(const device_t *info) 2x4 to 2x5 -> Mixer interface 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices).*/ - azt2316a->sb = malloc(sizeof(sb_t)); - memset(azt2316a->sb, 0, sizeof(sb_t)); + azt2316a->sb = calloc(1, sizeof(sb_t)); azt2316a->sb->opl_enabled = device_get_config_int("opl"); @@ -1238,7 +1236,7 @@ azt_init(const device_t *info) fm_driver_get(FM_YMF262, &azt2316a->sb->opl); sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1); - sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); + sb_dsp_init(&azt2316a->sb->dsp, SBPRO2_DSP_302, azt2316a->type, azt2316a); sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); @@ -1259,8 +1257,7 @@ azt_init(const device_t *info) sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb); if (azt2316a->cur_mpu401_enabled) { - azt2316a->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(azt2316a->mpu, 0, sizeof(mpu_t)); + azt2316a->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(azt2316a->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401")); } else azt2316a->mpu = NULL; @@ -1318,142 +1315,127 @@ azt_speed_changed(void *priv) static const device_config_t azt1605_config[] = { // clang-format off { - .name = "codec", - .description = "CODEC", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "CS4248", - .value = AD1848_TYPE_CS4248 - }, - { - .description = "CS4231", - .value = AD1848_TYPE_CS4231 - }, + .name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = AD1848_TYPE_CS4248, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "CS4248", .value = AD1848_TYPE_CS4248 }, + { .description = "CS4231", .value = AD1848_TYPE_CS4231 }, + { .description = "" } }, - .default_int = AD1848_TYPE_CS4248 + .bios = { { 0 } } }, { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_int = 0 + .name = "wss_interrupt_after_config", + .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "addr", - .description = "SB Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "Use EEPROM setting", - .value = 0 - }, - { - .description = "" - } - } - }, - { - .name = "sb_dma8", - .description = "SB low DMA", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } + .name = "addr", + .description = "SB Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "Use EEPROM setting", .value = 0 }, + { .description = "" } }, - .default_int = 1 + .bios = { { 0 } } }, { - .name = "wss_irq", - .description = "WSS IRQ", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } + .name = "sb_dma8", + .description = "SB low DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } }, - .default_int = 10 + .bios = { { 0 } } }, - { - .name = "wss_dma", - .description = "WSS DMA", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 0 + { + .name = "wss_irq", + .description = "WSS IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 10, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } }, - { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "wss_dma", + .description = "WSS DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 @@ -1462,119 +1444,111 @@ static const device_config_t azt1605_config[] = { static const device_config_t azt2316a_config[] = { // clang-format off { - .name = "codec", - .description = "CODEC", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "CS4248", - .value = AD1848_TYPE_CS4248 - }, - { - .description = "CS4231", - .value = AD1848_TYPE_CS4231 - }, + .name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = AD1848_TYPE_CS4248, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "CS4248", .value = AD1848_TYPE_CS4248 }, + { .description = "CS4231", .value = AD1848_TYPE_CS4231 }, + { .description = "" } }, - .default_int = AD1848_TYPE_CS4248 + .bios = { { 0 } } }, { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_int = 0 + .name = "wss_interrupt_after_config", + .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "addr", - .description = "SB Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "Use EEPROM setting", - .value = 0 - }, - { - .description = "" - } - } - }, - { - .name = "wss_irq", - .description = "WSS IRQ", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } + .name = "addr", + .description = "SB Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "Use EEPROM setting", .value = 0 }, + { .description = "" } }, - .default_int = 10 + .bios = { { 0 } } }, { - .name = "wss_dma", - .description = "WSS DMA", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } + .name = "wss_irq", + .description = "WSS IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 10, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 11", .value = 11 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } }, - .default_int = 0 + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "wss_dma", + .description = "WSS DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "receive_input401", + .description = "Receive MIDI input", + .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 @@ -1583,12 +1557,12 @@ static const device_config_t azt2316a_config[] = { const device_t azt2316a_device = { .name = "Aztech Sound Galaxy Pro 16 AB (Washington)", .internal_name = "azt2316a", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = SB_SUBTYPE_CLONE_AZT2316A_0X11, .init = azt_init, .close = azt_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = azt_speed_changed, .force_redraw = NULL, .config = azt2316a_config @@ -1597,12 +1571,12 @@ const device_t azt2316a_device = { const device_t azt1605_device = { .name = "Aztech Sound Galaxy Nova 16 Extra (Clinton)", .internal_name = "azt1605", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = SB_SUBTYPE_CLONE_AZT1605_0X0C, .init = azt_init, .close = azt_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = azt_speed_changed, .force_redraw = NULL, .config = azt1605_config diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index d548763ce..a41f53865 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -497,7 +497,7 @@ cmi8x38_sb_mixer_write(uint16_t addr, uint8_t val, void *priv) /* Set TDMA channels if auto-detection is enabled. */ if ((dev->io_regs[0x27] & 0x01) && (mixer->index == 0x81)) { dev->tdma_8 = dev->sb->dsp.sb_8_dmanum; - if (dev->sb->dsp.sb_type >= SB16) + if (dev->sb->dsp.sb_type >= SB16_DSP_404) dev->tdma_16 = dev->sb->dsp.sb_16_dmanum; } } else { @@ -879,7 +879,7 @@ cmi8x38_write(uint16_t addr, uint8_t val, void *priv) dev->sb->dsp.sbleftright_default = !!(val & 0x02); /* Enable or disable SB16 mode. */ - dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2 : SB16; + dev->sb->dsp.sb_type = (val & 0x01) ? SBPRO2_DSP_302 : SB16_DSP_405; break; case 0x22: @@ -1434,8 +1434,7 @@ cmi8x38_reset(void *priv) static void * cmi8x38_init(const device_t *info) { - cmi8x38_t *dev = malloc(sizeof(cmi8x38_t)); - memset(dev, 0, sizeof(cmi8x38_t)); + cmi8x38_t *dev = calloc(1, sizeof(cmi8x38_t)); /* Set the chip type. */ if ((info->local == CMEDIA_CMI8738_6CH) && !device_get_config_int("six_channel")) @@ -1509,11 +1508,15 @@ cmi8x38_close(void *priv) static const device_config_t cmi8x38_config[] = { // clang-format off { - .name = "receive_input", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1522,18 +1525,26 @@ static const device_config_t cmi8x38_config[] = { static const device_config_t cmi8738_config[] = { // clang-format off { - .name = "six_channel", - .description = "6CH variant (6-channel)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "six_channel", + .description = "6CH variant (6-channel)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1547,7 +1558,7 @@ const device_t cmi8338_device = { .init = cmi8x38_init, .close = cmi8x38_close, .reset = cmi8x38_reset, - { .available = NULL }, + .available = NULL, .speed_changed = cmi8x38_speed_changed, .force_redraw = NULL, .config = cmi8x38_config @@ -1561,7 +1572,7 @@ const device_t cmi8338_onboard_device = { .init = cmi8x38_init, .close = cmi8x38_close, .reset = cmi8x38_reset, - { .available = NULL }, + .available = NULL, .speed_changed = cmi8x38_speed_changed, .force_redraw = NULL, .config = cmi8x38_config @@ -1575,7 +1586,7 @@ const device_t cmi8738_device = { .init = cmi8x38_init, .close = cmi8x38_close, .reset = cmi8x38_reset, - { .available = NULL }, + .available = NULL, .speed_changed = cmi8x38_speed_changed, .force_redraw = NULL, .config = cmi8738_config @@ -1589,7 +1600,7 @@ const device_t cmi8738_onboard_device = { .init = cmi8x38_init, .close = cmi8x38_close, .reset = cmi8x38_reset, - { .available = NULL }, + .available = NULL, .speed_changed = cmi8x38_speed_changed, .force_redraw = NULL, .config = cmi8x38_config @@ -1603,7 +1614,7 @@ const device_t cmi8738_6ch_onboard_device = { .init = cmi8x38_init, .close = cmi8x38_close, .reset = cmi8x38_reset, - { .available = NULL }, + .available = NULL, .speed_changed = cmi8x38_speed_changed, .force_redraw = NULL, .config = cmi8x38_config diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index d33eba83a..66dff80f3 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -95,15 +95,15 @@ cms_write(uint16_t addr, uint8_t val, void *priv) int chip = (addr & 2) >> 1; switch (addr & 0xf) { - case 1: + case 0x1: /* SAA #1 Register Select Port */ cms->addrs[0] = val & 31; break; - case 3: + case 0x3: /* SAA #2 Register Select Port */ cms->addrs[1] = val & 31; break; - case 0: - case 2: + case 0x0: /* SAA #1 Data Port */ + case 0x2: /* SAA #2 Data Port */ cms_update(cms); cms->regs[chip][cms->addrs[chip] & 31] = val; switch (cms->addrs[chip] & 31) { @@ -145,8 +145,9 @@ cms_write(uint16_t addr, uint8_t val, void *priv) break; } break; - case 0x6: - case 0x7: + + case 0x6: /* GameBlaster Write Port */ + case 0x7: /* GameBlaster Write Port */ cms->latched_data = val; break; @@ -161,14 +162,14 @@ cms_read(uint16_t addr, void *priv) const cms_t *cms = (cms_t *) priv; switch (addr & 0xf) { - case 0x1: + case 0x1: /* SAA #1 Register Select Port */ return cms->addrs[0]; - case 0x3: + case 0x3: /* SAA #2 Register Select Port */ return cms->addrs[1]; - case 0x4: + case 0x4: /* GameBlaster Read port (Always returns 0x7F) */ return 0x7f; - case 0xa: - case 0xb: + case 0xa: /* GameBlaster Read Port */ + case 0xb: /* GameBlaster Read Port */ return cms->latched_data; default: @@ -180,8 +181,7 @@ cms_read(uint16_t addr, void *priv) void * cms_init(UNUSED(const device_t *info)) { - cms_t *cms = malloc(sizeof(cms_t)); - memset(cms, 0, sizeof(cms_t)); + cms_t *cms = calloc(1, sizeof(cms_t)); uint16_t addr = device_get_config_hex16("base"); io_sethandler(addr, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); @@ -200,42 +200,23 @@ cms_close(void *priv) static const device_config_t cms_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x210", - .value = 0x210 - }, - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "" - } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x210", .value = 0x210 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x250", .value = 0x250 }, + { .description = "0x260", .value = 0x260 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -249,7 +230,7 @@ const device_t cms_device = { .init = cms_init, .close = cms_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = cms_config diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 95d183e8f..17ea48dd3 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -12,15 +12,16 @@ * * Authors: RichardG, * - * Copyright 2021-2022 RichardG. + * Copyright 2021-2025 RichardG. */ #include +#include #include #include #include #include #include - +#define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> #include <86box/dma.h> @@ -46,10 +47,19 @@ #define CRYSTAL_NOEEPROM 0x100 enum { - CRYSTAL_CS4235 = 0xdd, - CRYSTAL_CS4236B = 0xcb, + CRYSTAL_CS4232 = 0x32, /* no chip ID; dummy value */ + CRYSTAL_CS4236 = 0x36, /* no chip ID; dummy value */ + CRYSTAL_CS4236B = 0xab, /* report an older revision ID to make the values nice and incremental */ CRYSTAL_CS4237B = 0xc8, - CRYSTAL_CS4238B = 0xc9 + CRYSTAL_CS4238B = 0xc9, + CRYSTAL_CS4235 = 0xdd, + CRYSTAL_CS4239 = 0xde +}; +enum { + CRYSTAL_RAM_CMD = 0, + CRYSTAL_RAM_ADDR_LO = 1, + CRYSTAL_RAM_ADDR_HI = 2, + CRYSTAL_RAM_DATA = 3 }; enum { CRYSTAL_SLAM_NONE = 0, @@ -58,27 +68,43 @@ enum { CRYSTAL_SLAM_BYTE2 = 3 }; +#ifdef ENABLE_CS423X_LOG +int cs423x_do_log = ENABLE_CS423X_LOG; + +static void +cs423x_log(const char *fmt, ...) +{ + va_list ap; + + if (cs423x_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define cs423x_log(fmt, ...) +#endif + static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0x79, 0xBC, 0x5E, 0xAF, 0x57, 0x2B, 0x15, 0x8A, 0xC5, 0xE2, 0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13, 0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A }; -static const uint8_t cs4236b_eeprom[8224] = { +static const uint8_t cs4236_default[] = { // clang-format off /* Chip configuration */ - 0x55, 0xbb, /* magic */ - 0x00, 0x00, /* length */ 0x00, 0x03, /* CD-ROM and modem decode */ 0x80, /* misc. config */ 0x80, /* global config */ - 0x0b, /* chip ID */ + 0x0b, /* [code base byte (CS4236B+)] / reserved (CS4236) */ 0x20, 0x04, 0x08, 0x10, 0x80, 0x00, 0x00, /* reserved */ 0x00, /* external decode length */ 0x48, /* reserved */ 0x75, 0xb9, 0xfc, /* IRQ routing */ 0x10, 0x03, /* DMA routing */ - /* PnP resources */ - 0x00 + /* Default PnP data */ + 0x0e, 0x63, 0x42, 0x36, 0xff, 0xff, 0xff, 0xff, 0x00 /* hinted by documentation to be just the header */ // clang-format on }; @@ -97,6 +123,7 @@ typedef struct cs423x_t { uint16_t ram_addr; uint16_t eeprom_size : 11; uint16_t pnp_offset; + uint16_t pnp_size; uint8_t type; uint8_t ad1848_type; uint8_t regs[8]; @@ -117,8 +144,10 @@ typedef struct cs423x_t { } cs423x_t; static void cs423x_slam_enable(cs423x_t *dev, uint8_t enable); +static void cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv); static void cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig); static void cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv); +static void cs423x_reset(void *priv); static void cs423x_nvram(cs423x_t *dev, uint8_t save) @@ -130,6 +159,8 @@ cs423x_nvram(cs423x_t *dev, uint8_t save) else (void) !fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, fp); fclose(fp); + } else { + cs423x_log("CS423x: EEPROM data %s failed\n", save ? "save" : "load"); } } @@ -147,17 +178,32 @@ cs423x_read(uint16_t addr, void *priv) ret |= 0x04; break; - case 4: /* Control Indirect Data Register */ - ret = dev->indirect_regs[dev->regs[3]]; + case 3: /* Control Indirect Access Register (CS4236B+) */ + /* Intel VS440FX BIOS tells CS4236 from CS4232 through the upper bits. Setting them is enough. */ + if (dev->type >= CRYSTAL_CS4236) + ret |= 0xf0; + break; + + case 4: /* Control Indirect Data Register (CS4236B+) / Control Data Register (CS4236) */ + if (dev->type >= CRYSTAL_CS4236B) + ret = dev->indirect_regs[dev->regs[3]]; break; case 5: /* Control/RAM Access */ - /* Reading RAM is undocumented; the Windows drivers do so. */ - if (dev->ram_dl == 3) - ret = dev->ram_data[dev->ram_addr++]; + /* Reading RAM is undocumented, but performed by: + - Windows drivers (unknown purpose) + - Intel VS440FX BIOS (PnP ROM checksum recalculation) */ + if (dev->ram_dl == CRYSTAL_RAM_DATA) { + ret = dev->ram_data[dev->ram_addr]; + cs423x_log("CS423x: RAM read(%04X) = %02X\n", dev->ram_addr, ret); + dev->ram_addr++; + } break; - case 7: /* Global Status */ + case 7: /* Global Status (CS4236+) */ + if (dev->type < CRYSTAL_CS4236) + break; + /* Context switching: take active context and interrupt flag, then clear interrupt flag. */ ret &= 0xc0; dev->regs[7] &= 0x80; @@ -175,6 +221,8 @@ cs423x_read(uint16_t addr, void *priv) break; } + cs423x_log("CS423x: read(%X) = %02X\n", reg, ret); + return ret; } @@ -182,53 +230,86 @@ static void cs423x_write(uint16_t addr, uint8_t val, void *priv) { cs423x_t *dev = (cs423x_t *) priv; - uint8_t reg = addr & 0x07; + uint8_t reg = addr & 7; + + cs423x_log("CS423x: write(%X, %02X)\n", reg, val); switch (reg) { + case 0: /* Joystick and Power Control */ + if (dev->type <= CRYSTAL_CS4232) + val &= 0xeb; + if ((dev->type >= CRYSTAL_CS4235) && (addr == 0) && (val & 0x08)) { + /* CS4235+ through X26 backdoor only (hence the addr check): WSS off (one-way trip?) */ + io_removehandler(dev->wss_base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &dev->ad1848); + io_removehandler(dev->wss_base, 4, NULL, NULL, NULL, cs423x_ctxswitch_write, NULL, NULL, dev); + dev->wss_base = 0; + } + break; + case 1: /* EEPROM Interface */ + if (dev->type <= CRYSTAL_CS4232) + val &= 0x37; if (val & 0x04) i2c_gpio_set(dev->i2c, val & 0x01, val & 0x02); break; - case 3: /* Control Indirect Access Register */ + case 2: /* Block Power Down (CS4236+) */ + if (dev->type < CRYSTAL_CS4236) + return; + break; + + case 3: /* Control Indirect Access Register (CS4236B+) */ + if (dev->type < CRYSTAL_CS4236) /* must be writable on CS4236 for the aforementioned VS440FX BIOS check */ + return; val &= 0x0f; break; - case 4: /* Control Indirect Data Register */ + case 4: /* Control Indirect Data Register (CS4236B+) / Control Data Register (CS4236) */ + if (dev->type < CRYSTAL_CS4236) { + return; + } else if (dev->type == CRYSTAL_CS4236) { + val &= 0x40; + break; + } switch (dev->regs[3] & 0x0f) { case 0: /* WSS Master Control */ - if (val & 0x80) + if ((dev->type < CRYSTAL_CS4235) && (val & 0x80)) ad1848_init(&dev->ad1848, dev->ad1848_type); val = 0x00; break; - case 1: /* Version / Chip ID */ - case 7: /* Reserved */ - case 9 ... 15: /* unspecified */ + case 1: /* Version / Chip ID */ + case 7: /* Reserved */ + case 10 ... 15: /* unspecified */ return; - case 2: /* 3D Space and {Center|Volume} */ - case 6: /* Upper Channel Status */ + case 2: /* 3D Space and {Center|Volume} (CS4237B+) */ if (dev->type < CRYSTAL_CS4237B) return; break; - case 3: /* 3D Enable */ + case 3: /* 3D Enable (CS4237B+) */ if (dev->type < CRYSTAL_CS4237B) return; val &= 0xe0; break; - case 4: /* Consumer Serial Port Enable */ + case 4: /* Consumer Serial Port Enable (CS423[78]B, unused on CS4235+) */ if (dev->type < CRYSTAL_CS4237B) return; val &= 0xf0; break; - case 5: /* Lower Channel Status */ + case 5: /* Lower Channel Status (CS423[78]B, unused on CS4235+) */ + if (dev->type < CRYSTAL_CS4237B) + return; + if (dev->type < CRYSTAL_CS4235) /* bit 0 changed from reserved to unused on CS4235 */ + val &= 0xfe; + break; + + case 6: /* Upper Channel Status (CS423[78]B, unused on CS4235+) */ if (dev->type < CRYSTAL_CS4237B) return; - val &= 0xfe; break; case 8: /* CS9236 Wavetable Control */ @@ -240,6 +321,16 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) ad1848_updatevolmask(&dev->ad1848); break; + case 9: /* Power Management (CS4235+) */ + if (dev->type < CRYSTAL_CS4235) + return; + if ((dev->indirect_regs[dev->regs[3]] & 0x80) && !(val & 0x80)) { + cs423x_reset(dev); + return; + } + val &= 0x83; + break; + default: break; } @@ -248,7 +339,7 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) case 5: /* Control/RAM Access */ switch (dev->ram_dl) { - case 0: /* commands */ + case CRYSTAL_RAM_CMD: /* commands */ switch (val) { case 0x55: /* Disable PnP Key */ dev->pnp_enable = 0; @@ -266,7 +357,7 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) break; case 0xaa: /* Download RAM */ - dev->ram_dl = 1; + dev->ram_dl = CRYSTAL_RAM_ADDR_LO; break; default: @@ -274,17 +365,19 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) } break; - case 1: /* low address byte */ + case CRYSTAL_RAM_ADDR_LO: /* low address byte */ dev->ram_addr = val; - dev->ram_dl++; + dev->ram_dl = CRYSTAL_RAM_ADDR_HI; break; - case 2: /* high address byte */ - dev->ram_addr |= (val << 8); - dev->ram_dl++; + case CRYSTAL_RAM_ADDR_HI: /* high address byte */ + dev->ram_addr |= val << 8; + dev->ram_dl = CRYSTAL_RAM_DATA; + cs423x_log("CS423x: RAM start(%04X)\n", dev->ram_addr); break; - case 3: /* data */ + case CRYSTAL_RAM_DATA: /* data */ + cs423x_log("CS423x: RAM write(%04X, %02X)\n", dev->ram_addr, val); dev->ram_data[dev->ram_addr++] = val; break; @@ -296,14 +389,16 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) case 6: /* RAM Access End */ /* TriGem Delhi-III BIOS writes undocumented value 0x40 instead of 0x00. */ if ((val == 0x00) || (val == 0x40)) { - dev->ram_dl = 0; + cs423x_log("CS423x: RAM end\n"); + dev->ram_dl = CRYSTAL_RAM_CMD; /* Update PnP state and resource data. */ + dev->pnp_size = (dev->type >= CRYSTAL_CS4236) ? 384 : 256; /* we don't know the length */ cs423x_pnp_enable(dev, 1, 0); } break; - case 7: /* Global Status */ + case 7: /* Global Status (CS4236+) */ return; default: @@ -319,6 +414,9 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) cs423x_t *dev = (cs423x_t *) priv; uint8_t idx; + if ((dev->slam_state != CRYSTAL_SLAM_NONE) || (val == slam_init_key[dev->key_pos])) /* cut down on ISAPnP-related noise */ + cs423x_log("CS423x: slam_write(%02X)\n", val); + switch (dev->slam_state) { case CRYSTAL_SLAM_NONE: /* Not in SLAM: read and compare Crystal key. */ @@ -333,6 +431,7 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) } /* Enter SLAM. */ + cs423x_log("CS423x: SLAM unlocked\n"); dev->slam_state = CRYSTAL_SLAM_INDEX; } } else { @@ -343,6 +442,8 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) case CRYSTAL_SLAM_INDEX: /* Intercept the Activate Audio Device command. */ if (val == 0x79) { + cs423x_log("CS423x: Exiting SLAM\n"); + /* Apply the last logical device's configuration. */ if (dev->slam_config) { cs423x_pnp_config_changed(dev->slam_ld, dev->slam_config, dev); @@ -363,6 +464,7 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) case CRYSTAL_SLAM_BYTE1: case CRYSTAL_SLAM_BYTE2: /* Write register value: two bytes for I/O ports, single byte otherwise. */ + cs423x_log("CS423x: SLAM write(%02X, %02X)\n", dev->slam_reg, val); switch (dev->slam_reg) { case 0x06: /* Card Select Number */ isapnp_set_csn(dev->pnp_card, val); @@ -373,10 +475,9 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) if (dev->slam_config) cs423x_pnp_config_changed(dev->slam_ld, dev->slam_config, dev); else - dev->slam_config = (isapnp_device_config_t *) malloc(sizeof(isapnp_device_config_t)); + dev->slam_config = (isapnp_device_config_t *) calloc(1, sizeof(isapnp_device_config_t)); /* Start new logical device. */ - memset(dev->slam_config, 0, sizeof(isapnp_device_config_t)); dev->slam_ld = val; break; @@ -433,7 +534,7 @@ cs423x_slam_write(UNUSED(uint16_t addr), uint8_t val, void *priv) break; } - /* Prepare for the next register, unless a two-byte read returns above. */ + /* Prepare for the next register, unless a two-byte write returns above. */ dev->slam_state = CRYSTAL_SLAM_INDEX; break; @@ -454,8 +555,11 @@ cs423x_slam_enable(cs423x_t *dev, uint8_t enable) /* Enable SLAM if the CKD bit is not set. */ if (enable && !(dev->ram_data[0x4002] & 0x10)) { + cs423x_log("CS423x: Enabling SLAM\n"); dev->slam_enable = 1; io_sethandler(0x279, 1, NULL, NULL, NULL, cs423x_slam_write, NULL, NULL, dev); + } else { + cs423x_log("CS423x: Disabling SLAM\n"); } } @@ -471,6 +575,7 @@ cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv) /* Flip context bit. */ dev->regs[7] ^= 0x80; ctx ^= 0x80; + cs423x_log("CS423x: Context switch to %s\n", ctx ? "WSS" : "SBPro"); /* Update CD audio filter. FIXME: not thread-safe: filter function TOCTTOU in sound_cd_thread! */ @@ -501,8 +606,8 @@ cs423x_get_buffer(int32_t *buffer, int len, void *priv) /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ ad1848_update(&dev->ad1848); - /* Don't output anything if the analog section is powered down. */ - if (!(dev->indirect_regs[2] & 0xa4)) { + /* Don't output anything if the analog section or DAC is powered down. */ + if (!(dev->regs[2] & 0xb4) && !(dev->indirect_regs[9] & 0x04)) { for (int c = 0; c < len * 2; c += 2) { buffer[c] += dev->ad1848.buffer[c] / 2; buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2; @@ -515,35 +620,34 @@ cs423x_get_buffer(int32_t *buffer, int len, void *priv) static void cs423x_get_music_buffer(int32_t *buffer, int len, void *priv) { - cs423x_t *dev = (cs423x_t *) priv; - int opl_wss = dev->opl_wss; - const int32_t *opl_buf = NULL; + cs423x_t *dev = (cs423x_t *) priv; /* Output audio from the WSS codec, and also the OPL if we're in charge of it. */ - if (opl_wss) - opl_buf = dev->sb->opl.update(dev->sb->opl.priv); + if (dev->opl_wss) { + const int32_t *opl_buf = dev->sb->opl.update(dev->sb->opl.priv); - /* Don't output anything if the analog section is powered down. */ - if (!(dev->indirect_regs[2] & 0xa4)) { - for (int c = 0; c < len * 2; c += 2) { - if (opl_wss) { + /* Don't output anything if the analog section, DAC (DAC2 instead on CS4235+) or FM synth is powered down. */ + uint8_t bpd_mask = (dev->type >= CRYSTAL_CS4235) ? 0xb1 : 0xb5; + if (!(dev->regs[2] & bpd_mask) && !(dev->indirect_regs[9] & 0x06)) { + for (int c = 0; c < len * 2; c += 2) { buffer[c] += (opl_buf[c] * dev->ad1848.fm_vol_l) >> 16; buffer[c + 1] += (opl_buf[c + 1] * dev->ad1848.fm_vol_r) >> 16; } } - } - if (opl_wss) dev->sb->opl.reset_buffer(dev->sb->opl.priv); + } } static void cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) { + cs423x_log("CS423x: Updating PnP ROM=%d hwconfig=%d\n", update_rom, update_hwconfig); + if (dev->pnp_card) { /* Update PnP resource data if requested. */ if (update_rom) - isapnp_update_card_rom(dev->pnp_card, &dev->ram_data[dev->pnp_offset], 384); + 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 @@ -551,9 +655,10 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) 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); -#endif +#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. */ @@ -568,7 +673,7 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) } /* Update SPS. */ - if (dev->type != CRYSTAL_CS4235) { + if ((dev->type >= CRYSTAL_CS4236B) && (dev->type <= CRYSTAL_CS4238B)) { if (dev->ram_data[0x4003] & 0x04) dev->indirect_regs[8] |= 0x04; else @@ -581,6 +686,20 @@ cs423x_pnp_enable(cs423x_t *dev, uint8_t update_rom, uint8_t update_hwconfig) else dev->ad1848.xregs[4] &= ~0x10; + if (dev->type == CRYSTAL_CS4236) { + /* Update VCEN. */ + if (dev->ram_data[0x4002] & 0x04) + dev->regs[4] |= 0x40; + else + dev->regs[4] &= ~0x40; + } + + if (dev->type >= CRYSTAL_CS4235) { + /* Update X18 and X19 values. */ + dev->ad1848.xregs[18] = (dev->ad1848.xregs[18] & ~0x3e) | (dev->ram_data[0x400b] & 0x3e); + dev->ad1848.xregs[19] = dev->ram_data[0x4005]; + } + /* Inform WSS codec of the changes. */ ad1848_updatevolmask(&dev->ad1848); } @@ -689,6 +808,34 @@ cs423x_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv } } +static void +cs423x_load_defaults(cs423x_t *dev, uint8_t *dest) +{ + switch (dev->type) { + case CRYSTAL_CS4236: + case CRYSTAL_CS4236B: + case CRYSTAL_CS4237B: + case CRYSTAL_CS4238B: + case CRYSTAL_CS4235: + case CRYSTAL_CS4239: + memcpy(dest, cs4236_default, sizeof(cs4236_default)); + dev->pnp_size = 9; /* header-only PnP ROM size */ + + switch (dev->type) { + case CRYSTAL_CS4236: + dest[4] = 0x43; /* code base byte */ + break; + + case CRYSTAL_CS4235: + case CRYSTAL_CS4239: + dest[4] = 0x05; /* code base byte */ + dest[12] = 0x08; /* external decode length */ + break; + } + break; + } +} + static void cs423x_reset(void *priv) { @@ -697,9 +844,20 @@ cs423x_reset(void *priv) /* Clear RAM. */ memset(dev->ram_data, 0, sizeof(dev->ram_data)); + /* Load default configuration data to RAM. */ + cs423x_load_defaults(dev, &dev->ram_data[0x4000]); + if (dev->eeprom) { - /* Load EEPROM data to RAM. */ - memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], MIN(384, ((dev->eeprom_data[2] << 8) | dev->eeprom_data[3]) - 4)); + /* Load EEPROM data to RAM if the magic bytes are present. */ + if ((dev->eeprom_data[0] == 0x55) && (dev->eeprom_data[1] == 0xbb)) { + cs423x_log("CS423x: EEPROM data valid, loading to RAM\n"); + dev->pnp_size = (dev->eeprom_data[2] << 8) | dev->eeprom_data[3]; + if (dev->pnp_size > 384) + dev->pnp_size = 384; + memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4); + } else { + cs423x_log("CS423x: EEPROM data invalid, ignoring\n"); + } /* Save EEPROM contents to file. */ cs423x_nvram(dev, 1); @@ -729,45 +887,60 @@ cs423x_reset(void *priv) static void * cs423x_init(const device_t *info) { - cs423x_t *dev = malloc(sizeof(cs423x_t)); - memset(dev, 0, sizeof(cs423x_t)); + cs423x_t *dev = calloc(1, sizeof(cs423x_t)); /* Initialize model-specific data. */ dev->type = info->local & 0xff; + cs423x_log("CS423x: init(%02X)\n", dev->type); switch (dev->type) { - case CRYSTAL_CS4235: + case CRYSTAL_CS4236: case CRYSTAL_CS4236B: case CRYSTAL_CS4237B: case CRYSTAL_CS4238B: - /* Same WSS codec and EEPROM structure. */ - dev->ad1848_type = (dev->type == CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : AD1848_TYPE_CS4236; - dev->pnp_offset = 0x4013; + case CRYSTAL_CS4235: + case CRYSTAL_CS4239: + /* Different WSS codec families. */ + dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : AD1848_TYPE_CS4236); - /* Different Chip Version and ID registers, which shouldn't be reset by ad1848_init */ + /* Different Chip Version and ID values (N/A on CS4236), which shouldn't be reset by ad1848_init. */ dev->ad1848.xregs[25] = dev->type; - if (!(info->local & CRYSTAL_NOEEPROM)) { - /* Load EEPROM contents from template. */ - memcpy(dev->eeprom_data, cs4236b_eeprom, sizeof(cs4236b_eeprom)); + /* Same EEPROM structure. */ + dev->pnp_offset = 0x4013; + if (!(info->local & CRYSTAL_NOEEPROM)) { + /* Start a new EEPROM with the default configuration data. */ + cs423x_load_defaults(dev, &dev->eeprom_data[4]); + + /* Load PnP resource data ROM. */ FILE *fp = rom_fopen(PNP_ROM_CS4236B, "rb"); if (fp) { - (void) !fread(&(dev->eeprom_data[23]), 1, 8201, fp); + uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x1ff) + 4; + /* This is wrong. The header field only indicates PnP resource data length, and real chips use + it to locate the firmware patch area, but we don't need any of that, so we can get away + with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */ + dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp); fclose(fp); + } else { + dev->pnp_size = 0; } - /* Set content size. */ - dev->eeprom_data[2] = sizeof(cs4236b_eeprom) >> 8; - dev->eeprom_data[3] = sizeof(cs4236b_eeprom) & 0xff; + /* Populate EEPROM header if the PnP ROM was loaded. */ + if (dev->pnp_size) { + dev->eeprom_data[0] = 0x55; + dev->eeprom_data[1] = 0xbb; + dev->eeprom_data[2] = dev->pnp_size >> 8; + dev->eeprom_data[3] = dev->pnp_size; + } - /* Set PnP card ID and EEPROM file name. */ + /* Patch PnP ROM and set EEPROM file name. */ switch (dev->type) { - case CRYSTAL_CS4235: - dev->eeprom_data[8] = 0x05; - dev->eeprom_data[16] = 0x08; - dev->eeprom_data[26] = 0x25; - dev->eeprom_data[44] = '5'; - dev->nvr_path = "cs4235.nvr"; + case CRYSTAL_CS4236: + if (dev->pnp_size) { + dev->eeprom_data[26] = 0x36; + dev->eeprom_data[45] = ' '; + } + dev->nvr_path = "cs4236.nvr"; break; case CRYSTAL_CS4236B: @@ -775,15 +948,37 @@ cs423x_init(const device_t *info) break; case CRYSTAL_CS4237B: - dev->eeprom_data[26] = 0x37; - dev->eeprom_data[44] = '7'; - dev->nvr_path = "cs4237b.nvr"; + if (dev->pnp_size) { + dev->eeprom_data[26] = 0x37; + dev->eeprom_data[44] = '7'; + } + dev->nvr_path = "cs4237b.nvr"; break; case CRYSTAL_CS4238B: - dev->eeprom_data[26] = 0x38; - dev->eeprom_data[44] = '8'; - dev->nvr_path = "cs4238b.nvr"; + if (dev->pnp_size) { + dev->eeprom_data[26] = 0x38; + dev->eeprom_data[44] = '8'; + } + dev->nvr_path = "cs4238b.nvr"; + break; + + case CRYSTAL_CS4235: + if (dev->pnp_size) { + dev->eeprom_data[26] = 0x25; + dev->eeprom_data[44] = '5'; + dev->eeprom_data[45] = ' '; + } + dev->nvr_path = "cs4235.nvr"; + break; + + case CRYSTAL_CS4239: + if (dev->pnp_size) { + dev->eeprom_data[26] = 0x29; + dev->eeprom_data[44] = '9'; + dev->eeprom_data[45] = ' '; + } + dev->nvr_path = "cs4239.nvr"; break; default: @@ -794,9 +989,9 @@ cs423x_init(const device_t *info) cs423x_nvram(dev, 0); } - /* Initialize game port. The '7B and '8B game port only responds to 6 I/O ports; the remaining - 2 ports are reserved on those chips, and probably connected to the Digital Assist feature. */ - dev->gameport = gameport_add(((dev->type == CRYSTAL_CS4235) || (dev->type == CRYSTAL_CS4236B)) ? &gameport_pnp_device : &gameport_pnp_6io_device); + /* Initialize game port. The game port on all B chips only + responds to 6 I/O ports; the remaining 2 are reserved. */ + dev->gameport = gameport_add((dev->ad1848_type == CRYSTAL_CS4236B) ? &gameport_pnp_6io_device : &gameport_pnp_device); break; @@ -807,8 +1002,8 @@ cs423x_init(const device_t *info) /* Initialize I2C bus for the EEPROM. */ dev->i2c = i2c_gpio_init("nvr_cs423x"); - /* Initialize I2C EEPROM if the contents are valid. */ - if ((dev->eeprom_data[0] == 0x55) && (dev->eeprom_data[1] == 0xbb)) + /* Initialize I2C EEPROM if enabled. */ + if (!(info->local & CRYSTAL_NOEEPROM)) dev->eeprom = i2c_eeprom_init(i2c_gpio_get_bus(dev->i2c), 0x50, dev->eeprom_data, sizeof(dev->eeprom_data), 1); /* Initialize ISAPnP. */ @@ -836,6 +1031,8 @@ cs423x_close(void *priv) { cs423x_t *dev = (cs423x_t *) priv; + cs423x_log("CS423x: close()\n"); + /* Save EEPROM contents to file. */ if (dev->eeprom) { cs423x_nvram(dev, 1); @@ -864,12 +1061,12 @@ cs423x_speed_changed(void *priv) const device_t cs4235_device = { .name = "Crystal CS4235", .internal_name = "cs4235", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CRYSTAL_CS4235, .init = cs423x_init, .close = cs423x_close, .reset = cs423x_reset, - { .available = cs423x_available }, + .available = cs423x_available, .speed_changed = cs423x_speed_changed, .force_redraw = NULL, .config = NULL @@ -878,12 +1075,26 @@ const device_t cs4235_device = { const device_t cs4235_onboard_device = { .name = "Crystal CS4235 (On-Board)", .internal_name = "cs4235_onboard", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CRYSTAL_CS4235 | CRYSTAL_NOEEPROM, .init = cs423x_init, .close = cs423x_close, .reset = cs423x_reset, - { .available = cs423x_available }, + .available = cs423x_available, + .speed_changed = cs423x_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t cs4236_onboard_device = { + .name = "Crystal CS4236 (On-Board)", + .internal_name = "cs4236_onboard", + .flags = DEVICE_ISA16, + .local = CRYSTAL_CS4236 | CRYSTAL_NOEEPROM, + .init = cs423x_init, + .close = cs423x_close, + .reset = cs423x_reset, + .available = cs423x_available, .speed_changed = cs423x_speed_changed, .force_redraw = NULL, .config = NULL @@ -892,12 +1103,26 @@ const device_t cs4235_onboard_device = { const device_t cs4236b_device = { .name = "Crystal CS4236B", .internal_name = "cs4236b", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CRYSTAL_CS4236B, .init = cs423x_init, .close = cs423x_close, .reset = cs423x_reset, - { .available = cs423x_available }, + .available = cs423x_available, + .speed_changed = cs423x_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t cs4236b_onboard_device = { + .name = "Crystal CS4236B", + .internal_name = "cs4236b", + .flags = DEVICE_ISA16, + .local = CRYSTAL_CS4236B | CRYSTAL_NOEEPROM, + .init = cs423x_init, + .close = cs423x_close, + .reset = cs423x_reset, + .available = cs423x_available, .speed_changed = cs423x_speed_changed, .force_redraw = NULL, .config = NULL @@ -906,12 +1131,12 @@ const device_t cs4236b_device = { const device_t cs4237b_device = { .name = "Crystal CS4237B", .internal_name = "cs4237b", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CRYSTAL_CS4237B, .init = cs423x_init, .close = cs423x_close, .reset = cs423x_reset, - { .available = cs423x_available }, + .available = cs423x_available, .speed_changed = cs423x_speed_changed, .force_redraw = NULL, .config = NULL @@ -920,12 +1145,12 @@ const device_t cs4237b_device = { const device_t cs4238b_device = { .name = "Crystal CS4238B", .internal_name = "cs4238b", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = CRYSTAL_CS4238B, .init = cs423x_init, .close = cs423x_close, .reset = cs423x_reset, - { .available = cs423x_available }, + .available = cs423x_available, .speed_changed = cs423x_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 5f13d2f8e..822abeeaa 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -328,7 +328,7 @@ emu8k_log(const char *fmt, ...) static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) { - const register emu8k_mem_pointers_t addrmem = { { addr } }; + register const emu8k_mem_pointers_t addrmem = { { addr } }; return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; } @@ -2171,8 +2171,7 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) emu8k->rom[0x7ffff] = 0; } - emu8k->empty = malloc(2 * BLOCK_SIZE_WORDS); - memset(emu8k->empty, 0, 2 * BLOCK_SIZE_WORDS); + emu8k->empty = calloc(2, BLOCK_SIZE_WORDS); int j = 0; for (; j < 0x8; j++) { @@ -2186,8 +2185,7 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) /*Clip to 28MB, since that's the max that we can address. */ if (onboard_ram > 0x7000) onboard_ram = 0x7000; - emu8k->ram = malloc(onboard_ram * 1024); - memset(emu8k->ram, 0, onboard_ram * 1024); + emu8k->ram = calloc(1024, onboard_ram); const int i_end = onboard_ram >> 7; int i = 0; for (; i < i_end; i++, j++) { diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index d0af5c564..43638473c 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -16,9 +16,9 @@ #include <86box/pic.h> #include <86box/sound.h> #include <86box/timer.h> -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX # include <86box/snd_ad1848.h> -#endif +#endif /*USE_GUSMAX */ #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -144,11 +144,11 @@ typedef struct gus_t { uint8_t usrr; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX uint8_t max_ctrl; ad1848_t ad1848; -#endif +#endif /*USE_GUSMAX */ } gus_t; static int gus_gf1_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; @@ -256,9 +256,9 @@ writegus(uint16_t addr, uint8_t val, void *priv) int d; int old; uint16_t port; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX uint16_t csioport; -#endif +#endif /*USE_GUSMAX */ if ((addr == 0x388) || (addr == 0x389)) port = addr; @@ -606,10 +606,10 @@ writegus(uint16_t addr, uint8_t val, void *priv) gus->irq_midi = gus->irq; } else gus->irq_midi = gus_midi_irqs[(val >> 3) & 7]; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if (gus->type == GUS_MAX) ad1848_setirq(&gus->ad1848, gus->irq); -#endif +#endif /*USE_GUSMAX */ gus->sb_nmi = val & 0x80; } else { @@ -622,10 +622,10 @@ writegus(uint16_t addr, uint8_t val, void *priv) gus->dma2 = gus->dma; } else gus->dma2 = gus_dmas[(val >> 3) & 7]; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if (gus->type == GUS_MAX) ad1848_setdma(&gus->ad1848, gus->dma2); -#endif +#endif /*USE_GUSMAX */ } break; case 1: @@ -683,7 +683,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) break; case 0x306: case 0x706: -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if (gus->type == GUS_MAX) { if (gus->dma >= 4) val |= 0x10; @@ -703,7 +703,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) } } } -#endif +#endif /*USE_GUSMAX */ break; default: @@ -755,11 +755,11 @@ readgus(uint16_t addr, void *priv) return val; case 0x20F: -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if (gus->type == GUS_MAX) val = 0x02; else -#endif +#endif /*USE_GUSMAX */ val = 0x00; break; @@ -878,11 +878,11 @@ readgus(uint16_t addr, void *priv) break; case 0x306: case 0x706: -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if (gus->type == GUS_MAX) val = 0x0a; /* GUS MAX */ else -#endif +#endif /*USE_GUSMAX */ val = 0xff; /*Pre 3.7 - no mixer*/ break; @@ -939,7 +939,7 @@ readgus(uint16_t addr, void *priv) gus->ad_status &= ~0x01; #ifdef OLD_NMI_BEHAVIOR nmi = 0; -#endif +#endif /* OLD_NMI_BEHAVIOR */ fallthrough; case 0x389: val = gus->ad_data; @@ -1182,24 +1182,24 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) { gus_t *gus = (gus_t *) priv; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_update(&gus->ad1848); -#endif +#endif /*USE_GUSMAX */ gus_update(gus); for (int c = 0; c < len * 2; c++) { -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); -#endif +#endif /*USE_GUSMAX */ buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; } -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) gus->ad1848.pos = 0; -#endif +#endif /*USE_GUSMAX */ gus->pos = 0; } @@ -1332,9 +1332,9 @@ gus_reset(void *priv) gus->usrr = 0; -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX gus->max_ctrl = 0; -#endif +#endif /*USE_GUSMAX */ gus->irq_state = 0; gus->midi_irq_state = 0; @@ -1348,12 +1348,10 @@ gus_init(UNUSED(const device_t *info)) int c; double out = 1.0; uint8_t gus_ram = device_get_config_int("gus_ram"); - gus_t *gus = malloc(sizeof(gus_t)); - memset(gus, 0x00, sizeof(gus_t)); + gus_t *gus = calloc(1, sizeof(gus_t)); gus->gus_end_ram = 1 << (18 + gus_ram); - gus->ram = (uint8_t *) malloc(gus->gus_end_ram); - memset(gus->ram, 0x00, (gus->gus_end_ram)); + gus->ram = (uint8_t *) calloc(1, gus->gus_end_ram); for (c = 0; c < 32; c++) { gus->ctrl[c] = 1; @@ -1383,7 +1381,7 @@ gus_init(UNUSED(const device_t *info)) io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); ad1848_setirq(&gus->ad1848, 5); @@ -1391,7 +1389,7 @@ gus_init(UNUSED(const device_t *info)) io_sethandler(0x10C + gus->base, 4, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &gus->ad1848); } -#endif +#endif /*USE_GUSMAX */ timer_add(&gus->samp_timer, gus_poll_wave, gus, 1); timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); @@ -1424,116 +1422,91 @@ gus_speed_changed(void *priv) else gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) +#ifdef USE_GUSMAX if ((gus->type == GUS_MAX) && (gus->max_ctrl)) ad1848_speed_changed(&gus->ad1848); -#endif +#endif /*USE_GUSMAX */ } static const device_config_t gus_config[] = { // clang-format off { - .name = "type", - .description = "GUS type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "Classic", - .value = GUS_CLASSIC - }, -#if defined(DEV_BRANCH) && defined(USE_GUSMAX) - { - .description = "MAX", - .value = GUS_MAX - }, -#endif - { NULL } + .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", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "210H", - .value = 0x210 - }, - { - .description = "220H", - .value = 0x220 - }, - { - .description = "230H", - .value = 0x230 - }, - { - .description = "240H", - .value = 0x240 - }, - { - .description = "250H", - .value = 0x250 - }, - { - .description = "260H", - .value = 0x260 - }, + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "210H", .value = 0x210 }, + { .description = "220H", .value = 0x220 }, + { .description = "230H", .value = 0x230 }, + { .description = "240H", .value = 0x240 }, + { .description = "250H", .value = 0x250 }, + { .description = "260H", .value = 0x260 }, + { NULL } }, + .bios = { { 0 } } }, { - .name = "gus_ram", - "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "256 KB", - .value = 0 - }, - { - .description = "512 KB", - .value = 1 - }, - { - .description = "1 MB", - .value = 2 - }, - { NULL } - } + .name = "gus_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "256 KB", .value = 0 }, + { .description = "512 KB", .value = 1 }, + { .description = "1 MB", .value = 2 }, + { NULL } + }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format off }; const device_t gus_device = { - .name = "Gravis UltraSound", + .name = "Gravis UltraSound", .internal_name = "gus", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = gus_init, - .close = gus_close, - .reset = gus_reset, - { .available = NULL }, + .flags = DEVICE_ISA16, + .local = 0, + .init = gus_init, + .close = gus_close, + .reset = gus_reset, + .available = NULL, .speed_changed = gus_speed_changed, - .force_redraw = NULL, - .config = gus_config + .force_redraw = NULL, + .config = gus_config }; diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 8fb526f14..0462818a0 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -7,10 +7,10 @@ #include "cpu.h" #include <86box/86box.h> #include <86box/filters.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> -#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct lpt_dac_t { @@ -82,8 +82,7 @@ dac_get_buffer(int32_t *buffer, int len, void *priv) static void * dac_init(void *lpt) { - lpt_dac_t *lpt_dac = malloc(sizeof(lpt_dac_t)); - memset(lpt_dac, 0, sizeof(lpt_dac_t)); + lpt_dac_t *lpt_dac = calloc(1, sizeof(lpt_dac_t)); lpt_dac->lpt = lpt; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index bd794fffb..875230518 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -7,10 +7,10 @@ #include "cpu.h" #include <86box/86box.h> #include <86box/filters.h> +#include <86box/timer.h> #include <86box/lpt.h> #include <86box/machine.h> #include <86box/sound.h> -#include <86box/timer.h> #include <86box/plat_unused.h> typedef struct dss_t { @@ -115,8 +115,7 @@ dss_callback(void *priv) static void * dss_init(void *lpt) { - dss_t *dss = malloc(sizeof(dss_t)); - memset(dss, 0, sizeof(dss_t)); + dss_t *dss = calloc(1, sizeof(dss_t)); dss->lpt = lpt; diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 21595e373..bec2ed39c 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1804,106 +1804,59 @@ mpu401_standalone_close(void *priv) static const device_config_t mpu401_standalone_config[] = { // clang-format off { - .name = "base", - .description = "MPU-401 Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x330, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x300", - .value = 0x300 - }, - { - .description = "0x320", - .value = 0x320 - }, - { - .description = "0x330", - .value = 0x330 - }, - { - .description = "0x332", - .value = 0x332 - }, - { - .description = "0x334", - .value = 0x334 - }, - { - .description = "0x336", - .value = 0x336 - }, - { - .description = "0x340", - .value = 0x340 - }, - { - .description = "0x350", - .value = 0x350 - }, - { .description = "" } - } + .name = "base", + .description = "MPU-401 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x330, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x250", .value = 0x250 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x320", .value = 0x320 }, + { .description = "0x330", .value = 0x330 }, + { .description = "0x332", .value = 0x332 }, + { .description = "0x334", .value = 0x334 }, + { .description = "0x336", .value = 0x336 }, + { .description = "0x340", .value = 0x340 }, + { .description = "0x350", .value = 0x350 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "MPU-401 IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 2, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 6", - .value = 6 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .name = "irq", + .description = "MPU-401 IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 6", .value = 6 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1912,46 +1865,34 @@ static const device_config_t mpu401_standalone_config[] = { static const device_config_t mpu401_standalone_mca_config[] = { // clang-format off { - .name = "irq", - .description = "MPU-401 IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 9, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 6", - .value = 6 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 9", - .value = 9 - }, - { .description = "" } - } + .name = "irq", + .description = "MPU-401 IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 9, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 4", .value = 4 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 6", .value = 6 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 9", .value = 9 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1965,7 +1906,7 @@ const device_t mpu401_device = { .init = mpu401_standalone_init, .close = mpu401_standalone_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mpu401_standalone_config @@ -1979,7 +1920,7 @@ const device_t mpu401_mca_device = { .init = mpu401_standalone_init, .close = mpu401_standalone_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = mpu401_standalone_mca_config diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index d98b3ccc2..1ee687f1e 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -39,7 +39,22 @@ uint8_t fm_driver_get(int chip_id, fm_drv_t *drv) { switch (chip_id) { - case FM_YM3812: + case FM_YM2149: /* SSG */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2149_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM3526: /* OPL */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym3526_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_Y8950: /* MSX-Audio (OPL with ADPCM) */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&y8950_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM3812: /* OPL2 */ if (fm_driver == FM_DRV_NUKED) { *drv = nuked_opl_drv; drv->priv = device_add_inst(&ym3812_nuked_device, fm_dev_inst[fm_driver][chip_id]++); @@ -49,7 +64,7 @@ fm_driver_get(int chip_id, fm_drv_t *drv) } break; - case FM_YMF262: + case FM_YMF262: /* OPL3 */ if (fm_driver == FM_DRV_NUKED) { *drv = nuked_opl_drv; drv->priv = device_add_inst(&ymf262_nuked_device, fm_dev_inst[fm_driver][chip_id]++); @@ -59,21 +74,115 @@ fm_driver_get(int chip_id, fm_drv_t *drv) } break; - case FM_YMF289B: + case FM_YMF289B: /* OPL3-L */ *drv = ymfm_drv; drv->priv = device_add_inst(&ymf289b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); break; - case FM_YMF278B: + case FM_YMF278B: /* OPL4 */ *drv = ymfm_drv; drv->priv = device_add_inst(&ymf278b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); break; + + case FM_YM2413: /* OPLL */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2413_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2423: /* OPLL-X */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2423_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YMF281: /* OPLLP */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ymf281_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_DS1001: /* Konami VRC7 MMC */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ds1001_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2151: /* OPM */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2151_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2203: /* OPN */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2203_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2608: /* OPNA */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2608_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YMF288: /* OPN3L */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ymf288_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2610: /* OPNB */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2610_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2610B: /* OPNB2 */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2610b_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2612: /* OPN2 */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2612_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM3438: /* OPN2C */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym3438_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YMF276: /* OPN2L */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ymf276_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM2164: /* OPP */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2164_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + + case FM_YM3806: /* OPQ */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym3806_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; + +#if 0 + case FM_YMF271: /* OPX */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ymf271_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; +#endif + + case FM_YM2414: /* OPZ */ + *drv = ymfm_drv; + drv->priv = device_add_inst(&ym2414_ymfm_device, fm_dev_inst[fm_driver][chip_id]++); + break; case FM_ESFM: *drv = esfmu_opl_drv; drv->priv = device_add_inst(&esfm_esfmu_device, fm_dev_inst[fm_driver][chip_id]++); break; +#ifdef USE_LIBSERIALPORT + case FM_OPL2BOARD: + *drv = ymfm_opl2board_drv; + drv->priv = device_add_inst(&ym_opl2board_device, fm_dev_inst[fm_driver][chip_id]++); + break; +#endif + default: return 0; } diff --git a/src/sound/snd_opl2board.c b/src/sound/snd_opl2board.c new file mode 100644 index 000000000..632ad85f1 --- /dev/null +++ b/src/sound/snd_opl2board.c @@ -0,0 +1,195 @@ +/* + * 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. + * + * Interface to the OPL2Board External audio device (USB) + * + * + * Authors: Jose Phillips + * Fred N. van Kempen, + * Miran Grca, + * + * Copyright 2024 Jose Phillips. + * Copyright 2017-2020 Fred N. van Kempen. + * Copyright 2016-2020 Miran Grca. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mca.h> +#include <86box/sound.h> +#include <86box/timer.h> +#include <86box/snd_opl.h> +#include <86box/plat_unused.h> + + +#ifdef ENABLE_OPL2DEVICE_LOG +int opl2board_device_do_log = ENABLE_OPL2DEVICE_LOG; + +static void +opl2board_device_log(const char *fmt, ...) +{ + va_list ap; + + if (opl2board_device_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define opl2board_device_log(fmt, ...) +#endif + +typedef struct opl2board_device_t { + fm_drv_t opl; + uint8_t pos_regs[8]; +} opl2board_device_t; + +static void +opl2board_device_get_buffer(int32_t *buffer, int len, void *priv) +{ + opl2board_device_t *serial = (opl2board_device_t *) priv; + + const int32_t *opl_buf = serial->opl.update(serial->opl.priv); + + for (int c = 0; c < len * 2; c++) + buffer[c] += opl_buf[c]; + + serial->opl.reset_buffer(serial->opl.priv); +} + +uint8_t +opl2board_device_mca_read(int port, void *priv) +{ + const opl2board_device_t *serial = (opl2board_device_t *) priv; + + opl2board_device_log("opl2board_device_mca_read: port=%04x\n", port); + + return serial->pos_regs[port & 7]; +} + +void +opl2board_device_mca_write(int port, uint8_t val, void *priv) +{ + opl2board_device_t *serial = (opl2board_device_t *) priv; + + if (port < 0x102) + return; + + opl2board_device_log("opl2board_device_mca_write: port=%04x val=%02x\n", port, val); + + switch (port) { + case 0x102: + if ((serial->pos_regs[2] & 1) && !(val & 1)) + io_removehandler(0x0388, 0x0002, + serial->opl.read, NULL, NULL, + serial->opl.write, NULL, NULL, + serial->opl.priv); + if (!(serial->pos_regs[2] & 1) && (val & 1)) + io_sethandler(0x0388, 0x0002, + serial->opl.read, NULL, NULL, + serial->opl.write, NULL, NULL, + serial->opl.priv); + break; + + default: + break; + } + + serial->pos_regs[port & 7] = val; +} + +uint8_t +opl2board_device_mca_feedb(void *priv) +{ + const opl2board_device_t *serial = (opl2board_device_t *) priv; + + return (serial->pos_regs[2] & 1); +} + +void * +opl2board_device_init(UNUSED(const device_t *info)) +{ + opl2board_device_t *serial = calloc(1, sizeof(opl2board_device_t)); + + opl2board_device_log("opl2board_device_init\n"); + fm_driver_get(FM_OPL2BOARD, &serial->opl); + io_sethandler(0x0388, 0x0002, + serial->opl.read, NULL, NULL, + serial->opl.write, NULL, NULL, + serial->opl.priv); + music_add_handler(opl2board_device_get_buffer, serial); + + return serial; +} + +void * +opl2board_device_mca_init(const device_t *info) +{ + opl2board_device_t *serial = opl2board_device_init(info); + + io_removehandler(0x0388, 0x0002, + serial->opl.read, NULL, NULL, + serial->opl.write, NULL, NULL, + serial->opl.priv); + mca_add(opl2board_device_mca_read, + opl2board_device_mca_write, + opl2board_device_mca_feedb, + NULL, + serial); + serial->pos_regs[0] = 0xd7; + serial->pos_regs[1] = 0x70; + + return serial; +} + +void +opl2board_device_close(void *priv) +{ + opl2board_device_t *serial = (opl2board_device_t *) priv; + free(serial); +} + + +static const device_config_t opl2board_config[] = { + { + .name = "host_serial_path", + .description = "Host Serial Device", + .type = CONFIG_SERPORT, + .default_string = "", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +const device_t opl2board_device = { + .name = "OPL2Board (External Device)", + .internal_name = "opl2board_device", + .flags = DEVICE_ISA, + .local = 0, + .init = opl2board_device_init, + .close = opl2board_device_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = opl2board_config +}; diff --git a/src/sound/snd_opl_esfm.c b/src/sound/snd_opl_esfm.c index 78cbec11d..bcd2a56e9 100644 --- a/src/sound/snd_opl_esfm.c +++ b/src/sound/snd_opl_esfm.c @@ -34,6 +34,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/snd_opl.h> +#include <86box/plat_unused.h> #define RSM_FRAC 10 @@ -175,7 +176,7 @@ esfm_drv_set_do_cycles(void *priv, int8_t do_cycles) } static void * -esfm_drv_init(const device_t *info) +esfm_drv_init(UNUSED(const device_t *info)) { esfm_drv_t *dev = (esfm_drv_t *) calloc(1, sizeof(esfm_drv_t)); dev->flags = FLAG_CYCLES | FLAG_OPL3; @@ -242,6 +243,7 @@ esfm_drv_read(uint16_t port, void *priv) if (dev->status & STAT_TMR_OVER) ret |= STAT_TMR_ANY; break; + case 0x0001: ret = ESFM_read_port(&dev->opl, port & 3); switch (dev->opl.addr_latch & 0x5ff) { @@ -256,6 +258,7 @@ esfm_drv_read(uint16_t port, void *priv) break; } break; + case 0x0002: case 0x0003: ret = 0xff; @@ -338,18 +341,18 @@ const device_t esfm_esfmu_device = { .init = esfm_drv_init, .close = esfm_drv_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; const fm_drv_t esfmu_opl_drv = { - &esfm_drv_read, - &esfm_drv_write, - &esfm_drv_update, - &esfm_drv_reset_buffer, - &esfm_drv_set_do_cycles, - NULL, - NULL, + .read = &esfm_drv_read, + .write = &esfm_drv_write, + .update = &esfm_drv_update, + .reset_buffer = &esfm_drv_reset_buffer, + .set_do_cycles = &esfm_drv_set_do_cycles, + .priv = NULL, + .generate = NULL, }; diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index f1132867b..03851a589 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -68,9 +68,6 @@ #define RSM_FRAC 10 -// #define OPL_FREQ FREQ_48000 -#define OPL_FREQ FREQ_49716 - // Channel types enum { ch_2op = 0, @@ -1276,7 +1273,7 @@ OPL3_Reset(opl3_chip *chip, uint32_t samplerate) } chip->noise = 1; - chip->rateratio = (samplerate << RSM_FRAC) / 49716; + chip->rateratio = (samplerate << RSM_FRAC) / FREQ_49716; chip->tremoloshift = 4; chip->vibshift = 1; @@ -1538,7 +1535,7 @@ nuked_drv_init(const device_t *info) dev->status = 0x06; /* Initialize the NukedOPL object. */ - OPL3_Reset(&dev->opl, OPL_FREQ); + OPL3_Reset(&dev->opl, FREQ_49716); timer_add(&dev->timers[0], nuked_timer_1, dev, 0); timer_add(&dev->timers[1], nuked_timer_2, dev, 0); @@ -1659,7 +1656,7 @@ const device_t ym3812_nuked_device = { .init = nuked_drv_init, .close = nuked_drv_close, .reset = NULL, - { .available = NULL }, + .available = NULL , .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -1673,18 +1670,18 @@ const device_t ymf262_nuked_device = { .init = nuked_drv_init, .close = nuked_drv_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL }; const fm_drv_t nuked_opl_drv = { - &nuked_drv_read, - &nuked_drv_write, - &nuked_drv_update, - &nuked_drv_reset_buffer, - &nuked_drv_set_do_cycles, - NULL, - NULL, + .read = &nuked_drv_read, + .write = &nuked_drv_write, + .update = &nuked_drv_update, + .reset_buffer = &nuked_drv_reset_buffer, + .set_do_cycles = &nuked_drv_set_do_cycles, + .priv = NULL, + .generate = NULL, }; diff --git a/src/sound/snd_opl_opl2board.cpp b/src/sound/snd_opl_opl2board.cpp new file mode 100644 index 000000000..286e62d4f --- /dev/null +++ b/src/sound/snd_opl_opl2board.cpp @@ -0,0 +1,527 @@ +/* + * 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. + * + * Interface to the YMFM External audio device (USB) + * For OPL2Board arduino based. + * + * Authors: Jose Phillips, + * Adrien Moulin, + * + * Copyright 2024 Jose Phillips. + * Copyright 2022 Adrien Moulin. + */ +#include +#include +#include +#include +#include +#include "ymfm/ymfm_opl.h" +#include + +extern "C" { +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/sound.h> +#include <86box/snd_opl.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/plat_unused.h> +#include <86box/config.h> +#include <86box/ini.h> +#include <86box/device.h> + +// Disable c99-designator to avoid the warnings in *_ymfm_device +#ifdef __clang__ +# if __has_warning("-Wc99-designator") +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wc99-designator" +# endif +#endif +} + +#define RSM_FRAC 10 + +enum { + FLAG_CYCLES = (1 << 0) +}; + +uint8_t lastval = 0x00; + +class OPLBOARDChipBase { +public: + OPLBOARDChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate) + : m_buf_pos(0) + , m_flags(0) + , m_type(type) + , m_samplerate(samplerate) + { + memset(m_buffer, 0, sizeof(m_buffer)); + } + + virtual ~OPLBOARDChipBase() + { + } + + fm_type type() const { return m_type; } + int8_t flags() const { return m_flags; } + void set_do_cycles(int8_t do_cycles) { do_cycles ? m_flags |= FLAG_CYCLES : m_flags &= ~FLAG_CYCLES; } + int32_t *buffer() const { return (int32_t *) m_buffer; } + void reset_buffer() { m_buf_pos = 0; } + + virtual uint32_t sample_rate() const = 0; + + virtual void write(uint16_t addr, uint8_t data) = 0; + virtual void generate(int32_t *data, uint32_t num_samples) = 0; + virtual int32_t *update() = 0; + virtual uint8_t read(uint16_t addr) = 0; + virtual void set_clock(uint32_t clock) = 0; + +protected: + int32_t m_buffer[MUSICBUFLEN * 2]; + int m_buf_pos; + int *m_buf_pos_global; + int8_t m_flags; + fm_type m_type; + uint32_t m_samplerate; +}; + +template +class OPLBOARDChip : public OPLBOARDChipBase, public ymfm::ymfm_interface { +public: + OPLBOARDChip(uint32_t clock, fm_type type, uint32_t samplerate) + : OPLBOARDChipBase(clock, type, samplerate) + , m_chip(*this) + , m_clock(clock) + , m_samplerate(samplerate) + , m_samplecnt(0) + { + memset(m_samples, 0, sizeof(m_samples)); + memset(m_oldsamples, 0, sizeof(m_oldsamples)); + m_rateratio = (samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); + m_clock_us = 1000000.0 / (double) m_clock; + m_subtract[0] = 80.0; + m_subtract[1] = 320.0; + m_type = type; + m_buf_pos_global = (samplerate == FREQ_49716) ? &music_pos_global : &wavetable_pos_global; + + if (m_type == FM_YMF278B) { + if (rom_load_linear("roms/sound/yamaha/yrw801.rom", 0, 0x200000, 0, m_yrw801) == 0) { + fatal("YRW801 ROM image \"roms/sound/yamaha/yrw801.rom\" not found\n"); + } + } + + timer_add(&m_timers[0], OPLBOARDChip::timer1, this, 0); + timer_add(&m_timers[1], OPLBOARDChip::timer2, this, 0); + } + + virtual uint32_t sample_rate() const override + { + return m_chip.sample_rate(m_clock); + } + + virtual void ymfm_set_timer(uint32_t tnum, int32_t duration_in_clocks) override + { + if (tnum > 1) + return; + + m_duration_in_clocks[tnum] = duration_in_clocks; + pc_timer_t *timer = &m_timers[tnum]; + if (duration_in_clocks < 0) + timer_stop(timer); + else { + double period = m_clock_us * duration_in_clocks; + if (period < m_subtract[tnum]) + m_engine->engine_timer_expired(tnum); + else + timer_on_auto(timer, period); + } + } + + virtual void set_clock(uint32_t clock) override + { + m_clock = clock; + m_clock_us = 1000000.0 / (double) m_clock; + m_rateratio = (m_samplerate << RSM_FRAC) / m_chip.sample_rate(m_clock); + + ymfm_set_timer(0, m_duration_in_clocks[0]); + ymfm_set_timer(1, m_duration_in_clocks[1]); + } + + virtual void generate(int32_t *data, uint32_t num_samples) override + { + for (uint32_t i = 0; i < num_samples; i++) { + m_chip.generate(&m_output); + if ((m_type == FM_YMF278B) && (sizeof(m_output.data) > (4 * sizeof(int32_t)))) { + if (ChipType::OUTPUTS == 1) { + *data++ = m_output.data[4]; + *data++ = m_output.data[4]; + } else { + *data++ = m_output.data[4]; + *data++ = m_output.data[5]; + } + } else if (ChipType::OUTPUTS == 1) { + *data++ = m_output.data[0]; + *data++ = m_output.data[0]; + } else { + *data++ = m_output.data[0]; + *data++ = m_output.data[1 % ChipType::OUTPUTS]; + } + } + } + +#if 0 + virtual void generate_resampled(int32_t *data, uint32_t num_samples) override + { + if ((m_samplerate == FREQ_49716) || (m_samplerate == FREQ_44100)) { + generate(data, num_samples); + return; + } + + for (uint32_t i = 0; i < num_samples; i++) { + while (m_samplecnt >= m_rateratio) { + m_oldsamples[0] = m_samples[0]; + m_oldsamples[1] = m_samples[1]; + m_chip.generate(&m_output); + if ((m_type == FM_YMF278B) && (sizeof(m_output.data) > (4 * sizeof(int32_t)))) { + if (ChipType::OUTPUTS == 1) { + m_samples[0] = m_output.data[4]; + m_samples[1] = m_output.data[4]; + } else { + m_samples[0] = m_output.data[4]; + m_samples[1] = m_output.data[5]; + } + } else if (ChipType::OUTPUTS == 1) { + m_samples[0] = m_output.data[0]; + m_samples[1] = m_output.data[0]; + } else { + m_samples[0] = m_output.data[0]; + m_samples[1] = m_output.data[1 % ChipType::OUTPUTS]; + } + m_samplecnt -= m_rateratio; + } + + *data++ = ((int32_t) ((m_oldsamples[0] * (m_rateratio - m_samplecnt) + + m_samples[0] * m_samplecnt) + / m_rateratio)); + *data++ = ((int32_t) ((m_oldsamples[1] * (m_rateratio - m_samplecnt) + + m_samples[1] * m_samplecnt) + / m_rateratio)); + + m_samplecnt += 1 << RSM_FRAC; + } + } +#endif + + virtual int32_t *update() override + { + if (m_buf_pos >= *m_buf_pos_global) + return m_buffer; + + generate(&m_buffer[m_buf_pos * 2], *m_buf_pos_global - m_buf_pos); + + for (; m_buf_pos < *m_buf_pos_global; m_buf_pos++) { + m_buffer[m_buf_pos * 2] /= 2; + m_buffer[(m_buf_pos * 2) + 1] /= 2; + } + + return m_buffer; + } + + virtual void write(uint16_t addr, uint8_t data) override + { + m_chip.write(addr, data); + } + + virtual uint8_t read(uint16_t addr) override + { + return m_chip.read(addr); + } + + virtual uint32_t get_special_flags(void) override + { + return ((m_type == FM_YMF262) || (m_type == FM_YMF289B) || (m_type == FM_YMF278B)) ? 0x8000 : 0x0000; + } + + static void timer1(void *priv) + { + OPLBOARDChip *drv = (OPLBOARDChip *) priv; + drv->m_engine->engine_timer_expired(0); + } + + static void timer2(void *priv) + { + OPLBOARDChip *drv = (OPLBOARDChip *) priv; + drv->m_engine->engine_timer_expired(1); + } + + virtual uint8_t ymfm_external_read(ymfm::access_class type, uint32_t address) override + { + if (type == ymfm::access_class::ACCESS_PCM && address < 0x200000) { + return m_yrw801[address]; + } + return 0xFF; + } + +private: + ChipType m_chip; + uint32_t m_clock; + double m_clock_us; + double m_subtract[2]; + typename ChipType::output_data m_output; + pc_timer_t m_timers[2]; + int32_t m_duration_in_clocks[2]; // Needed for clock switches. + uint32_t m_samplerate; + + // YRW801-M wavetable ROM. + uint8_t m_yrw801[0x200000]; + + // Resampling + int32_t m_rateratio; + int32_t m_samplecnt; + int32_t m_oldsamples[2]; + int32_t m_samples[2]; +}; + +extern "C" { +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include "cpu.h" +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/snd_opl.h> +#include <86box/device.h> +#include <86box/config.h> +#include <86box/ini.h> + +#ifdef ENABLE_OPL_LOG +int oplboard_do_log = ENABLE_OPL_LOG; + +static void +oplboard_log(const char *fmt, ...) +{ + va_list ap; + + if (oplboard_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define oplboard_log(fmt, ...) +#endif + +struct sp_port *port; + +void opl2board_init() { + device_add(&opl2board_device); + const char* port_name = device_get_config_string("host_serial_path"); + device_context_restore(); + + enum sp_return result; + + result = sp_get_port_by_name(port_name, &port); + if (result != SP_OK) { + oplboard_log("Error: Cannot find port %s\n", port_name); + return; + } + + result = sp_open(port, SP_MODE_READ_WRITE); + if (result != SP_OK) { + oplboard_log ("Error: Cannot open port %s\n", port_name); + return; + } + + // Set port configuration this values are hardcoded. + sp_set_baudrate(port, 115200); + sp_set_bits(port, 8); + sp_set_parity(port, SP_PARITY_NONE); + sp_set_stopbits(port, 1); + sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE); + + oplboard_log("OPL2Board Serial port %s initialized at 115200 baud.\n", port_name); +} + +void opl2board_write(uint8_t data) { + if (port == NULL) { + oplboard_log(stderr, "Error: OPL2Board Port not initialized.\n"); + + return; + } + + enum sp_return result = sp_blocking_write(port, &data, sizeof(data), 1000); + if (result < 0) { + oplboard_log(stderr, "Error: Failed to write to OPL2Board port.\n"); + } else { + oplboard_log("OPL2Board: data sent: %02X\n", data); + } +} + +void opl2board_reset() { + + // Reset all voices to 0 + oplboard_log("Performing OPL2Board reset\n"); + for (uint8_t i = 0x00; i < 0xFF; i++) { + if (i >= 0x40 && i <= 0x55) { + opl2board_write(i); + opl2board_write(0x3F); + } else { + opl2board_write (i); + opl2board_write(0x00); + } } +} + +void opl2board_close() { + + if (port != NULL) { + opl2board_reset(); + sp_close(port); + sp_free_port(port); + port = NULL; + oplboard_log("OPL2Board port closed.\n"); + } +} + +static void * +ymfm_opl2board_drv_init(const device_t *info) +{ + OPLBOARDChipBase *fm; + + switch (info->local) { + default: + case FM_OPL2BOARD: + fm = (OPLBOARDChipBase *) new OPLBOARDChip(3579545, FM_OPL2BOARD, FREQ_49716); + break; + } + fm->set_do_cycles(1); + + return fm; +} + +static void +ymfm_opl2board_drv_close(void *priv) +{ + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + opl2board_close(); + if (drv != NULL) + delete drv; +} + +static uint8_t +ymfm_opl2board_drv_read(uint16_t port, void *priv) +{ + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + if ((port == 0x380) || (port == 0x381)) + port |= 4; + + /* Point to register read port. */ + if (drv->flags() & FLAG_CYCLES) + cycles -= ((int) (isa_timing * 8)); + + uint8_t ret = drv->read(port); + drv->update(); + + oplboard_log("OPLBoard read port %04x, status = %02x\n", port, ret); + return ret; +} + +static void +ymfm_opl2board_drv_write(uint16_t port, uint8_t val, void *priv) +{ + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + oplboard_log("OPLBoard write port %04x value = %02x\n", port, val); + if ((port == 0x380) || (port == 0x381)) + port |= 4; + // Allow initialization of adlib + if ((val == 0x04 || val == 0x02) || (lastval == 0x04 || lastval == 0x02)) + drv->write(port, val); + + lastval = val; + opl2board_write(val); + drv->update(); +} + +static int32_t * +ymfm_opl2board_drv_update(void *priv) +{ + if (port == NULL) { + opl2board_init(); + opl2board_reset(); + } + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + return drv->update(); +} + +static void +ymfm_opl2board_drv_reset_buffer(void *priv) +{ + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + drv->reset_buffer(); +} + +static void +ymfm_opl2board_drv_set_do_cycles(void *priv, int8_t do_cycles) +{ + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + drv->set_do_cycles(do_cycles); +} + +static void +ymfm_opl2board_drv_generate(void *priv, int32_t *data, uint32_t num_samples) +{ + OPLBOARDChipBase *drv = (OPLBOARDChipBase *) priv; + + // drv->generate_resampled(data, num_samples); + drv->generate(data, num_samples); +} + +const device_t ym_opl2board_device = { + .name = "YMOPL2Board (External Device)", + .internal_name = "ym_opl2board_device", + .flags = 0, + .local = FM_OPL2BOARD, + .init = ymfm_opl2board_drv_init, + .close = ymfm_opl2board_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const fm_drv_t ymfm_opl2board_drv { + .read = &ymfm_opl2board_drv_read, + .write = &ymfm_opl2board_drv_write, + .update = &ymfm_opl2board_drv_update, + .reset_buffer = &ymfm_opl2board_drv_reset_buffer, + .set_do_cycles = &ymfm_opl2board_drv_set_do_cycles, + .priv = NULL, + .generate = ymfm_opl2board_drv_generate +}; + +#ifdef __clang__ +# if __has_warning("-Wc99-designator") +# pragma clang diagnostic pop +# endif +#endif + +} diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index ccd77ed39..fb00401d5 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -18,7 +18,16 @@ #include #include #include +#include "ymfm/ymfm_ssg.h" +#include "ymfm/ymfm_misc.h" #include "ymfm/ymfm_opl.h" +#include "ymfm/ymfm_opm.h" +#include "ymfm/ymfm_opn.h" +#include "ymfm/ymfm_opq.h" +#if 0 +#include "ymfm/ymfm_opx.h" +#endif +#include "ymfm/ymfm_opz.h" extern "C" { #define HAVE_STDARG_H @@ -38,13 +47,10 @@ extern "C" { # pragma clang diagnostic ignored "-Wc99-designator" # endif #endif - } #define RSM_FRAC 10 -#define OPL_FREQ FREQ_48000 - enum { FLAG_CYCLES = (1 << 0) }; @@ -322,24 +328,126 @@ ymfm_drv_init(const device_t *info) YMFMChipBase *fm; switch (info->local) { + case FM_YM2149: /* OPL */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2149, FREQ_49716); + break; + + case FM_YM3526: /* OPL */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3526, FREQ_49716); + break; + + case FM_Y8950: /* MSX-Audio (OPL with ADPCM) */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_Y8950, FREQ_49716); + break; + default: - case FM_YM3812: + case FM_YM3812: /* OPL2 */ fm = (YMFMChipBase *) new YMFMChip(3579545, FM_YM3812, FREQ_49716); break; - case FM_YMF262: + case FM_YMF262: /* OPL3 */ fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF262, FREQ_49716); break; - case FM_YMF289B: + case FM_YMF289B: /* OPL3-L */ /* According to the datasheet, we should be using 33868800, but YMFM appears to cheat and does it using the same values as the YMF262. */ fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF289B, FREQ_49716); break; - case FM_YMF278B: + case FM_YMF278B: /* OPL4 */ fm = (YMFMChipBase *) new YMFMChip(33868800, FM_YMF278B, FREQ_44100); break; + + case FM_YM2413: /* OPLL */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2413, FREQ_49716); + break; + + case FM_YM2423: /* OPLL-X */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2423, FREQ_49716); + break; + + case FM_YMF281: /* OPLLP */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF281, FREQ_49716); + break; + + case FM_DS1001: /* Konami VRC7 MMC */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_DS1001, FREQ_49716); + break; + + case FM_YM2151: /* OPM */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2151, FREQ_49716); + break; + + case FM_YM2203: /* OPN */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2203, FREQ_49716); + break; + + case FM_YM2608: /* OPNA */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2608, FREQ_49716); + break; + + case FM_YMF288: /* OPN3L */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF288, FREQ_49716); + break; + + case FM_YM2610: /* OPNB */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2610, FREQ_49716); + break; + + case FM_YM2610B: /* OPNB2 */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2610B, FREQ_49716); + break; + + case FM_YM2612: /* OPN2 */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2612, FREQ_49716); + break; + + case FM_YM3438: /* OPN2C */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3438, FREQ_49716); + break; + + case FM_YMF276: /* OPN2L */ + // TODO: Check function call, rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF276, FREQ_49716); + break; + + case FM_YM2164: /* OPP */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2164, FREQ_49716); + break; + + case FM_YM3806: /* OPQ */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM3806, FREQ_49716); + break; + +#if 0 + case FM_YMF271: /* OPX */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YMF271, FREQ_49716); + break; +#endif + + case FM_YM2414: /* OPZ */ + // TODO: Check rates and frequency + fm = (YMFMChipBase *) new YMFMChip(14318181, FM_YM2414, FREQ_49716); + break; } fm->set_do_cycles(1); @@ -379,6 +487,7 @@ static void ymfm_drv_write(uint16_t port, uint8_t val, void *priv) { YMFMChipBase *drv = (YMFMChipBase *) priv; + ymfm_log("YMFM write port %04x value = %02x\n", port, val); if ((port == 0x380) || (port == 0x381)) port |= 4; @@ -406,6 +515,7 @@ static void ymfm_drv_set_do_cycles(void *priv, int8_t do_cycles) { YMFMChipBase *drv = (YMFMChipBase *) priv; + drv->set_do_cycles(do_cycles); } @@ -413,10 +523,53 @@ static void ymfm_drv_generate(void *priv, int32_t *data, uint32_t num_samples) { YMFMChipBase *drv = (YMFMChipBase *) priv; + // drv->generate_resampled(data, num_samples); drv->generate(data, num_samples); } +const device_t ym2149_ymfm_device = { + .name = "Yamaha 2149 SSG (YMFM)", + .internal_name = "ym2149_ymfm", + .flags = 0, + .local = FM_YM2149, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym3526_ymfm_device = { + .name = "Yamaha YM3526 OPL (YMFM)", + .internal_name = "ym3526_ymfm", + .flags = 0, + .local = FM_YM3526, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t y8950_ymfm_device = { + .name = "Yamaha Y8950 (YMFM)", + .internal_name = "y8950_ymfm", + .flags = 0, + .local = FM_Y8950, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t ym3812_ymfm_device = { .name = "Yamaha YM3812 OPL2 (YMFM)", .internal_name = "ym3812_ymfm", @@ -473,14 +626,255 @@ const device_t ymf278b_ymfm_device = { .config = NULL }; +const device_t ym2413_ymfm_device = { + .name = "Yamaha YM2413 OPLL (YMFM)", + .internal_name = "ym2413_ymfm", + .flags = 0, + .local = FM_YM2413, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2423_ymfm_device = { + .name = "Yamaha YM2423 OPLL-X (YMFM)", + .internal_name = "ym2423_ymfm", + .flags = 0, + .local = FM_YM2423, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ymf281_ymfm_device = { + .name = "Yamaha YMF281 OPLLP (YMFM)", + .internal_name = "ymf281_ymfm", + .flags = 0, + .local = FM_YMF281, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ds1001_ymfm_device = { + .name = "Konami VRC7 MMC (YMFM)", + .internal_name = "ds1001_ymfm", + .flags = 0, + .local = FM_DS1001, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2151_ymfm_device = { + .name = "Yamaha YM2151 OPM (YMFM)", + .internal_name = "ym2151_ymfm", + .flags = 0, + .local = FM_YM2151, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2203_ymfm_device = { + .name = "Yamaha YM2203 OPN (YMFM)", + .internal_name = "ym2203_ymfm", + .flags = 0, + .local = FM_YM2203, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2608_ymfm_device = { + .name = "Yamaha YM2608 OPNA (YMFM)", + .internal_name = "ym2608_ymfm", + .flags = 0, + .local = FM_YM2608, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ymf288_ymfm_device = { + .name = "Yamaha YMF288 OPN3L (YMFM)", + .internal_name = "ymf288_ymfm", + .flags = 0, + .local = FM_YMF288, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2610_ymfm_device = { + .name = "Yamaha YM2610 OPNB (YMFM)", + .internal_name = "ym2610_ymfm", + .flags = 0, + .local = FM_YM2610, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2610b_ymfm_device = { + .name = "Yamaha YM2610b OPNB2 (YMFM)", + .internal_name = "ym2610b_ymfm", + .flags = 0, + .local = FM_YM2610B, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2612_ymfm_device = { + .name = "Yamaha YM2612 OPN2 (YMFM)", + .internal_name = "ym2612_ymfm", + .flags = 0, + .local = FM_YM2612, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym3438_ymfm_device = { + .name = "Yamaha YM3438 OPN2C (YMFM)", + .internal_name = "ym3438_ymfm", + .flags = 0, + .local = FM_YM3438, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ymf276_ymfm_device = { + .name = "Yamaha YMF276 OPN2L (YMFM)", + .internal_name = "ymf276_ymfm", + .flags = 0, + .local = FM_YMF276, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym2164_ymfm_device = { + .name = "Yamaha YM2164 OPP (YMFM)", + .internal_name = "ym2164_ymfm", + .flags = 0, + .local = FM_YM2164, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ym3806_ymfm_device = { + .name = "Yamaha YM3806 OPQ (YMFM)", + .internal_name = "ym3806_ymfm", + .flags = 0, + .local = FM_YM3806, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +#if 0 +const device_t ymf271_ymfm_device = { + .name = "Yamaha YMF271 OPX (YMFM)", + .internal_name = "ym271_ymfm", + .flags = 0, + .local = FM_YMF271, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; +#endif + +const device_t ym2414_ymfm_device = { + .name = "Yamaha YM2414 OPZ (YMFM)", + .internal_name = "ym2414_ymfm", + .flags = 0, + .local = FM_YM2414, + .init = ymfm_drv_init, + .close = ymfm_drv_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + + const fm_drv_t ymfm_drv { - &ymfm_drv_read, - &ymfm_drv_write, - &ymfm_drv_update, - &ymfm_drv_reset_buffer, - &ymfm_drv_set_do_cycles, - NULL, - ymfm_drv_generate, + .read = &ymfm_drv_read, + .write = &ymfm_drv_write, + .update = &ymfm_drv_update, + .reset_buffer = &ymfm_drv_reset_buffer, + .set_do_cycles = &ymfm_drv_set_do_cycles, + .priv = NULL, + .generate = ymfm_drv_generate, }; #ifdef __clang__ diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index 3b649639a..d0b05741a 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -394,7 +394,7 @@ optimc_init(const device_t *info) optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262; sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B); - sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc); + sb_dsp_init(&optimc->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, optimc); sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); @@ -419,8 +419,7 @@ optimc_init(const device_t *info) music_add_handler(sb_get_music_buffer_sbpro, optimc->sb); sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ - optimc->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(optimc->mpu, 0, sizeof(mpu_t)); + optimc->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(optimc->mpu, optimc->cur_mpu401_addr, optimc->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401")); if (device_get_config_int("receive_input")) @@ -457,18 +456,26 @@ mirosound_pcm10_available(void) static const device_config_t optimc_config[] = { // clang-format off { - .name = "receive_input", - .description = "Receive input (SB MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 @@ -477,12 +484,12 @@ static const device_config_t optimc_config[] = { const device_t acermagic_s20_device = { .name = "AcerMagic S20", .internal_name = "acermagic_s20", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0xE3 | OPTIMC_CS4231, .init = optimc_init, .close = optimc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = optimc_speed_changed, .force_redraw = NULL, .config = optimc_config @@ -491,12 +498,12 @@ const device_t acermagic_s20_device = { const device_t mirosound_pcm10_device = { .name = "miroSOUND PCM10", .internal_name = "mirosound_pcm10", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0xE3 | OPTIMC_OPL4, .init = optimc_init, .close = optimc_close, .reset = NULL, - { .available = mirosound_pcm10_available }, + .available = mirosound_pcm10_available, .speed_changed = optimc_speed_changed, .force_redraw = NULL, .config = optimc_config diff --git a/src/sound/snd_pas16.c b/src/sound/snd_pas16.c index 80a2c9a7b..353f9a3d5 100644 --- a/src/sound/snd_pas16.c +++ b/src/sound/snd_pas16.c @@ -86,6 +86,7 @@ * Copyright 2008-2024 Sarah Walker. * Copyright 2024 Miran Grca. */ +#define _USE_MATH_DEFINES #include #include #include @@ -705,6 +706,7 @@ static uint8_t pas16_in(uint16_t port, void *priv) { pas16_t *pas16 = (pas16_t *) priv; + scsi_bus_t *scsi_bus = NULL; uint8_t ret = 0xff; port -= pas16->base; @@ -783,9 +785,11 @@ pas16_in(uint16_t port, void *priv) ret = t128_read(0x1e00, pas16->scsi); break; case 0x5c01: - if (pas16->has_scsi) + if (pas16->has_scsi) { + scsi_bus = &pas16->scsi->ncr.scsibus; /* Bits 0-6 must absolutely be set for SCSI hard disk drivers to work. */ - ret = (((pas16->scsi->ncr.dma_mode != DMA_IDLE) && (pas16->scsi->status & 0x04)) << 7) | 0x7f; + ret = (((scsi_bus->tx_mode != PIO_TX_BUS) && (pas16->scsi->status & 0x04)) << 7) | 0x7f; + } break; case 0x5c03: if (pas16->has_scsi) @@ -1020,7 +1024,7 @@ pas16_nsc_mixer_reset(nsc_mixer_t *mixer) mixer->lmc1982_regs[LMC1982_REG_ISELECT] = 0x01; mixer->lmc1982_regs[LMC1982_REG_LES] = 0x00; mixer->lmc1982_regs[LMC1982_REG_BASS] = mixer->lmc1982_regs[LMC1982_REG_TREBLE] = 0x06; - mixer->lmc1982_regs[LMC1982_REG_VOL_L] = mixer->lmc1982_regs[LMC1982_REG_VOL_R] = 0x28; + mixer->lmc1982_regs[LMC1982_REG_VOL_L] = mixer->lmc1982_regs[LMC1982_REG_VOL_R] = 0x00; /*0x28*/ /*Note by TC1995: otherwise the volume gets lowered too much*/ mixer->lmc1982_regs[LMC1982_REG_MODE] = 0x05; lmc1982_recalc(mixer); @@ -1182,10 +1186,11 @@ pas16_scsi_callback(void *priv) { pas16_t * pas16 = (pas16_t *) priv; t128_t * dev = pas16->scsi; + scsi_bus_t * scsi_bus = &dev->ncr.scsibus; t128_callback(pas16->scsi); - if ((dev->ncr.dma_mode != DMA_IDLE) && (dev->status & 0x04)) { + if ((scsi_bus->tx_mode != PIO_TX_BUS) && (dev->status & 0x04)) { timer_stop(&pas16->scsi_timer); pas16->timeout_status &= 0x7f; } @@ -1666,7 +1671,7 @@ pas16_out(uint16_t port, uint8_t val, void *priv) - A 16-bit sample always takes two ctr_clock() ticks. */ static uint16_t -pas16_dma_channel_read(pas16_t *pas16, int channel) +pas16_dma_channel_read(pas16_t *pas16, UNUSED(int channel)) { int status; uint16_t ret; @@ -2314,9 +2319,8 @@ pas16_init(const device_t *info) pas16->has_scsi = (!pas16->type) || (pas16->type == 0x0f); fm_driver_get(FM_YMF262, &pas16->opl); sb_dsp_set_real_opl(&pas16->dsp, 1); - sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); - pas16->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(pas16->mpu, 0, sizeof(mpu_t)); + sb_dsp_init(&pas16->dsp, SB_DSP_201, SB_SUBTYPE_DEFAULT, pas16); + pas16->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(pas16->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&pas16->dsp, pas16->mpu); @@ -2397,25 +2401,37 @@ pas16_close(void *priv) static const device_config_t pas16_config[] = { { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (PAS MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -2428,7 +2444,7 @@ const device_t pasplus_device = { .init = pas16_init, .close = pas16_close, .reset = pas16_reset, - { .available = NULL }, + .available = NULL, .speed_changed = pas16_speed_changed, .force_redraw = NULL, .config = pas16_config @@ -2437,12 +2453,12 @@ const device_t pasplus_device = { const device_t pas16_device = { .name = "Pro Audio Spectrum 16", .internal_name = "pas16", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x0f, .init = pas16_init, .close = pas16_close, .reset = pas16_reset, - { .available = NULL }, + .available = NULL, .speed_changed = pas16_speed_changed, .force_redraw = NULL, .config = pas16_config @@ -2451,12 +2467,12 @@ const device_t pas16_device = { const device_t pas16d_device = { .name = "Pro Audio Spectrum 16D", .internal_name = "pas16d", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x0c, .init = pas16_init, .close = pas16_close, .reset = pas16_reset, - { .available = NULL }, + .available = NULL, .speed_changed = pas16_speed_changed, .force_redraw = NULL, .config = pas16_config diff --git a/src/sound/snd_ps1.c b/src/sound/snd_ps1.c index 60b4515f8..15cad0051 100644 --- a/src/sound/snd_ps1.c +++ b/src/sound/snd_ps1.c @@ -166,8 +166,7 @@ ps1snd_get_buffer(int32_t *buffer, int len, void *priv) static void * ps1snd_init(UNUSED(const device_t *info)) { - ps1snd_t *ps1snd = malloc(sizeof(ps1snd_t)); - memset(ps1snd, 0x00, sizeof(ps1snd_t)); + ps1snd_t *ps1snd = calloc(1, sizeof(ps1snd_t)); sn76489_init(&ps1snd->sn76489, 0x0205, 0x0001, SN76496, 4000000); @@ -203,7 +202,7 @@ const device_t ps1snd_device = { .init = ps1snd_init, .close = ps1snd_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 1e6f48ae3..7de8ec824 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -193,8 +193,7 @@ pssj_get_buffer(int32_t *buffer, int len, void *priv) void * pssj_init(UNUSED(const device_t *info)) { - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); + pssj_t *pssj = calloc(1, sizeof(pssj_t)); sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); @@ -208,8 +207,7 @@ pssj_init(UNUSED(const device_t *info)) void * pssj_1e0_init(UNUSED(const device_t *info)) { - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); + pssj_t *pssj = calloc(1, sizeof(pssj_t)); sn76489_init(&pssj->sn76489, 0x01e0, 0x0004, PSSJ, 3579545); @@ -223,8 +221,7 @@ pssj_1e0_init(UNUSED(const device_t *info)) void * pssj_isa_init(UNUSED(const device_t *info)) { - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); + pssj_t *pssj = calloc(1, sizeof(pssj_t)); uint16_t addr = device_get_config_hex16("base"); @@ -248,40 +245,23 @@ pssj_close(void *priv) static const device_config_t pssj_isa_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x2C0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x0C0", - .value = 0x0C0 - }, - { - .description = "0x0E0", - .value = 0x0E0 - }, - { - .description = "0x1C0", - .value = 0x1C0 - }, - { - .description = "0x1E0", - .value = 0x1E0 - }, - { - .description = "0x2C0", - .value = 0x2C0 - }, - { - .description = "0x2E0", - .value = 0x2E0 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x2C0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x0C0", .value = 0x0C0 }, + { .description = "0x0E0", .value = 0x0E0 }, + { .description = "0x1C0", .value = 0x1C0 }, + { .description = "0x1E0", .value = 0x1E0 }, + { .description = "0x2C0", .value = 0x2C0 }, + { .description = "0x2E0", .value = 0x2E0 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -295,7 +275,7 @@ const device_t pssj_device = { .init = pssj_init, .close = pssj_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -309,7 +289,7 @@ const device_t pssj_1e0_device = { .init = pssj_1e0_init, .close = pssj_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -323,7 +303,7 @@ const device_t pssj_isa_device = { .init = pssj_isa_init, .close = pssj_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = pssj_isa_config diff --git a/src/sound/snd_resid.cpp b/src/sound/snd_resid.cpp index d7082e47e..b0503cac2 100644 --- a/src/sound/snd_resid.cpp +++ b/src/sound/snd_resid.cpp @@ -20,22 +20,21 @@ typedef struct psid_t { psid_t *psid; void * -sid_init(void) +sid_init(uint8_t type) { -#if 0 - psid_t *psid; -#endif - reSIDfp::SamplingMethod method = reSIDfp::DECIMATE; + reSIDfp::SamplingMethod method = reSIDfp::RESAMPLE; float cycles_per_sec = 14318180.0 / 16.0; - psid = new psid_t; -#if 0 - psid = (psid_t *) malloc(sizeof(sound_t)); -#endif + psid = new psid_t; psid->sid = new SID; - psid->sid->setChipModel(reSIDfp::MOS8580); - psid->sid->enableFilter(true); + switch (type) { + default: + case 0: + psid->sid->setChipModel(reSIDfp::MOS6581); + case 1: + psid->sid->setChipModel(reSIDfp::MOS8580); + } psid->sid->reset(); @@ -43,14 +42,13 @@ sid_init(void) psid->sid->write(c, 0); try { - psid->sid->setSamplingParameters(cycles_per_sec, method, (float) RESID_FREQ, 0.9 * (float) RESID_FREQ / 2.0); + psid->sid->setSamplingParameters(cycles_per_sec, method, (float) RESID_FREQ); } catch (reSIDfp::SIDError) { #if 0 printf("reSID failed!\n"); #endif } - psid->sid->setChipModel(reSIDfp::MOS6581); psid->sid->input(0); return (void *) psid; @@ -59,9 +57,6 @@ sid_init(void) void sid_close(UNUSED(void *priv)) { -#if 0 - psid_t *psid = (psid_t *) priv; -#endif delete psid->sid; #if 0 free(psid); @@ -71,10 +66,6 @@ sid_close(UNUSED(void *priv)) void sid_reset(UNUSED(void *priv)) { -#if 0 - psid_t *psid = (psid_t *) priv; -#endif - psid->sid->reset(); for (uint8_t c = 0; c < 32; c++) @@ -84,33 +75,22 @@ sid_reset(UNUSED(void *priv)) uint8_t sid_read(uint16_t addr, UNUSED(void *priv)) { -#if 0 - psid_t *psid = (psid_t *) priv; -#endif - return psid->sid->read(addr & 0x1f); -#if 0 - return 0xFF; -#endif } void sid_write(uint16_t addr, uint8_t val, UNUSED(void *priv)) { -#if 0 - psid_t *psid = (psid_t *) priv; -#endif - psid->sid->write(addr & 0x1f, val); } #define CLOCK_DELTA(n) (int) (((14318180.0 * n) / 16.0) / (float) RESID_FREQ) static void -fillbuf2(int &count, int16_t *buf, int len) +fillbuf2(int &count, int16_t *buf, UNUSED(int len)) { - int c; - c = psid->sid->clock(count, buf); + int c = psid->sid->clock(count, buf); + if (!c) *buf = psid->last_sample; psid->last_sample = *buf; @@ -118,9 +98,6 @@ fillbuf2(int &count, int16_t *buf, int len) void sid_fillbuf(int16_t *buf, int len, UNUSED(void *priv)) { -#if 0 - psid_t *psid = (psid_t *) priv; -#endif int x = CLOCK_DELTA(len); fillbuf2(x, buf, len); diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 88a7d875a..4f8b8a0bd 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1,21 +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. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Sound Blaster emulation. + * Sound Blaster emulation. * + * Authors: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Jasmine Iwanek, * - * - * Authors: Sarah Walker, - * Miran Grca, - * TheCollector1995, - * - * Copyright 2008-2020 Sarah Walker. - * Copyright 2016-2020 Miran Grca. + * Copyright 2008-2020 Sarah Walker. + * Copyright 2016-2020 Miran Grca. + * Copyright 2024-2025 Jasmine Iwanek. */ #include #include @@ -43,18 +43,40 @@ #include <86box/snd_sb.h> #include <86box/plat_unused.h> -#define PNP_ROM_SB_16_PNP "roms/sound/creative/CTL0024A.BIN" -#define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" -#define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN" -#define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" -#define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN" -#define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" -#define PNP_ROM_SB_AWE64 "roms/sound/creative/CTL009DA.BIN" -#define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" +#define SB_1 0 +#define SB_15 1 +#define SB_2 2 + +#define SB_16_PNP_NOIDE 0 +#define SB_16_PNP_IDE 1 + +#define SB_VIBRA16XV 0 +#define SB_VIBRA16C 1 +#define SB_VIBRA16CL 2 + +#define SB_32_PNP 0 +#define SB_AWE32_PNP 1 +#define SB_AWE64_VALUE 2 +#define SB_AWE64_NOIDE 3 +#define SB_AWE64_IDE 4 +#define SB_AWE64_GOLD 5 + +#define PNP_ROM_SB_16_PNP_NOIDE "roms/sound/creative/CT2941 PnP.BIN" +#define PNP_ROM_SB_16_PNP_IDE "roms/sound/creative/CTL0024A.BIN" /* CT2940 */ +#define PNP_ROM_SB_VIBRA16C "roms/sound/creative/CT4180 PnP.BIN" +#define PNP_ROM_SB_VIBRA16CL "roms/sound/creative/CT4100 PnP.BIN" +#define PNP_ROM_SB_VIBRA16XV "roms/sound/creative/CT4170 PnP.BIN" +#define PNP_ROM_SB_GOLDFINCH "roms/sound/creative/CT1920 PnP.BIN" +#define PNP_ROM_SB_32_PNP "roms/sound/creative/CT3600 PnP.BIN" +#define PNP_ROM_SB_AWE32_PNP "roms/sound/creative/CT3980 PnP.BIN" +#define PNP_ROM_SB_AWE64_VALUE "roms/sound/creative/CT4520 PnP.BIN" +#define PNP_ROM_SB_AWE64_NOIDE "roms/sound/creative/CT4380 PnP noIDE.BIN" +#define PNP_ROM_SB_AWE64_IDE "roms/sound/creative/CTL009DA.BIN" /* CT4381? */ +#define PNP_ROM_SB_AWE64_GOLD "roms/sound/creative/CT4540 PnP.BIN" /* TODO: Find real ESS PnP ROM dumps. */ -#define PNP_ROM_ESS0100 "roms/sound/ess/ESS0100.BIN" -#define PNP_ROM_ESS0102 "roms/sound/ess/ESS0102.BIN" -#define PNP_ROM_ESS0968 "roms/sound/ess/ESS0968.BIN" +#define PNP_ROM_ESS0100 "roms/sound/ess/ESS0100.BIN" +#define PNP_ROM_ESS0102 "roms/sound/ess/ESS0102.BIN" +#define PNP_ROM_ESS0968 "roms/sound/ess/ESS0968.BIN" /* 0 to 7 -> -14dB to 0dB i 2dB steps. 8 to 15 -> 0 to +14dB in 2dB steps. Note that for positive dB values, this is not amplitude, it is amplitude - 1. */ @@ -126,8 +148,8 @@ sb_log(const char *fmt, ...) static void sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + sb_t *sb = (sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; double out_mono; sb_dsp_update(&sb->dsp); @@ -136,8 +158,8 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) cms_update(&sb->cms); for (int c = 0; c < len * 2; c += 2) { - double out_l = 0.0; - double out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; if (sb->cms_enabled) { out_l += sb->cms.buffer[c]; @@ -177,15 +199,15 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv) static void sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv) { - const sb_t *sb = (const sb_t *) priv; - const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - const int32_t *opl_buf = NULL; + const sb_t *sb = (const sb_t *) priv; + const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; + const int32_t *opl_buf = NULL; opl_buf = sb->opl.update(sb->opl.priv); for (int c = 0; c < len * 2; c += 2) { - double out_l = 0.0; - double out_r = 0.0; + double out_l = 0.0; + double out_r = 0.0; const double out_mono = ((double) opl_buf[c]) * 0.7171630859375; @@ -270,7 +292,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) if (!sb->opl_enabled) return; - if (sb->dsp.sb_type == SBPRO) { + if (sb->dsp.sb_type == SBPRO_DSP_300) { opl_buf = sb->opl.update(sb->opl.priv); opl2_buf = sb->opl2.update(sb->opl2.priv); } else @@ -282,7 +304,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) out_l = 0.0; out_r = 0.0; - if (sb->dsp.sb_type == SBPRO) { + if (sb->dsp.sb_type == SBPRO_DSP_300) { /* Two chips for LEFT and RIGHT channels. Each chip stores data into the LEFT channel only (no sample alternating.) */ out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375; @@ -304,7 +326,7 @@ sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv) } sb->opl.reset_buffer(sb->opl.priv); - if (sb->dsp.sb_type == SBPRO) + if (sb->dsp.sb_type == SBPRO_DSP_300) sb->opl2.reset_buffer(sb->opl2.priv); } @@ -323,8 +345,8 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv) static void sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; double bass_treble; sb_dsp_update(&sb->dsp); @@ -490,11 +512,32 @@ sb_get_music_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) sb->opl.reset_buffer(sb->opl.priv); } +static void +sb_get_wavetable_buffer_goldfinch(int32_t *buffer, const int len, void *priv) +{ + goldfinch_t *goldfinch = (goldfinch_t *) priv; + + emu8k_update(&goldfinch->emu8k); + + for (int c = 0; c < len * 2; c += 2) { + double out_l = 0.0; + double out_r = 0.0; + + out_l += ((double) goldfinch->emu8k.buffer[c]); + out_r += ((double) goldfinch->emu8k.buffer[c + 1]); + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + goldfinch->emu8k.pos = 0; +} + static void sb_get_wavetable_buffer_sb16_awe32(int32_t *buffer, const int len, void *priv) { - sb_t *sb = (sb_t *) priv; - const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; + sb_t *sb = (sb_t *) priv; + const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; double bass_treble; emu8k_update(&sb->emu8k); @@ -1118,7 +1161,7 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0xff: - if ((sb->dsp.sb_type > SBAWE32) && !sb->dsp.sb_16_dma_supported) { + if ((sb->dsp.sb_type > SBAWE32_DSP_412) && !sb->dsp.sb_16_dma_supported) { /* Bit 5: High DMA channel enabled (0 = yes, 1 = no); Bit 2: ????; @@ -1175,14 +1218,13 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) { const sb_t *sb = (sb_t *) priv; const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - uint8_t ret = 0xff; - - if (!(addr & 1)) - ret = mixer->index; + uint8_t ret = 0xff; sb_log("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - if ((mixer->index >= 0x30) && (mixer->index <= 0x47)) + if (!(addr & 1)) + ret = 0xff /*mixer->index*/; + else if ((mixer->index >= 0x30) && (mixer->index <= 0x47)) ret = mixer->regs[mixer->index]; else { switch (mixer->index) { @@ -1303,10 +1345,10 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) /* http://the.earth.li/~tfm/oldpage/sb_mixer.html - 0x10, 0x20, 0x80. */ const uint8_t temp = ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0) | ((sb->dsp.sb_irq401) ? 4 : 0); - if (sb->dsp.sb_type >= SBAWE32) - ret = temp | 0x80; + if (sb->dsp.sb_type >= SBAWE32_DSP_412) + ret = temp | 0x80; else - ret = temp | 0x40; + ret = temp | 0x40; break; case 0x83: @@ -1332,23 +1374,23 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) ret |= 0x01; break; - case 0x49: /* Undocumented register used by some Creative drivers. */ - case 0x4a: /* Undocumented register used by some Creative drivers. */ - case 0x8c: /* Undocumented register used by some Creative drivers. */ - case 0x8e: /* Undocumented register used by some Creative drivers. */ - case 0x90: /* 3D Enhancement switch. */ - case 0xfd: /* Undocumented register used by some Creative drivers. */ - case 0xfe: /* Undocumented register used by some Creative drivers. */ + case 0x49: /* Undocumented register used by some Creative drivers. */ + case 0x4a: /* Undocumented register used by some Creative drivers. */ + case 0x8c: /* Undocumented register used by some Creative drivers. */ + case 0x8e: /* Undocumented register used by some Creative drivers. */ + case 0x90: /* 3D Enhancement switch. */ + case 0xfd: /* Undocumented register used by some Creative drivers. */ + case 0xfe: /* Undocumented register used by some Creative drivers. */ ret = mixer->regs[mixer->index]; break; - case 0xff: /* Undocumented register used by some Creative drivers. - This and the upper bits of 0x82 seem to affect the - playback volume: - - Register FF = FF: Volume playback normal. - - Register FF = Not FF: Volume playback low unless - bit 6 of 82h is set. */ - if (sb->dsp.sb_type > SBAWE32) + case 0xff: /* Undocumented register used by some Creative drivers. + This and the upper bits of 0x82 seem to affect the + playback volume: + - Register FF = FF: Volume playback normal. + - Register FF = Not FF: Volume playback low unless + bit 6 of 82h is set. */ + if (sb->dsp.sb_type > SBAWE32_DSP_412) ret = mixer->regs[mixer->index]; break; @@ -1375,9 +1417,9 @@ sb_ct1745_mixer_reset(sb_t *sb) } static void -ess_base_write(uint16_t addr, uint8_t val, void *priv) +ess_base_write(uint16_t addr, UNUSED(uint8_t val), void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; switch (addr & 0x000f) { case 0x0002: @@ -1396,7 +1438,7 @@ ess_base_write(uint16_t addr, uint8_t val, void *priv) static uint8_t ess_base_read(uint16_t addr, void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; switch (addr & 0x000f) { case 0x0002: @@ -1421,17 +1463,17 @@ ess_base_read(uint16_t addr, void *priv) } static void -ess_fm_midi_write(uint16_t addr, uint8_t val, void *priv) +ess_fm_midi_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; ess->dsp.activity &= 0x7f; } static uint8_t -ess_fm_midi_read(uint16_t addr, void *priv) +ess_fm_midi_read(UNUSED(uint16_t addr), void *priv) { - sb_t * ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; ess->dsp.activity &= 0x7f; @@ -1452,9 +1494,6 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) if (!(addr & 1)) { mixer->index = val; mixer->regs[0x01] = val; - if (val == 0x40) { - mixer->ess_id_str_pos = 0; - } } else { if (mixer->index == 0) { /* Reset */ @@ -1473,6 +1512,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) mixer->regs[0x3c] = 0x05; mixer->regs[0x3e] = 0x00; + mixer->regs[0x64] = 0x08; + sb_dsp_set_stereo(&ess->dsp, mixer->regs[0x0e] & 2); } else { mixer->regs[mixer->index] = val; @@ -1510,8 +1551,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x0E: - mixer->output_filter = !(mixer->regs[0xE] & 0x20); - mixer->stereo = mixer->regs[0xE] & 2; + mixer->output_filter = !(mixer->regs[0xE] & 0x20); + mixer->stereo = mixer->regs[0xE] & 2; sb_dsp_set_stereo(&ess->dsp, val & 2); break; @@ -1525,6 +1566,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) break; case 0x1C: + mixer->regs[mixer->index] = val & 0x2f; if ((mixer->regs[0x1C] & 0x07) == 0x07) { mixer->input_selector = INPUT_MIXER_L | INPUT_MIXER_R; } else if ((mixer->regs[0x1C] & 0x07) == 0x06) { @@ -1547,21 +1589,27 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) /* More compatibility: SoundBlaster Pro selects register 020h for 030h, 022h for 032h, 026h for 036h, and 028h for 038h. */ - case 0x30: case 0x32: case 0x36: case 0x38: + case 0x30: + case 0x32: + case 0x36: + case 0x38: case 0x3e: mixer->regs[mixer->index - 0x10] = (val & 0xee); break; - case 0x00: case 0x04: case 0x3a: case 0x3c: + case 0x00: + case 0x04: + case 0x3a: + case 0x3c: break; case 0x64: - mixer->regs[mixer->index] = (mixer->regs[mixer->index] & 0xf7) | 0x20; - // mixer->regs[mixer->index] &= ~0x8; + if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) + mixer->regs[mixer->index] = (mixer->regs[mixer->index] & 0xf7) | 0x20; break; case 0x40: - { + if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) { uint16_t mpu401_base_addr = 0x300 | ((mixer->regs[0x40] << 1) & 0x30); sb_log("mpu401_base_addr = %04X\n", mpu401_base_addr); @@ -1572,7 +1620,7 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); - if (ess->dsp.sb_subtype != SB_SUBTYPE_ESS_ES1688) { + if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) { /* Not on ES1688. */ io_removehandler(0x0388, 0x0004, ess->opl.read, NULL, NULL, @@ -1585,53 +1633,56 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) ess->opl.priv); } } - switch ((mixer->regs[0x40] >> 5) & 0x7) { - default: - break; - case 0: - mpu401_base_addr = 0x0000; - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, -1); - break; - case 1: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, -1); - break; - case 2: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); - break; - case 3: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 11); - break; - case 4: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 9); - break; - case 5: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 5); - break; - case 6: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 7); - break; - case 7: - mpu401_change_addr(ess->mpu, mpu401_base_addr); - mpu401_setirq(ess->mpu, 10); - break; - } + + if (ess->mpu != NULL) + switch ((mixer->regs[0x40] >> 5) & 0x7) { + default: + break; + case 0: + mpu401_base_addr = 0x0000; + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, -1); + break; + case 1: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, -1); + break; + case 2: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, ess->dsp.sb_irqnum); + break; + case 3: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 11); + break; + case 4: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 9); + break; + case 5: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 5); + break; + case 6: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 7); + break; + case 7: + mpu401_change_addr(ess->mpu, mpu401_base_addr); + mpu401_setirq(ess->mpu, 10); + break; + } ess->midi_addr = mpu401_base_addr; io_sethandler(addr, 0x0002, ess_fm_midi_read, NULL, NULL, ess_fm_midi_write, NULL, NULL, ess); - break; } + break; default: - sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + sb_log("ess: Unknown mixer register WRITE: %02X\t%02X\n", + mixer->index, mixer->regs[mixer->index]); break; } } @@ -1655,58 +1706,88 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) uint8_t ess_mixer_read(uint16_t addr, void *priv) { - const sb_t * ess = (sb_t *) priv; + const sb_t *ess = (sb_t *) priv; const ess_mixer_t *mixer = &ess->mixer_ess; uint8_t ret = 0x0a; if (!(addr & 1)) ret = mixer->index; - else switch (mixer->index) { - case 0x00: - case 0x0a: - case 0x0c: - case 0x0e: - case 0x14: - case 0x02: - case 0x06: - case 0x30: - case 0x32: - case 0x36: - case 0x38: - case 0x3e: - ret = mixer->regs[mixer->index]; - break; - - case 0x04: - case 0x22: - case 0x26: - case 0x28: - case 0x2e: - ret = mixer->regs[mixer->index] | 0x11; - break; - - case 0x40: - if (ess->dsp.sb_subtype == SB_SUBTYPE_ESS_ES1688) + else + switch (mixer->index) { + case 0x00: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x14: + case 0x1a: + case 0x02: + case 0x06: + case 0x30: + case 0x32: + case 0x36: + case 0x38: + case 0x3e: ret = mixer->regs[mixer->index]; - else - ret = 0x0a; - break; + break; - case 0x48: - ret = mixer->regs[mixer->index]; - break; + case 0x04: + case 0x22: + case 0x26: + case 0x28: + case 0x2e: + ret = mixer->regs[mixer->index] | 0x11; + break; - /* Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. */ - case 0x64: - ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; - break; + /* Bit 1 always set, bits 7-6 always clear on both the real ES688 and ES1688. */ + case 0x1c: + ret = mixer->regs[mixer->index] | 0x10; + break; - default: - sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } + /* + Real ES688: Always 0x00; + Real ES1688: Bit 2 always clear. + */ + case 0x40: + if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index]; + else if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index] & 0xfb; + else + ret = 0x00; + break; - sb_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + /* + Real ES688: Always 0x00; + Real ES1688: All bits writable. + */ + case 0x48: + if (ess->dsp.sb_subtype >= SB_SUBTYPE_ESS_ES1688) + ret = mixer->regs[mixer->index]; + else + ret = 0x00; + break; + + /* + Return 0x00 so it has bit 3 clear, so NT 5.x drivers don't misdetect it as ES1788. + Bit 3 set and writable: ESSCFG detects the card as ES1788 if register 70h is read-only, + otherwise, as ES1887. + Bit 3 set and read-only: ESSCFG detects the card as ES1788 if register 70h is read-only, + otherwise, as ES1888. + Real ES688 and ES1688: Always 0x00. + */ + case 0x64: + if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) + ret = (mixer->regs[mixer->index] & 0xf7) | 0x20; + else + ret = 0x00; + break; + + default: + sb_log("ess: Unknown mixer register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } + + sb_log("[%04X:%08X] [R] %04X = %02X (%02X)\n", CS, cpu_state.pc, addr, ret, mixer->index); return ret; } @@ -1731,8 +1812,8 @@ sb_mcv_read(int port, void *priv) void sb_mcv_write(int port, uint8_t val, void *priv) { - uint16_t addr; - sb_t *sb = (sb_t *) priv; + uint16_t addr = 0; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1784,8 +1865,8 @@ sb_mcv_feedb(void *priv) static uint8_t sb_pro_mcv_read(int port, void *priv) { - const sb_t *sb = (sb_t *) priv; - uint8_t ret = sb->pos_regs[port & 7]; + const sb_t *sb = (sb_t *) priv; + uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_pro_mcv_read: port=%04x ret=%02x\n", port, ret); @@ -1795,8 +1876,8 @@ sb_pro_mcv_read(int port, void *priv) static void sb_pro_mcv_write(int port, uint8_t val, void *priv) { - uint16_t addr; - sb_t *sb = (sb_t *) priv; + uint16_t addr = 0; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -1855,8 +1936,8 @@ sb_pro_mcv_write(int port, uint8_t val, void *priv) static uint8_t sb_16_reply_mca_read(int port, void *priv) { - const sb_t *sb = (sb_t *) priv; - uint8_t ret = sb->pos_regs[port & 7]; + const sb_t *sb = (sb_t *) priv; + uint8_t ret = sb->pos_regs[port & 7]; sb_log("sb_16_reply_mca_read: port=%04x ret=%02x\n", port, ret); @@ -1866,8 +1947,8 @@ sb_16_reply_mca_read(int port, void *priv) static void sb_16_reply_mca_write(const int port, const uint8_t val, void *priv) { - uint16_t addr; - sb_t *sb = (sb_t *) priv; + uint16_t addr = 0; + sb_t *sb = (sb_t *) priv; if (port < 0x102) return; @@ -2083,7 +2164,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void mpu401_change_addr(sb->mpu, 0); if (config->activate) { - uint8_t val = config->irq[0].irq; + uint8_t val = config->irq[0].irq; addr = config->io[0].base; if (addr != ISAPNP_IO_DISABLED) { @@ -2137,11 +2218,12 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void break; case 1: /* IDE */ - ide_pnp_config_changed(0, config, (void *) 3); + if (sb->has_ide) + ide_pnp_config_changed(0, config, (void *) 3); break; case 2: /* Reserved (16) / WaveTable (32+) */ - if (sb->dsp.sb_type > SB16) + if (sb->dsp.sb_type >= SBAWE32_DSP_412) emu8k_change_addr(&sb->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); break; @@ -2154,7 +2236,7 @@ sb_16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void static void sb_vibra16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { - sb_t *sb = (sb_t *) priv; + sb_t *sb = (sb_t *) priv; switch (ld) { case 0: /* Audio */ @@ -2167,6 +2249,21 @@ sb_vibra16_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, } } +static void +goldfinch_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + goldfinch_t *goldfinch = (goldfinch_t *) priv; + + switch (ld) { + default: + break; + + case 0: /* WaveTable */ + emu8k_change_addr(&goldfinch->emu8k, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; + } +} + static void sb_awe32_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -2189,7 +2286,7 @@ sb_awe32_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, vo } static void -sb_awe64_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe64_pnp_ide_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2210,7 +2307,7 @@ sb_awe64_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, vo } static void -sb_awe64_gold_pnp_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) +sb_awe64_pnp_noide_config_changed(const uint8_t ld, isapnp_device_config_t *config, void *priv) { sb_t *sb = (sb_t *) priv; @@ -2268,9 +2365,6 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co ess_base_write, NULL, NULL, ess); - ess->mixer_ess.ess_id_str[2] = 0x00; - ess->mixer_ess.ess_id_str[3] = 0x00; - addr = ess->opl_pnp_addr; if (addr) { ess->opl_pnp_addr = 0; @@ -2288,7 +2382,8 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co addr = ess->midi_addr; if (addr) { ess->midi_addr = 0; - mpu401_change_addr(ess->mpu, 0); + if (ess->mpu != NULL) + mpu401_change_addr(ess->mpu, 0); io_removehandler(addr, 0x0002, ess_fm_midi_read, NULL, NULL, ess_fm_midi_write, NULL, NULL, @@ -2298,7 +2393,7 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co sb_dsp_setaddr(&ess->dsp, 0); sb_dsp_setirq(&ess->dsp, 0); - if (ess->pnp == 3) + if ((ess->pnp == 3) && (ess->mpu != NULL)) mpu401_setirq(ess->mpu, -1); sb_dsp_setdma8(&ess->dsp, ISAPNP_DMA_DISABLED); sb_dsp_setdma16_8(&ess->dsp, ISAPNP_DMA_DISABLED); @@ -2336,9 +2431,6 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co ess_base_read, NULL, NULL, ess_base_write, NULL, NULL, ess); - - ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; - ess->mixer_ess.ess_id_str[3] = addr & 0xff; } addr = config->io[1].base; @@ -2357,7 +2449,8 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co if (ess->pnp == 3) { addr = config->io[2].base; if (addr != ISAPNP_IO_DISABLED) { - mpu401_change_addr(ess->mpu, addr); + if (ess->mpu != NULL) + mpu401_change_addr(ess->mpu, addr); io_sethandler(addr, 0x0002, ess_fm_midi_read, NULL, NULL, ess_fm_midi_write, NULL, NULL, @@ -2368,7 +2461,7 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co val = config->irq[0].irq; if (val != ISAPNP_IRQ_DISABLED) { sb_dsp_setirq(&ess->dsp, val); - if (ess->pnp == 3) + if ((ess->pnp == 3) && (ess->mpu != NULL)) mpu401_setirq(ess->mpu, val); } @@ -2383,7 +2476,7 @@ ess_x688_pnp_config_changed(UNUSED(const uint8_t ld), isapnp_device_config_t *co case 1: if (ess->pnp == 3) { /* Game */ gameport_remap(ess->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); - } else { /* MPU-401 */ + } else if (ess->mpu != NULL) { /* MPU-401 */ mpu401_change_addr(ess->mpu, 0); mpu401_setirq(ess->mpu, -1); @@ -2431,7 +2524,7 @@ ess_x688_mca_read(const int port, void *priv) static void ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv) { - sb_t *ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; if (port < 0x102) return; @@ -2594,7 +2687,7 @@ ess_soundpiper_mca_write(const int port, const uint8_t val, void *priv) static void ess_chipchat_mca_write(int port, uint8_t val, void *priv) { - sb_t *ess = (sb_t *) priv; + sb_t *ess = (sb_t *) priv; if (port < 0x102) return; @@ -2723,182 +2816,62 @@ ess_chipchat_mca_write(int port, uint8_t val, void *priv) } void * -sb_1_init(UNUSED(const device_t *info)) +sb_init(UNUSED(const device_t *info)) { - /* SB1/2 port mappings, 210h to 260h in 10h steps - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip */ - sb_t * sb = malloc(sizeof(sb_t)); - const uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - fm_driver_get(FM_YM3812, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB1, 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")); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - io_sethandler(0x0388, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - } - - sb->cms_enabled = 1; - memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, - cms_read, NULL, NULL, - cms_write, NULL, NULL, - &sb->cms); - - sb->mixer_enabled = 0; - sound_add_handler(sb_get_buffer_sb2, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb2, sb); - sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - return sb; -} - -void * -sb_15_init(UNUSED(const device_t *info)) -{ - /* SB1/2 port mappings, 210h to 260h in 10h steps - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip */ - sb_t * sb = malloc(sizeof(sb_t)); - const uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - fm_driver_get(FM_YM3812, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB15, 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")); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - if (sb->opl_enabled) { - io_sethandler(addr + 8, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - io_sethandler(0x0388, 0x0002, - sb->opl.read, NULL, NULL, - sb->opl.write, NULL, NULL, - sb->opl.priv); - } - - sb->cms_enabled = device_get_config_int("cms"); - if (sb->cms_enabled) { - memset(&sb->cms, 0, sizeof(cms_t)); - io_sethandler(addr, 0x0004, - cms_read, NULL, NULL, - cms_write, NULL, NULL, - &sb->cms); - } - - sb->mixer_enabled = 0; - sound_add_handler(sb_get_buffer_sb2, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb2, sb); - sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - return sb; -} - -void * -sb_mcv_init(UNUSED(const device_t *info)) -{ - /* SB1/2 port mappings, 210h to 260h in 10h steps - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip */ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); - - sb->opl_enabled = device_get_config_int("opl"); - if (sb->opl_enabled) - fm_driver_get(FM_YM3812, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); - sb_dsp_setaddr(&sb->dsp, 0); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - - sb->mixer_enabled = 0; - sound_add_handler(sb_get_buffer_sb2, sb); - if (sb->opl_enabled) - music_add_handler(sb_get_music_buffer_sb2, sb); - sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); - - /* I/O handlers activated in sb_mcv_write */ - mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb); - sb->pos_regs[0] = 0x84; - sb->pos_regs[1] = 0x50; - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - return sb; -} - -void * -sb_2_init(UNUSED(const device_t *info)) -{ - /* SB2 port mappings, 220h or 240h. - 2x0 to 2x3 -> CMS chip - 2x6, 2xA, 2xC, 2xE -> DSP chip - 2x8, 2x9, 388 and 389 FM chip - "CD version" also uses 250h or 260h for - 2x0 to 2x3 -> CDROM interface - 2x4 to 2x5 -> Mixer interface */ + /* SB1.x port mappings, 210h to 260h in 10h steps: + (SB2 port mappings are 220h or 240h) + 2x0 to 2x3 -> CMS chip + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip + SB2 "CD version" also uses 250h or 260h: + 2x0 to 2x3 -> CDROM interface + 2x4 to 2x5 -> Mixer interface */ /* My SB 2.0 mirrors the OPL2 at ports 2x0/2x1. Presumably this mirror is disabled when the CMS chips are present. This mirror may also exist on SB 1.5 & MCV, however I am unable to test this. It shouldn't exist on SB 1.0 as the CMS chips are always present there. Syndicate requires this mirror - for music to play.*/ - sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_hex16("base"); - uint16_t mixer_addr = device_get_config_int("mixaddr"); + for music to play. */ + sb_t *sb = calloc(1, sizeof(sb_t)); + const uint16_t addr = device_get_config_hex16("base"); + uint16_t mixer_addr = 0x0000; + uint8_t model = 0; - memset(sb, 0, sizeof(sb_t)); + switch (info->local) { + default: + case SB_1: + model = SB_DSP_105; + sb->cms_enabled = 1; + break; + + case SB_15: + model = SB_DSP_200; + sb->cms_enabled = device_get_config_int("cms"); + break; + + case SB_2: + model = SB_DSP_201; + sb->cms_enabled = device_get_config_int("cms"); + mixer_addr = device_get_config_int("mixaddr"); + break; + } sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get(FM_YM3812, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); + 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")); - if (mixer_addr > 0x000) + + if (mixer_addr > 0x0000) sb_ct1335_mixer_reset(sb); - sb->cms_enabled = device_get_config_int("cms"); /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { - if (!sb->cms_enabled) { + // TODO: See if this applies to the SB1.5 as well + if ((!sb->cms_enabled) && ((model == SB_DSP_201) || (model == SB_DSP_202))) { io_sethandler(addr, 0x0002, sb->opl.read, NULL, NULL, sb->opl.write, NULL, NULL, @@ -2930,6 +2903,7 @@ sb_2_init(UNUSED(const device_t *info)) sb); } else sb->mixer_enabled = 0; + sound_add_handler(sb_get_buffer_sb2, sb); if (sb->opl_enabled) music_add_handler(sb_get_music_buffer_sb2, sb); @@ -2941,6 +2915,41 @@ sb_2_init(UNUSED(const device_t *info)) return sb; } +void * +sb_mcv_init(UNUSED(const device_t *info)) +{ + /* SB1/2 port mappings, 210h to 260h in 10h steps + 2x6, 2xA, 2xC, 2xE -> DSP chip + 2x8, 2x9, 388 and 389 FM chip */ + sb_t *sb = calloc(1, sizeof(sb_t)); + + sb->opl_enabled = device_get_config_int("opl"); + if (sb->opl_enabled) + fm_driver_get(FM_YM3812, &sb->opl); + + sb_dsp_set_real_opl(&sb->dsp, 1); + sb_dsp_init(&sb->dsp, SB_DSP_105, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); + + sb->mixer_enabled = 0; + sound_add_handler(sb_get_buffer_sb2, sb); + if (sb->opl_enabled) + music_add_handler(sb_get_music_buffer_sb2, sb); + sound_set_cd_audio_filter(sb2_filter_cd_audio, sb); + + /* I/O handlers activated in sb_mcv_write */ + mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb); + sb->pos_regs[0] = 0x84; + sb->pos_regs[1] = 0x50; + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + + return sb; +} + static uint8_t sb_pro_v1_opl_read(uint16_t port, void *priv) { @@ -2970,9 +2979,8 @@ sb_pro_v1_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) { @@ -2983,7 +2991,7 @@ sb_pro_v1_init(UNUSED(const device_t *info)) } sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO_DSP_300, 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")); @@ -3033,16 +3041,15 @@ sb_pro_v2_init(UNUSED(const device_t *info)) 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) 2x0+10 to 2x0+13 CDROM interface. */ - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); - memset(sb, 0, sizeof(sb_t)); sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, 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")); @@ -3087,14 +3094,13 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) 2x4 to 2x5 -> Mixer interface 2x6, 2xA, 2xC, 2xE -> DSP chip 2x8, 2x9, 388 and 389 FM chip (9 voices) */ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; @@ -3116,13 +3122,12 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) static void * sb_pro_compat_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, sb); sb_ct1345_mixer_reset(sb); sb->mixer_enabled = 1; @@ -3130,8 +3135,7 @@ sb_pro_compat_init(UNUSED(const device_t *info)) if (sb->opl_enabled) music_add_handler(sb_get_music_buffer_sbpro, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, 1); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3141,18 +3145,16 @@ sb_pro_compat_init(UNUSED(const device_t *info)) static void * sb_16_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); const uint16_t addr = device_get_config_hex16("base"); const uint16_t mpu_addr = device_get_config_hex16("base401"); - memset(sb, 0x00, sizeof(sb_t)); - sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get((int) (intptr_t) info->local, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32_DSP_413 : SB16_DSP_405, 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")); @@ -3188,8 +3190,7 @@ sb_16_init(UNUSED(const device_t *info)) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART, device_get_config_int("receive_input401")); } else @@ -3199,7 +3200,7 @@ 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 = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); @@ -3209,14 +3210,13 @@ sb_16_init(UNUSED(const device_t *info)) static void * sb_16_reply_mca_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0x00, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3229,8 +3229,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3250,23 +3249,28 @@ sb_16_reply_mca_init(UNUSED(const device_t *info)) } static int -sb_16_pnp_available(void) +sb_16_pnp_noide_available(void) { - return rom_present(PNP_ROM_SB_16_PNP); + return rom_present(PNP_ROM_SB_16_PNP_NOIDE); +} + +static int +sb_16_pnp_ide_available(void) +{ + return rom_present(PNP_ROM_SB_16_PNP_IDE); } static void * sb_16_pnp_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0x00, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); sb->pnp = 1; sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3278,8 +3282,7 @@ sb_16_pnp_init(UNUSED(const device_t *info)) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3288,91 +3291,23 @@ sb_16_pnp_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); - device_add(&ide_qua_pnp_device); - other_ide_present++; + // Does it have IDE? + if (info->local != SB_16_PNP_NOIDE) { + device_add(&ide_qua_pnp_device); + other_ide_present++; - uint8_t *pnp_rom = NULL; - - FILE *fp = rom_fopen(PNP_ROM_SB_16_PNP, "rb"); - if (fp) { - if (fread(sb->pnp_rom, 1, 390, fp) == 390) - pnp_rom = sb->pnp_rom; - fclose(fp); + sb->has_ide = 1; } - isapnp_add_card(pnp_rom, 390, sb_16_pnp_config_changed, - NULL, NULL, NULL, sb); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_setaddr(&sb->dsp, 0); - sb_dsp_setirq(&sb->dsp, 0); - sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); - sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); - - mpu401_change_addr(sb->mpu, 0); - ide_remove_handlers(3); - - sb->gameport_addr = 0; - gameport_remap(sb->gameport, 0); - - return sb; -} - -static int -sb_vibra16xv_available(void) -{ - return rom_present(PNP_ROM_SB_VIBRA16XV); -} - -static int -sb_vibra16c_available(void) -{ - return rom_present(PNP_ROM_SB_VIBRA16C); -} - -static void * -sb_vibra16_pnp_init(UNUSED(const device_t *info)) -{ - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0x00, sizeof(sb_t)); - - sb->pnp = 1; - - sb->opl_enabled = 1; - fm_driver_get(FM_YMF262, &sb->opl); - - sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); - /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ - sb_dsp_setdma16_supported(&sb->dsp, info->local != 0); - sb_ct1745_mixer_reset(sb); - - sb->mixer_enabled = 1; - sb->mixer_sb16.output_filter = 1; - sound_add_handler(sb_get_buffer_sb16_awe32, sb); - music_add_handler(sb_get_music_buffer_sb16_awe32, sb); - sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); - if (device_get_config_int("control_pc_speaker")) - sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); - mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); - sb_dsp_set_mpu(&sb->dsp, sb->mpu); - - if (device_get_config_int("receive_input")) - midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - - sb->gameport = gameport_add(&gameport_pnp_device); - const char *pnp_rom_file = NULL; + uint16_t pnp_rom_len = 512; switch (info->local) { - case 0: - pnp_rom_file = PNP_ROM_SB_VIBRA16XV; + case SB_16_PNP_NOIDE: + pnp_rom_file = PNP_ROM_SB_16_PNP_NOIDE; break; - case 1: - pnp_rom_file = PNP_ROM_SB_VIBRA16C; + case SB_16_PNP_IDE: + pnp_rom_file = PNP_ROM_SB_16_PNP_IDE; break; default: @@ -3383,16 +3318,129 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) if (pnp_rom_file) { FILE *fp = rom_fopen(pnp_rom_file, "rb"); if (fp) { - if (fread(sb->pnp_rom, 1, 512, fp) == 512) + if (fread(sb->pnp_rom, 1, pnp_rom_len, fp) == pnp_rom_len) + pnp_rom = sb->pnp_rom; + fclose(fp); + } + } + + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_16_pnp_config_changed, + NULL, NULL, NULL, sb); + + sb_dsp_set_real_opl(&sb->dsp, 1); + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, 0); + sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); + + mpu401_change_addr(sb->mpu, 0); + + if (info->local != SB_16_PNP_NOIDE) + ide_remove_handlers(3); + + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); + + return sb; +} + +static int +sb_vibra16c_available(void) +{ + return rom_present(PNP_ROM_SB_VIBRA16C); +} + +static int +sb_vibra16cl_available(void) +{ + return rom_present(PNP_ROM_SB_VIBRA16CL); +} + +static int +sb_vibra16xv_available(void) +{ + return rom_present(PNP_ROM_SB_VIBRA16XV); +} + +static void * +sb_vibra16_pnp_init(UNUSED(const device_t *info)) +{ + sb_t *sb = calloc(1, sizeof(sb_t)); + + sb->pnp = 1; + + sb->opl_enabled = 1; + fm_driver_get(FM_YMF262, &sb->opl); + + sb_dsp_set_real_opl(&sb->dsp, 1); + sb_dsp_init(&sb->dsp, (info->local == SB_VIBRA16XV) ? SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb); + /* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */ + sb_dsp_setdma16_supported(&sb->dsp, info->local != SB_VIBRA16XV); + sb_ct1745_mixer_reset(sb); + + sb->mixer_enabled = 1; + sb->mixer_sb16.output_filter = 1; + sound_add_handler(sb_get_buffer_sb16_awe32, sb); + music_add_handler(sb_get_music_buffer_sb16_awe32, sb); + sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + if (device_get_config_int("control_pc_speaker")) + sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); + + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&sb->dsp, sb->mpu); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + + switch (info->local) { + case SB_VIBRA16C: /* CTL7001 */ + case SB_VIBRA16CL: /* CTL7002 */ + sb->gameport = gameport_add(&gameport_pnp_device); + break; + + case SB_VIBRA16XV: /* CTL7005 */ + sb->gameport = gameport_add(&gameport_pnp_1io_device); + break; + + default: + break; + } + + const char *pnp_rom_file = NULL; + switch (info->local) { + case SB_VIBRA16C: + pnp_rom_file = PNP_ROM_SB_VIBRA16C; + break; + + case SB_VIBRA16CL: + pnp_rom_file = PNP_ROM_SB_VIBRA16CL; + break; + + case SB_VIBRA16XV: + pnp_rom_file = PNP_ROM_SB_VIBRA16XV; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + uint16_t pnp_rom_len = 512; + if (fp) { + if (fread(sb->pnp_rom, 1, pnp_rom_len, fp) == pnp_rom_len) pnp_rom = sb->pnp_rom; fclose(fp); } } switch (info->local) { - case 0: - case 1: - isapnp_add_card(pnp_rom, 512, sb_vibra16_pnp_config_changed, + case SB_VIBRA16C: + case SB_VIBRA16CL: + case SB_VIBRA16XV: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_vibra16_pnp_config_changed, NULL, NULL, NULL, sb); break; @@ -3416,28 +3464,27 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info)) static void * sb_16_compat_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SB16_DSP_405, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_dsp_setdma16_enabled(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); - sb->opl_enabled = 1; + sb->opl_enabled = 1; sb->mixer_enabled = 1; sound_add_handler(sb_get_buffer_sb16_awe32, sb); music_add_handler(sb_get_music_buffer_sb16_awe32, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + 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); - sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); @@ -3450,6 +3497,12 @@ sb_awe32_available(void) return rom_present(EMU8K_ROM_PATH); } +static int +sb_goldfinch_available(void) +{ + return sb_awe32_available() && rom_present(PNP_ROM_SB_GOLDFINCH); +} + static int sb_32_pnp_available(void) { @@ -3469,9 +3522,15 @@ sb_awe64_value_available(void) } static int -sb_awe64_available(void) +sb_awe64_noide_available(void) { - return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64); + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64_NOIDE); +} + +static int +sb_awe64_ide_available(void) +{ + return sb_awe32_available() && rom_present(PNP_ROM_SB_AWE64_IDE); } static int @@ -3483,7 +3542,7 @@ sb_awe64_gold_available(void) static void * sb_awe32_init(UNUSED(const device_t *info)) { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); uint16_t addr = device_get_config_hex16("base"); uint16_t mpu_addr = device_get_config_hex16("base401"); uint16_t emu_addr = device_get_config_hex16("emu_base"); @@ -3496,7 +3555,7 @@ sb_awe32_init(UNUSED(const device_t *info)) fm_driver_get(FM_YMF262, &sb->opl); sb_dsp_set_real_opl(&sb->dsp, 1); - sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, SBAWE32_DSP_412, 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")); @@ -3533,7 +3592,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); if (mpu_addr) { - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + 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")); @@ -3546,28 +3605,72 @@ 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 = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); return sb; } +static void * +sb_goldfinch_init(const device_t *info) +{ + goldfinch_t *goldfinch = calloc(1, sizeof(goldfinch_t)); + int onboard_ram = device_get_config_int("onboard_ram"); + + wavetable_add_handler(sb_get_wavetable_buffer_goldfinch, goldfinch); + + emu8k_init(&goldfinch->emu8k, 0, onboard_ram); + + const char *pnp_rom_file = NULL; + switch (info->local) { + case 0: + pnp_rom_file = PNP_ROM_SB_GOLDFINCH; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + uint16_t pnp_rom_len = 256; + if (fp) { + if (fread(goldfinch->pnp_rom, 1, pnp_rom_len, fp) == pnp_rom_len) + pnp_rom = goldfinch->pnp_rom; + fclose(fp); + } + } + + switch (info->local) { + case 0: + isapnp_add_card(pnp_rom, sizeof(goldfinch->pnp_rom), goldfinch_pnp_config_changed, + NULL, NULL, NULL, goldfinch); + break; + + default: + break; + } + + emu8k_change_addr(&goldfinch->emu8k, 0); + + return goldfinch; +} + static void * sb_awe32_pnp_init(const device_t *info) { - sb_t *sb = malloc(sizeof(sb_t)); + sb_t *sb = calloc(1, sizeof(sb_t)); int onboard_ram = device_get_config_int("onboard_ram"); - memset(sb, 0x00, sizeof(sb_t)); - sb->pnp = 1; sb->opl_enabled = 1; fm_driver_get(FM_YMF262, &sb->opl); - sb_dsp_init(&sb->dsp, ((info->local == 2) || (info->local == 3) || (info->local == 4)) ? - SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_init(&sb->dsp, (info->local >= SB_AWE64_VALUE) ? + SBAWE64_DSP_416 : SBAWE32_DSP_413, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setdma16_supported(&sb->dsp, 1); sb_ct1745_mixer_reset(sb); @@ -3581,8 +3684,7 @@ sb_awe32_pnp_init(const device_t *info) if (device_get_config_int("control_pc_speaker")) sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb); - sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); + sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3593,30 +3695,37 @@ sb_awe32_pnp_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); - if ((info->local != 2) && (info->local != 4)) { + // Does it have IDE? + if ((info->local != SB_AWE64_VALUE) && (info->local != SB_AWE64_NOIDE) && (info->local != SB_AWE64_GOLD)) { device_add(&ide_qua_pnp_device); other_ide_present++; + + sb->has_ide = 1; } const char *pnp_rom_file = NULL; switch (info->local) { - case 0: + case SB_32_PNP: pnp_rom_file = PNP_ROM_SB_32_PNP; break; - case 1: + case SB_AWE32_PNP: pnp_rom_file = PNP_ROM_SB_AWE32_PNP; break; - case 2: + case SB_AWE64_VALUE: pnp_rom_file = PNP_ROM_SB_AWE64_VALUE; break; - case 3: - pnp_rom_file = PNP_ROM_SB_AWE64; + case SB_AWE64_NOIDE: + pnp_rom_file = PNP_ROM_SB_AWE64_NOIDE; break; - case 4: + case SB_AWE64_IDE: + pnp_rom_file = PNP_ROM_SB_AWE64_IDE; + break; + + case SB_AWE64_GOLD: pnp_rom_file = PNP_ROM_SB_AWE64_GOLD; break; @@ -3626,30 +3735,36 @@ sb_awe32_pnp_init(const device_t *info) uint8_t *pnp_rom = NULL; if (pnp_rom_file) { - FILE *fp = rom_fopen(pnp_rom_file, "rb"); + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + uint16_t pnp_rom_len = 512; if (fp) { - if (fread(sb->pnp_rom, 1, 512, fp) == 512) + if (fread(sb->pnp_rom, 1, pnp_rom_len, fp) == pnp_rom_len) pnp_rom = sb->pnp_rom; fclose(fp); } } switch (info->local) { - case 0: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb); + case SB_32_PNP: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_16_pnp_config_changed, + NULL, NULL, NULL, sb); break; - case 1: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe32_pnp_config_changed, NULL, NULL, NULL, sb); + case SB_AWE32_PNP: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe32_pnp_config_changed, + NULL, NULL, NULL, sb); break; - case 3: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_pnp_config_changed, NULL, NULL, NULL, sb); + case SB_AWE64_IDE: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_pnp_ide_config_changed, + NULL, NULL, NULL, sb); break; - case 2: - case 4: - isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_gold_pnp_config_changed, NULL, NULL, NULL, sb); + case SB_AWE64_VALUE: + case SB_AWE64_NOIDE: + case SB_AWE64_GOLD: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_awe64_pnp_noide_config_changed, + NULL, NULL, NULL, sb); break; default: @@ -3662,7 +3777,8 @@ sb_awe32_pnp_init(const device_t *info) sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); mpu401_change_addr(sb->mpu, 0); - if ((info->local != 2) && (info->local != 4)) + + if ((info->local != SB_AWE64_VALUE) && (info->local != SB_AWE64_NOIDE) && (info->local != SB_AWE64_GOLD)) ide_remove_handlers(3); emu8k_change_addr(&sb->emu8k, 0); @@ -3677,7 +3793,7 @@ sb_awe32_pnp_init(const device_t *info) static void * ess_x688_init(UNUSED(const device_t *info)) { - sb_t *ess = calloc(sizeof(sb_t), 1); + sb_t *ess = calloc(sizeof(sb_t), 1); const uint16_t addr = device_get_config_hex16("base"); const uint16_t ide_ctrl = (const uint16_t) device_get_config_int("ide_ctrl"); const uint16_t ide_base = ide_ctrl & 0x0fff; @@ -3687,7 +3803,7 @@ ess_x688_init(UNUSED(const device_t *info)) fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setaddr(&ess->dsp, addr); sb_dsp_setirq(&ess->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&ess->dsp, device_get_config_int("dma")); @@ -3746,11 +3862,6 @@ ess_x688_init(UNUSED(const device_t *info)) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ess->dsp); if (info->local) { - ess->mixer_ess.ess_id_str[0] = 0x16; - ess->mixer_ess.ess_id_str[1] = 0x88; - ess->mixer_ess.ess_id_str[2] = (addr >> 8) & 0xff; - ess->mixer_ess.ess_id_str[3] = addr & 0xff; - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); /* NOTE: The MPU is initialized disabled and with no IRQ assigned. * It will be later initialized by the guest OS's drivers. */ @@ -3768,6 +3879,8 @@ ess_x688_init(UNUSED(const device_t *info)) ide_set_side(4, ide_side); ide_set_irq(4, ide_irq); other_ide_present++; + + ess->has_ide = 1; } return ess; @@ -3794,19 +3907,18 @@ ess_1688_968_pnp_available(void) static void * ess_x688_pnp_init(UNUSED(const device_t *info)) { - sb_t *ess = calloc(sizeof(sb_t), 1); - int len = 512; + sb_t *ess = calloc(sizeof(sb_t), 1); ess->pnp = 1 + (int) info->local; fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); - ess->mixer_enabled = 1; + ess->mixer_enabled = 1; sound_add_handler(sb_get_buffer_ess, ess); music_add_handler(sb_get_music_buffer_ess, ess); sound_set_cd_audio_filter(ess_filter_cd_audio, ess); @@ -3816,12 +3928,6 @@ ess_x688_pnp_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, &ess->dsp); - /* Not on ES688. */ - ess->mixer_ess.ess_id_str[0] = 0x16; - ess->mixer_ess.ess_id_str[1] = 0x88; - ess->mixer_ess.ess_id_str[2] = 0x00; - ess->mixer_ess.ess_id_str[3] = 0x00; - ess->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); /* NOTE: The MPU is initialized disabled and with no IRQ assigned. * It will be later initialized by the guest OS's drivers. */ @@ -3833,21 +3939,24 @@ ess_x688_pnp_init(UNUSED(const device_t *info)) device_add(&ide_qua_pnp_device); other_ide_present++; + ess->has_ide = 1; + const char *pnp_rom_file = NULL; + uint16_t pnp_rom_len = 512; switch (info->local) { case 0: pnp_rom_file = PNP_ROM_ESS0100; - len = 145; + pnp_rom_len = 145; break; case 1: pnp_rom_file = PNP_ROM_ESS0102; - len = 145; + pnp_rom_len = 145; break; case 2: pnp_rom_file = PNP_ROM_ESS0968; - len = 135; + pnp_rom_len = 135; break; default: @@ -3858,13 +3967,13 @@ ess_x688_pnp_init(UNUSED(const device_t *info)) if (pnp_rom_file) { FILE *fp = rom_fopen(pnp_rom_file, "rb"); if (fp) { - if (fread(ess->pnp_rom, 1, len, fp) == len) + if (fread(ess->pnp_rom, 1, pnp_rom_len, fp) == pnp_rom_len) pnp_rom = ess->pnp_rom; fclose(fp); } } - isapnp_add_card(pnp_rom, len, ess_x688_pnp_config_changed, + isapnp_add_card(pnp_rom, sizeof(ess->pnp_rom), ess_x688_pnp_config_changed, NULL, NULL, NULL, ess); sb_dsp_setaddr(&ess->dsp, 0); @@ -3891,11 +4000,11 @@ ess_x688_mca_init(UNUSED(const device_t *info)) fm_driver_get(info->local ? FM_ESFM : FM_YMF262, &ess->opl); sb_dsp_set_real_opl(&ess->dsp, 1); - sb_dsp_init(&ess->dsp, SBPRO2, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); + sb_dsp_init(&ess->dsp, SBPRO2_DSP_302, info->local ? SB_SUBTYPE_ESS_ES1688 : SB_SUBTYPE_ESS_ES688, ess); sb_dsp_setdma16_supported(&ess->dsp, 0); ess_mixer_reset(ess); - ess->mixer_enabled = 1; + ess->mixer_enabled = 1; sound_add_handler(sb_get_buffer_ess, ess); music_add_handler(sb_get_music_buffer_ess, ess); sound_set_cd_audio_filter(ess_filter_cd_audio, ess); @@ -3941,6 +4050,16 @@ sb_close(void *priv) free(sb); } +static void +sb_goldfinch_close(void *priv) +{ + goldfinch_t *goldfinch = (goldfinch_t *) priv; + + emu8k_close(&goldfinch->emu8k); + + free(goldfinch); +} + static void sb_awe32_close(void *priv) { @@ -3962,211 +4081,165 @@ sb_speed_changed(void *priv) // clang-format off static const device_config_t sb_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x210", - .value = 0x210 - }, - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x260", - .value = 0x260 }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x210", .value = 0x210 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x250", .value = 0x250 }, + { .description = "0x260", .value = 0x260 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { "" } - } + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 - }, + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t sb15_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x210", - .value = 0x210 - }, - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x210", .value = 0x210 }, + { .description = "0x220", .value = 0x220 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x250", .value = 0x250 }, + { .description = "0x260", .value = 0x260 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "irq", .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "cms", - .description = "Enable CMS", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "cms", + .description = "Enable CMS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -4175,1028 +4248,888 @@ static const device_config_t sb2_config[] = { { .name = "base", .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x260", - .value = 0x260 - }, - { .description = "" } - } + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "mixaddr", - .description = "Mixer", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "Disabled", - .value = 0 - }, - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x260", - .value = 0x260 - }, - { .description = "" } - } + .name = "mixaddr", + .description = "Mixer", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x250", .value = 0x250 }, + { .description = "0x260", .value = 0x260 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "cms", - .description = "Enable CMS", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "cms", + .description = "Enable CMS", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t sb_mcv_config[] = { { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 3", .value = 3 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t sb_pro_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 7, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t sb_pro_mcv_config[] = { { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t sb_16_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "0x280", - .value = 0x280 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, + { .description = "0x280", .value = 0x280 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "base401", - .description = "MPU-401 Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x330, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "Disabled", - .value = 0 - }, - { - .description = "0x300", - .value = 0x300 - }, - { - .description = "0x330", - .value = 0x330 - }, - { .description = "" } - } + .name = "base401", + .description = "MPU-401 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x330, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x330", .value = 0x330 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "Low DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .name = "dma", + .description = "Low DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma16", - .description = "High DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 5", - .value = 5 - }, - { - .description = "DMA 6", - .value = 6 - }, - { - .description = "DMA 7", - .value = 7 - }, - { .description = "" } - } + .name = "dma16", + .description = "High 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 = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_16_pnp_config[] = { { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_goldfinch_config[] = { + { + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "None", .value = 0 }, + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "2 MB", .value = 2048 }, + { .description = "4 MB", .value = 4096 }, + { .description = "8 MB", .value = 8192 }, + { .description = "16 MB", .value = 16384 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t sb_32_pnp_config[] = { { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "None", - .value = 0 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "28 MB", - .value = 28672 - }, - { .description = "" } - } + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "None", .value = 0 }, + { .description = "512 KB", .value = 512 }, + { .description = "2 MB", .value = 2048 }, + { .description = "8 MB", .value = 8192 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_awe32_config[] = { { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x220, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "0x280", - .value = 0x280 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x220", .value = 0x220 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x260", .value = 0x260 }, + { .description = "0x280", .value = 0x280 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "emu_base", - .description = "EMU8000 Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x620, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x620", - .value = 0x620 - }, - { - .description = "0x640", - .value = 0x640 - }, - { - .description = "0x660", - .value = 0x660 - }, - { - .description = "0x680", - .value = 0x680 - }, - { .description = ""} - } + .name = "emu_base", + .description = "EMU8000 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x620, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x620", .value = 0x620 }, + { .description = "0x640", .value = 0x640 }, + { .description = "0x660", .value = 0x660 }, + { .description = "0x680", .value = 0x680 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "base401", - .description = "MPU-401 Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x330, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "Disabled", - .value = 0 - }, - { - .description = "0x300", - .value = 0x300 - }, - { - .description = "0x330", - .value = 0x330 - }, - { .description = "" } - } + .name = "base401", + .description = "MPU-401 Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x330, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "0x300", .value = 0x300 }, + { .description = "0x330", .value = 0x330 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "Low DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + .name = "dma", + .description = "Low DMA", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "dma16", - .description = "High DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 5, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "DMA 5", - .value = 5 - }, - { - .description = "DMA 6", - .value = 6 - }, - { - .description = "DMA 7", - .value = 7 - }, - { .description = "" } - } + .name = "dma16", + .description = "High 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 = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "None", - .value = 0 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "28 MB", - .value = 28672 - }, - { "" } - } + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "None", .value = 0 }, + { .description = "512 KB", .value = 512 }, + { .description = "2 MB", .value = 2048 }, + { .description = "8 MB", .value = 8192 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_awe32_pnp_config[] = { { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "None", - .value = 0 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "28 MB", - .value = 28672 - }, - { .description = "" } - } + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "None", .value = 0 }, + { .description = "512 KB", .value = 512 }, + { .description = "2 MB", .value = 2048 }, + { .description = "8 MB", .value = 8192 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_awe64_value_config[] = { { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 512, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "4 MB", - .value = 4096 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "12 MB", - .value = 12288 - }, - { - .description = "16 MB", - .value = 16384 - }, - { - .description = "20 MB", - .value = 20480 - }, - { - .description = "24 MB", - .value = 24576 - }, - { - .description = "28 MB", - .value = 28672 - }, - { .description = "" } - } + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "2 MB", .value = 2048 }, + { .description = "4 MB", .value = 4096 }, + { .description = "8 MB", .value = 8192 }, + { .description = "12 MB", .value = 12288 }, + { .description = "16 MB", .value = 16384 }, + { .description = "20 MB", .value = 20480 }, + { .description = "24 MB", .value = 24576 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_awe64_config[] = { { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 1024, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "4 MB", - .value = 4096 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "12 MB", - .value = 12288 - }, - { - .description = "16 MB", - .value = 16384 - }, - { - .description = "20 MB", - .value = 20480 - }, - { - .description = "24 MB", - .value = 24576 - }, - { - .description = "28 MB", - .value = 28672 - }, - { .description = "" } - } + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1024 }, + { .description = "2 MB", .value = 2048 }, + { .description = "4 MB", .value = 4096 }, + { .description = "8 MB", .value = 8192 }, + { .description = "12 MB", .value = 12288 }, + { .description = "16 MB", .value = 16384 }, + { .description = "20 MB", .value = 20480 }, + { .description = "24 MB", .value = 24576 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 sb_awe64_gold_config[] = { { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 4096, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "4 MB", - .value = 4096 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "12 MB", - .value = 12288 - }, - { - .description = "16 MB", - .value = 16384 - }, - { - .description = "20 MB", - .value = 20480 - }, - { - .description = "24 MB", - .value = 24576 - }, - { - .description = "28 MB", - .value = 28672 - }, - { .description = "" } - } + .name = "onboard_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4096, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "4 MB", .value = 4096 }, + { .description = "8 MB", .value = 8192 }, + { .description = "12 MB", .value = 12288 }, + { .description = "16 MB", .value = 16384 }, + { .description = "20 MB", .value = 20480 }, + { .description = "24 MB", .value = 24576 }, + { .description = "28 MB", .value = 28672 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -5206,296 +5139,237 @@ static const device_config_t ess_688_config[] = { .name = "base", .description = "Address", .type = CONFIG_HEX16, - .default_string = "", + .default_string = NULL, .default_int = 0x220, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { .description = "" } - } + { .description = "0x220", .value = 0x220 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x250", .value = 0x250 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "irq", .description = "IRQ", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 5, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "dma", .description = "DMA", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 1, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "ide_ctrl", .description = "IDE Controller", .type = CONFIG_HEX16, - .default_string = "", + .default_string = NULL, .default_int = 0x0000, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "Disabled", - .value = 0x0000 - }, - { - .description = "0x170, IRQ 15", - .value = 0xf170 - }, - { - .description = "0x1E8, IRQ 11", - .value = 0xb1e8 - }, - { - .description = "0x168, IRQ 9", - .value = 0x9168 - }, - { - .description = "0x168, IRQ 10", - .value = 0xa168 - }, - { .description = "" } - } + { .description = "Disabled", .value = 0x0000 }, + { .description = "0x170, IRQ 15", .value = 0xf170 }, + { .description = "0x1E8, IRQ 11", .value = 0xb1e8 }, + { .description = "0x168, IRQ 9", .value = 0x9168 }, + { .description = "0x168, IRQ 10", .value = 0xa168 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "receive_input", - .description = "Receive input (DSP MIDI)", + .description = "Receive MIDI input", .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format on static const device_config_t ess_1688_config[] = { { .name = "base", .description = "Address", .type = CONFIG_HEX16, - .default_string = "", + .default_string = NULL, .default_int = 0x220, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { .description = "" } - } + { .description = "0x220", .value = 0x220 }, + { .description = "0x230", .value = 0x230 }, + { .description = "0x240", .value = 0x240 }, + { .description = "0x250", .value = 0x250 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "irq", .description = "IRQ", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 5, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { .description = "" } - } + { .description = "IRQ 2", .value = 2 }, + { .description = "IRQ 5", .value = 5 }, + { .description = "IRQ 7", .value = 7 }, + { .description = "IRQ 10", .value = 10 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "dma", .description = "DMA", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 1, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "DMA 0", - .value = 0 - }, - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { .description = "" } - } + { .description = "DMA 0", .value = 0 }, + { .description = "DMA 1", .value = 1 }, + { .description = "DMA 3", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "ide_ctrl", .description = "IDE Controller", .type = CONFIG_HEX16, - .default_string = "", + .default_string = NULL, .default_int = 0x0000, - .file_filter = "", + .file_filter = NULL, .spinner = { 0 }, .selection = { - { - .description = "Disabled", - .value = 0x0000 - }, - { - .description = "0x170, IRQ 15", - .value = 0xf170 - }, - { - .description = "0x1E8, IRQ 11", - .value = 0xb1e8 - }, - { - .description = "0x168, IRQ 9", - .value = 0x9168 - }, - { - .description = "0x168, IRQ 10", - .value = 0xa168 - }, - { .description = "" } - } + { .description = "Disabled", .value = 0x0000 }, + { .description = "0x170, IRQ 15", .value = 0xf170 }, + { .description = "0x1E8, IRQ 11", .value = 0xb1e8 }, + { .description = "0x168, IRQ 9", .value = 0x9168 }, + { .description = "0x168, IRQ 10", .value = 0xa168 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 0 + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .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 ess_688_pnp_config[] = { { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format on static const device_config_t ess_1688_pnp_config[] = { { - .name = "control_pc_speaker", - .description = "Control PC speaker", - .type = CONFIG_BINARY, + .name = "control_pc_speaker", + .description = "Control PC speaker", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 0 + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input", - .description = "Receive input (DSP MIDI)", - .type = CONFIG_BINARY, + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 1 + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "receive_input401", - .description = "Receive input (MPU-401)", - .type = CONFIG_BINARY, + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .type = CONFIG_BINARY, .default_string = "", - .default_int = 0 + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -5505,11 +5379,11 @@ const device_t sb_1_device = { .name = "Sound Blaster v1.0", .internal_name = "sb", .flags = DEVICE_ISA, - .local = 0, - .init = sb_1_init, + .local = SB_1, + .init = sb_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_config @@ -5519,11 +5393,11 @@ const device_t sb_15_device = { .name = "Sound Blaster v1.5", .internal_name = "sb1.5", .flags = DEVICE_ISA, - .local = 0, - .init = sb_15_init, + .local = SB_15, + .init = sb_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb15_config @@ -5537,7 +5411,7 @@ const device_t sb_mcv_device = { .init = sb_mcv_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_mcv_config @@ -5547,11 +5421,11 @@ const device_t sb_2_device = { .name = "Sound Blaster v2.0", .internal_name = "sb2.0", .flags = DEVICE_ISA, - .local = 0, - .init = sb_2_init, + .local = SB_2, + .init = sb_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb2_config @@ -5565,7 +5439,7 @@ const device_t sb_pro_v1_device = { .init = sb_pro_v1_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_pro_config @@ -5579,7 +5453,7 @@ const device_t sb_pro_v2_device = { .init = sb_pro_v2_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_pro_config @@ -5593,7 +5467,7 @@ const device_t sb_pro_mcv_device = { .init = sb_pro_mcv_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_pro_mcv_config @@ -5602,12 +5476,12 @@ const device_t sb_pro_mcv_device = { const device_t sb_pro_compat_device = { .name = "Sound Blaster Pro (Compatibility)", .internal_name = "sbpro_compat", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = sb_pro_compat_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = NULL @@ -5616,68 +5490,26 @@ const device_t sb_pro_compat_device = { const device_t sb_16_device = { .name = "Sound Blaster 16", .internal_name = "sb16", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = FM_YMF262, .init = sb_16_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_config }; -const device_t sb_vibra16s_onboard_device = { - .name = "Sound Blaster ViBRA 16S (On-Board)", - .internal_name = "sb_vibra16s_onboard", - .flags = DEVICE_ISA | DEVICE_AT, - .local = FM_YMF289B, - .init = sb_16_init, - .close = sb_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = sb_speed_changed, - .force_redraw = NULL, - .config = sb_16_config -}; - -const device_t sb_vibra16s_device = { - .name = "Sound Blaster ViBRA 16S", - .internal_name = "sb_vibra16s", - .flags = DEVICE_ISA | DEVICE_AT, - .local = FM_YMF289B, - .init = sb_16_init, - .close = sb_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = sb_speed_changed, - .force_redraw = NULL, - .config = sb_16_config -}; - -const device_t sb_vibra16xv_device = { - .name = "Sound Blaster ViBRA 16XV", - .internal_name = "sb_vibra16xv", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = sb_vibra16_pnp_init, - .close = sb_close, - .reset = NULL, - { .available = sb_vibra16xv_available }, - .speed_changed = sb_speed_changed, - .force_redraw = NULL, - .config = sb_16_pnp_config -}; - const device_t sb_vibra16c_onboard_device = { .name = "Sound Blaster ViBRA 16C (On-Board)", .internal_name = "sb_vibra16c_onboard", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, + .flags = DEVICE_ISA16, + .local = SB_VIBRA16C, .init = sb_vibra16_pnp_init, .close = sb_close, .reset = NULL, - { .available = sb_vibra16c_available }, + .available = sb_vibra16c_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_pnp_config @@ -5686,12 +5518,96 @@ const device_t sb_vibra16c_onboard_device = { const device_t sb_vibra16c_device = { .name = "Sound Blaster ViBRA 16C", .internal_name = "sb_vibra16c", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, + .flags = DEVICE_ISA16, + .local = SB_VIBRA16C, .init = sb_vibra16_pnp_init, .close = sb_close, .reset = NULL, - { .available = sb_vibra16c_available }, + .available = sb_vibra16c_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16cl_onboard_device = { + .name = "Sound Blaster ViBRA 16CL (On-Board)", + .internal_name = "sb_vibra16cl_onboard", + .flags = DEVICE_ISA16, + .local = SB_VIBRA16CL, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16cl_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16cl_device = { + .name = "Sound Blaster ViBRA 16CL", + .internal_name = "sb_vibra16cl", + .flags = DEVICE_ISA16, + .local = SB_VIBRA16CL, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16cl_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16s_onboard_device = { + .name = "Sound Blaster ViBRA 16S (On-Board)", + .internal_name = "sb_vibra16s_onboard", + .flags = DEVICE_ISA16, + .local = FM_YMF289B, + .init = sb_16_init, + .close = sb_close, + .reset = NULL, + .available = NULL, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_config +}; + +const device_t sb_vibra16s_device = { + .name = "Sound Blaster ViBRA 16S", + .internal_name = "sb_vibra16s", + .flags = DEVICE_ISA16, + .local = FM_YMF289B, + .init = sb_16_init, + .close = sb_close, + .reset = NULL, + .available = NULL, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_config +}; + +const device_t sb_vibra16xv_onboard_device = { + .name = "Sound Blaster ViBRA 16XV (On-Board)", + .internal_name = "sb_vibra16xv_onboard", + .flags = DEVICE_ISA16, + .local = SB_VIBRA16XV, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16xv_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16xv_device = { + .name = "Sound Blaster ViBRA 16XV", + .internal_name = "sb_vibra16xv", + .flags = DEVICE_ISA16, + .local = SB_VIBRA16XV, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_vibra16xv_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_pnp_config @@ -5705,7 +5621,7 @@ const device_t sb_16_reply_mca_device = { .init = sb_16_reply_mca_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_pnp_config @@ -5714,12 +5630,26 @@ const device_t sb_16_reply_mca_device = { const device_t sb_16_pnp_device = { .name = "Sound Blaster 16 PnP", .internal_name = "sb16_pnp", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, + .flags = DEVICE_ISA16, + .local = SB_16_PNP_NOIDE, .init = sb_16_pnp_init, .close = sb_close, .reset = NULL, - { .available = sb_16_pnp_available }, + .available = sb_16_pnp_noide_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_16_pnp_ide_device = { + .name = "Sound Blaster 16 PnP (IDE)", + .internal_name = "sb16_pnp_ide", + .flags = DEVICE_ISA16, + .local = SB_16_PNP_IDE, + .init = sb_16_pnp_init, + .close = sb_close, + .reset = NULL, + .available = sb_16_pnp_ide_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_16_pnp_config @@ -5728,12 +5658,12 @@ const device_t sb_16_pnp_device = { const device_t sb_16_compat_device = { .name = "Sound Blaster 16 (Compatibility)", .internal_name = "sb16_compat", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 1, .init = sb_16_compat_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = NULL @@ -5742,26 +5672,40 @@ const device_t sb_16_compat_device = { const device_t sb_16_compat_nompu_device = { .name = "Sound Blaster 16 (Compatibility - MPU-401 Off)", .internal_name = "sb16_compat", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = sb_16_compat_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = NULL }; +const device_t sb_goldfinch_device = { + .name = "Creative EMU8000 PnP (Goldfinch)", + .internal_name = "sb_goldfinch", + .flags = DEVICE_ISA16, + .local = 0, + .init = sb_goldfinch_init, + .close = sb_goldfinch_close, + .reset = NULL, + .available = sb_goldfinch_available, + .speed_changed = NULL, + .force_redraw = NULL, + .config = sb_goldfinch_config +}; + const device_t sb_32_pnp_device = { .name = "Sound Blaster 32 PnP", .internal_name = "sb32_pnp", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, + .flags = DEVICE_ISA16, + .local = SB_32_PNP, .init = sb_awe32_pnp_init, .close = sb_awe32_close, .reset = NULL, - { .available = sb_32_pnp_available }, + .available = sb_32_pnp_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_32_pnp_config @@ -5770,12 +5714,12 @@ const device_t sb_32_pnp_device = { const device_t sb_awe32_device = { .name = "Sound Blaster AWE32", .internal_name = "sbawe32", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = sb_awe32_init, .close = sb_awe32_close, .reset = NULL, - { .available = sb_awe32_available }, + .available = sb_awe32_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_awe32_config @@ -5784,12 +5728,12 @@ const device_t sb_awe32_device = { const device_t sb_awe32_pnp_device = { .name = "Sound Blaster AWE32 PnP", .internal_name = "sbawe32_pnp", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 1, + .flags = DEVICE_ISA16, + .local = SB_AWE32_PNP, .init = sb_awe32_pnp_init, .close = sb_awe32_close, .reset = NULL, - { .available = sb_awe32_pnp_available }, + .available = sb_awe32_pnp_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_awe32_pnp_config @@ -5798,12 +5742,12 @@ const device_t sb_awe32_pnp_device = { const device_t sb_awe64_value_device = { .name = "Sound Blaster AWE64 Value", .internal_name = "sbawe64_value", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 2, + .flags = DEVICE_ISA16, + .local = SB_AWE64_VALUE, .init = sb_awe32_pnp_init, .close = sb_awe32_close, .reset = NULL, - { .available = sb_awe64_value_available }, + .available = sb_awe64_value_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_awe64_value_config @@ -5812,12 +5756,26 @@ const device_t sb_awe64_value_device = { const device_t sb_awe64_device = { .name = "Sound Blaster AWE64", .internal_name = "sbawe64", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 3, + .flags = DEVICE_ISA16, + .local = SB_AWE64_NOIDE, .init = sb_awe32_pnp_init, .close = sb_awe32_close, .reset = NULL, - { .available = sb_awe64_available }, + .available = sb_awe64_noide_available, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_awe64_config +}; + +const device_t sb_awe64_ide_device = { + .name = "Sound Blaster AWE64 (IDE)", + .internal_name = "sbawe64_ide", + .flags = DEVICE_ISA16, + .local = SB_AWE64_IDE, + .init = sb_awe32_pnp_init, + .close = sb_awe32_close, + .reset = NULL, + .available = sb_awe64_ide_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_awe64_config @@ -5826,12 +5784,12 @@ const device_t sb_awe64_device = { const device_t sb_awe64_gold_device = { .name = "Sound Blaster AWE64 Gold", .internal_name = "sbawe64_gold", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 4, + .flags = DEVICE_ISA16, + .local = SB_AWE64_GOLD, .init = sb_awe32_pnp_init, .close = sb_awe32_close, .reset = NULL, - { .available = sb_awe64_gold_available }, + .available = sb_awe64_gold_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = sb_awe64_gold_config @@ -5845,7 +5803,7 @@ const device_t ess_688_device = { .init = ess_x688_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_688_config @@ -5859,7 +5817,7 @@ const device_t ess_ess0100_pnp_device = { .init = ess_x688_pnp_init, .close = sb_close, .reset = NULL, - { .available = ess_688_pnp_available }, + .available = ess_688_pnp_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_688_pnp_config @@ -5873,7 +5831,7 @@ const device_t ess_1688_device = { .init = ess_x688_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_1688_config @@ -5887,7 +5845,7 @@ const device_t ess_ess0102_pnp_device = { .init = ess_x688_pnp_init, .close = sb_close, .reset = NULL, - { .available = ess_1688_pnp_available }, + .available = ess_1688_pnp_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_1688_pnp_config @@ -5901,7 +5859,7 @@ const device_t ess_ess0968_pnp_device = { .init = ess_x688_pnp_init, .close = sb_close, .reset = NULL, - { .available = ess_1688_968_pnp_available }, + .available = ess_1688_968_pnp_available, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_1688_pnp_config @@ -5915,7 +5873,7 @@ const device_t ess_soundpiper_16_mca_device = { .init = ess_x688_mca_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_688_pnp_config @@ -5929,7 +5887,7 @@ const device_t ess_soundpiper_32_mca_device = { .init = ess_x688_mca_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_1688_pnp_config @@ -5943,10 +5901,8 @@ const device_t ess_chipchat_16_mca_device = { .init = ess_x688_mca_init, .close = sb_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = sb_speed_changed, .force_redraw = NULL, .config = ess_1688_pnp_config }; - - diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 2513d36f6..9ce0b9fb7 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -77,13 +77,33 @@ static int sb_commands[256] = { -1, -1, 0, 0, -1, -1, -1, -1, -1, 1, 2, -1, -1, -1, -1, 0 }; +#if 0 +// Currently unused, here for reference if ever needed +char sb202_copyright[] = "COPYRIGHT(C) CREATIVE TECHNOLOGY PTE. LTD. (1991) " +#endif char sb16_copyright[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992."; -uint16_t sb_dsp_versions[] = { 0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x40c, 0x40d, 0x410 }; +uint16_t sb_dsp_versions[] = { + 0, /* Pad */ + 0, /* SADLIB - No DSP */ + 0x105, /* SB_DSP_105 - SB1/1.5, DSP v1.05 */ + 0x200, /* SB_DSP_200 - SB1.5/2, DSP v2.00 */ + 0x201, /* SB_DSP_201 - SB1.5/2, DSP v2.01 - needed for high-speed DMA */ + 0x202, /* SB_DSP_202 - SB2, DSP v2.02 */ + 0x300, /* SB_PRO_DSP_300 - SB Pro, DSP v3.00 */ + 0x302, /* SBPRO2_DSP_302 - SB Pro 2, DSP v3.02 + OPL3 */ + 0x404, /* SB16_DSP_404 - DSP v4.04 + OPL3 */ + 0x405, /* SB16_405 - DSP v4.05 + OPL3 */ + 0x406, /* SB16_406 - DSP v4.06 + OPL3 */ + 0x40b, /* SB16_411 - DSP v4.11 + OPL3 */ + 0x40c, /* SBAWE32 - DSP v4.12 + OPL3 */ + 0x40d, /* SBAWE32PNP - DSP v4.13 + OPL3 */ + 0x410 /* SBAWE64 - DSP v4.16 + OPL3 */ +}; /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 }; @@ -446,11 +466,47 @@ sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu) mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp); } +static void +sb_stop_dma(const sb_dsp_t *dsp) +{ + dma_set_drq(dsp->sb_8_dmanum, 0); + + if (dsp->sb_16_dmanum != 0xff) { + if (dsp->sb_16_dmanum == 4) + dma_set_drq(dsp->sb_8_dmanum, 0); + else + dma_set_drq(dsp->sb_16_dmanum, 0); + } + + if (dsp->sb_16_8_dmanum != 0xff) + dma_set_drq(dsp->sb_16_8_dmanum, 0); +} + +static void +sb_finish_dma(sb_dsp_t *dsp) +{ + if (dsp->ess_playback_mode) { + ESSreg(0xB8) &= ~0x01; + dma_set_drq(dsp->sb_8_dmanum, 0); + } else + sb_stop_dma(dsp); +} + void sb_dsp_reset(sb_dsp_t *dsp) { midi_clear_buffer(); + if (dsp->sb_8_enable) { + dsp->sb_8_enable = 0; + sb_finish_dma(dsp); + } + + if (dsp->sb_16_enable) { + dsp->sb_16_enable = 0; + sb_finish_dma(dsp); + } + timer_disable(&dsp->output_timer); timer_disable(&dsp->input_timer); @@ -489,7 +545,7 @@ sb_doreset(sb_dsp_t *dsp) sb_commands[8] = 1; sb_commands[9] = 1; } else { - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) sb_commands[8] = 1; else sb_commands[8] = -1; @@ -565,22 +621,6 @@ sb_resume_dma(const sb_dsp_t *dsp, const int is_8) } } -static void -sb_stop_dma(const sb_dsp_t *dsp) -{ - dma_set_drq(dsp->sb_8_dmanum, 0); - - if (dsp->sb_16_dmanum != 0xff) { - if (dsp->sb_16_dmanum == 4) - dma_set_drq(dsp->sb_8_dmanum, 0); - else - dma_set_drq(dsp->sb_16_dmanum, 0); - } - - if (dsp->sb_16_8_dmanum != 0xff) - dma_set_drq(dsp->sb_16_8_dmanum, 0); -} - void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { @@ -1186,7 +1226,7 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the current DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_8051_ram[0x20] = dsp->sb_command; } @@ -1212,15 +1252,15 @@ sb_exec_command(sb_dsp_t *dsp) switch (dsp->sb_command) { case 0x01: /* ???? */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; break; case 0x03: /* ASP status */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) sb_add_data(dsp, 0); break; case 0x04: /* ASP set mode register */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_asp_mode = dsp->sb_data[0]; if (dsp->sb_asp_mode & 4) dsp->sb_asp_ram_index = 0; @@ -1228,7 +1268,7 @@ sb_exec_command(sb_dsp_t *dsp) } /* else DSP Status (Obsolete) */ break; case 0x05: /* ASP set codec parameter */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); } break; @@ -1258,9 +1298,9 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ break; } - if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + if (dsp->sb_type == SBAWE64_DSP_416) /* AWE64 has no ASP or a socket for it */ sb_add_data(dsp, 0xFF); - else if (dsp->sb_type >= SB16) + else if (dsp->sb_type >= SB16_DSP_404) sb_add_data(dsp, 0x18); break; case 0x09: /* AZTECH mode set */ @@ -1276,7 +1316,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ @@ -1295,7 +1335,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ if (dsp->sb_asp_mode & 8) dsp->sb_asp_ram_index = 0; @@ -1339,11 +1379,11 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x1C: /* 8-bit autoinit DMA output */ - if (dsp->sb_type >= SB15) + if (dsp->sb_type >= SB_DSP_200) sb_start_dma(dsp, 1, 1, 0, dsp->sb_8_autolen); break; case 0x1F: /* 2-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { + if (dsp->sb_type >= SB_DSP_200) { sb_start_dma(dsp, 1, 1, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; @@ -1368,7 +1408,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x28: /* Direct ADC, 8-bit (Burst) */ break; case 0x2C: /* 8-bit autoinit DMA input */ - if (dsp->sb_type >= SB15) + if (dsp->sb_type >= SB_DSP_200) sb_start_dma_i(dsp, 1, 1, 0, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); break; case 0x30: /* MIDI Polling mode input */ @@ -1385,7 +1425,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x33: /* MIDI Read Timestamp Interrupt */ break; case 0x34: /* MIDI In poll */ - if (dsp->sb_type < SB2) + if (dsp->sb_type < SB_DSP_200) break; sb_dsp_log("MIDI poll in\n"); dsp->midi_in_poll = 1; @@ -1393,7 +1433,7 @@ sb_exec_command(sb_dsp_t *dsp) dsp->uart_irq = 0; break; case 0x35: /* MIDI In irq */ - if (dsp->sb_type < SB2) + if (dsp->sb_type < SB_DSP_200) break; sb_dsp_log("MIDI irq in\n"); dsp->midi_in_poll = 0; @@ -1412,7 +1452,7 @@ sb_exec_command(sb_dsp_t *dsp) temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%f)\n", temp, dsp->sblatcho); - if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16)) + if ((dsp->sb_freq != temp) && (dsp->sb_type >= SB16_DSP_404)) recalc_sb16_filter(0, temp); dsp->sb_freq = temp; if (IS_ESS(dsp)) { @@ -1421,7 +1461,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sblatcho = (double) ((double) TIMER_USEC * (1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); sb_dsp_log("Sample rate - %ihz (%f)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; @@ -1439,7 +1479,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x47: /* Continue Auto-Initialize DMA, 16-bit */ break; case 0x48: /* Set DSP block transfer size */ - dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); + if (dsp->sb_type >= SB_DSP_200) + dsp->sb_8_autolen = dsp->sb_data[0] + (dsp->sb_data[1] << 8); break; case 0x65: /* 4-bit ESPCM output with reference */ case 0x64: /* 4-bit ESPCM output */ @@ -1514,7 +1555,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x7D: /* 4-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { + if (dsp->sb_type >= SB_DSP_200) { sb_start_dma(dsp, 1, 1, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; @@ -1522,7 +1563,7 @@ sb_exec_command(sb_dsp_t *dsp) } break; case 0x7F: /* 2.6-bit ADPCM autoinit output */ - if (dsp->sb_type >= SB15) { + if (dsp->sb_type >= SB_DSP_200) { sb_start_dma(dsp, 1, 1, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = dsp->dma_readb(dsp->dma_priv); dsp->sb_8_length--; @@ -1535,24 +1576,24 @@ 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 >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // 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 >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // 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 >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // 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 >= SB2) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404)) // TODO docs need validated sb_start_dma_i(dsp, 1, 0, 0, dsp->sb_8_autolen); break; case 0xA0: /* Set input mode to mono */ case 0xA8: /* Set input mode to stereo */ - if ((dsp->sb_type < SB2) || (dsp->sb_type > SBPRO2)) + if ((dsp->sb_type < SBPRO_DSP_300) || (dsp->sb_type > SBPRO2_DSP_302)) break; /* TODO: Implement. 3.xx-only command. */ break; @@ -1564,7 +1605,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xB5: case 0xB6: case 0xB7: /* 16-bit DMA output */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1578,7 +1619,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xBD: case 0xBE: case 0xBF: /* 16-bit DMA input */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma_i(dsp, 0, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_16_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1592,7 +1633,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xC5: case 0xC6: case 0xC7: /* 8-bit DMA output */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1606,7 +1647,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0xCD: case 0xCE: case 0xCF: /* 8-bit DMA input */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { sb_start_dma_i(dsp, 1, dsp->sb_command & 4, dsp->sb_data[0], dsp->sb_data[1] + (dsp->sb_data[2] << 8)); dsp->sb_8_autolen = dsp->sb_data[1] + (dsp->sb_data[2] << 8); @@ -1618,20 +1659,20 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0xD1: /* Speaker on */ if (IS_NOT_ESS(dsp)) { - if (dsp->sb_type < SB15) { + if (dsp->sb_type < SB_DSP_200) { dsp->sb_8_pause = 1; sb_stop_dma(dsp); - } else if (dsp->sb_type < SB16) + } else if (dsp->sb_type < SB16_DSP_404) dsp->muted = 0; } dsp->sb_speaker = 1; break; case 0xD3: /* Speaker off */ if (IS_NOT_ESS(dsp)) { - if (dsp->sb_type < SB15) { + if (dsp->sb_type < SB_DSP_201) { dsp->sb_8_pause = 1; sb_stop_dma(dsp); - } else if (dsp->sb_type < SB16) + } else if (dsp->sb_type < SB16_DSP_404) dsp->muted = 1; } dsp->sb_speaker = 0; @@ -1641,32 +1682,38 @@ sb_exec_command(sb_dsp_t *dsp) sb_resume_dma(dsp, 1); break; case 0xD5: /* Pause 16-bit DMA */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_16_pause = 1; sb_stop_dma(dsp); } break; case 0xD6: /* Continue 16-bit DMA */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { dsp->sb_16_pause = 0; sb_resume_dma(dsp, 1); } break; case 0xD8: /* Get speaker status */ - sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); + if (dsp->sb_type >= SB_DSP_200) + sb_add_data(dsp, dsp->sb_speaker ? 0xff : 0); break; case 0xD9: /* Exit 16-bit auto-init mode */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->sb_16_autoinit = 0; break; case 0xDA: /* Exit 8-bit auto-init mode */ - dsp->sb_8_autoinit = 0; + if (dsp->sb_type >= SB_DSP_200) + dsp->sb_8_autoinit = 0; break; case 0xE0: /* DSP identification */ sb_add_data(dsp, ~dsp->sb_data[0]); break; case 0xE1: /* Get DSP version */ if (IS_ESS(dsp)) { + /* + 0x03 0x01 (Sound Blaster Pro compatibility) confirmed by both the + ES1888 datasheet and the probing of the real ES688 and ES1688 cards. + */ sb_add_data(dsp, 0x3); sb_add_data(dsp, 0x1); break; @@ -1697,14 +1744,17 @@ sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, dsp->sbe2); break; case 0xE3: /* DSP copyright */ - if (dsp->sb_type >= SB16) { + if (dsp->sb_type >= SB16_DSP_404) { c = 0; while (sb16_copyright[c]) sb_add_data(dsp, sb16_copyright[c++]); sb_add_data(dsp, 0); - } else if (IS_ESS(dsp)) { - sb_add_data(dsp, 0); - } + } /* else if (IS_ESS(dsp)) + sb_add_data(dsp, 0); */ + /* + TODO: What ESS card returns 0x00 here? Probing of the real ES688 and ES1688 cards + revealed that they in fact return nothing on this command. + */ break; case 0xE4: /* Write test register */ dsp->sb_test = dsp->sb_data[0]; @@ -1716,12 +1766,26 @@ sb_exec_command(sb_dsp_t *dsp) break; case SB_SUBTYPE_ESS_ES688: sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x04); + /* + 80h: ESSCFG fails to detect the AudioDrive; + 81h-83h: ES??88, Windows 3.1 driver expects MPU-401 and gives a legacy mixer error; + 84h: ES688, Windows 3.1 driver expects MPU-401, returned by DOSBox-X; + 85h-87h: ES688, Windows 3.1 driver does not expect MPU-401: + 85h: Returned by MSDOS622's real ESS688, + 86h: Returned by Dizzy's real ES688. + We return 86h if MPU is absent, 84h otherwise, who knows what the actual + PnP ES688 returns here. + */ + sb_add_data(dsp, 0x80 | ((dsp->mpu != NULL) ? 0x04 : 0x06)); break; case SB_SUBTYPE_ESS_ES1688: - // Determined via Windows driver debugging. sb_add_data(dsp, 0x68); - sb_add_data(dsp, 0x80 | 0x09); + /* + 89h: ES1688, returned by DOSBox-X, determined via Windows driver + debugging; + 8Bh: ES1688, returned by both MSDOS622's and Dizzy's real ES1688's. + */ + sb_add_data(dsp, 0x80 | 0x0b); break; } } @@ -1741,15 +1805,15 @@ sb_exec_command(sb_dsp_t *dsp) timer_set_delay_u64(&dsp->irq16_timer, (10ULL * TIMER_USEC)); break; case 0xF8: - if (dsp->sb_type < SB16) + if (dsp->sb_type < SB16_DSP_404) sb_add_data(dsp, 0); break; case 0xF9: /* SB16 8051 RAM read */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); break; case 0xFA: /* SB16 8051 RAM write */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; break; case 0xFF: /* No, that's not how you program auto-init DMA */ @@ -1759,11 +1823,24 @@ sb_exec_command(sb_dsp_t *dsp) * http://the.earth.li/~tfm/oldpage/sb_dsp.html * http://www.synchrondata.com/pheaven/www/area19.htm * http://www.dcee.net/Files/Programm/Sound/ - * 0E3h DSP Copyright SBPro2??? - * 0F0h Sine Generator SB - * 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 - * 0F2h IRQ Request, 8-bit SB + * https://github.com/schlae/sb-firmware/blob/master/sbv202.asm + * 008h Halt (Infinate Loop) SB2??? + * 018h DMA playback with auto init DMA. SB2??? + * 028h Auto-init direct ADC SB2??? + * 036h (Timestamp) SB??? + * 037h (Timestamp) SB??? + * 050h Stops playback of SRAM samples SB??? + * 051h Plays back samples stored in SRAM. SB??? + * 058h Load data into SRAM SB??? + * 059h Fetches the samples and then immediately plays them back. SB??? + * 078h Auto-init DMA ADPCM SB2??? + * 07Ah 2.6-bit ADPCM SB??? + * 0E3h DSP Copyright SBPro2??? (SBPRO2_DSP_302) + * 0F0h Sine Generator SB (SB_DSP_105, DSP20x) + * 0F1h DSP Auxiliary Status (Obsolete) SB-Pro2 (DSP20x, SBPRO2_DSP_302) + * 0F2h IRQ Request, 8-bit SB (SB_DSP_105, DSP20x) * 0F3h IRQ Request, 16-bit SB16 + * 0F4h Perform ROM checksum SB (SB_DSP_105, DSP20x) * 0FBh DSP Status SB16 * 0FCh DSP Auxiliary Status SB16 * 0FDh DSP Command Status SB16 @@ -1776,7 +1853,7 @@ sb_exec_command(sb_dsp_t *dsp) /* Update 8051 ram with the last DSP command. See https://github.com/joncampbell123/dosbox-x/issues/1044 */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16_DSP_404) dsp->sb_8051_ram[0x30] = dsp->sb_command; } @@ -1795,31 +1872,31 @@ sb_do_reset(sb_dsp_t *dsp, const uint8_t v) } void -sb_write(uint16_t a, uint8_t v, void *priv) +sb_write(uint16_t addr, uint8_t val, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; - sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, a, v); + sb_dsp_log("[%04X:%08X] DSP: [W] %04X = %02X\n", CS, cpu_state.pc, addr, val); /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xE))) - a &= 0xfffe; + if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xE))) + addr &= 0xfffe; - switch (a & 0xF) { + switch (addr & 0xF) { case 6: /* Reset */ - sb_do_reset(dsp, v); + sb_do_reset(dsp, val); - if (!(v & 2) && (dsp->espcm_fifo_reset & 2)) { + if (!(val & 2) && (dsp->espcm_fifo_reset & 2)) { fifo_reset(dsp->espcm_fifo); } - dsp->espcm_fifo_reset = v; + dsp->espcm_fifo_reset = val; dsp->uart_midi = 0; dsp->uart_irq = 0; dsp->onebyte_midi = 0; return; case 0xC: /* Command/data write */ if (dsp->uart_midi || dsp->onebyte_midi) { - midi_raw_out_byte(v); + midi_raw_out_byte(val); dsp->onebyte_midi = 0; return; } @@ -1832,8 +1909,8 @@ sb_write(uint16_t a, uint8_t v, void *priv) return; } if (dsp->sb_data_stat == -1) { - dsp->sb_command = v; - if (v == 0x01) + dsp->sb_command = val; + if (val == 0x01) sb_add_data(dsp, 0); dsp->sb_data_stat++; if (IS_AZTECH(dsp)) { @@ -1860,7 +1937,7 @@ sb_write(uint16_t a, uint8_t v, void *priv) } } } else { - dsp->sb_data[dsp->sb_data_stat++] = v; + dsp->sb_data[dsp->sb_data_stat++] = val; } if (dsp->sb_data_stat == sb_commands[dsp->sb_command] || sb_commands[dsp->sb_command] == -1) { sb_exec_command(dsp); @@ -1879,17 +1956,17 @@ sb_write(uint16_t a, uint8_t v, void *priv) } uint8_t -sb_read(uint16_t a, void *priv) +sb_read(uint16_t addr, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *) priv; uint8_t ret = 0x00; /* Sound Blasters prior to Sound Blaster 16 alias the I/O ports. */ - if ((dsp->sb_type < SB16) && (IS_NOT_ESS(dsp) || ((a & 0xF) != 0xF))) + if ((dsp->sb_type < SB16_DSP_404) && (IS_NOT_ESS(dsp) || ((addr & 0xF) != 0xF))) /* Exception: ESS AudioDrive does not alias port base+0xf */ - a &= 0xfffe; + addr &= 0xfffe; - switch (a & 0xf) { + switch (addr & 0xf) { case 0x6: if (IS_ESS(dsp)) { ret = (dsp->espcm_fifo_reset & 0x03) | 0x08 | (dsp->activity & 0xe0); @@ -1897,6 +1974,14 @@ sb_read(uint16_t a, void *priv) } else ret = 0xff; break; + case 0x7: + case 0xB: + /* + These two ports are tested for random noise by OS/2 Warp 4.0, so + return 0xff to get through said test. + */ + ret = 0xff; + break; case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) ret = MPU401_ReadData(dsp->mpu); @@ -1919,7 +2004,7 @@ sb_read(uint16_t a, void *priv) if (dsp->state == DSP_S_RESET_WAIT) dsp->state = DSP_S_NORMAL; if ((dsp->state == DSP_S_NORMAL) || IS_ESS(dsp)) { - if (dsp->sb_8_enable || dsp->sb_type >= SB16) + if (dsp->sb_8_enable || dsp->sb_type >= SB16_DSP_404) dsp->busy_count = (dsp->busy_count + 1) & 3; else dsp->busy_count = 0; @@ -1944,7 +2029,7 @@ sb_read(uint16_t a, void *priv) ret = 0x80; } else { sb_dsp_log("SB Write Data Creative read 0xff\n"); - if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp)) ret = 0xaa; else ret = 0xff; @@ -1954,12 +2039,14 @@ sb_read(uint16_t a, void *priv) ret = 0x00; } else { sb_dsp_log("SB Write Data Creative read 0x7f\n"); - if ((dsp->sb_type >= SB2) && (dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + if ((dsp->sb_type >= SB_DSP_201) && (dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp)) ret = 0x2a; else ret = 0x7f; } - } else + } else if (IS_AZTECH(dsp)) + ret = 0x00; + else ret = 0xff; break; case 0xE: /* Read data ready */ @@ -1976,15 +2063,13 @@ sb_read(uint16_t a, void *priv) ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; } else { sb_dsp_log("SB Read Data Creative read %02X\n", (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff); - if ((dsp->sb_type < SB16) && IS_NOT_ESS(dsp)) + if ((dsp->sb_type < SB16_DSP_404) && IS_NOT_ESS(dsp)) ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x2a : 0xaa; else ret = (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7f : 0xff; } - if (dsp->state == DSP_S_RESET_WAIT) { - ret &= 0x7f; + if (dsp->state == DSP_S_RESET_WAIT) dsp->state = DSP_S_NORMAL; - } break; case 0xF: /* 16-bit ack */ if (IS_NOT_ESS(dsp)) { @@ -2089,11 +2174,11 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) /* Default values. Use sb_dsp_setxxx() methods to change. */ dsp->sb_irqnum = 7; dsp->sb_8_dmanum = 1; - if (type >= SB16) + if (type >= SB16_DSP_404) dsp->sb_16_dmanum = 5; else dsp->sb_16_dmanum = 0xff; - if ((type >= SB16) || IS_ESS(dsp)) + if ((type >= SB16_DSP_404) || IS_ESS(dsp)) dsp->sb_16_8_dmanum = 0x1; dsp->mpu = NULL; @@ -2125,7 +2210,7 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) a set frequency command is sent. */ recalc_sb16_filter(0, 3200 * 2); } - if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2)) { + if (IS_ESS(dsp) || (dsp->sb_type >= SBPRO2_DSP_302)) { /* OPL3 or dual OPL2 is stereo. */ if (dsp->sb_has_real_opl) recalc_opl_filter(FREQ_49716 * 2); @@ -2206,16 +2291,6 @@ sb_dsp_dma_attach(sb_dsp_t *dsp, dsp->dma_priv = priv; } -static void -sb_finish_dma(sb_dsp_t *dsp) -{ - if (dsp->ess_playback_mode) { - ESSreg(0xB8) &= ~0x01; - dma_set_drq(dsp->sb_8_dmanum, 0); - } else - sb_stop_dma(dsp); -} - void sb_espcm_fifoctl_run(sb_dsp_t *dsp) { diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index d7bfa87b9..569d698d5 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -21,7 +21,15 @@ static float volslog[16] = { 7.51785f, 9.46440f, 11.9194f, 15.0000f }; -void +static int +sn76489_check_tap_2(sn76489_t *sn76489) +{ + int ret = ((sn76489->shift >> sn76489->white_noise_tap_2) & 1); + + return (sn76489->type == SN76496) ? ret : !ret; +} + +static void sn76489_update(sn76489_t *sn76489) { for (; sn76489->pos < sound_pos_global; sn76489->pos++) { @@ -42,24 +50,28 @@ sn76489_update(sn76489_t *sn76489) result += (((sn76489->shift & 1) ^ 1) * 127 * volslog[sn76489->vol[0]] * 2); sn76489->count[0] -= (512 * sn76489->psgconst); - while (sn76489->count[0] < 0 && sn76489->latch[0]) { + while ((sn76489->count[0] < 0) && sn76489->latch[0]) { sn76489->count[0] += (sn76489->latch[0] * 4); if (!(sn76489->noise & 4)) { - if (sn76489->shift & 1) - sn76489->shift |= 0x8000; - sn76489->shift >>= 1; + if ((sn76489->shift >> sn76489->white_noise_tap_1) & 1) { + sn76489->shift >>= 1; + sn76489->shift |= sn76489->feedback_mask; + } else + sn76489->shift >>= 1; } else { - if ((sn76489->shift & 1) ^ ((sn76489->shift >> 1) & 1)) - sn76489->shift |= 0x8000; - sn76489->shift >>= 1; + if (((sn76489->shift >> sn76489->white_noise_tap_1) & 1) ^ sn76489_check_tap_2(sn76489)) { + sn76489->shift >>= 1; + sn76489->shift |= sn76489->feedback_mask; + } else + sn76489->shift >>= 1; } } - sn76489->buffer[sn76489->pos] = result; + sn76489->buffer[sn76489->pos] = (sn76489->type == NCR8496) ? -result : result; } } -void +static void sn76489_get_buffer(int32_t *buffer, int len, void *priv) { sn76489_t *sn76489 = (sn76489_t *) priv; @@ -74,7 +86,7 @@ sn76489_get_buffer(int32_t *buffer, int len, void *priv) sn76489->pos = 0; } -void +static void sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv) { sn76489_t *sn76489 = (sn76489_t *) priv; @@ -125,15 +137,13 @@ sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv) sn76489->vol[1] = 0xf - data; break; case 0x60: - if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) - sn76489->shift = 0x4000; + if (((data & 4) != (sn76489->noise & 4)) || (sn76489->type == SN76496)) + sn76489->shift = sn76489->feedback_mask; sn76489->noise = data & 0xf; if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; else sn76489->latch[0] = 0x400 << (data & 3); - if (!sn76489->extra_divide) - sn76489->latch[0] &= 0x3ff; if (!sn76489->latch[0]) sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; break; @@ -146,22 +156,24 @@ sn76489_write(UNUSED(uint16_t addr), uint8_t data, void *priv) break; } } else { + /* NCR8496 ignores writes to registers 1, 3, 5, 6 and 7 with bit 7 clear. */ + if ((sn76489->type != SN76496) && ((sn76489->firstdat & 0x10) || ((sn76489->firstdat & 0x70) == 0x60))) + return; + if ((sn76489->firstdat & 0x70) == 0x60 && (sn76489->type == SN76496)) { - if ((data & 4) != (sn76489->noise & 4) || sn76489->type == SN76496) - sn76489->shift = 0x4000; + if (sn76489->type == SN76496) + sn76489->shift = sn76489->feedback_mask; sn76489->noise = data & 0xf; if ((data & 3) == 3) sn76489->latch[0] = sn76489->latch[1]; else sn76489->latch[0] = 0x400 << (data & 3); if (!sn76489->latch[0]) - sn76489->latch[0] = 1024 << 6; + sn76489->latch[0] = (sn76489->extra_divide ? 2048 : 1024) << 6; } else if ((sn76489->firstdat & 0x70) != 0x60) { - if (sn76489->extra_divide) - sn76489->freqhi[sn76489->lasttone] = data & 0x7F; - else - sn76489->freqhi[sn76489->lasttone] = data & 0x3F; - freq = sn76489->freqlo[sn76489->lasttone] | (sn76489->freqhi[sn76489->lasttone] << 4); + sn76489->freqhi[sn76489->lasttone] = data & 0x7F; + freq = sn76489->freqlo[sn76489->lasttone] | + (sn76489->freqhi[sn76489->lasttone] << 4); if (!sn76489->extra_divide) freq &= 0x3ff; if (!freq) @@ -177,12 +189,6 @@ void sn74689_set_extra_divide(sn76489_t *sn76489, int enable) { sn76489->extra_divide = enable; - - if (!enable) { - for (uint8_t c = 1; c < 4; c++) - sn76489->latch[c] &= ~(0x400 << 6); - sn76489->latch[0] &= ~(0x400 << 6); - } } void @@ -190,6 +196,16 @@ sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int fre { sound_add_handler(sn76489_get_buffer, sn76489); + if (type == SN76496) { + sn76489->white_noise_tap_1 = 0; + sn76489->white_noise_tap_2 = 1; + sn76489->feedback_mask = 0x4000; + } else { + sn76489->white_noise_tap_1 = 1; + sn76489->white_noise_tap_2 = 5; + sn76489->feedback_mask = 0x8000; + } + sn76489->latch[0] = sn76489->latch[1] = sn76489->latch[2] = sn76489->latch[3] = 0x3FF << 6; sn76489->vol[0] = 0; sn76489->vol[1] = sn76489->vol[2] = sn76489->vol[3] = 8; @@ -200,7 +216,7 @@ sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int fre sn76489->count[2] = (rand() & 0x3FF) << 6; sn76489->count[3] = (rand() & 0x3FF) << 6; sn76489->noise = 3; - sn76489->shift = 0x4000; + sn76489->shift = sn76489->feedback_mask; sn76489->type = type; sn76489->psgconst = (((double) freq / 64.0) / (double) FREQ_48000); @@ -212,8 +228,7 @@ sn76489_init(sn76489_t *sn76489, uint16_t base, uint16_t size, int type, int fre void * sn76489_device_init(UNUSED(const device_t *info)) { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = calloc(1, sizeof(sn76489_t)); sn76489_init(sn76489, 0x00c0, 0x0008, SN76496, 3579545); @@ -223,8 +238,7 @@ sn76489_device_init(UNUSED(const device_t *info)) void * ncr8496_device_init(UNUSED(const device_t *info)) { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = calloc(1, sizeof(sn76489_t)); sn76489_init(sn76489, 0x00c0, 0x0008, NCR8496, 3579545); @@ -234,8 +248,7 @@ ncr8496_device_init(UNUSED(const device_t *info)) void * tndy_device_init(UNUSED(const device_t *info)) { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = calloc(1, sizeof(sn76489_t)); uint16_t addr = device_get_config_hex16("base"); @@ -255,40 +268,23 @@ sn76489_device_close(void *priv) static const device_config_t tndy_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0C0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x0C0", - .value = 0x0C0 - }, - { - .description = "0x0E0", - .value = 0x0E0 - }, - { - .description = "0x1C0", - .value = 0x1C0 - }, - { - .description = "0x1E0", - .value = 0x1E0 - }, - { - .description = "0x2C0", - .value = 0x2C0 - }, - { - .description = "0x2E0", - .value = 0x2E0 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x0C0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x0C0", .value = 0x0C0 }, + { .description = "0x0E0", .value = 0x0E0 }, + { .description = "0x1C0", .value = 0x1C0 }, + { .description = "0x1E0", .value = 0x1E0 }, + { .description = "0x2C0", .value = 0x2C0 }, + { .description = "0x2E0", .value = 0x2E0 }, + { .description = "" } + }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -302,7 +298,7 @@ const device_t sn76489_device = { .init = sn76489_device_init, .close = sn76489_device_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -316,7 +312,7 @@ const device_t ncr8496_device = { .init = ncr8496_device_init, .close = sn76489_device_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -330,7 +326,7 @@ const device_t tndy_device = { .init = tndy_device_init, .close = sn76489_device_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = tndy_config diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index 1f3c294ce..f1620b817 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -21,6 +21,10 @@ typedef struct ssi2001_t { int gameport_enabled; } ssi2001_t; +typedef struct entertainer_t { + uint8_t regs; +} entertainer_t; + static void ssi2001_update(ssi2001_t *ssi2001) { @@ -66,10 +70,9 @@ ssi2001_write(uint16_t addr, uint8_t val, void *priv) void * ssi2001_init(UNUSED(const device_t *info)) { - ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); - memset(ssi2001, 0, sizeof(ssi2001_t)); + ssi2001_t *ssi2001 = calloc(1, sizeof(ssi2001_t)); - ssi2001->psid = sid_init(); + ssi2001->psid = sid_init(0); sid_reset(ssi2001->psid); uint16_t addr = device_get_config_hex16("base"); ssi2001->gameport_enabled = device_get_config_int("gameport"); @@ -90,52 +93,121 @@ ssi2001_close(void *priv) free(ssi2001); } +static uint8_t +entertainer_read(UNUSED(uint16_t addr), UNUSED(void *priv)) +{ + return 0xa5; +} + +static void +entertainer_write(UNUSED(uint16_t addr), uint8_t val, void *priv) +{ + entertainer_t *entertainer = (entertainer_t *) priv; + entertainer->regs = val; +} + +void * +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); + 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); + io_sethandler(0x280, 0x0020, ssi2001_read, NULL, NULL, ssi2001_write, NULL, NULL, ssi2001); + if (ssi2001->gameport_enabled) + gameport_remap(gameport_add(&gameport_201_device), 0x201); + sound_add_handler(ssi2001_get_buffer, ssi2001); + return ssi2001; +} + +void +entertainer_close(void *priv) +{ + ssi2001_t *ssi2001 = (ssi2001_t *) priv; + + sid_close(ssi2001->psid); + + free(ssi2001); +} + static const device_config_t ssi2001_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x280, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x280", - .value = 0x280 - }, - { - .description = "0x2A0", - .value = 0x2A0 - }, - { - .description = "0x2C0", - .value = 0x2C0 - }, - { - .description = "0x2E0", - .value = 0x2E0 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x280, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x280", .value = 0x280 }, + { .description = "0x2A0", .value = 0x2A0 }, + { .description = "0x2C0", .value = 0x2C0 }, + { .description = "0x2E0", .value = 0x2E0 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { "gameport", "Enable Game port", CONFIG_BINARY, "", 1 }, - { "", "", -1 } + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } // clang-format off }; -const device_t ssi2001_device = -{ - .name = "Innovation SSI-2001", - .internal_name = "ssi2001", - .flags = DEVICE_ISA, - .local = 0, - .init = ssi2001_init, - .close = ssi2001_close, - .reset = NULL, - { .available = NULL }, - .speed_changed = NULL, - .force_redraw = NULL, - .config = ssi2001_config +static const device_config_t entertainer_config[] = { + // clang-format off + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + +const device_t ssi2001_device = { + .name = "Innovation SSI-2001", + .internal_name = "ssi2001", + .flags = DEVICE_ISA, + .local = 0, + .init = ssi2001_init, + .close = ssi2001_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ssi2001_config +}; + +const device_t entertainer_device = { + .name = "The Entertainer", + .internal_name = "Entertainer", + .flags = DEVICE_ISA, + .local = 1, + .init = entertainer_init, + .close = entertainer_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = entertainer_config }; diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index da88b29e9..874638a80 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -107,8 +107,7 @@ wss_get_music_buffer(int32_t *buffer, int len, void *priv) void * wss_init(UNUSED(const device_t *info)) { - wss_t *wss = malloc(sizeof(wss_t)); - memset(wss, 0, sizeof(wss_t)); + wss_t *wss = calloc(1, sizeof(wss_t)); uint16_t addr = device_get_config_hex16("base"); wss->opl_enabled = device_get_config_int("opl"); @@ -209,8 +208,7 @@ ncr_audio_mca_feedb(void *priv) void * ncr_audio_init(UNUSED(const device_t *info)) { - wss_t *wss = malloc(sizeof(wss_t)); - memset(wss, 0, sizeof(wss_t)); + wss_t *wss = calloc(1, sizeof(wss_t)); fm_driver_get(FM_YMF262, &wss->opl); ad1848_init(&wss->ad1848, AD1848_TYPE_DEFAULT); @@ -247,39 +245,32 @@ wss_speed_changed(void *priv) static const device_config_t wss_config[] = { // clang-format off { - .name = "base", - .description = "Address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x530, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "0x530", - .value = 0x530 - }, - { - .description = "0x604", - .value = 0x604 - }, - { - .description = "0xe80", - .value = 0xe80 - }, - { - .description = "0xf40", - .value = 0xf40 - }, - { .description = "" } - } + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x530, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "0x530", .value = 0x530 }, + { .description = "0x604", .value = 0x604 }, + { .description = "0xe80", .value = 0xe80 }, + { .description = "0xf40", .value = 0xf40 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "opl", - .description = "Enable OPL", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "opl", + .description = "Enable OPL", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -288,12 +279,12 @@ static const device_config_t wss_config[] = { const device_t wss_device = { .name = "Windows Sound System", .internal_name = "wss", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = wss_init, .close = wss_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = wss_speed_changed, .force_redraw = NULL, .config = wss_config @@ -307,7 +298,7 @@ const device_t ncr_business_audio_device = { .init = ncr_audio_init, .close = wss_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = wss_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/sound/sound.c b/src/sound/sound.c index 254e529ca..28cb96629 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -122,16 +122,21 @@ static const SOUND_CARD sound_cards[] = { { &sb_pro_v2_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 }, { &sb_awe64_value_device }, { &sb_awe64_device }, + { &sb_awe64_ide_device }, { &sb_awe64_gold_device }, { &sb_vibra16c_device }, + { &sb_vibra16cl_device }, { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &ssi2001_device }, + { &entertainer_device }, { &pasplus_device }, { &pas16_device }, { &pas16d_device }, @@ -148,11 +153,15 @@ static const SOUND_CARD sound_cards[] = { { &ess_soundpiper_32_mca_device }, { &cmi8338_device }, { &cmi8738_device }, + { &es1370_device }, { &es1371_device }, { &es1373_device }, { &ct5880_device }, { &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/CMakeLists.txt b/src/sound/ymfm/CMakeLists.txt index e1ff35369..fcc07093f 100644 --- a/src/sound/ymfm/CMakeLists.txt +++ b/src/sound/ymfm/CMakeLists.txt @@ -9,4 +9,14 @@ # CMake build script. # -add_library(ymfm STATIC ymfm_misc.cpp ymfm_opl.cpp ymfm_opm.cpp ymfm_opn.cpp ymfm_opq.cpp ymfm_opz.cpp ymfm_pcm.cpp ymfm_adpcm.cpp) \ No newline at end of file +add_library(ymfm STATIC + ymfm_adpcm.cpp + ymfm_misc.cpp + ymfm_opl.cpp + ymfm_opm.cpp + ymfm_opn.cpp + ymfm_opq.cpp + ymfm_opz.cpp + ymfm_pcm.cpp + ymfm_ssg.cpp +) diff --git a/src/sound/ymfm/ymfm.h b/src/sound/ymfm/ymfm.h index c5986d66b..062247a82 100644 --- a/src/sound/ymfm/ymfm.h +++ b/src/sound/ymfm/ymfm.h @@ -42,12 +42,11 @@ #include #include #include +#include #include #include #include -#define SNPRINTF_BUFFER_SIZE_CALC (256 - (end - &buffer[0])) - namespace ymfm { @@ -111,17 +110,6 @@ inline int32_t clamp(int32_t value, int32_t minval, int32_t maxval) } -//------------------------------------------------- -// array_size - return the size of an array -//------------------------------------------------- - -template -constexpr uint32_t array_size(ArrayType (&array)[ArraySize]) -{ - return ArraySize; -} - - //------------------------------------------------- // count_leading_zeros - return the number of // leading zeros in a 32-bit value; CPU-optimized @@ -256,7 +244,8 @@ inline int16_t roundtrip_fp(int32_t value) // apply the shift back and forth to zero out bits that are lost exponent -= 1; - return (value >> exponent) << exponent; + int32_t mask = (1 << exponent) - 1; + return value & ~mask; } @@ -352,7 +341,7 @@ public: { // create file char name[20]; - snprintf(name, sizeof(name), "wavlog-%02d.wav", m_index); + snprintf(&name[0], sizeof(name), "wavlog-%02d.wav", m_index); FILE *out = fopen(name, "wb"); // make the wav file header @@ -485,7 +474,7 @@ public: class ymfm_engine_callbacks { public: - virtual ~ymfm_engine_callbacks() = default; + virtual ~ymfm_engine_callbacks() = default; // timer callback; called by the interface when a timer fires virtual void engine_timer_expired(uint32_t tnum) = 0; @@ -509,6 +498,7 @@ class ymfm_interface public: virtual ~ymfm_interface() = default; + // the following functions must be implemented by any derived classes; the // default implementations are sufficient for some minimal operation, but will // likely need to be overridden to integrate with the outside world; they are diff --git a/src/sound/ymfm/ymfm_fm.h b/src/sound/ymfm/ymfm_fm.h index 81795f8fe..d40409fdd 100644 --- a/src/sound/ymfm/ymfm_fm.h +++ b/src/sound/ymfm/ymfm_fm.h @@ -267,7 +267,7 @@ public: // assign operators void assign(uint32_t index, fm_operator *op) { - assert(index < array_size(m_op)); + assert(index < m_op.size()); m_op[index] = op; if (op != nullptr) op->set_choffs(m_choffs); @@ -330,7 +330,7 @@ private: uint32_t m_choffs; // channel offset in registers int16_t m_feedback[2]; // feedback memory for operator 1 mutable int16_t m_feedback_in; // next input value for op 1 feedback (set in output) - fm_operator *m_op[4]; // up to 4 operators + std::array *, 4> m_op; // up to 4 operators RegisterType &m_regs; // direct reference to registers fm_engine_base &m_owner; // reference to the owning engine }; diff --git a/src/sound/ymfm/ymfm_fm.ipp b/src/sound/ymfm/ymfm_fm.ipp index a3ee8d333..f2ec83945 100644 --- a/src/sound/ymfm/ymfm_fm.ipp +++ b/src/sound/ymfm/ymfm_fm.ipp @@ -839,12 +839,12 @@ void fm_channel::save_restore(ymfm_saved_state &state) template void fm_channel::keyonoff(uint32_t states, keyon_type type, uint32_t chnum) { - for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++) + for (uint32_t opnum = 0; opnum < m_op.size(); opnum++) if (m_op[opnum] != nullptr) m_op[opnum]->keyonoff(bitfield(states, opnum), type); if (debug::LOG_KEYON_EVENTS && ((debug::GLOBAL_FM_CHANNEL_MASK >> chnum) & 1) != 0) - for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++) + for (uint32_t opnum = 0; opnum < m_op.size(); opnum++) if (m_op[opnum] != nullptr) debug::log_keyon("%c%s\n", bitfield(states, opnum) ? '+' : '-', m_regs.log_keyon(m_choffs, m_op[opnum]->opoffs()).c_str()); } @@ -860,7 +860,7 @@ bool fm_channel::prepare() uint32_t active_mask = 0; // prepare all operators and determine if they are active - for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++) + for (uint32_t opnum = 0; opnum < m_op.size(); opnum++) if (m_op[opnum] != nullptr) if (m_op[opnum]->prepare()) active_mask |= 1 << opnum; @@ -880,7 +880,7 @@ void fm_channel::clock(uint32_t env_counter, int32_t lfo_raw_pm) m_feedback[0] = m_feedback[1]; m_feedback[1] = m_feedback_in; - for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++) + for (uint32_t opnum = 0; opnum < m_op.size(); opnum++) if (m_op[opnum] != nullptr) m_op[opnum]->clock(env_counter, lfo_raw_pm); @@ -888,7 +888,7 @@ void fm_channel::clock(uint32_t env_counter, int32_t lfo_raw_pm) useful temporary code for envelope debugging if (m_choffs == 0x101) { - for (uint32_t opnum = 0; opnum < array_size(m_op); opnum++) + for (uint32_t opnum = 0; opnum < m_op.size(); opnum++) { auto &op = *m_op[((opnum & 1) << 1) | ((opnum >> 1) & 1)]; printf(" %c%03X%c%c ", @@ -1522,11 +1522,11 @@ void fm_engine_base::engine_timer_expired(uint32_t tnum) m_modified_channels |= 1 << chnum; } - // Make sure the array does not go out of bounds to keep gcc happy - if ((tnum < 2) || (sizeof(m_timer_running) > (2 * sizeof(uint8_t)))) { - // reset - m_timer_running[tnum] = false; - } + // Make sure the array does not go out of bounds to keep gcc happy + if ((tnum < 2) || (sizeof(m_timer_running) > (2 * sizeof(uint8_t)))) { + // reset + m_timer_running[tnum] = false; + } update_timer(tnum, 1, 0); } diff --git a/src/sound/ymfm/ymfm_opl.cpp b/src/sound/ymfm/ymfm_opl.cpp index bb91c5dc0..8e8025fd9 100644 --- a/src/sound/ymfm/ymfm_opl.cpp +++ b/src/sound/ymfm/ymfm_opl.cpp @@ -386,9 +386,9 @@ std::string opl_registers_base::log_keyon(uint32_t choffs, uint32_t op uint32_t opnum = (opoffs & 31) - 2 * ((opoffs & 31) / 8) + 18 * bitfield(opoffs, 8); char buffer[256]; - char *end = &buffer[0]; + int end = 0; - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u", + end += snprintf(&buffer[end], sizeof(buffer) - end, "%2u.%02u freq=%04X fb=%u alg=%X mul=%X tl=%02X ksr=%u ns=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u", chnum, opnum, ch_block_freq(choffs), ch_feedback(choffs), @@ -405,25 +405,25 @@ std::string opl_registers_base::log_keyon(uint32_t choffs, uint32_t op op_eg_sustain(opoffs)); if (OUTPUTS > 1) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " out=%c%c%c%c", + end += snprintf(&buffer[end], sizeof(buffer) - end, " out=%c%c%c%c", ch_output_0(choffs) ? 'L' : '-', ch_output_1(choffs) ? 'R' : '-', ch_output_2(choffs) ? '0' : '-', ch_output_3(choffs) ? '1' : '-'); if (op_lfo_am_enable(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", lfo_am_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u", lfo_am_depth()); if (op_lfo_pm_enable(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", lfo_pm_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u", lfo_pm_depth()); if (waveform_enable() && op_waveform(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=%u", op_waveform(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " wf=%u", op_waveform(opoffs)); if (is_rhythm(choffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rhy=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " rhy=1"); if (DYNAMIC_OPS) { operator_mapping map; operator_map(map); if (bitfield(map.chan[chnum], 16, 8) != 0xff) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " 4op"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " 4op"); } return buffer; @@ -685,9 +685,9 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) uint32_t opnum = opoffs; char buffer[256]; - char *end = &buffer[0]; + int end = 0; - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X inst=%X fb=%u mul=%X", + end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X inst=%X fb=%u mul=%X", chnum, opnum, ch_block_freq(choffs), ch_instrument(choffs), @@ -695,11 +695,11 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) op_multiple(opoffs)); if (bitfield(opoffs, 0) == 1 || (is_rhythm(choffs) && choffs >= 6)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " vol=%X", op_volume(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " vol=%X", op_volume(opoffs)); else - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " tl=%02X", ch_total_level(choffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " tl=%02X", ch_total_level(choffs)); - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u", + end += snprintf(&buffer[end], sizeof(buffer) - end, " ksr=%u ksl=%u adr=%X/%X/%X sl=%X sus=%u/%u", op_ksr(opoffs), op_ksl(opoffs), op_attack_rate(opoffs), @@ -710,13 +710,13 @@ std::string opll_registers::log_keyon(uint32_t choffs, uint32_t opoffs) ch_sustain(choffs)); if (op_lfo_am_enable(opoffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am=1"); if (op_lfo_pm_enable(opoffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=1"); if (op_waveform(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " wf=1"); if (is_rhythm(choffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rhy=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " rhy=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opm.cpp b/src/sound/ymfm/ymfm_opm.cpp index c72badb57..03f54fb90 100644 --- a/src/sound/ymfm/ymfm_opm.cpp +++ b/src/sound/ymfm/ymfm_opm.cpp @@ -60,17 +60,17 @@ opm_registers::opm_registers() : { // waveform 0 is a sawtooth uint8_t am = index ^ 0xff; - int8_t pm = int8_t(index); + uint8_t pm = index; m_lfo_waveform[0][index] = am | (pm << 8); // waveform 1 is a square wave am = bitfield(index, 7) ? 0 : 0xff; - pm = int8_t(am ^ 0x80); + pm = am ^ 0x80; m_lfo_waveform[1][index] = am | (pm << 8); // waveform 2 is a triangle wave am = bitfield(index, 7) ? (index << 1) : ((index ^ 0xff) << 1); - pm = int8_t(bitfield(index, 6) ? am : ~am); + pm = bitfield(index, 6) ? am : ~am; m_lfo_waveform[2][index] = am | (pm << 8); // waveform 3 is noise; it is filled in dynamically @@ -330,7 +330,7 @@ uint32_t opm_registers::compute_phase_step(uint32_t choffs, uint32_t opoffs, opd if (pm_sensitivity < 6) delta += lfo_raw_pm >> (6 - pm_sensitivity); else - delta += lfo_raw_pm << (pm_sensitivity - 5); + delta += uint32_t(lfo_raw_pm) << (pm_sensitivity - 5); } // apply delta and convert to a frequency number @@ -354,9 +354,9 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs) uint32_t opnum = opoffs; char buffer[256]; - char *end = &buffer[0]; + int end = 0; - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X dt2=%u dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", chnum, opnum, ch_block_freq(choffs), op_detune2(opoffs), @@ -376,14 +376,14 @@ std::string opm_registers::log_keyon(uint32_t choffs, uint32_t opoffs) bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); if (am || pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); + end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); if (noise_enable() && opoffs == 31) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " noise=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " noise=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opn.cpp b/src/sound/ymfm/ymfm_opn.cpp index 388162dfe..16ca3416c 100644 --- a/src/sound/ymfm/ymfm_opn.cpp +++ b/src/sound/ymfm/ymfm_opn.cpp @@ -409,9 +409,9 @@ std::string opn_registers_base::log_keyon(uint32_t choffs, uint32_t opof } char buffer[256]; - char *end = &buffer[0]; + int end = 0; - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X", + end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X", chnum, opnum, block_freq, op_detune(opoffs), @@ -427,21 +427,21 @@ std::string opn_registers_base::log_keyon(uint32_t choffs, uint32_t opof op_sustain_level(opoffs)); if (OUTPUTS > 1) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " out=%c%c", + end += snprintf(&buffer[end], sizeof(buffer) - end, " out=%c%c", ch_output_0(choffs) ? 'L' : '-', ch_output_1(choffs) ? 'R' : '-'); if (op_ssg_eg_enable(opoffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " ssg=%X", op_ssg_eg_mode(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " ssg=%X", op_ssg_eg_mode(opoffs)); bool am = (op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0); if (am) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", ch_lfo_am_sens(choffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u", ch_lfo_am_sens(choffs)); bool pm = (ch_lfo_pm_sens(choffs) != 0); if (pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", ch_lfo_pm_sens(choffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u", ch_lfo_pm_sens(choffs)); if (am || pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X", lfo_rate()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X", lfo_rate()); if (multi_freq() && choffs == 2) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " multi=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " multi=1"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opn.h b/src/sound/ymfm/ymfm_opn.h index bab68ed93..daed8b0bf 100644 --- a/src/sound/ymfm/ymfm_opn.h +++ b/src/sound/ymfm/ymfm_opn.h @@ -793,7 +793,7 @@ public: ymf276(ymfm_interface &intf) : ym2612(intf) { } // generate one sample of sound - void generate(output_data *output, uint32_t numsamples); + void generate(output_data *output, uint32_t numsamples = 1); }; } diff --git a/src/sound/ymfm/ymfm_opq.cpp b/src/sound/ymfm/ymfm_opq.cpp index e6f6fa5ea..78ae16164 100644 --- a/src/sound/ymfm/ymfm_opq.cpp +++ b/src/sound/ymfm/ymfm_opq.cpp @@ -339,9 +339,9 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs) uint32_t opnum = opoffs; char buffer[256]; - char *end = &buffer[0]; + int end = 0; - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u freq=%04X dt=%+2d fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", chnum, opnum, (opoffs & 1) ? ch_block_freq_24(choffs) : ch_block_freq_13(choffs), int32_t(op_detune(opoffs)) - 0x20, @@ -360,14 +360,14 @@ std::string opq_registers::log_keyon(uint32_t choffs, uint32_t opoffs) bool am = (lfo_enable() && op_lfo_am_enable(opoffs) && ch_lfo_am_sens(choffs) != 0); if (am) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u", ch_lfo_am_sens(choffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u", ch_lfo_am_sens(choffs)); bool pm = (lfo_enable() && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u", ch_lfo_pm_sens(choffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u", ch_lfo_pm_sens(choffs)); if (am || pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X", lfo_rate()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X", lfo_rate()); if (ch_reverb(choffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " reverb"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " reverb"); return buffer; } diff --git a/src/sound/ymfm/ymfm_opx.h b/src/sound/ymfm/ymfm_opx.h index 9f9bbdba7..f8ee1c34f 100644 --- a/src/sound/ymfm/ymfm_opx.h +++ b/src/sound/ymfm/ymfm_opx.h @@ -105,7 +105,7 @@ public: static constexpr uint8_t STATUS_IRQ = 0; // constructor - opz_registers(); + opx_registers(); // reset to initial state void reset(); @@ -244,17 +244,17 @@ protected: // IMPLEMENTATION CLASSES //********************************************************* -// ======================> ym2414 +// ======================> ymf271 -class ym2414 +class ymf271 { public: - using fm_engine = fm_engine_base; + using fm_engine = fm_engine_base; static constexpr uint32_t OUTPUTS = fm_engine::OUTPUTS; using output_data = fm_engine::output_data; // constructor - ym2414(ymfm_interface &intf); + ymf271(ymfm_interface &intf); // reset void reset(); @@ -287,4 +287,4 @@ protected: } -#endif // YMFM_OPZ_H +#endif // YMFM_OPX_H diff --git a/src/sound/ymfm/ymfm_opz.cpp b/src/sound/ymfm/ymfm_opz.cpp index a5ec912aa..1178417bb 100644 --- a/src/sound/ymfm/ymfm_opz.cpp +++ b/src/sound/ymfm/ymfm_opz.cpp @@ -129,17 +129,17 @@ opz_registers::opz_registers() : { // waveform 0 is a sawtooth uint8_t am = index ^ 0xff; - int8_t pm = int8_t(index); + uint8_t pm = index; m_lfo_waveform[0][index] = am | (pm << 8); // waveform 1 is a square wave am = bitfield(index, 7) ? 0 : 0xff; - pm = int8_t(am ^ 0x80); + pm = am ^ 0x80; m_lfo_waveform[1][index] = am | (pm << 8); // waveform 2 is a triangle wave am = bitfield(index, 7) ? (index << 1) : ((index ^ 0xff) << 1); - pm = int8_t(bitfield(index, 6) ? am : ~am); + pm = bitfield(index, 6) ? am : ~am; m_lfo_waveform[2][index] = am | (pm << 8); // waveform 3 is noise; it is filled in dynamically @@ -555,16 +555,16 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs) uint32_t opnum = opoffs; char buffer[256]; - char *end = &buffer[0]; + int end = 0; - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, "%u.%02u", chnum, opnum); + end += snprintf(&buffer[end], sizeof(buffer) - end, "%u.%02u", chnum, opnum); if (op_fix_mode(opoffs)) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " fixfreq=%X fine=%X shift=%X", op_fix_frequency(opoffs), op_fine(opoffs), op_fix_range(opoffs)); else - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " freq=%04X dt2=%u fine=%X", ch_block_freq(choffs), op_detune2(opoffs), op_fine(opoffs)); - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", + end += snprintf(&buffer[end], sizeof(buffer) - end, " dt=%u fb=%u alg=%X mul=%X tl=%02X ksr=%u adsr=%02X/%02X/%02X/%X sl=%X out=%c%c", op_detune(opoffs), ch_feedback(choffs), ch_algorithm(choffs), @@ -580,32 +580,32 @@ std::string opz_registers::log_keyon(uint32_t choffs, uint32_t opoffs) ch_output_1(choffs) ? 'R' : '-'); if (op_eg_shift(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " egshift=%u", op_eg_shift(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " egshift=%u", op_eg_shift(opoffs)); bool am = (lfo_am_depth() != 0 && ch_lfo_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am=%u/%02X", ch_lfo_am_sens(choffs), lfo_am_depth()); bool pm = (lfo_pm_depth() != 0 && ch_lfo_pm_sens(choffs) != 0); if (pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm=%u/%02X", ch_lfo_pm_sens(choffs), lfo_pm_depth()); if (am || pm) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); + end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo=%02X/%c", lfo_rate(), "WQTN"[lfo_waveform()]); bool am2 = (lfo2_am_depth() != 0 && ch_lfo2_am_sens(choffs) != 0 && op_lfo_am_enable(opoffs) != 0); if (am2) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " am2=%u/%02X", ch_lfo2_am_sens(choffs), lfo2_am_depth()); bool pm2 = (lfo2_pm_depth() != 0 && ch_lfo2_pm_sens(choffs) != 0); if (pm2) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth()); + end += snprintf(&buffer[end], sizeof(buffer) - end, " pm2=%u/%02X", ch_lfo2_pm_sens(choffs), lfo2_pm_depth()); if (am2 || pm2) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]); + end += snprintf(&buffer[end], sizeof(buffer) - end, " lfo2=%02X/%c", lfo2_rate(), "WQTN"[lfo2_waveform()]); if (op_reverb_rate(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " rev=%u", op_reverb_rate(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " rev=%u", op_reverb_rate(opoffs)); if (op_waveform(opoffs) != 0) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " wf=%u", op_waveform(opoffs)); + end += snprintf(&buffer[end], sizeof(buffer) - end, " wf=%u", op_waveform(opoffs)); if (noise_enable() && opoffs == 31) - end += snprintf(end, SNPRINTF_BUFFER_SIZE_CALC, " noise=1"); + end += snprintf(&buffer[end], sizeof(buffer) - end, " noise=1"); return buffer; } diff --git a/src/timer.c b/src/timer.c index 6ddf8ebb5..9fed37511 100644 --- a/src/timer.c +++ b/src/timer.c @@ -4,6 +4,7 @@ #include #include <86box/86box.h> #include <86box/timer.h> +#include <86box/nv/vid_nv_rivatimer.h> uint64_t TIMER_USEC; uint32_t timer_target; @@ -30,7 +31,8 @@ timer_enable(pc_timer_t *timer) timer_disable(timer); if (timer->next || timer->prev) - fatal("timer_enable - timer->next\n"); + fatal("timer_disable(): Attempting to enable a non-isolated " + "timer incorrectly marked as disabled\n"); /*List currently empty - add to head*/ if (!timer_head) { @@ -91,7 +93,8 @@ timer_disable(pc_timer_t *timer) return; if (!timer->next && !timer->prev && timer != timer_head) - fatal("timer_disable - !timer->next\n"); + fatal("timer_disable(): Attempting to disable an isolated " + "non-head timer incorrectly marked as enabled\n"); timer->flags &= ~TIMER_ENABLED; timer->in_callback = 0; @@ -168,6 +171,9 @@ timer_init(void) timer_target = 0ULL; tsc = 0; + /* Initialise the CPU-independent timer */ + rivatimer_init(); + timer_inited = 1; } diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 4cbda5c83..91fa25f39 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -10,14 +10,19 @@ # # Authors: Cacodemon345 # David Hrdlička, +# Jasmine Iwanek, # # Copyright 2021 Cacodemon345. # Copyright 2021 David Hrdlička. # Copyright 2021 Andreas J. Reichel. -# Copyright 2021-2022 Jasmine Iwanek. +# Copyright 2021-2024 Jasmine Iwanek. # -add_library(plat OBJECT unix.c unix_serial_passthrough.c unix_netsocket.c) +add_library(plat OBJECT + unix.c + unix_serial_passthrough.c + unix_netsocket.c +) if (NOT CPPTHREADS) target_sources(plat PRIVATE unix_thread.c) @@ -27,7 +32,11 @@ set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) target_link_libraries(86Box Threads::Threads) -add_library(ui OBJECT unix_sdl.c unix_cdrom.c dummy_cdrom_ioctl.c) +add_library(ui OBJECT + unix_sdl.c + unix_cdrom.c + dummy_cdrom_ioctl.c +) target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) target_link_libraries(ui ${CMAKE_DL_LIBS}) diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 15eca9400..86f380d22 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 4.2.1 +Version: 4.3 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Fri Jul 26 2024 Robert de Rooy 4.2.1-1 +* Sat Aug 31 Jasmine Iwanek 4.3-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 7fbac6d7f..6618f21d2 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -11,7 +11,7 @@ net.86box.86Box.desktop - + diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index ed19dfb1f..bddfabb5b 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -17,218 +17,226 @@ * Copyright 2023 Miran Grca. */ #include +#ifdef ENABLE_IOCTL_LOG #include +#endif #include #include #include #include #include #define HAVE_STDARG_H -#include <86box/86box.h> #include <86box/scsi_device.h> #include <86box/cdrom.h> +#include <86box/log.h> #include <86box/plat_unused.h> -#include <86box/plat_cdrom.h> +#include <86box/plat_cdrom_ioctl.h> /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static int toc_valid = 0; +typedef struct ioctl_t { + cdrom_t *dev; + void *log; + void *handle; + char path[256]; +} ioctl_t; -#ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG -int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; +#ifdef ENABLE_IOCTL_LOG +int ioctl_do_log = ENABLE_IOCTL_LOG; void -dummy_cdrom_ioctl_log(const char *fmt, ...) +ioctl_log(void *priv, const char *fmt, ...) { - va_list ap; - - if (dummy_cdrom_ioctl_do_log) { + if (ioctl_do_log) { + va_list ap; va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(priv, fmt, ap); va_end(ap); } } #else -# define dummy_cdrom_ioctl_log(fmt, ...) +# define ioctl_log(priv, fmt, ...) #endif -static int -plat_cdrom_open(void) +/* Internal functions. */ +static void +ioctl_close_handle(UNUSED(const ioctl_t *ioctl)) { - return 0; } static int -plat_cdrom_load(void) +ioctl_open_handle(UNUSED(ioctl_t *ioctl)) { return 0; } static void -plat_cdrom_read_toc(void) +ioctl_read_toc(ioctl_t *ioctl) { - if (!toc_valid) - toc_valid = 1; } -int -plat_cdrom_is_track_audio(uint32_t sector) +/* Shared functions. */ +static int +ioctl_get_track_info(UNUSED(const void *local), UNUSED(const uint32_t track), + UNUSED(int end), UNUSED(track_info_t *ti)) { - plat_cdrom_read_toc(); + return 0; +} + +static void +ioctl_get_raw_track_info(UNUSED(const void *local), int *num, uint8_t *rti) +{ + *num = 1; + memset(rti, 0x00, 11); +} + +static int +ioctl_is_track_pre(const void *local, UNUSED(const uint32_t sector)) +{ + ioctl_t *ioctl = (ioctl_t *) local; + + ioctl_read_toc(ioctl); const int ret = 0; - dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + ioctl_log("ioctl_is_track_audio(%08X): %i\n", sector, ret); return ret; } -int -plat_cdrom_is_track_pre(uint32_t sector) +static int +ioctl_read_sector(const void *local, UNUSED(uint8_t *buffer), UNUSED(uint32_t const sector)) { - plat_cdrom_read_toc(); + ioctl_t *ioctl = (ioctl_t *) local; - const int ret = 0; + ioctl_open_handle(ioctl); - dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); + ioctl_close_handle(ioctl); - return ret; -} - -uint32_t -plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) -{ - plat_cdrom_read_toc(); - - return 0x00000000; -} - -uint32_t -plat_cdrom_get_last_block(void) -{ - plat_cdrom_read_toc(); - - return 0x00000000; -} - -int -plat_cdrom_ext_medium_changed(void) -{ - int ret = 0; - - dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); - - return ret; -} - -void -plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) -{ - plat_cdrom_read_toc(); - - *st_track = 1; - *end = 1; - lead_out->min = 0; - lead_out->sec = 0; - lead_out->fr = 2; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", - *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); -} - -/* This replaces both Info and EndInfo, they are specified by a variable. */ -int -plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) -{ - plat_cdrom_read_toc(); - - if ((track < 1) || (track == 0xaa)) { - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); - return 0; - } - - start->min = 0; - start->sec = 0; - start->fr = 2; - - *track_num = 1; - *attr = 0x14; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", - track, start->min, start->sec, start->fr, *track_num, *attr); - - return 1; -} - -/* TODO: See if track start is adjusted by 150 or not. */ -int -plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) -{ - *track = 1; - *attr = 0x14; - *index = 1; - - rel_pos->min = 0; - rel_pos->sec = 0; - rel_pos->fr = 0; - abs_pos->min = 0; - abs_pos->sec = 0; - abs_pos->fr = 2; - - dummy_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); - - return 1; -} - -int -plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) -{ - dummy_cdrom_ioctl_log("BytesPerSector=2048\n"); - - return 2048; -} - -int -plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) -{ - plat_cdrom_open(); - - if (raw) { - dummy_cdrom_ioctl_log("Raw\n"); - /* Raw */ - } else { - dummy_cdrom_ioctl_log("Cooked\n"); - /* Cooked */ - } - plat_cdrom_close(); - dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector); + ioctl_log("ReadSector sector=%d.\n", sector); return 0; } -void -plat_cdrom_eject(void) +static uint8_t +ioctl_get_track_type(UNUSED(const void *local), UNUSED(const uint32_t sector)) { - plat_cdrom_open(); - plat_cdrom_close(); + return 0x00; } -void -plat_cdrom_close(void) +static uint32_t +ioctl_get_last_block(const void *local) { + ioctl_t *ioctl = (ioctl_t *) local; + + ioctl_read_toc(ioctl); + + return 0x00000000; } -int -plat_cdrom_set_drive(const char *drv) +static int +ioctl_read_dvd_structure(UNUSED(const void *local), UNUSED(const uint8_t layer), UNUSED(const uint8_t format), + UNUSED(uint8_t *buffer), UNUSED(uint32_t *info)) { - plat_cdrom_close(); + return -0x00052100; +} - toc_valid = 0; +static int +ioctl_is_dvd(UNUSED(const void *local)) +{ + return 0; +} - plat_cdrom_load(); +static int +ioctl_has_audio(UNUSED(const void *local)) +{ + return 0; +} + +static int +ioctl_is_empty(const void *local) +{ return 1; } + +static int +ioctl_ext_medium_changed(UNUSED(void *local)) +{ +#if 0 + ioctl_t *ioctl = (ioctl_t *) local; +#endif + int ret = 0; + + ioctl_log("ioctl_ext_medium_changed(): %i\n", ret); + + return ret; +} + +static void +ioctl_close(void *local) +{ + ioctl_t *ioctl = (ioctl_t *) local; + + ioctl_close_handle(ioctl); + ioctl->handle = NULL; + + ioctl_log(ioctl->log, "Log closed\n"); + + log_close(ioctl->log); + ioctl->log = NULL; +} + +static void +ioctl_load(const void *local) +{ + const ioctl_t *ioctl = (const ioctl_t *) local; + + if (ioctl_open_handle((ioctl_t *) ioctl)) { + ioctl_close_handle((ioctl_t *) ioctl); + + ioctl_read_toc((ioctl_t *) ioctl); + } +} + +static const cdrom_ops_t ioctl_ops = { + ioctl_get_track_info, + ioctl_get_raw_track_info, + ioctl_is_track_pre, + ioctl_read_sector, + ioctl_get_track_type, + ioctl_get_last_block, + ioctl_read_dvd_structure, + ioctl_is_dvd, + ioctl_has_audio, + ioctl_is_empty, + ioctl_close, + ioctl_load +}; + +/* Public functions. */ +void * +ioctl_open(cdrom_t *dev, const char *drv) +{ + ioctl_t *ioctl = (ioctl_t *) calloc(1, sizeof(ioctl_t)); + + if (ioctl != NULL) { + char n[1024] = { 0 }; + + sprintf(n, "CD-ROM %i IOCtl", dev->id + 1); + ioctl->log = log_open(n); + + memset(ioctl->path, 0x00, sizeof(ioctl->path)); + + sprintf(ioctl->path, "%s", drv); + ioctl_log(ioctl->log, "Path is %s\n", ioctl->path); + + ioctl->dev = dev; + + dev->ops = &ioctl_ops; + } + + return ioctl; +} diff --git a/src/unix/unix.c b/src/unix/unix.c index d4d73817f..7f653b9b6 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -61,7 +61,7 @@ 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[MAX_JOYSTICKS]; +joystick_t joystick_state[GAMEPORT_MAX][MAX_JOYSTICKS]; int joysticks_present; SDL_mutex *blitmtx; SDL_threadID eventthread; @@ -301,7 +301,7 @@ path_abs(char *path) } void -path_normalize(char *path) +path_normalize(UNUSED(char *path)) { /* No-op. */ } @@ -409,6 +409,8 @@ plat_mmap(size_t size, uint8_t executable) { #if defined __APPLE__ && defined MAP_JIT void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); +#elif defined(PROT_MPROTECT) + void *ret = mmap(0, size, PROT_MPROTECT(PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0)), MAP_ANON | MAP_PRIVATE, -1, 0); #else void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); #endif @@ -457,13 +459,13 @@ plat_remove(char *path) } void -ui_sb_update_icon_state(int tag, int state) +ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state)) { /* No-op. */ } void -ui_sb_update_icon(int tag, int active) +ui_sb_update_icon(UNUSED(int tag), UNUSED(int active)) { /* No-op. */ } @@ -475,7 +477,7 @@ plat_delay_ms(uint32_t count) } void -ui_sb_update_tip(int arg) +ui_sb_update_tip(UNUSED(int arg)) { /* No-op. */ } @@ -512,8 +514,9 @@ path_get_dirname(char *dest, const char *path) *dest = '\0'; } volatile int cpu_thread_run = 1; + void -ui_sb_set_text_w(wchar_t *wstr) +ui_sb_set_text_w(UNUSED(wchar_t *wstr)) { /* No-op. */ } @@ -531,7 +534,7 @@ strnicmp(const char *s1, const char *s2, size_t n) } void -main_thread(void *param) +main_thread(UNUSED(void *param)) { uint32_t old_time; uint32_t new_time; @@ -705,7 +708,7 @@ plat_power_off(void) } void -ui_sb_bugui(char *str) +ui_sb_bugui(UNUSED(char *str)) { /* No-op. */ } @@ -724,7 +727,7 @@ int real_sdl_w; int real_sdl_h; void -ui_sb_set_ready(int ready) +ui_sb_set_ready(UNUSED(int ready)) { /* No-op. */ } @@ -782,7 +785,7 @@ plat_init_rom_paths(void) strncpy(xdg_rom_path, getenv("XDG_DATA_HOME"), 1024); path_slash(xdg_rom_path); - strncat(xdg_rom_path, "86Box/", 1024); + strncat(xdg_rom_path, "86Box/", 1023); if (!plat_dir_check(xdg_rom_path)) plat_dir_create(xdg_rom_path); @@ -910,14 +913,14 @@ void (*f_rl_callback_handler_remove)(void) = NULL; #endif uint32_t -timer_onesec(uint32_t interval, void *param) +timer_onesec(uint32_t interval, UNUSED(void *param)) { pc_onesec(); return interval; } void -monitor_thread(void *param) +monitor_thread(UNUSED(void *param)) { #ifndef USE_CLI if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { @@ -1367,14 +1370,14 @@ main(int argc, char **argv) return 0; } char * -plat_vidapi_name(int i) +plat_vidapi_name(UNUSED(int i)) { return "default"; } /* Sets up the program language before initialization. */ uint32_t -plat_language_code(char *langcode) +plat_language_code(UNUSED(char *langcode)) { /* or maybe not */ return 0; @@ -1394,12 +1397,16 @@ plat_set_thread_name(void *thread, const char *name) if (thread) /* Apple pthread can only set self's name */ return; char truncated[64]; +#elif defined(Q_OS_NETBSD) + char truncated[64]; #else char truncated[16]; #endif strncpy(truncated, name, sizeof(truncated) - 1); #ifdef __APPLE__ pthread_setname_np(truncated); +#elif defined(Q_OS_NETBSD) + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated, "%s"); #else pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated); #endif @@ -1407,7 +1414,7 @@ plat_set_thread_name(void *thread, const char *name) /* Converts back the language code to LCID */ void -plat_language_code_r(uint32_t lcid, char *outbuf, int len) +plat_language_code_r(UNUSED(uint32_t lcid), UNUSED(char *outbuf), UNUSED(int len)) { /* or maybe not */ return; @@ -1445,7 +1452,7 @@ endblit(void) /* API */ void -ui_sb_mt32lcd(char *str) +ui_sb_mt32lcd(UNUSED(char *str)) { /* No-op. */ } diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index 186c7649b..b1096b0b4 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -32,6 +32,7 @@ #include <86box/hdd.h> #include <86box/scsi_device.h> #include <86box/cdrom.h> +#include <86box/cdrom_image.h> #include <86box/mo.h> #include <86box/zip.h> #include <86box/scsi_disk.h> @@ -69,7 +70,7 @@ cassette_eject(void) } void -cartridge_mount(uint8_t id, char *fn, uint8_t wp) +cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp)) { cart_close(id); cart_load(id, fn); @@ -120,7 +121,7 @@ floppy_eject(uint8_t id) } void -plat_cdrom_ui_update(uint8_t id, uint8_t reload) +plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload)) { cdrom_t *drv = &cdrom[id]; @@ -140,13 +141,13 @@ void cdrom_mount(uint8_t id, char *fn) { strcpy(cdrom[id].prev_image_path, cdrom[id].image_path); - if (cdrom[id].ops && cdrom[id].ops->exit) - cdrom[id].ops->exit(&(cdrom[id])); + if (cdrom[id].ops && cdrom[id].ops->close) + cdrom[id].ops->close(cdrom[id].local); cdrom[id].ops = NULL; memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '\\')) fn[strlen(fn) - 1] = '/'; - cdrom_image_open(&(cdrom[id]), fn); + image_open(&(cdrom[id]), fn); /* Signal media change to the emulated machine. */ if (cdrom[id].insert) cdrom[id].insert(cdrom[id].priv); @@ -187,8 +188,7 @@ mo_mount(uint8_t id, char *fn, uint8_t wp) mo_disk_close(dev); mo_drives[id].read_only = wp; - mo_load(dev, fn); - mo_insert(dev); + mo_load(dev, fn, 0); ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1); #if 0 @@ -245,8 +245,7 @@ zip_mount(uint8_t id, char *fn, uint8_t wp) zip_disk_close(dev); zip_drives[id].read_only = wp; - zip_load(dev, fn); - zip_insert(dev); + zip_load(dev, fn, 0); ui_sb_update_icon_state(SB_ZIP | id, strlen(zip_drives[id].image_path) ? 0 : 1); #if 0 diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 002e33fd6..651822335 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -533,19 +533,19 @@ ui_window_title(wchar_t *str) } void -ui_init_monitor(int monitor_index) +ui_init_monitor(UNUSED(int monitor_index)) { /* No-op. */ } void -ui_deinit_monitor(int monitor_index) +ui_deinit_monitor(UNUSED(int monitor_index)) { /* No-op. */ } void -plat_resize_request(int w, int h, int monitor_index) +plat_resize_request(UNUSED(int w), UNUSED(int h), int monitor_index) { atomic_store((&doresize_monitors[monitor_index]), 1); } diff --git a/src/unix/unix_serial_passthrough.c b/src/unix/unix_serial_passthrough.c index 0184ebbc0..a12346013 100644 --- a/src/unix/unix_serial_passthrough.c +++ b/src/unix/unix_serial_passthrough.c @@ -24,6 +24,9 @@ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) # define __BSD_VISIBLE 1 #endif +#ifdef __NetBSD__ +# define _NETBSD_VISIBLE 1 +#endif #include #include #include diff --git a/src/usb.c b/src/usb.c index 6bdc8e6c0..222062f4f 100644 --- a/src/usb.c +++ b/src/usb.c @@ -433,7 +433,7 @@ const device_t usb_device = { .init = usb_init, .close = usb_close, .reset = usb_reset, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 96d669ae1..fdd94f6c6 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -13,21 +13,73 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c - vid_compaq_cga.c vid_mda.c vid_hercules.c vid_herculesplus.c - vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c - vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c - vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c - vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68875_ramdac.c - vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_chips_69000.c - vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c - vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c - vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c - vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c - vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c - vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c - vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c - vid_bochs_vbe.c vid_ps55da2.c ) +add_library(vid OBJECT + agpgart.c + video.c + vid_table.c + vid_cga.c + vid_cga_comp.c + vid_compaq_cga.c + vid_mda.c + vid_hercules.c + vid_herculesplus.c + vid_incolor.c + vid_colorplus.c + vid_genius.c + vid_pgc.c + vid_im1024.c + vid_sigma.c + vid_wy700.c + vid_ega.c + vid_ega_render.c + vid_svga.c + vid_8514a.c + vid_svga_render.c + vid_ddc.c + vid_vga.c + vid_ati_eeprom.c + vid_ati18800.c + vid_ati28800.c + vid_ati_mach8.c + vid_ati_mach64.c + vid_ati68875_ramdac.c + vid_ati68860_ramdac.c + vid_bt481_ramdac.c + vid_bt48x_ramdac.c + vid_chips_69000.c + vid_av9194.c + vid_icd2061.c + vid_ics2494.c + vid_ics2595.c + vid_cl54xx.c + vid_et3000.c + vid_et4000.c + vid_sc1148x_ramdac.c + vid_sc1502x_ramdac.c + vid_et4000w32.c + vid_stg_ramdac.c + vid_ht216.c + vid_oak_oti.c + vid_paradise.c + vid_rtg310x.c + vid_f82c425.c + vid_ti_cf62011.c + vid_tvga.c vid_tgui9440.c + vid_tkd8001_ramdac.c + vid_att20c49x_ramdac.c + vid_s3.c vid_s3_virge.c + vid_ibm_rgb528_ramdac.c + vid_sdac_ramdac.c + vid_ogc.c + vid_mga.c + vid_nga.c + vid_tvp3026_ramdac.c + vid_att2xc498_ramdac.c + vid_xga.c + vid_bochs_vbe.c + vid_ps55da2.c + nv/nv_rivatimer.c +) if(G100) target_compile_definitions(vid PRIVATE USE_G100) @@ -37,10 +89,19 @@ if(XL24) target_compile_definitions(vid PRIVATE USE_XL24) endif() -add_library(voodoo OBJECT vid_voodoo.c vid_voodoo_banshee.c - vid_voodoo_banshee_blitter.c vid_voodoo_blitter.c vid_voodoo_display.c - vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c vid_voodoo_render.c - vid_voodoo_setup.c vid_voodoo_texture.c) +add_library(voodoo OBJECT + vid_voodoo.c + vid_voodoo_banshee.c + vid_voodoo_banshee_blitter.c + vid_voodoo_blitter.c + vid_voodoo_display.c + vid_voodoo_fb.c + vid_voodoo_fifo.c + vid_voodoo_reg.c + vid_voodoo_render.c + vid_voodoo_setup.c + vid_voodoo_texture.c +) if(NOT MSVC AND (ARCH STREQUAL "i386" OR ARCH STREQUAL "x86_64")) target_compile_options(voodoo PRIVATE "-msse2") diff --git a/src/video/agpgart.c b/src/video/agpgart.c index b8ae2bdc8..bf1976b73 100644 --- a/src/video/agpgart.c +++ b/src/video/agpgart.c @@ -167,7 +167,7 @@ const device_t agpgart_device = { .init = agpgart_init, .close = agpgart_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/nv/nv_rivatimer.c b/src/video/nv/nv_rivatimer.c new file mode 100644 index 000000000..12d40c026 --- /dev/null +++ b/src/video/nv/nv_rivatimer.c @@ -0,0 +1,274 @@ +/* + * 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. + * + * Fast, high-frequency, CPU-independent timer. + * + * + * + * Authors: Connor Hyde, I need a better email address ;^) + * + * Copyright 2024-2025 starfrost + */ + +/* See vid_nv_rivatimer.h comments for rationale behind not using the regular timer system + +Notes applicable to this file: +Since Windows XP, QueryPerformanceCounter and QueryPerformanceFrequency cannot fail so they are not checked. + +*/ + +#include <86box/nv/vid_nv_rivatimer.h> + +#ifdef _WIN32 +LARGE_INTEGER performance_frequency; +#endif + +rivatimer_t* rivatimer_head; // The head of the rivatimer list. +rivatimer_t* rivatimer_tail; // The tail of the rivatimer list. + +/* Functions only used in this translation unit */ +bool rivatimer_really_exists(rivatimer_t* rivatimer); // Determine if a rivatimer really exists in the linked list. + +void rivatimer_init(void) +{ + // Destroy all the rivatimers. + rivatimer_t* rivatimer_ptr = rivatimer_head; + + if (!rivatimer_ptr) + return; + + while (rivatimer_ptr) + { + // since we are destroing it + rivatimer_t* old_next = rivatimer_ptr->next; + rivatimer_destroy(rivatimer_ptr); + + rivatimer_ptr = old_next; + } + + + #ifdef _WIN32 + // Query the performance frequency. + QueryPerformanceFrequency(&performance_frequency); + #endif +} + +// Creates a rivatimer. +rivatimer_t* rivatimer_create(double period, void (*callback)(double real_time)) +{ + rivatimer_t* new_rivatimer = NULL; + + // See i + if (period <= 0 + || !callback) + { + fatal("Invalid rivatimer_create call: period <= 0 or no callback"); + } + + // If there are no rivatimers, create one + if (!rivatimer_head) + { + rivatimer_head = calloc(1, sizeof(rivatimer_t)); + rivatimer_head->prev = NULL; // indicate this is the first in the list even if we don't strictly need to + rivatimer_tail = rivatimer_head; + new_rivatimer = rivatimer_head; + } + else // Otherwise add a new one to the list + { + rivatimer_tail->next = calloc(1, sizeof(rivatimer_t)); + rivatimer_tail = rivatimer_tail->next; + new_rivatimer = rivatimer_tail; + } + + // sanity check + if (new_rivatimer) + { + new_rivatimer->running = false; + new_rivatimer->period = period; + new_rivatimer->next = NULL; // indicate this is the last in the list + new_rivatimer->callback = callback; + } + + return new_rivatimer; +} + +// Determines if a rivatimer really exists. +bool rivatimer_really_exists(rivatimer_t* rivatimer) +{ + rivatimer_t* current = rivatimer_head; + + if (!current) + return false; + + while (current) + { + if (current == rivatimer) + return true; + + current = current->next; + } + + return false; +} + +// Destroy a rivatimer. +void rivatimer_destroy(rivatimer_t* rivatimer_ptr) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_destroy: The timer was already destroyed, or never existed in the first place."); + + // Case: We are destroying the head + if (rivatimer_ptr == rivatimer_head) + { + // This is the only rivatimer + if (rivatimer_ptr->next == NULL) + { + rivatimer_head = NULL; + rivatimer_tail = NULL; + } + // This is not the only rivatimer + else + { + rivatimer_head = rivatimer_ptr->next; + rivatimer_head->prev = NULL; + // This is the only rivatimer and now there is only one + if (!rivatimer_head->next) + rivatimer_tail = rivatimer_head; + } + } + // Case: We are destroying the tail + else if (rivatimer_ptr == rivatimer_tail) + { + // We already covered the case where there is only one item above + rivatimer_tail = rivatimer_ptr->prev; + rivatimer_tail->next = NULL; + } + // Case: This is not the first or last rivatimer, so we don't need to set the head or tail + else + { + // Fix the break in the chain that this + if (rivatimer_ptr->next) + rivatimer_ptr->prev->next = rivatimer_ptr->next; + if (rivatimer_ptr->prev) + rivatimer_ptr->next->prev = rivatimer_ptr->prev; + } + + free(rivatimer_ptr); + rivatimer_ptr = NULL; //explicitly set to null +} + +void rivatimer_update_all(void) +{ + rivatimer_t* rivatimer_ptr = rivatimer_head; + + if (!rivatimer_ptr) + return; + + while (rivatimer_ptr) + { + // if it's not running skip it + if (!rivatimer_ptr->running) + { + rivatimer_ptr = rivatimer_ptr->next; + continue; + } + + #ifdef _WIN32 + LARGE_INTEGER current_time; + + QueryPerformanceCounter(¤t_time); + + double microseconds = ((double)current_time.QuadPart / 1000000.0) - (rivatimer_ptr->starting_time.QuadPart / 1000000.0); + #else + struct timespec current_time; + + clock_gettime(CLOCK_REALTIME, ¤t_time); + + double microseconds = ((double)current_time.tv_sec * 1000000.0) + ((double)current_time.tv_nsec / 1000.0); + #endif + + rivatimer_ptr->time += microseconds; + + // Reset the current time so we can actually restart + #ifdef _WIN32 + QueryPerformanceCounter(&rivatimer_ptr->starting_time); + #else + clock_gettime(CLOCK_REALTIME, &rivatimer_ptr->starting_time); + #endif + + // Time to fire + if (microseconds > rivatimer_ptr->period) + { + if (!rivatimer_ptr->callback) + { + pclog("Eh? No callback in RivaTimer?"); + continue; + } + + rivatimer_ptr->callback(microseconds); + } + + rivatimer_ptr = rivatimer_ptr->next; + } + +} + +void rivatimer_start(rivatimer_t* rivatimer_ptr) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_start: The timer has been destroyed, or never existed in the first place."); + + if (rivatimer_ptr->period <= 0) + fatal("rivatimer_start: Zero period!"); + + rivatimer_ptr->running = true; + + // Start off so rivatimer_update_all can actually update. + #ifdef _WIN32 + QueryPerformanceCounter(&rivatimer_ptr->starting_time); + #else + clock_gettime(CLOCK_REALTIME, &rivatimer_ptr->starting_time); + #endif +} + +void rivatimer_stop(rivatimer_t* rivatimer_ptr) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_stop: The timer has been destroyed, or never existed in the first place."); + + rivatimer_ptr->running = false; + rivatimer_ptr->time = 0; +} + +// Get the current time value of a rivatimer +double rivatimer_get_time(rivatimer_t* rivatimer_ptr) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_get_time: The timer has been destroyed, or never existed in the first place."); + + return rivatimer_ptr->time; +} + +void rivatimer_set_callback(rivatimer_t* rivatimer_ptr, void (*callback)(double real_time)) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_set_callback: The timer has been destroyed, or never existed in the first place."); + + if (!callback) + fatal("rivatimer_set_callback: No callback!"); + + rivatimer_ptr->callback = callback; +} + +void rivatimer_set_period(rivatimer_t* rivatimer_ptr, double period) +{ + if (!rivatimer_really_exists(rivatimer_ptr)) + fatal("rivatimer_set_period: The timer has been destroyed, or never existed in the first place."); + + rivatimer_ptr->period = period; +} \ No newline at end of file diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index e8ae527b5..379772820 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -35,6 +35,7 @@ #include <86box/thread.h> #include <86box/video.h> #include <86box/vid_8514a.h> +#include <86box/vid_8514a_device.h> #include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> @@ -42,12 +43,12 @@ #include <86box/vid_ati_mach8.h> #include "cpu.h" -#ifdef ATI_8514_ULTRA -#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN" - -static video_timings_t timing_8514ultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; +#ifdef CLAMP +# undef CLAMP #endif +#define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140_4k.BIN" + static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *priv); static uint8_t ibm8514_accel_inb(uint16_t port, void *priv); @@ -71,14 +72,25 @@ ibm8514_log(const char *fmt, ...) # define ibm8514_log(fmt, ...) #endif -#define WRITE8(addr, var, val) \ - switch ((addr) & 1) { \ - case 0: \ - var = (var & 0xff00) | (val); \ - break; \ - case 1: \ - var = (var & 0x00ff) | ((val) << 8); \ - break; \ +static int16_t +CLAMP(int16_t in, int16_t min, int16_t max) +{ + if (in < min) + return min; + if (in > max) + return max; + + return in; +} + +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ } #define READ8(addr, var) \ @@ -92,131 +104,139 @@ ibm8514_log(const char *fmt, ...) } -#define READ_PIXTRANS_WORD(cx, n) \ - if ((cmd <= 1) || (cmd == 5)) { \ +#define READ_PIXTRANS_WORD(cx, n) \ + if ((cmd <= 1) || (cmd == 5)) { \ temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } else { \ - temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } + } else { \ + temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ -#define READ(addr, dat) \ - if (dev->bpp) { \ +#define READ(addr, dat) \ + if (dev->bpp) \ dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ - } else { \ + else \ dat = (dev->vram[(addr) & (dev->vram_mask)]); \ + +#define READ_HIGH(addr, dat) \ + dat |= (dev->vram[(addr) & (dev->vram_mask)] << 8); + +#define MIX(mixmode, dest_dat, src_dat) \ + { \ + switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ + case 0x00: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x01: \ + dest_dat = 0; \ + break; \ + case 0x02: \ + dest_dat = ~0; \ + break; \ + case 0x03: \ + dest_dat = dest_dat; \ + break; \ + case 0x04: \ + dest_dat = ~src_dat; \ + break; \ + case 0x05: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x06: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x07: \ + dest_dat = src_dat; \ + break; \ + case 0x08: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x09: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0x0a: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0x0b: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0x0c: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0x0d: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0x0e: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0x0f: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + case 0x10: \ + dest_dat = MIN(src_dat, dest_dat); \ + break; \ + case 0x11: \ + dest_dat = dest_dat - src_dat; \ + break; \ + case 0x12: \ + dest_dat = src_dat - dest_dat; \ + break; \ + case 0x13: \ + dest_dat = src_dat + dest_dat; \ + break; \ + case 0x14: \ + dest_dat = MAX(src_dat, dest_dat); \ + break; \ + case 0x15: \ + dest_dat = (dest_dat - src_dat) >> 1; \ + break; \ + case 0x16: \ + dest_dat = (src_dat - dest_dat) >> 1; \ + break; \ + case 0x17: \ + dest_dat = (dest_dat + src_dat) >> 1; \ + break; \ + case 0x18: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x19: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x1a: \ + dest_dat = MAX(0, (src_dat - dest_dat)); \ + break; \ + case 0x1b: \ + if (dev->bpp) \ + dest_dat = MIN(0xffff, (dest_dat + src_dat)); \ + else \ + dest_dat = MIN(0xff, (dest_dat + src_dat)); \ + break; \ + case 0x1c: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1d: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1e: \ + dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ + break; \ + case 0x1f: \ + if (dev->bpp) \ + dest_dat = (0xffff < (src_dat + dest_dat)) ? 0xffff : ((src_dat + dest_dat) / 2); \ + else \ + dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ + break; \ + } \ } -#define MIX(mixmode, dest_dat, src_dat) \ - { \ - switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ - case 0x00: \ - dest_dat = ~dest_dat; \ - break; \ - case 0x01: \ - dest_dat = 0; \ - break; \ - case 0x02: \ - dest_dat = ~0; \ - break; \ - case 0x03: \ - dest_dat = dest_dat; \ - break; \ - case 0x04: \ - dest_dat = ~src_dat; \ - break; \ - case 0x05: \ - dest_dat = src_dat ^ dest_dat; \ - break; \ - case 0x06: \ - dest_dat = ~(src_dat ^ dest_dat); \ - break; \ - case 0x07: \ - dest_dat = src_dat; \ - break; \ - case 0x08: \ - dest_dat = ~(src_dat & dest_dat); \ - break; \ - case 0x09: \ - dest_dat = ~src_dat | dest_dat; \ - break; \ - case 0x0a: \ - dest_dat = src_dat | ~dest_dat; \ - break; \ - case 0x0b: \ - dest_dat = src_dat | dest_dat; \ - break; \ - case 0x0c: \ - dest_dat = src_dat & dest_dat; \ - break; \ - case 0x0d: \ - dest_dat = src_dat & ~dest_dat; \ - break; \ - case 0x0e: \ - dest_dat = ~src_dat & dest_dat; \ - break; \ - case 0x0f: \ - dest_dat = ~(src_dat | dest_dat); \ - break; \ - case 0x10: \ - dest_dat = MIN(src_dat, dest_dat); \ - break; \ - case 0x11: \ - dest_dat = dest_dat - src_dat; \ - break; \ - case 0x12: \ - dest_dat = src_dat - dest_dat; \ - break; \ - case 0x13: \ - dest_dat = src_dat + dest_dat; \ - break; \ - case 0x14: \ - dest_dat = MAX(src_dat, dest_dat); \ - break; \ - case 0x15: \ - dest_dat = (dest_dat - src_dat) >> 1; \ - break; \ - case 0x16: \ - dest_dat = (src_dat - dest_dat) >> 1; \ - break; \ - case 0x17: \ - dest_dat = (dest_dat + src_dat) >> 1; \ - break; \ - case 0x18: \ - dest_dat = MAX(0, (dest_dat - src_dat)); \ - break; \ - case 0x19: \ - dest_dat = MAX(0, (dest_dat - src_dat)); \ - break; \ - case 0x1a: \ - dest_dat = MAX(0, (src_dat - dest_dat)); \ - break; \ - case 0x1b: \ - dest_dat = MIN(~0, (dest_dat + src_dat)); \ - break; \ - case 0x1c: \ - dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ - break; \ - case 0x1d: \ - dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ - break; \ - case 0x1e: \ - dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ - break; \ - case 0x1f: \ - dest_dat = (~0 < (src_dat + dest_dat)) ? ~0 : ((src_dat + dest_dat) >> 1); \ - break; \ - } \ - } - -#define WRITE(addr, dat) \ - if (dev->bpp) { \ - vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ +#define WRITE(addr, dat) \ + if (dev->bpp) { \ + vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ - } else { \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ } int ibm8514_active = 0; @@ -261,10 +281,9 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in int frgd_mix = (dev->accel.frgd_mix >> 5) & 3; int bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; int cmd = dev->accel.cmd >> 13; - int and3 = dev->accel.cur_x & 3; if (dev->accel.cmd & 0x100) { - if (len != 1) { + if (len == 2) { /*Bus size*/ if (dev->accel.cmd & 0x200) /*16-bit*/ pixcnt = 16; @@ -273,200 +292,49 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in /*Pixel transfer data mode, can't be the same as Foreground/Background CPU data*/ if (pixcntl == 2) { - if ((frgd_mix == 2) || (bkgd_mix == 2)) { + if ((frgd_mix == 2) || (bkgd_mix == 2)) pixelxfer = val; - } else { - if (dev->accel.cmd & 2) { + else { + if (dev->accel.cmd & 0x02) { if (pixcnt == 16) { if ((cmd >= 2) && (dev->accel.cmd & 0x1000)) val = (val >> 8) | (val << 8); } - if (and3 == 3) { - if (dev->accel.cmd & 0x1000) - goto regular_nibble; - if (val & 0x02) - nibble |= 0x10; - if (val & 0x04) - nibble |= 0x08; - if (val & 0x08) - nibble |= 0x04; - if (val & 0x10) - nibble |= 0x02; - if (val & 0x200) - nibble |= 0x01; - if (val & 0x400) - nibble |= 0x80; - if (val & 0x800) - nibble |= 0x40; - if (val & 0x1000) - nibble |= 0x20; - } else if (and3 == 2) { - if (dev->accel.cmd & 0x1000) - goto regular_nibble; - if (val & 0x02) - nibble |= 0x20; - if (val & 0x04) - nibble |= 0x10; - if (val & 0x08) - nibble |= 0x08; - if (val & 0x10) - nibble |= 0x04; - if (val & 0x200) - nibble |= 0x02; - if (val & 0x400) - nibble |= 0x01; - if (val & 0x800) - nibble |= 0x80; - if (val & 0x1000) - nibble |= 0x40; - } else if (and3 == 1) { - if (dev->accel.cmd & 0x1000) - goto regular_nibble; - if (val & 0x02) - nibble |= 0x40; - if (val & 0x04) - nibble |= 0x20; - if (val & 0x08) - nibble |= 0x10; - if (val & 0x10) - nibble |= 0x08; - if (val & 0x200) - nibble |= 0x04; - if (val & 0x400) - nibble |= 0x02; - if (val & 0x800) - nibble |= 0x01; - if (val & 0x1000) - nibble |= 0x80; - } else { -regular_nibble: - if (val & 0x02) - nibble |= 0x80; - if (val & 0x04) - nibble |= 0x40; - if (val & 0x08) - nibble |= 0x20; - if (val & 0x10) - nibble |= 0x10; - if (val & 0x200) - nibble |= 0x08; - if (val & 0x400) - nibble |= 0x04; - if (val & 0x800) - nibble |= 0x02; - if (val & 0x1000) - nibble |= 0x01; - } - - if ((and3 == 0) || (dev->accel.cmd & 0x1000) || ((dev->accel.cmd & 8) && ibm8514_cpu_src(svga))) { - if ((dev->accel.cmd & 8) && ibm8514_cpu_src(svga)) { + if ((cmd <= 2) || (cmd == 4) || (cmd == 6)) { + if ((dev->accel.cmd & 0x08) && (cmd >= 2)) monoxfer = val; - } else - monoxfer = nibble; - ibm8514_accel_start(pixcnt, 1, monoxfer, pixelxfer, svga, len); - if (dev->accel.nibbleset != NULL) { - free(dev->accel.nibbleset); - dev->accel.nibbleset = NULL; - } - if (dev->accel.writemono != NULL) { - free(dev->accel.writemono); - dev->accel.writemono = NULL; - } - return; - } - - dev->accel.writemono[dev->accel.x_count] = nibble; - if (val & 0x1c00) { - if (and3 == 1) { + else { + if (val & 0x02) + nibble |= 0x80; + if (val & 0x04) + nibble |= 0x40; + if (val & 0x08) + nibble |= 0x20; + if (val & 0x10) + nibble |= 0x10; + if (val & 0x200) + nibble |= 0x08; + if (val & 0x400) + nibble |= 0x04; + if (val & 0x800) + nibble |= 0x02; if (val & 0x1000) - dev->accel.nibbleset[dev->accel.x_count] = 0x80; - else - dev->accel.nibbleset[dev->accel.x_count] = 0; - } else if (and3 == 2) { - if (val & 0x1000) { - if (val & 0x800) - dev->accel.nibbleset[dev->accel.x_count] = 0xc0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0x40; - } else if (val & 0x800) { - if (val & 0x1000) - dev->accel.nibbleset[dev->accel.x_count] = 0xc0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0x80; - } else - dev->accel.nibbleset[dev->accel.x_count] = 0; - } else if (and3 == 3) { - if (val & 0x1000) { - if (val & 0x800) { - if (val & 0x400) - dev->accel.nibbleset[dev->accel.x_count] = 0xe0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0x60; - } else if (val & 0x400) { - if (val & 0x800) - dev->accel.nibbleset[dev->accel.x_count] = 0xe0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0xa0; - } else - dev->accel.nibbleset[dev->accel.x_count] = 0x20; - } else if (val & 0x800) { - if (val & 0x400) { - if (val & 0x1000) - dev->accel.nibbleset[dev->accel.x_count] = 0xe0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0xc0; - } else if (val & 0x1000) { - if (val & 0x400) - dev->accel.nibbleset[dev->accel.x_count] = 0xe0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0x60; - } else - dev->accel.nibbleset[dev->accel.x_count] = 0x40; - } else if (val & 0x400) { - if (val & 0x800) { - if (val & 0x1000) - dev->accel.nibbleset[dev->accel.x_count] = 0xe0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0xc0; - } else if (val & 0x1000) { - if (val & 0x800) - dev->accel.nibbleset[dev->accel.x_count] = 0xe0; - else - dev->accel.nibbleset[dev->accel.x_count] = 0xa0; - } else - dev->accel.nibbleset[dev->accel.x_count] = 0x80; - } else - dev->accel.nibbleset[dev->accel.x_count] = 0; + nibble |= 0x01; + + monoxfer = nibble; } } else - dev->accel.nibbleset[dev->accel.x_count] = 0; - - dev->accel.x_count++; - if (dev->accel.x_count == dev->accel.sys_cnt) { - for (int i = 0; i < dev->accel.x_count; i++) { - dev->accel.writemono[i] &= ~dev->accel.nibbleset[i]; - dev->accel.writemono[i] |= dev->accel.nibbleset[i + 1]; - ibm8514_accel_start(pixcnt, 1, dev->accel.writemono[i], pixelxfer, svga, len); - } - - dev->accel.x_count = 0; - if (dev->accel.nibbleset != NULL) { - free(dev->accel.nibbleset); - dev->accel.nibbleset = NULL; - } - if (dev->accel.writemono != NULL) { - free(dev->accel.writemono); - dev->accel.writemono = NULL; - } - } - return; - } - monoxfer = val; + monoxfer = val; + } else + monoxfer = val; } - } else { + } else pixelxfer = val; - } - ibm8514_accel_start(pixcnt, 1, monoxfer, pixelxfer, svga, len); + + if (dev->accel.input) + ibm8514_accel_start(pixcnt >> 1, 1, monoxfer & 0xff, pixelxfer & 0xff, svga, len); + else + ibm8514_accel_start(pixcnt, 1, monoxfer & 0xffff, pixelxfer & 0xffff, svga, len); } } } @@ -482,172 +350,92 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) switch (port) { case 0x82e8: case 0xc2e8: - if (len == 1) - dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; - else + dev->fifo_idx++; + if (len == 2) dev->accel.cur_y = val & 0x7ff; break; - case 0x82e9: - case 0xc2e9: - if (len == 1) - dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); - break; case 0x86e8: case 0xc6e8: - if (len == 1) - dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; - else + dev->fifo_idx++; + if (len == 2) dev->accel.cur_x = val & 0x7ff; break; - case 0x86e9: - case 0xc6e9: - if (len == 1) { - dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); - } - break; case 0x8ae8: case 0xcae8: - if (len == 1) - dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; - else { - dev->accel.desty = val & 0x07ff; + dev->fifo_idx++; + if (len == 2) { + dev->accel.desty = val & 0x7ff; dev->accel.desty_axstp = val & 0x3fff; if (val & 0x2000) dev->accel.desty_axstp |= ~0x1fff; } break; - case 0x8ae9: - case 0xcae9: - if (len == 1) { - dev->accel.desty_axstp = (dev->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.desty_axstp |= ~0x1fff; - } - break; case 0x8ee8: case 0xcee8: - if (len == 1) - dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; - else { - dev->accel.destx = val & 0x07ff; + dev->fifo_idx++; + if (len == 2) { + dev->accel.destx = val & 0x7ff; dev->accel.destx_distp = val & 0x3fff; if (val & 0x2000) dev->accel.destx_distp |= ~0x1fff; } break; - case 0x8ee9: - case 0xcee9: - if (len == 1) { - dev->accel.destx_distp = (dev->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.destx_distp |= ~0x1fff; - } - break; case 0x92e8: - if (len != 1) + dev->fifo_idx++; + if (len == 2) dev->test = val; fallthrough; case 0xd2e8: - if (len == 1) - dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; - else { + if (len == 2) { dev->accel.err_term = val & 0x3fff; if (val & 0x2000) dev->accel.err_term |= ~0x1fff; } break; - case 0x92e9: - case 0xd2e9: - if (len == 1) { - dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - dev->accel.err_term |= ~0x1fff; - } - break; case 0x96e8: case 0xd6e8: - if (len == 1) - dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x700) | val; - else { + dev->fifo_idx++; + if (len == 2) { dev->accel.maj_axis_pcnt = val & 0x7ff; dev->accel.maj_axis_pcnt_no_limit = val; } break; - case 0x96e9: - case 0xd6e9: - if (len == 1) - dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); - break; case 0x9ae8: case 0xdae8: + dev->fifo_idx++; dev->accel.ssv_state = 0; - if (len == 1) - dev->accel.cmd = (dev->accel.cmd & 0xff00) | val; - else { + if (len == 2) { dev->data_available = 0; dev->data_available2 = 0; dev->accel.cmd = val; - if (port == 0xdae8) { - if (dev->accel.cmd & 0x100) - dev->accel.cmd_back = 0; - } - ibm8514_log("8514/A CMD=%04x.\n", dev->accel.cmd); - ibm8514_accel_start(-1, 0, -1, 0, svga, len); - } - break; - case 0x9ae9: - case 0xdae9: - if (len == 1) { - dev->data_available = 0; - dev->data_available2 = 0; - dev->accel.cmd = (dev->accel.cmd & 0xff) | (val << 8); - if (port == 0xdae9) { - if (dev->accel.cmd & 0x100) - dev->accel.cmd_back = 0; - } + dev->accel.cmd_back = 1; + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + + ibm8514_log("8514/A CMD=%04x, back=%d.\n", dev->accel.cmd, dev->accel.cmd_back); ibm8514_accel_start(-1, 0, -1, 0, svga, len); } break; case 0x9ee8: case 0xdee8: + dev->fifo_idx++; dev->accel.ssv_state = 1; - if (len == 1) - dev->accel.short_stroke = (dev->accel.short_stroke & 0xff00) | val; - else { + if (len == 2) { dev->accel.short_stroke = val; - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x >= 0x600) - dev->accel.cx |= ~0x5ff; - if (dev->accel.cur_y >= 0x600) - dev->accel.cy |= ~0x5ff; - if (dev->accel.cmd & 0x1000) { - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); - } else { - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); - } - } - break; - case 0x9ee9: - case 0xdee9: - dev->accel.ssv_state = 1; - if (len == 1) { - dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; + dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; + + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; @@ -663,146 +451,99 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) case 0xa2e8: case 0xe2e8: + dev->fifo_idx++; if (port == 0xe2e8) { - if (dev->accel.cmd_back) { - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; - else + if (len == 2) { + if (dev->accel.cmd_back) dev->accel.bkgd_color = val; - } else { - if (ibm8514_cpu_dest(svga)) - break; - ibm8514_accel_out_pixtrans(svga, port, val, len); + else { + if (ibm8514_cpu_dest(svga)) + break; + ibm8514_accel_out_pixtrans(svga, port, val, len); + } } } else { - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; - else + if (len == 2) dev->accel.bkgd_color = val; } break; - case 0xa2e9: - case 0xe2e9: - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); - break; case 0xa6e8: case 0xe6e8: + dev->fifo_idx++; if (port == 0xe6e8) { - if (dev->accel.cmd_back) { - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; - else + if (len == 2) { + if (dev->accel.cmd_back) dev->accel.frgd_color = val; - } else { - if (ibm8514_cpu_dest(svga)) - break; - ibm8514_accel_out_pixtrans(svga, port, val, len); + else { + if (ibm8514_cpu_dest(svga)) + break; + ibm8514_accel_out_pixtrans(svga, port, val, len); + } } } else { - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; - else + if (len == 2) dev->accel.frgd_color = val; } break; - case 0xa6e9: - case 0xe6e9: - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); - break; case 0xaae8: case 0xeae8: - if (len == 1) - dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; - else + dev->fifo_idx++; + if (len == 2) dev->accel.wrt_mask = val; break; - case 0xaae9: - case 0xeae9: - if (len == 1) - dev->accel.wrt_mask = (dev->accel.wrt_mask & 0xff00) | (val << 8); - break; case 0xaee8: case 0xeee8: - if (len == 1) - dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; - else + dev->fifo_idx++; + if (len == 2) dev->accel.rd_mask = val; break; - case 0xaee9: - case 0xeee9: - if (len == 1) - dev->accel.rd_mask = (dev->accel.rd_mask & 0xff00) | (val << 8); - break; case 0xb2e8: case 0xf2e8: - if (len == 1) - dev->accel.color_cmp = (dev->accel.color_cmp & 0x00ff) | val; - else + dev->fifo_idx++; + if (len == 2) dev->accel.color_cmp = val; break; - case 0xb2e9: - case 0xf2e9: - if (len == 1) - dev->accel.color_cmp = (dev->accel.color_cmp & 0xff00) | (val << 8); - break; case 0xb6e8: case 0xf6e8: + dev->fifo_idx++; dev->accel.bkgd_mix = val & 0xff; break; case 0xbae8: case 0xfae8: + dev->fifo_idx++; dev->accel.frgd_mix = val & 0xff; break; case 0xbee8: case 0xfee8: - if (len == 1) - dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff00) | val; - else { + dev->fifo_idx++; + if (len == 2) { dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) - dev->accel.clip_top = val & 0x7ff; - if ((dev->accel.multifunc_cntl >> 12) == 2) - dev->accel.clip_left = val & 0x7ff; + if ((dev->accel.multifunc_cntl >> 12) == 1) { + dev->accel.clip_top = dev->accel.multifunc[1] & 0x3ff; + if (dev->accel.multifunc[1] & 0x400) + dev->accel.clip_top |= ~0x3ff; + } + if ((dev->accel.multifunc_cntl >> 12) == 2) { + dev->accel.clip_left = dev->accel.multifunc[2] & 0x3ff; + if (dev->accel.multifunc[2] & 0x400) + dev->accel.clip_left |= ~0x3ff; + } if ((dev->accel.multifunc_cntl >> 12) == 3) - dev->accel.multifunc[3] = val & 0x7ff; + dev->accel.clip_bottom = dev->accel.multifunc[3] & 0x7ff; if ((dev->accel.multifunc_cntl >> 12) == 4) - dev->accel.multifunc[4] = val & 0x7ff; + dev->accel.clip_right = dev->accel.multifunc[4] & 0x7ff; - ibm8514_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); - if (port == 0xfee8) - dev->accel.cmd_back = 1; - else - dev->accel.cmd_back = 0; - } - break; - case 0xbee9: - case 0xfee9: - if (len == 1) { - dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); - dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) - dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; - - if ((dev->accel.multifunc_cntl >> 12) == 2) - dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; - - if (port == 0xfee9) - dev->accel.cmd_back = 1; - else - dev->accel.cmd_back = 0; } break; @@ -889,7 +630,6 @@ void ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint8_t old = 0; if (port & 0x8000) ibm8514_accel_out_fifo(svga, port, val, len); @@ -904,10 +644,8 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x6e8: /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1]) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; - } + dev->hdisped = val; + dev->hdisp = (dev->hdisped + 1) << 3; ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val); svga_recalctimings(svga); break; @@ -940,11 +678,9 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x16e8: case 0x16e9: /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1]) { - WRITE8(port, dev->v_disp, val); - dev->v_disp &= 0x1fff; - dev->vdisp = (dev->v_disp + 1) >> 1; - } + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = (dev->v_disp + 1) >> 1; ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); ibm8514_log("IBM 8514/A: (0x%04x): vdisp=0x%02x.\n", port, val); svga_recalctimings(svga); @@ -979,35 +715,37 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) break; case 0x42e8: - if (val & 1) - dev->subsys_stat &= ~1; - if (val & 2) - dev->subsys_stat &= ~2; - if (val & 4) - dev->subsys_stat &= ~4; - if (val & 8) - dev->subsys_stat &= ~8; + if (val & 0x01) + dev->subsys_stat &= ~0x01; + if (val & 0x02) + dev->subsys_stat &= ~0x02; + if (val & 0x04) + dev->subsys_stat &= ~0x04; + if (val & 0x08) + dev->subsys_stat &= ~0x08; break; case 0x42e9: - old = dev->subsys_cntl; dev->subsys_cntl = val; - if ((old ^ val) & 1) - dev->subsys_stat |= 1; - if ((old ^ val) & 2) - dev->subsys_stat |= 2; - if ((old ^ val) & 4) - dev->subsys_stat |= 4; - if ((old ^ val) & 8) - dev->subsys_stat |= 8; + if (val & 0x01) + dev->subsys_stat |= 0x01; + if (val & 0x02) + dev->subsys_stat |= 0x02; + if (val & 0x04) + dev->subsys_stat |= 0x04; + if (val & 0x08) + dev->subsys_stat |= 0x08; + + if ((val & 0xc0) == 0xc0) { + dev->fifo_idx = 0; + dev->force_busy = 0; + dev->force_busy2 = 0; + } break; case 0x4ae8: - case 0x4ae9: WRITE8(port, dev->accel.advfunc_cntl, val); - dev->on[0] = dev->accel.advfunc_cntl & 0x01; - vga_on = !dev->on[0]; - dev->vendor_mode[0] = 0; - ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + dev->on = dev->accel.advfunc_cntl & 0x01; + ibm8514_log("[%04X:%08X]: IBM 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); ibm8514_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); break; @@ -1044,29 +782,45 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) switch (port) { case 0x82e8: case 0xc2e8: - if (len != 1) + if (len == 2) temp = dev->accel.cur_y; break; case 0x86e8: case 0xc6e8: - if (len != 1) + if (len == 2) temp = dev->accel.cur_x; break; case 0x92e8: - if (len != 1) + if (len == 2) temp = dev->test; break; case 0x96e8: - if (len != 1) + if (len == 2) temp = dev->accel.maj_axis_pcnt; break; case 0x9ae8: case 0xdae8: - if (len != 1) { + if ((dev->fifo_idx >= 1) && (dev->fifo_idx <= 8)) { + temp |= (1 << (dev->fifo_idx - 1)); + switch (dev->accel.cmd >> 13) { + case 2: + case 3: + case 4: + case 6: + if (dev->accel.sy < 0) + dev->fifo_idx = 0; + break; + default: + if (!dev->accel.sy) + dev->fifo_idx = 0; + break; + } + } + if (len == 2) { if (dev->force_busy) temp |= 0x200; /*Hardware busy*/ dev->force_busy = 0; @@ -1080,10 +834,10 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) case 0xdae9: if (len == 1) { if (dev->force_busy2) - temp |= 2; /*Hardware busy*/ + temp |= 0x02; /*Hardware busy*/ dev->force_busy2 = 0; if (dev->data_available2) { - temp |= 1; /*Read Data available*/ + temp |= 0x01; /*Read Data available*/ dev->data_available2 = 0; } } @@ -1092,14 +846,19 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) case 0xe2e8: case 0xe6e8: if (ibm8514_cpu_dest(svga)) { - if (len != 1) { + if (len == 2) { cmd = (dev->accel.cmd >> 13); READ_PIXTRANS_WORD(dev->accel.cx, 0); - if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { - temp &= ~0xff00; - temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); - } - ibm8514_accel_out_pixtrans(svga, port, temp, len); + if (dev->accel.input) { + ibm8514_accel_out_pixtrans(svga, port, temp & 0xff, len); + if (dev->accel.odd_in) { /*WORDs on odd destination scan lengths.*/ + dev->accel.odd_in = 0; + temp &= ~0xff00; + READ_HIGH(dev->accel.dest + dev->accel.cx, temp); + } + ibm8514_accel_out_pixtrans(svga, port, (temp >> 8) & 0xff, len); + } else + ibm8514_accel_out_pixtrans(svga, port, temp, len); } } break; @@ -1113,16 +872,18 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) uint8_t ibm8514_accel_in(uint16_t port, svga_t *svga) { - ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint8_t temp = 0; - uint16_t clip_b_ibm = dev->accel.multifunc[3]; - uint16_t clip_r_ibm = dev->accel.multifunc[4]; - int cmd = (dev->accel.cmd >> 13); + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t temp = 0; + int16_t clip_t = dev->accel.clip_top; + int16_t clip_l = dev->accel.clip_left; + uint16_t clip_b_ibm = dev->accel.clip_bottom; + uint16_t clip_r_ibm = dev->accel.clip_right; + int cmd = dev->accel.cmd >> 13; switch (port) { case 0x2e8: if (dev->vc == dev->v_syncstart) - temp |= 2; + temp |= 0x02; ibm8514_log("0x2E8 read: Display Status=%02x.\n", temp); break; @@ -1150,23 +911,31 @@ ibm8514_accel_in(uint16_t port, svga_t *svga) case 0x42e8: case 0x42e9: if (dev->vc == dev->v_syncstart) - dev->subsys_stat |= 1; + dev->subsys_stat |= 0x01; if (cmd == 6) { - if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm)) - temp |= 2; + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r_ibm) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b_ibm)) + dev->subsys_stat |= 0x02; } else { - if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm)) - temp |= 2; + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r_ibm) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b_ibm)) + dev->subsys_stat |= 0x02; } - if (!dev->force_busy) - temp |= 8; + if (!dev->fifo_idx) { + if (!dev->force_busy && !dev->force_busy2) + temp |= 0x08; + } if (port & 1) - temp = 0x80; + temp = dev->vram_512k_8514 ? 0x00 : 0x80; else { - temp |= (dev->subsys_stat | 0x80); + temp |= (dev->subsys_stat | (dev->vram_512k_8514 ? 0x00 : 0x80)); temp |= 0x20; } break; @@ -1215,8 +984,11 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t dev->accel.ssv_len = ssv & 0x0f; dev->accel.ssv_dir = ssv & 0xe0; dev->accel.ssv_draw = ssv & 0x10; + dev->accel.ssv_len_back = dev->accel.ssv_len; if (ibm8514_cpu_src(svga)) { + dev->data_available = 0; + dev->data_available2 = 0; return; /*Wait for data from CPU*/ } } @@ -1234,8 +1006,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint16_t old_dest_dat; int frgd_mix; int bkgd_mix; - uint16_t clip_b = dev->accel.multifunc[3]; - uint16_t clip_r = dev->accel.multifunc[4]; + int16_t clip_t = dev->accel.clip_top; + int16_t clip_l = dev->accel.clip_left; + uint16_t clip_b = dev->accel.clip_bottom; + uint16_t clip_r = dev->accel.clip_right; int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; uint16_t mix_mask = dev->bpp ? 0x8000 : 0x80; uint16_t compare = dev->accel.color_cmp; @@ -1248,6 +1022,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint16_t bkgd_color = dev->accel.bkgd_color; uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; + int poly_src; if (!dev->bpp) { compare &= 0xff; @@ -1267,11 +1042,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; if (cpu_input) { - if ((dev->accel.cmd & 2) || (pixcntl == 2)) { + if ((dev->accel.cmd & 0x02) || (pixcntl == 2)) { if ((frgd_mix == 2) || (bkgd_mix == 2)) count >>= 3; else if (pixcntl == 2) { - if (dev->accel.cmd & 2) + if (dev->accel.cmd & 0x02) count >>= 1; else count >>= 3; @@ -1363,6 +1138,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat old_mix_dat = mix_dat; + if (cmd == 5 || cmd == 1 || (cmd == 2 && (dev->accel.multifunc[0x0a] & 0x06))) + ibm8514_log("CMD=%d, full=%04x, pixcntl=%d, filling=%02x.\n", cmd, dev->accel.cmd, pixcntl, dev->accel.multifunc[0x0a] & 0x06); + /*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)*/ @@ -1371,9 +1149,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (dev->accel.ssv_state == 0) break; - if (dev->accel.cmd & 8) { + if (dev->accel.cmd & 0x08) { while (count-- && dev->accel.ssv_len >= 0) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -1391,17 +1172,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat default: break; } + READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); if (dev->accel.ssv_draw) { - if ((dev->accel.cmd & 4) && dev->accel.ssv_len) { + if ((dev->accel.cmd & 0x04) && dev->accel.ssv_len) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + } else if (!(dev->accel.cmd & 0x04)) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } @@ -1415,8 +1203,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else cpu_dat >>= 8; - if (!dev->accel.ssv_len) + if (!dev->accel.ssv_len) { + dev->accel.cmd_back = 1; break; + } switch (dev->accel.ssv_dir & 0xe0) { case 0x00: @@ -1456,8 +1246,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } else { while (count-- && (dev->accel.ssv_len >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left) && (dev->accel.cx <= clip_r) && - (dev->accel.cy >= dev->accel.clip_top) && (dev->accel.cy <= clip_b)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -1478,15 +1270,21 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); if (dev->accel.ssv_draw) { - if ((dev->accel.cmd & 4) && dev->accel.ssv_len) { + if ((dev->accel.cmd & 0x04) && dev->accel.ssv_len) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + } else if (!(dev->accel.cmd & 0x04)) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } @@ -1500,73 +1298,39 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else cpu_dat >>= 8; - if (!dev->accel.ssv_len) + if (!dev->accel.ssv_len) { + dev->accel.cmd_back = 1; break; + } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cy--; - break; - case 0x20: - dev->accel.cy--; - break; - case 0x40: - dev->accel.cx--; - break; - case 0x60: - dev->accel.cx++; - break; - case 0x80: - dev->accel.cy++; - break; - case 0xa0: - dev->accel.cy++; - break; - case 0xc0: - dev->accel.cx--; - break; - case 0xe0: - dev->accel.cx++; - break; - - default: - break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx--; - break; - case 0x20: - dev->accel.cx++; - break; - case 0x40: - dev->accel.cy--; - break; - case 0x60: - dev->accel.cy--; - break; - case 0x80: - dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx++; - break; - case 0xc0: + if (dev->accel.cmd & 0x40) { + if (dev->accel.cmd & 0x80) dev->accel.cy++; - break; - case 0xe0: - dev->accel.cy++; - break; + else + dev->accel.cy--; - default: - break; + if (dev->accel.err_term >= dev->accel.ssv_len_back) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + } else + dev->accel.err_term += dev->accel.desty_axstp; + } else { + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + if (dev->accel.err_term >= dev->accel.ssv_len_back) { + dev->accel.err_term += dev->accel.destx_distp; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + } else + dev->accel.err_term += dev->accel.desty_axstp; } dev->accel.ssv_len--; @@ -1578,47 +1342,25 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 1: /*Draw line*/ if (!cpu_input) { - dev->accel.xx_count = 0; - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; + dev->accel.output = 0; + dev->accel.x_count = 0; + dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; dev->accel.sy = dev->accel.maj_axis_pcnt; - ibm8514_log("Line Draw 8514/A, frgdmix=%d, bkgdmix=%d, c(%d,%d), pixcntl=%d, sy=%d, polyfill=%x, selfrmix=%02x, selbkmix=%02x, bkgdcol=%02x, frgdcol=%02x, clipt=%d, clipb=%d.\n", frgd_mix, bkgd_mix, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.multifunc[0x0a] & 6, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, bkgd_color, frgd_color, dev->accel.clip_top, clip_b); + ibm8514_log("Line Draw 8514/A CMD=%04x, frgdmix=%d, bkgdmix=%d, c(%d,%d), pixcntl=%d, sy=%d, polyfill=%x, selfrmix=%02x, selbkmix=%02x, bkgdcol=%02x, frgdcol=%02x, clipt=%d, clipb=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.multifunc[0x0a] & 6, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, bkgd_color, frgd_color, dev->accel.clip_top, clip_b); if (ibm8514_cpu_src(svga)) { - if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 8) { - if (and3 == 1) { - dev->accel.sy += 4; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 4; - else - dev->accel.cx -= 4; - } else if (and3 == 2) { - dev->accel.sy += 5; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 5; - else - dev->accel.cx -= 5; - } else if (and3 == 3) { - dev->accel.sy += 6; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 6; - else - dev->accel.cx -= 6; - } else { - dev->accel.sy += 3; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 3; - else - dev->accel.cx -= 3; - } + if (dev->accel.cmd & 0x02) { + if (!(dev->accel.cmd & 0x1000)) { + if (dev->accel.cmd & 0x08) + dev->accel.output = 1; } } dev->data_available = 0; @@ -1631,12 +1373,18 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } - if (dev->accel.cmd & 8) { /*Vector Line*/ - if (ibm8514_cpu_dest(svga) && cpu_input && (dev->accel.cmd & 2)) + if (dev->accel.cmd & 0x08) { /*Vector Line*/ + if (ibm8514_cpu_dest(svga) && cpu_input && (dev->accel.cmd & 0x02)) count >>= 1; - dev->accel.xx_count++; + + if (dev->accel.cmd & 0x02) + ibm8514_log("Line Draw Vector Single pixtrans=%04x, count=%d.\n", mix_dat, count); + while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { @@ -1651,94 +1399,72 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); } else { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; + if (dev->accel.output) { + switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; - default: - break; + default: + break; + } + } else { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } } } READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); + if (dev->accel.output) { + MIX(mix_dat & 0x01, dest_dat, src_dat); + } else { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + } dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 2) && ibm8514_cpu_src(svga)) { - if (and3 == 1) { - if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 2) { - if (dev->accel.xx_count == 2) { - if (count <= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 3) { - if (dev->accel.xx_count == 2) { - if (count <= 1) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } - } else { - if (dev->accel.xx_count == 1) { - if (!count) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } + if ((dev->accel.cmd & 0x02) && ibm8514_cpu_src(svga)) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } else { if (ibm8514_cpu_src(svga) || !cpu_input) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + } else if (!(dev->accel.cmd & 0x04)) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } @@ -1746,17 +1472,27 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } - mix_dat <<= 1; - mix_dat |= 1; + if (!dev->accel.sy) { + dev->accel.cmd_back = 1; + if (!cpu_input) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } + break; + } + + if (dev->accel.output) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } + if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; - if (dev->accel.sy == 0) { - break; - } - switch (dev->accel.cmd & 0xe0) { case 0x00: dev->accel.cx++; @@ -1793,21 +1529,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy--; } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - } else { /*Bresenham*/ + dev->accel.x_count = 0; + dev->accel.output = 0; + } else { /*Bresenham Line*/ if (pixcntl == 1) { dev->accel.temp_cnt = 8; while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; + mix_dat = old_mix_dat; } - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { if (ibm8514_cpu_dest(svga)) { READ((dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat); } else - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; break; @@ -1827,13 +1566,19 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); + MIX(mix_dat & 0x01, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + } else if (!(dev->accel.cmd & 0x04)) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } @@ -1846,7 +1591,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else cpu_dat >>= 8; - if (dev->accel.sy == 0) { + if (!dev->accel.sy) { + dev->accel.cmd_back = 1; break; } @@ -1856,7 +1602,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -1870,7 +1616,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cx--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -1884,7 +1630,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } else { while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx) <= clip_r && (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { @@ -1919,13 +1668,19 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + } else if (!(dev->accel.cmd & 0x04)) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } } @@ -1938,8 +1693,14 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else cpu_dat >>= 8; - if (dev->accel.sy == 0) + if (!dev->accel.sy) { + dev->accel.cmd_back = 1; + if (!cpu_input) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } break; + } if (dev->accel.cmd & 0x40) { if (dev->accel.cmd & 0x80) @@ -1947,7 +1708,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -1961,7 +1722,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cx--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -1974,8 +1735,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy--; } } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; } break; @@ -1983,79 +1742,60 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: /*Rectangle fill (Y direction)*/ case 4: /*Rectangle fill (Y direction using nibbles)*/ if (!cpu_input) { - dev->accel.x_count = 0; - dev->accel.xx_count = 0; - dev->accel.odd_out = 0; - dev->accel.odd_in = 0; - dev->accel.input = 0; - dev->accel.output = 0; - dev->accel.newdest_out = 0; - dev->accel.newdest_in = 0; - - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + dev->accel.x_count = 0; + dev->accel.output = 0; + dev->accel.input = 0; + dev->accel.input2 = 0; + dev->accel.odd_in = 0; dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); else - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); if (cmd == 4) - dev->accel.cmd |= 2; + dev->accel.cmd |= 0x02; else if (cmd == 3) - dev->accel.cmd &= ~2; + dev->accel.cmd &= ~0x02; if (ibm8514_cpu_src(svga)) { - if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 0x02) { if (!(dev->accel.cmd & 0x1000)) { - if (!(dev->accel.cmd & 8)) { - dev->accel.sx += and3; - dev->accel.nibbleset = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.writemono = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; + if (dev->accel.cmd & 0x08) { + dev->accel.x_count = dev->accel.cx - (and3 + 3); + dev->accel.sx += (and3 + 3); } else { - if (and3 == 1) { - dev->accel.sx += 4; + dev->accel.x_count = dev->accel.cx; + if (and3) { if (dev->accel.cmd & 0x20) - dev->accel.cx += 4; + dev->accel.x_count -= and3; else - dev->accel.cx -= 4; - } else if (and3 == 2) { - dev->accel.sx += 5; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 5; - else - dev->accel.cx -= 5; - } else if (and3 == 3) { - dev->accel.sx += 6; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 6; - else - dev->accel.cx -= 6; - } else { - dev->accel.sx += 3; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 3; - else - dev->accel.cx -= 3; + dev->accel.x_count += and3; + + dev->accel.sx += 8; } } } } else { - if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { - if (!(dev->accel.sx & 1)) { - dev->accel.output = 1; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) - dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); - else - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + if (dev->accel.cmd & 0x1000) { + if (dev->accel.cmd & 0x200) { + if (dev->accel.cmd & 0x04) { + dev->accel.output = 1; + dev->accel.sx -= 2; + } } } } @@ -2063,35 +1803,35 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->data_available2 = 0; return; /*Wait for data from CPU*/ } else if (ibm8514_cpu_dest(svga)) { - if (!(dev->accel.cmd & 2) && (frgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { - if (!(dev->accel.sx & 1)) { - dev->accel.input = 1; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) - dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); - else - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; - } - } else if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 8) { - dev->accel.sx += and3; - dev->accel.nibbleset = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.writemono = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; + if (!(dev->accel.cmd & 0x02)) { + if (dev->accel.cmd & 0x1000) { + if (dev->accel.cmd & 0x200) { + if (!(dev->accel.sx & 1) && !(dev->accel.cmd & 0x04)) { + dev->accel.input = 1; + } else if (dev->accel.cmd & 0x04) { + dev->accel.input2 = 1; + dev->accel.sx -= 2; + } + } } } + ibm8514_log("INPUT=%d.\n", dev->accel.input); dev->data_available = 1; dev->data_available2 = 1; return; /*Wait for data from CPU*/ } } - if (dev->accel.cmd & 2) { + ibm8514_log("Rectangle %d: full=%04x, odd=%d, c(%d,%d), frgdmix=%d, bkgdmix=%d, xcount=%d, and3=%d, len(%d,%d), CURX=%d, Width=%d, pixcntl=%d, mix_dat=%08x, count=%d, cpu_data=%08x, cpu_input=%d.\n", cmd, dev->accel.cmd, dev->accel.input, dev->accel.cx, dev->accel.cy, frgd_mix, bkgd_mix, dev->accel.x_count, and3, dev->accel.sx, dev->accel.sy, dev->accel.cur_x, dev->accel.maj_axis_pcnt, pixcntl, mix_dat, count, cpu_dat, cpu_input); + + if (dev->accel.cmd & 0x08) { /*Vectored Rectangle*/ if (cpu_input) { -rect_fill_pix: - if ((dev->accel.cmd & 8) && ibm8514_cpu_src(svga)) { - dev->accel.xx_count++; + if (ibm8514_cpu_src(svga)) { while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -2112,77 +1852,27 @@ rect_fill_pix: READ(dev->accel.dest + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (and3 == 1) { - if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 2) { - if (dev->accel.xx_count == 2) { - if (count <= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 3) { - if (dev->accel.xx_count == 2) { - if (count <= 1) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else { - if (dev->accel.xx_count == 1) { - if (!count) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } + if ((dev->accel.cmd & 0x02) && (dev->accel.x_count != dev->accel.cx)) + goto skip_vector_rect_write; + + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } } - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - switch (dev->accel.cmd & 0xe0) { case 0x00: dev->accel.cx++; @@ -2207,17 +1897,42 @@ rect_fill_pix: break; } +skip_vector_rect_write: + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.x_count++; + break; + case 0x20: + dev->accel.x_count++; + break; + case 0x60: + dev->accel.x_count--; + break; + case 0x80: + dev->accel.x_count--; + break; + case 0xa0: + dev->accel.x_count--; + break; + case 0xe0: + dev->accel.x_count++; + break; + + default: + break; + } + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + mix_dat <<= 1; + mix_dat |= 1; + dev->accel.sx--; if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (and3 == 1) - dev->accel.sx += 4; - else if (and3 == 2) - dev->accel.sx += 5; - else if (and3 == 3) - dev->accel.sx += 6; - else - dev->accel.sx += 3; if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx + 1); @@ -2248,34 +1963,65 @@ rect_fill_pix: break; } - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); else - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.sy--; + dev->accel.x_count = 0; + + if (dev->accel.sy < 0) + dev->accel.cmd_back = 1; return; } } - break; - } - if (count < 8) { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } + } else + ibm8514_log("Vectored Rectangle with destination reads (TODO).\n"); + } else + ibm8514_log("Vectored Rectangle with normal processing (TODO).\n"); + } else { /*Normal Rectangle*/ + if (cpu_input) { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { + mix_dat = mix_mask; /* Mix data = forced to foreground register. */ + } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { + /* Mix data = current video memory value. */ + READ(dev->accel.dest + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } - if (ibm8514_cpu_dest(svga)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else + if (ibm8514_cpu_dest(svga)) { + READ(dev->accel.dest + dev->accel.cx, src_dat); + if (pixcntl == 3) + src_dat = ((src_dat & rd_mask) == rd_mask); + } else { + if (dev->accel.cmd & 0x02) { + switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -2293,418 +2039,117 @@ rect_fill_pix: default: break; } + } + } - READ(dev->accel.dest + dev->accel.cx, dest_dat); + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + if (dev->accel.cmd & 0x02) { + MIX(mix_dat & 0x01, dest_dat, src_dat); + if ((dev->accel.x_count != dev->accel.cx) && !(dev->accel.cmd & 0x1000) && and3) + goto skip_nibble_rect_write; - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - else - dev->accel.dest = dev->accel.cy * dev->pitch; - - dev->accel.sy--; - return; - } - } - } else { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { - mix_dat = 1; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? 1 : 0; - } - - if (ibm8514_cpu_dest(svga)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else { - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - } - - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - mix_dat >>= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - if (!(dev->accel.cmd & 0x1000)) - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cur_x >= 0x600) - dev->accel.cx |= ~0x5ff; - } - } - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - else - dev->accel.dest = dev->accel.cy * dev->pitch; - - dev->accel.sy--; - return; - } - } - } - } else { - goto rect_fill; - } - } else { - if (cpu_input) { - if (pixcntl == 2) { - goto rect_fill_pix; - } else { - if (dev->accel.input && !dev->accel.output) { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - if (!dev->accel.odd_in && !dev->accel.sx) { - READ(dev->accel.newdest_in + dev->accel.cur_x, src_dat); - READ(dev->accel.newdest_in + dev->accel.cur_x, dest_dat); - } else { - READ(dev->accel.dest + dev->accel.cx, src_dat); - READ(dev->accel.dest + dev->accel.cx, dest_dat); - } - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (!dev->accel.odd_in && !dev->accel.sx) { - WRITE(dev->accel.newdest_in + dev->accel.cur_x, dest_dat); - } else { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.odd_in) { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.odd_in = 0; - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); - } else { - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; - } - dev->accel.sy--; - return; + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } else { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.sx--; - dev->accel.cx = dev->accel.cur_x; - dev->accel.odd_in = 1; - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - dev->accel.newdest_in = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); - } else { - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->pitch; - } - dev->accel.sy--; - return; - } - } - } - } else if (dev->accel.output && !dev->accel.input) { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - src_dat = cpu_dat; - if (!dev->accel.odd_out && !dev->accel.sx) { - READ(dev->accel.newdest_out + dev->accel.cur_x, dest_dat); - } else { - READ(dev->accel.dest + dev->accel.cx, dest_dat); - } - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (!dev->accel.odd_out && !dev->accel.sx) { - WRITE(dev->accel.newdest_out + dev->accel.cur_x, dest_dat); - } else { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.odd_out) { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.odd_out = 0; - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); - } else { - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; - } - dev->accel.sy--; - return; - } - } else { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.odd_out = 1; - dev->accel.sx--; - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) { - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); - } else { - dev->accel.dest = dev->accel.cy * dev->pitch; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; - } - dev->accel.sy--; - return; - } - } - } - } else { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (ibm8514_cpu_dest(svga)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); + if (ibm8514_cpu_dest(svga) && (cmd == 2)) { if (pixcntl == 3) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } - } else - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - if (ibm8514_cpu_dest(svga)) { - if (pixcntl == 3) { - MIX(mix_dat & mix_mask, dest_dat, src_dat); - } - } else { MIX(mix_dat & mix_mask, dest_dat, src_dat); } - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } else { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + } + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - else - dev->accel.dest = dev->accel.cy * dev->pitch; - - dev->accel.sy--; - return; - } } } + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + +skip_nibble_rect_write: + if (dev->accel.cmd & 0x20) + dev->accel.x_count++; + else + dev->accel.x_count--; + + if (dev->accel.cmd & 0x02) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + if (dev->accel.input) + dev->accel.odd_in = 1; + if (dev->accel.output || dev->accel.input2) + dev->accel.sx -= 2; + + if (dev->accel.cmd & 0x20) + dev->accel.cx -= (dev->accel.sx + 1); + else + dev->accel.cx += (dev->accel.sx + 1); + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + + dev->accel.sy--; + dev->accel.x_count = 0; + + if (dev->accel.sy < 0) + dev->accel.cmd_back = 1; + return; + } } } else { -rect_fill: if (pixcntl == 1) { if (dev->accel.cmd & 0x40) { - count = dev->accel.maj_axis_pcnt + 1; + count = (dev->accel.maj_axis_pcnt & 0x7ff) + 1; dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { mix_dat >>= 8; dev->accel.temp_cnt = 8; } - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -2713,8 +2158,6 @@ rect_fill: src_dat = frgd_color; break; case 2: - src_dat = 0; - break; case 3: src_dat = 0; break; @@ -2725,11 +2168,16 @@ rect_fill: READ(dev->accel.dest + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } @@ -2750,36 +2198,41 @@ rect_fill: dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; + dev->accel.cx -= (dev->accel.sx + 1); } else - dev->accel.cx += (dev->accel.sx) + 1; + dev->accel.cx += (dev->accel.sx + 1); if (dev->accel.cmd & 0x80) dev->accel.cy++; else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); else - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.sy--; - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + if (dev->accel.sy < 0) + dev->accel.cmd_back = 1; return; } } } else { dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { + while (count-- && (dev->accel.sy >= 0)) { if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; + mix_dat = old_mix_dat; } - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; break; @@ -2787,8 +2240,6 @@ rect_fill: src_dat = frgd_color; break; case 2: - src_dat = 0; - break; case 3: src_dat = 0; break; @@ -2799,11 +2250,16 @@ rect_fill: READ(dev->accel.dest + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); + MIX(mix_dat & 0x01, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } @@ -2821,167 +2277,229 @@ rect_fill: dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; + dev->accel.cx -= (dev->accel.sx + 1); } else - dev->accel.cx += (dev->accel.sx) + 1; + dev->accel.cx += (dev->accel.sx + 1); if (dev->accel.cmd & 0x80) dev->accel.cy++; else dev->accel.cy--; - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); else - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); dev->accel.sy--; if (dev->accel.sy < 0) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + if (cmd != 4) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } + dev->accel.cmd_back = 1; return; } } } } - } else { - if ((dev->accel.multifunc[0x0a] & 6) == 4) { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - READ(dev->accel.dest + dev->accel.cx, mix_dat); - if ((mix_dat & rd_mask_polygon) == rd_mask_polygon) - dev->accel.fill_state = !dev->accel.fill_state; + } else if ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) { /*Polygon Draw Type A*/ + ibm8514_log("Polygon Draw Type A: Clipping: L=%d, R=%d, T=%d, B=%d, C(%d,%d), sx=%d, sy=%d.\n", clip_l, clip_r, clip_t, clip_b, dev->accel.cx, dev->accel.cy, dev->accel.sx, dev->accel.sy); + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + case 3: + src_dat = 0; + break; - READ(dev->accel.dest + dev->accel.cx, dest_dat); - old_dest_dat = dest_dat; - if (dev->accel.fill_state) { - if (!(rd_mask_polygon & 1) && (wrt_mask & 1)) { - MIX(mix_dat ^ rd_mask_polygon, dest_dat, mix_dat); - ibm8514_log("Filling c(%d,%d) without bit 0 of rdmask=%02x, wrtmask=%02x, mixdat=%02x, dest=%02x, old=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, old_dest_dat); - dest_dat &= ~rd_mask_polygon; - } else if ((rd_mask_polygon & 1) && (wrt_mask & 1)) { - ibm8514_log("Filling c(%d,%d) with bit 0 of rdmask=%02x, wrtmask=%02x.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask); - dest_dat &= ~(rd_mask_polygon & wrt_mask); + default: + break; + } + + READ(dev->accel.dest + dev->accel.cx, poly_src); + if ((poly_src & rd_mask_polygon) == rd_mask_polygon) + dev->accel.fill_state ^= 1; + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + old_dest_dat = dest_dat; + if (dev->accel.fill_state) { + if (rd_mask_polygon & 0x01) { + if (wrt_mask & 0x01) { + dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State On, Write Mask 1, Read Mask 1.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); } } else { - if (!(rd_mask_polygon & 1) && (wrt_mask & 1)) - dest_dat &= ~rd_mask_polygon; - else if ((rd_mask_polygon & 1) && (wrt_mask & 1)) - dest_dat &= ~(rd_mask_polygon & wrt_mask); + if (wrt_mask & 0x01) { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat &= ~rd_mask_polygon; /*Fill State On, Write Mask 1, Read Mask 0.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } } + } else { + if (rd_mask_polygon & 0x01) { + if (wrt_mask & 0x01) { + dest_dat &= ~(rd_mask_polygon & wrt_mask); /*Fill State Off, Write Mask 1, Read Mask 1.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } else { + if (wrt_mask & 0x01) { + dest_dat &= ~rd_mask_polygon; /*Fill State Off, Write Mask 1, Read Mask 0.*/ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + } + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back); + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } else + ibm8514_log("Out of bounds DrawA C(%d,%d).\n", dev->accel.cx, dev->accel.cy); + + mix_dat <<= 1; + mix_dat |= 1; + + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.fill_state = 0; + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) + dev->accel.cx -= (dev->accel.sx + 1); + else + dev->accel.cx += (dev->accel.sx + 1); + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + + dev->accel.sy--; + + if (dev->accel.sy < 0) { + ibm8514_log(".\n"); + dev->accel.cmd_back = 1; + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + return; + } + } + } + } else { + ibm8514_log("Polygon Draw Type=%02x, CX=%d, CY=%d, SY=%d, CL=%d, CR=%d.\n", dev->accel.multifunc[0x0a] & 0x06, dev->accel.cx, dev->accel.cy, dev->accel.sy, clip_l, clip_r); + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + if (!bkgd_mix && (dev->accel.cmd & 0x40) && ((dev->accel.frgd_mix & 0x1f) == 7) && ((dev->accel.bkgd_mix & 0x1f) == 3) && !dev->bpp && (bkgd_color == 0x00)) /*For some reason, the September 1992 Mach8/32 drivers for Win3.x don't set the background colors properly.*/ + src_dat = frgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + case 3: + src_dat = 0; + break; + + default: + break; + } + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - ibm8514_log("Results c(%d,%d):rdmask=%02x, wrtmask=%02x, mix=%02x, destdat=%02x, nowrite=%d.\n", dev->accel.cx, dev->accel.cy, rd_mask_polygon, wrt_mask, mix_dat, dest_dat, dev->accel.cx_back); + if (dev->accel.cmd & 0x10) { WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } + } else + ibm8514_log("Outside clipping.\n"); + + mix_dat <<= 1; + mix_dat |= 1; + + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.fill_state = 0; + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; if (dev->accel.cmd & 0x20) - dev->accel.cx++; + dev->accel.cx -= (dev->accel.sx + 1); else - dev->accel.cx--; + dev->accel.cx += (dev->accel.sx + 1); - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.fill_state = 0; - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) - dev->accel.cx -= (dev->accel.sx) + 1; - else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - dev->accel.dest = dev->accel.cy * dev->pitch; - - dev->accel.sy--; - - if (dev->accel.sy < 0) { - ibm8514_log(".\n"); - return; - } - } - } - } else { - ibm8514_log("Rectangle Fill Normal CMD=%04x, CURRENT(%d,%d), sx=%d, FR(%02x), linedraw=%d.\n", dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.sx, frgd_color, dev->accel.linedraw); - while (count-- && dev->accel.sy >= 0) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - if (!bkgd_mix && (dev->accel.cmd & 0x40) && ((dev->accel.frgd_mix & 0x1f) == 7) && ((dev->accel.bkgd_mix & 0x1f) == 3) && !dev->bpp && (bkgd_color == 0x00)) /*For some reason, the September 1992 Mach8/32 drivers for Win3.x don't set the background colors properly.*/ - src_dat = frgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = 0; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - - - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - if (dev->accel.cmd & 0x10) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; else - dev->accel.cx--; + dev->accel.cy--; - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.fill_state = 0; - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else if (dev->bpp) + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - if (dev->accel.cmd & 0x20) - dev->accel.cx -= (dev->accel.sx) + 1; - else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - if (((dev->local & 0xff) >= 0x02) && dev->accel.ge_offset && ((dev->accel_bpp == 24) || (dev->accel_bpp == 8))) - dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); - else - dev->accel.dest = dev->accel.cy * dev->pitch; - - dev->accel.sy--; - - if (dev->accel.sy < 0) { + dev->accel.sy--; + if (dev->accel.sy < 0) { + if (cmd != 4) { dev->accel.cur_x = dev->accel.cx; dev->accel.cur_y = dev->accel.cy; - return; } + dev->accel.cmd_back = 1; + return; } } } @@ -2992,23 +2510,22 @@ rect_fill: case 5: /*Draw Polygon Boundary Line*/ { if (!cpu_input) { + dev->accel.sy = dev->accel.maj_axis_pcnt_no_limit; + dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - dev->accel.sy = dev->accel.maj_axis_pcnt_no_limit; - if (dev->accel.cmd & 0x80) dev->accel.oldcy = dev->accel.cy + 1; else dev->accel.oldcy = dev->accel.cy - 1; - dev->accel.oldcx = 0; - - ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cur_x_nolimit, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.clip_left, clip_r, dev->accel.clip_top, clip_b, compare_mode, dev->accel.multifunc[0x0a]); + ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, clip_l, clip_r, clip_t, clip_b, dev->accel.multifunc[0x0a]); if (ibm8514_cpu_src(svga)) { dev->data_available = 0; @@ -3021,14 +2538,14 @@ rect_fill: } } - if (dev->accel.cmd & 8) { + if (dev->accel.cmd & 0x08) { /*Vectored Boundary Line*/ while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx < 0) - dev->accel.cx = 0; - if (dev->accel.cy < 0) - dev->accel.cy = 0; + dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r); - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -3050,16 +2567,22 @@ rect_fill: READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); if (dev->accel.cmd & 0x10) { - if (dev->accel.sy && (dev->accel.cmd & 4)) { + if (dev->accel.sy && (dev->accel.cmd & 0x04)) { if (dev->accel.oldcy != dev->accel.cy) { WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); } - } else if (!(dev->accel.cmd & 4)) { + } else if (!(dev->accel.cmd & 0x04)) { if (dev->accel.oldcy != dev->accel.cy) { WRITE((dev->accel.cy * dev->pitch) + (dev->accel.cx), dest_dat); } @@ -3075,8 +2598,10 @@ rect_fill: else cpu_dat >>= 8; - if (!dev->accel.sy) + if (!dev->accel.sy) { + dev->accel.cmd_back = 1; break; + } switch (dev->accel.cmd & 0xe0) { case 0x00: @@ -3120,14 +2645,14 @@ rect_fill: dev->accel.sy--; } - } else { + } else { /*Vectored Bresenham*/ while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx < 0) - dev->accel.cx = 0; - if (dev->accel.cy < 0) - dev->accel.cy = 0; + dev->accel.cx = CLAMP(dev->accel.cx, clip_l, clip_r); - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx < clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; @@ -3148,19 +2673,21 @@ rect_fill: READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); if ((dev->accel.cmd & 0x14) == 0x14) { if (dev->accel.sy) { - if (dev->accel.cmd & 0x40) { + if (dev->accel.oldcy != dev->accel.cy) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else { - if (dev->accel.oldcy != dev->accel.cy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } } } } @@ -3174,16 +2701,19 @@ rect_fill: else cpu_dat >>= 8; - if (!dev->accel.sy) + if (!dev->accel.sy) { + dev->accel.cmd_back = 1; break; + } if (dev->accel.cmd & 0x40) { + dev->accel.oldcy = dev->accel.cy; if (dev->accel.cmd & 0x80) dev->accel.cy++; else dev->accel.cy--; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -3198,7 +2728,7 @@ rect_fill: dev->accel.cx--; dev->accel.oldcy = dev->accel.cy; - if (dev->accel.err_term >= 0) { + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt_no_limit) { dev->accel.err_term += dev->accel.destx_distp; if (dev->accel.cmd & 0x80) dev->accel.cy++; @@ -3218,38 +2748,50 @@ rect_fill: if (!cpu_input) /*!cpu_input is trigger to start operation*/ { dev->accel.x_count = 0; - dev->accel.output = 0; - - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; dev->accel.dx = dev->accel.destx; - dev->accel.dy = dev->accel.desty; - if (dev->accel.destx >= 0x600) dev->accel.dx |= ~0x5ff; + + dev->accel.dy = dev->accel.desty; if (dev->accel.desty >= 0x600) dev->accel.dy |= ~0x5ff; dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x >= 0x600) dev->accel.cx |= ~0x5ff; + + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.cy |= ~0x5ff; - dev->accel.src = dev->accel.cy * dev->pitch; - dev->accel.dest = dev->accel.dy * dev->pitch; + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } else if (dev->bpp) { + dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + } else { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } dev->accel.fill_state = 0; if (ibm8514_cpu_src(svga)) { - if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 0x02) { if (!(dev->accel.cmd & 0x1000)) { - dev->accel.sx += (dev->accel.cur_x & 3); - dev->accel.nibbleset = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.writemono = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; + dev->accel.x_count = dev->accel.cx; + if (and3) { + if (dev->accel.cmd & 0x20) + dev->accel.x_count -= and3; + else + dev->accel.x_count += and3; + + dev->accel.sx += 8; + } } } dev->data_available = 0; @@ -3262,495 +2804,398 @@ rect_fill: } } - if (dev->accel.cmd & 2) { - if (cpu_input) { -bitblt_pix: - if (count < 8) { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } - } - break; - - default: - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.src = dev->accel.cy * dev->pitch; - dev->accel.dest = dev->accel.dy * dev->pitch; - dev->accel.sy--; - return; + ibm8514_log("BitBLT: full=%04x, odd=%d, c(%d,%d), d(%d,%d), xcount=%d, and3=%d, len(%d,%d), CURX=%d, Width=%d, pixcntl=%d, mix_dat=%08x, count=%d, cpu_data=%08x, cpu_input=%d.\n", dev->accel.cmd, dev->accel.input, dev->accel.cx, dev->accel.cy, dev->accel.dx, dev->accel.dy, dev->accel.x_count, and3, dev->accel.sx, dev->accel.sy, dev->accel.cur_x, dev->accel.maj_axis_pcnt, pixcntl, mix_dat, count, cpu_dat, cpu_input); + if (cpu_input) { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { + if (pixcntl == 3) { + if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + if (dev->accel.cmd & 0x02) + mix_dat = mix_dat ? 0x01 : 0x00; + else + mix_dat = mix_dat ? mix_mask : 0x00; + } else if (dev->accel.cmd & 0x10) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + if (dev->accel.cmd & 0x02) + mix_dat = mix_dat ? 0x01 : 0x00; + else + mix_dat = mix_dat ? mix_mask : 0x00; } } - } else { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? 1 : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? 1 : 0; + if (dev->accel.cmd & 0x02) { + switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) + src_dat = ((src_dat & rd_mask) == rd_mask); } - } - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } - } - break; + break; - default: - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - - mix_dat >>= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - if (!(dev->accel.cmd & 0x1000)) - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cur_x >= 0x600) - dev->accel.cx |= ~0x5ff; - dev->accel.dx = dev->accel.destx; - if (dev->accel.destx >= 0x600) - dev->accel.dx |= ~0x5ff; - } - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->pitch; - dev->accel.src = dev->accel.cy * dev->pitch; - dev->accel.sy--; - return; - } - } - } - } else { - goto bitblt; - } - } else { - if (cpu_input) { - if (pixcntl == 2) { - goto bitblt_pix; - } else { - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } - } - break; - - default: - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->pitch; - dev->accel.src = dev->accel.cy * dev->pitch; - dev->accel.sy--; - return; - } - } - } - } else { -bitblt: - if (pixcntl == 1) { - if (dev->accel.cmd & 0x40) { - count = dev->accel.maj_axis_pcnt + 1; - dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { - if (!dev->accel.temp_cnt) { - mix_dat >>= 8; - dev->accel.temp_cnt = 8; - } - if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = 0; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - break; - - default: - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - - if (dev->accel.temp_cnt > 0) { - dev->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; - } - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->pitch; - dev->accel.src = dev->accel.cy * dev->pitch; - dev->accel.sy--; - return; - } + default: + break; } } else { - dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { - if (!dev->accel.temp_cnt) { - dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; - } - if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = 0; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - break; - - default: - break; + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) + src_dat = ((src_dat & rd_mask) == rd_mask); } + break; - READ(dev->accel.dest + dev->accel.dx, dest_dat); + default: + break; + } + } - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + READ(dev->accel.dest + dev->accel.dx, dest_dat); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + if (dev->accel.cmd & 0x02) { + MIX(mix_dat & 0x01, dest_dat, src_dat); + if ((dev->accel.x_count != dev->accel.cx) && !(dev->accel.cmd & 0x1000) && and3) + goto skip_nibble_bitblt_write; + + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } else { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + } + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + +skip_nibble_bitblt_write: + if (dev->accel.cmd & 0x20) + dev->accel.x_count++; + else + dev->accel.x_count--; + + if (dev->accel.cmd & 0x02) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } + + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx + 1); + dev->accel.cx -= (dev->accel.sx + 1); + } else { + dev->accel.dx += (dev->accel.sx + 1); + dev->accel.cx += (dev->accel.sx + 1); + } + + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; + } + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } else if (dev->bpp) { + dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + } else { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } + + dev->accel.sy--; + dev->accel.x_count = 0; + + if (dev->accel.sy < 0) + dev->accel.cmd_back = 1; + return; + } + } + } else { + if (pixcntl == 1) { + if (dev->accel.cmd & 0x40) { + count = (dev->accel.maj_axis_pcnt & 0x7ff) + 1; + dev->accel.temp_cnt = 8; + while (count-- && (dev->accel.sy >= 0)) { + if (!dev->accel.temp_cnt) { + mix_dat >>= 8; + dev->accel.temp_cnt = 8; + } + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + break; + + default: + break; } + READ(dev->accel.dest + dev->accel.dx, dest_dat); + + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + + if (dev->accel.temp_cnt > 0) { dev->accel.temp_cnt--; - mix_dat >>= 1; + mix_dat <<= 1; + mix_dat |= 1; + } + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; + dev->accel.dx -= (dev->accel.sx + 1); + dev->accel.cx -= (dev->accel.sx + 1); } else { - dev->accel.dx--; - dev->accel.cx--; + dev->accel.dx += (dev->accel.sx + 1); + dev->accel.cx += (dev->accel.sx + 1); } - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->pitch; - dev->accel.src = dev->accel.cy * dev->pitch; - dev->accel.sy--; - - if (dev->accel.sy < 0) { - return; - } + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; } + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } else if (dev->bpp) { + dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + } else { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } + + dev->accel.sy--; + + if (dev->accel.sy < 0) + dev->accel.cmd_back = 1; + return; } } } else { - if ((dev->accel_bpp == 24) && ((dev->local & 0xff) >= 0x02) && (dev->accel.cmd == 0xc2b5)) { - int64_t cx; - int64_t dx; + dev->accel.temp_cnt = 8; + while (count-- && (dev->accel.sy >= 0)) { + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat = old_mix_dat; + } + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { + switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + break; - cx = (int64_t) dev->accel.cx; - dx = (int64_t) dev->accel.dx; - - while (1) { - if ((dx >= (((int64_t)dev->accel.clip_left) * 3)) && (dx <= (((uint64_t)clip_r) * 3)) && - (dev->accel.dy >= (dev->accel.clip_top << 1)) && (dev->accel.dy <= (clip_b << 1))) { - - READ(dev->accel.src + (dev->accel.ge_offset << 2) + cx, src_dat); - READ(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); - - dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); - - WRITE(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); + default: + break; } - cx++; - dx++; + READ(dev->accel.dest + dev->accel.dx, dest_dat); - dev->accel.sx--; - if (dev->accel.sx < 0) - return; + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & 0x01, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } } - return; - } - ibm8514_log("BitBLT 8514/A=%04x, selfrmix=%d, selbkmix=%d, d(%d,%d), c(%d,%d), pixcntl=%d, sy=%d, frgdmix=%02x, bkgdmix=%02x, rdmask=%02x, wrtmask=%02x, linedraw=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, dev->accel.rd_mask, wrt_mask, dev->accel.linedraw); + dev->accel.temp_cnt--; + mix_dat >>= 1; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx + 1); + dev->accel.cx -= (dev->accel.sx + 1); + } else { + dev->accel.dx += (dev->accel.sx + 1); + dev->accel.cx += (dev->accel.sx + 1); + } + + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; + } + + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } else if (dev->bpp) { + dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + } else { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } + dev->accel.sy--; + + if (dev->accel.sy < 0) { + dev->accel.destx = dev->accel.dx; + dev->accel.desty = dev->accel.dy; + dev->accel.cmd_back = 1; + return; + } + } + } + } + } else { + if ((dev->accel_bpp == 24) && (dev->accel.cmd == 0xc2b5)) { + int64_t cx; + int64_t dx; + + cx = (int64_t) dev->accel.cx; + dx = (int64_t) dev->accel.dx; + + while (1) { + if ((dx >= (((int64_t)clip_l) * 3)) && + (dx <= (((uint64_t)clip_r) * 3)) && + (dev->accel.dy >= (clip_t << 1)) && + (dev->accel.dy <= (clip_b << 1))) { + + READ(dev->accel.src + cx, src_dat); + READ(dev->accel.dest + dx, dest_dat); + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dx, dest_dat); + } + + cx++; + dx++; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.cmd_back = 1; + return; + } + } + } else { while (count-- && dev->accel.sy >= 0) { - if ((dev->accel.dx >= dev->accel.clip_left) && (dev->accel.dx <= clip_r) && - (dev->accel.dy >= dev->accel.clip_top) && (dev->accel.dy <= clip_b)) { + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { if (pixcntl == 3) { if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { READ(dev->accel.src + dev->accel.cx, mix_dat); @@ -3775,9 +3220,8 @@ bitblt: case 3: READ(dev->accel.src + dev->accel.cx, src_dat); if (pixcntl == 3) { - if ((dev->accel.cmd & 0x10) && !(dev->accel.cmd & 0x40)) { + if ((dev->accel.cmd & 0x10) && !(dev->accel.cmd & 0x40)) src_dat = ((src_dat & rd_mask) == rd_mask); - } } break; @@ -3787,12 +3231,18 @@ bitblt: READ(dev->accel.dest + dev->accel.dx, dest_dat); - if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (dev->accel.cmd & 4) { - if (dev->accel.sx > 0) { + if (dev->accel.cmd & 0x04) { + if (dev->accel.sx) { WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } else { @@ -3817,15 +3267,13 @@ bitblt: dev->accel.fill_state = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.dx = dev->accel.destx; - - if (dev->accel.destx >= 0x600) - dev->accel.dx |= ~0x5ff; - - dev->accel.cx = dev->accel.cur_x; - - if (dev->accel.cur_x >= 0x600) - dev->accel.cx |= ~0x5ff; + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx + 1); + dev->accel.cx -= (dev->accel.sx + 1); + } else { + dev->accel.dx += (dev->accel.sx + 1); + dev->accel.cx += (dev->accel.sx + 1); + } if (dev->accel.cmd & 0x80) { dev->accel.dy++; @@ -3835,12 +3283,24 @@ bitblt: dev->accel.cy--; } - dev->accel.dest = dev->accel.dy * dev->pitch; - dev->accel.src = dev->accel.cy * dev->pitch; + if ((dev->accel_bpp == 24) || (dev->accel_bpp <= 8)) { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } else if (dev->bpp) { + dev->accel.src = (dev->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + } else { + dev->accel.src = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } dev->accel.sy--; - if (dev->accel.sy < 0) + if (dev->accel.sy < 0) { + dev->accel.destx = dev->accel.dx; + dev->accel.desty = dev->accel.dy; + dev->accel.cmd_back = 1; return; + } } } } @@ -3891,16 +3351,16 @@ ibm8514_render_8bpp(svga_t *svga) for (int x = 0; x <= dev->h_disp; x += 8) { dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); - p[0] = dev->pallook[dat & 0xff]; - p[1] = dev->pallook[(dat >> 8) & 0xff]; - p[2] = dev->pallook[(dat >> 16) & 0xff]; - p[3] = dev->pallook[(dat >> 24) & 0xff]; + 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]); - p[4] = dev->pallook[dat & 0xff]; - p[5] = dev->pallook[(dat >> 8) & 0xff]; - p[6] = dev->pallook[(dat >> 16) & 0xff]; - p[7] = dev->pallook[(dat >> 24) & 0xff]; + 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; p += 8; @@ -3917,9 +3377,8 @@ ibm8514_render_15bpp(svga_t *svga) uint32_t *p; uint32_t dat; - if ((dev->displine + svga->y_add) < 0) { + if ((dev->displine + svga->y_add) < 0) return; - } if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; @@ -3958,9 +3417,8 @@ ibm8514_render_16bpp(svga_t *svga) uint32_t *p; uint32_t dat; - if ((dev->displine + svga->y_add) < 0) { + if ((dev->displine + svga->y_add) < 0) return; - } if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; @@ -4146,6 +3604,12 @@ ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga) buffer32->line[dev->displine + svga->y_add][svga->x_add + dev->h_disp + i] = svga->overscan_color; } +void +ibm8514_set_poll(svga_t *svga) +{ + timer_set_callback(&svga->timer, ibm8514_poll); +} + void ibm8514_poll(void *priv) { @@ -4155,16 +3619,16 @@ ibm8514_poll(void *priv) int wx; int wy; - ibm8514_log("IBM 8514/A poll.\n"); - if (dev->on[0] || dev->on[1]) { + ibm8514_log("IBM 8514/A poll=%x.\n", dev->on); + if (dev->on) { ibm8514_log("ON!\n"); if (!dev->linepos) { - if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) { + if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; dev->hwcursor_oddeven = 0; } - if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); dev->hwcursor_oddeven = 1; } @@ -4195,7 +3659,7 @@ ibm8514_poll(void *priv) if (dev->hwcursor_on) { if (svga->hwcursor_draw) - svga->hwcursor_draw(svga, dev->displine + svga->y_add); + svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); dev->hwcursor_on--; if (dev->hwcursor_on && dev->interlace) dev->hwcursor_on--; @@ -4304,14 +3768,11 @@ ibm8514_recalctimings(svga_t *svga) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; svga->render8514 = ibm8514_render_blank; -#ifdef ATI_8514_ULTRA if (dev->extensions) { if (svga->ext8514 != NULL) ati8514_recalctimings(svga); - } else -#endif - { - if (dev->on[0]) { + } else { + if (dev->on) { dev->h_total = dev->htotal + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); @@ -4333,18 +3794,22 @@ ibm8514_recalctimings(svga_t *svga) else svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - if (dev->interlace) - dev->dispend >>= 1; - if (dev->dispend == 766) dev->dispend += 2; if (dev->dispend == 478) dev->dispend += 2; + if (dev->interlace) + dev->dispend >>= 1; + dev->pitch = 1024; dev->rowoffset = 0x80; - svga->map8 = dev->pallook; + if (dev->vram_512k_8514) { + if (dev->h_disp == 640) + dev->pitch = 640; + } + dev->accel_bpp = 8; svga->render8514 = ibm8514_render_8bpp; ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->accel.advfunc_cntl & 4, !ibm8514_standalone_enabled); } @@ -4391,20 +3856,21 @@ ibm8514_mca_reset(void *priv) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; ibm8514_log("MCA reset.\n"); - dev->on[0] = 0; - dev->on[1] = 0; - vga_on = 1; -#ifdef ATI_8514_ULTRA + dev->on = 0; if (dev->extensions) ati8514_mca_write(0x102, 0, svga); else -#endif ibm8514_mca_write(0x102, 0, svga); + + svga_set_poll(svga); } static void * ibm8514_init(const device_t *info) { + uint32_t bios_addr = 0; + uint16_t bios_rom_eeprom = 0x0000; + if (svga_get_pri() == NULL) return NULL; @@ -4414,18 +3880,23 @@ ibm8514_init(const device_t *info) svga->dev8514 = dev; svga->ext8514 = NULL; - dev->vram_size = 1024 << 10; + dev->vram_amount = device_get_config_int("memory"); + dev->vram_512k_8514 = dev->vram_amount == 512; + dev->vram_size = dev->vram_amount << 10; dev->vram = calloc(dev->vram_size, 1); dev->changedvram = calloc((dev->vram_size >> 12) + 1, 1); dev->vram_mask = dev->vram_size - 1; dev->map8 = dev->pallook; dev->local = 0; + dev->accel_bpp = 8; dev->type = info->flags; dev->bpp = 0; -#ifdef ATI_8514_ULTRA dev->extensions = device_get_config_int("extensions"); + bios_addr = device_get_config_hex20("bios_addr"); + if (dev->type & DEVICE_MCA) + bios_addr = 0xc6000; switch (dev->extensions) { case 1: @@ -4433,29 +3904,28 @@ ibm8514_init(const device_t *info) mach_t * mach = (mach_t *) calloc(1, sizeof(mach_t)); svga->ext8514 = mach; + rom_init(&dev->bios_rom, + BIOS_MACH8_ROM_PATH, + bios_addr, 0x1000, 0xfff, + 0, MEM_MAPPING_EXTERNAL); + + ati8514_init(svga, svga->ext8514, svga->dev8514); + mach->accel.scratch0 = ((((bios_addr >> 7) - 0x1000) >> 4)); + bios_rom_eeprom = mach->accel.scratch0; if (dev->type & DEVICE_MCA) { - rom_init(&dev->bios_rom, - BIOS_MACH8_ROM_PATH, - 0xc6000, 0x2000, 0x1fff, - 0, MEM_MAPPING_EXTERNAL); 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); mca_add(ati8514_mca_read, ati8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); - ati_eeprom_load(&mach->eeprom, "ati8514_mca.nvr", 0); + ati_eeprom_load_mach8(&mach->eeprom, "ati8514_mca.nvr", 1); mem_mapping_disable(&dev->bios_rom.mapping); - } else { - rom_init(&dev->bios_rom, - BIOS_MACH8_ROM_PATH, - 0xd0000, 0x2000, 0x1fff, - 0, MEM_MAPPING_EXTERNAL); - ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0); - dev->bios_addr = dev->bios_rom.mapping.base; - } - ati8514_init(svga, svga->ext8514, svga->dev8514); + } else + ati_eeprom_load_mach8(&mach->eeprom, "ati8514.nvr", 0); break; } - fallthrough; + fallthrough; default: ibm8514_io_set(svga); @@ -4466,16 +3936,6 @@ ibm8514_init(const device_t *info) } break; } -#else - ibm8514_io_set(svga); - - if (dev->type & DEVICE_MCA) { - dev->pos_regs[0] = 0x7f; - dev->pos_regs[1] = 0xef; - mca_add(ibm8514_mca_read, ibm8514_mca_write, ibm8514_mca_feedb, ibm8514_mca_reset, svga); - } -#endif - return svga; } @@ -4484,13 +3944,10 @@ ibm8514_close(void *priv) { svga_t *svga = (svga_t *) priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - -#ifdef ATI_8514_ULTRA mach_t *mach = (mach_t *) svga->ext8514; if (mach) free(mach); -#endif if (dev) { free(dev->vram); @@ -4516,72 +3973,130 @@ ibm8514_force_redraw(void *priv) svga->fullchange = changeframecount; } -#ifdef ATI_8514_ULTRA // clang-format off -static const device_config_t ext8514_config[] = { +static const device_config_t isa_ext8514_config[] = { { - .name = "extensions", - .description = "Vendor", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "IBM", - .value = 0 - }, - { - .description = "ATI", - .value = 1 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .type = CONFIG_END - } + .name = "extensions", + .description = "Vendor", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IBM", .value = 0 }, + { .description = "ATI", .value = 1 }, + { .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 = "CC00h", .value = 0xcc000 }, + { .description = "CE00h", .value = 0xce000 }, + { .description = "D000h", .value = 0xd0000 }, + { .description = "D200h", .value = 0xd2000 }, + { .description = "D400h", .value = 0xd4000 }, + { .description = "D600h", .value = 0xd6000 }, + { .description = "D800h", .value = 0xd8000 }, + { .description = "DA00h", .value = 0xda000 }, + { .description = "DC00h", .value = 0xdc000 }, + { .description = "DE00h", .value = 0xde000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + +// clang-format off +static const device_config_t mca_ext8514_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "extensions", + .description = "Vendor", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "IBM", .value = 0 }, + { .description = "ATI", .value = 1 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; -#endif // clang-format off const device_t gen8514_isa_device = { - .name = "IBM 8514/A clone (ISA)", + .name = "IBM 8514/A clone (ISA)", .internal_name = "8514_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = 0, - .init = ibm8514_init, - .close = ibm8514_close, - .reset = NULL, - { .available = NULL }, + .flags = DEVICE_ISA16, + .local = 0, + .init = ibm8514_init, + .close = ibm8514_close, + .reset = NULL, + .available = NULL, .speed_changed = ibm8514_speed_changed, - .force_redraw = ibm8514_force_redraw, -#ifdef ATI_8514_ULTRA - .config = ext8514_config -#else - .config = NULL -#endif + .force_redraw = ibm8514_force_redraw, + .config = isa_ext8514_config }; const device_t ibm8514_mca_device = { - .name = "IBM 8514/A (MCA)", + .name = "IBM 8514/A (MCA)", .internal_name = "8514_mca", - .flags = DEVICE_MCA, - .local = 0, - .init = ibm8514_init, - .close = ibm8514_close, - .reset = NULL, - { .available = NULL }, + .flags = DEVICE_MCA, + .local = 0, + .init = ibm8514_init, + .close = ibm8514_close, + .reset = NULL, + .available = NULL, .speed_changed = ibm8514_speed_changed, - .force_redraw = ibm8514_force_redraw, -#ifdef ATI_8514_ULTRA - .config = ext8514_config -#else - .config = NULL -#endif + .force_redraw = ibm8514_force_redraw, + .config = mca_ext8514_config }; - void ibm8514_device_add(void) { diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 7f0993ef8..9a9be6ff6 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -329,27 +329,21 @@ ati18800_force_redraw(void *priv) static const device_config_t ati18800_wonder_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, + .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 = "" - } - } + { .description = "256 KB", .value = 256 }, + { .description = "512 KB", .value = 512 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; const device_t ati18800_wonder_device = { @@ -360,7 +354,7 @@ const device_t ati18800_wonder_device = { .init = ati18800_init, .close = ati18800_close, .reset = NULL, - { .available = ati18800_wonder_available }, + .available = ati18800_wonder_available, .speed_changed = ati18800_speed_changed, .force_redraw = ati18800_force_redraw, .config = ati18800_wonder_config @@ -374,7 +368,7 @@ const device_t ati18800_vga88_device = { .init = ati18800_init, .close = ati18800_close, .reset = NULL, - { .available = ati18800_vga88_available }, + .available = ati18800_vga88_available, .speed_changed = ati18800_speed_changed, .force_redraw = ati18800_force_redraw, .config = NULL @@ -388,7 +382,7 @@ const device_t ati18800_device = { .init = ati18800_init, .close = ati18800_close, .reset = NULL, - { .available = ati18800_available }, + .available = ati18800_available, .speed_changed = ati18800_speed_changed, .force_redraw = ati18800_force_redraw, .config = NULL diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 368312fcb..156e95425 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -36,10 +36,11 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define VGAWONDERXL 1 -#if defined(DEV_BRANCH) && defined(USE_XL24) -# define VGAWONDERXL24 2 -#endif +#define VGAWONDERXL 1 +#define VGAWONDERXLPLUS 2 +#ifdef USE_XL24 +# define VGAWONDERXL24 3 +#endif /* USE_XL24 */ #define BIOS_ATIKOR_PATH "roms/video/ati28800/atikorvga.bin" #define BIOS_ATIKOR_4620P_PATH_L "roms/machines/spc4620p/31005h.u8" @@ -52,13 +53,14 @@ #define BIOS_VGAXL_EVEN_PATH "roms/video/ati28800/xleven.bin" #define BIOS_VGAXL_ODD_PATH "roms/video/ati28800/xlodd.bin" -#if defined(DEV_BRANCH) && defined(USE_XL24) +#ifdef USE_XL24 # define BIOS_XL24_EVEN_PATH "roms/video/ati28800/112-14318-102.bin" # define BIOS_XL24_ODD_PATH "roms/video/ati28800/112-14319-102.bin" -#endif +#endif /* USE_XL24 */ -#define BIOS_ROM_PATH "roms/video/ati28800/bios.bin" -#define BIOS_VGAXL_ROM_PATH "roms/video/ati28800/ATI_VGAWonder_XL.bin" +#define BIOS_ROM_PATH "roms/video/ati28800/bios.bin" +#define BIOS_VGAXL_ROM_PATH "roms/video/ati28800/ATI_VGAWonder_XL.bin" +#define BIOS_VGAXL_PLUS_ROM_PATH "roms/video/ati28800/VGAWonder1024D_XL_Plus_VGABIOS_U19.BIN" typedef struct ati28800_t { svga_t svga; @@ -183,7 +185,7 @@ ati28800_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: - if (ati28800->type == 1) + if ((ati28800->type == VGAWONDERXL) || (ati28800->type == VGAWONDERXLPLUS)) sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); else svga_out(addr, val, svga); @@ -339,7 +341,7 @@ ati28800_in(uint16_t addr, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: - if (ati28800->type == 1) + if ((ati28800->type == VGAWONDERXL) || (ati28800->type == VGAWONDERXLPLUS)) return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); return svga_in(addr, svga); @@ -609,7 +611,17 @@ ati28800_init(const device_t *info) ati28800->svga.ramdac = device_add(&sc11486_ramdac_device); break; -#if defined(DEV_BRANCH) && defined(USE_XL24) + case VGAWONDERXLPLUS: + ati28800->id = 6; + rom_init(&ati28800->bios_rom, + BIOS_VGAXL_PLUS_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + ati28800->svga.ramdac = device_add(&sc11483_ramdac_device); + ati28800->memory = 1024; + break; + +#ifdef USE_XL24 case VGAWONDERXL24: ati28800->id = 6; rom_init_interleaved(&ati28800->bios_rom, @@ -618,7 +630,7 @@ ati28800_init(const device_t *info) 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; -#endif +#endif /* USE_XL24 */ default: ati28800->id = 5; @@ -653,11 +665,15 @@ ati28800_init(const device_t *info) ati_eeprom_load(&ati28800->eeprom, "ati28800xl.nvr", 0); break; -#if defined(DEV_BRANCH) && defined(USE_XL24) + case VGAWONDERXLPLUS: + ati_eeprom_load(&ati28800->eeprom, "ati28800_wonder1024d_xl_plus.nvr", 0); + break; + +#ifdef USE_XL24 case VGAWONDERXL24: ati_eeprom_load(&ati28800->eeprom, "ati28800xl24.nvr", 0); break; -#endif +#endif /* USE_XL24 */ default: ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); @@ -685,13 +701,19 @@ compaq_ati28800_available(void) return (rom_present(BIOS_VGAXL_ROM_PATH)); } -#if defined(DEV_BRANCH) && defined(USE_XL24) +static int +ati28800_wonder1024d_xl_plus_available(void) +{ + return (rom_present(BIOS_VGAXL_PLUS_ROM_PATH)); +} + +#ifdef USE_XL24 static int ati28800_wonderxl24_available(void) { return (rom_present(BIOS_XL24_EVEN_PATH) && rom_present(BIOS_XL24_ODD_PATH)); } -#endif +#endif /* USE_XL24 */ static void ati28800_close(void *priv) @@ -722,63 +744,45 @@ ati28800_force_redraw(void *priv) // clang-format off static const device_config_t ati28800_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; -#if defined(DEV_BRANCH) && defined(USE_XL24) +#ifdef USE_XL24 static const device_config_t ati28800_wonderxl_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; -#endif +#endif /* USE_XL24 */ // clang-format on const device_t ati28800_device = { @@ -789,7 +793,7 @@ const device_t ati28800_device = { .init = ati28800_init, .close = ati28800_close, .reset = NULL, - { .available = ati28800_available }, + .available = ati28800_available, .speed_changed = ati28800_speed_changed, .force_redraw = ati28800_force_redraw, .config = ati28800_config @@ -803,7 +807,7 @@ const device_t ati28800k_device = { .init = ati28800k_init, .close = ati28800_close, .reset = NULL, - { .available = ati28800k_available }, + .available = ati28800k_available, .speed_changed = ati28800_speed_changed, .force_redraw = ati28800_force_redraw, .config = ati28800_config @@ -817,7 +821,7 @@ const device_t ati28800k_spc4620p_device = { .init = ati28800k_init, .close = ati28800_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = ati28800_speed_changed, .force_redraw = ati28800_force_redraw, .config = NULL @@ -831,7 +835,7 @@ const device_t ati28800k_spc6033p_device = { .init = ati28800k_init, .close = ati28800_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = ati28800_speed_changed, .force_redraw = ati28800_force_redraw, .config = NULL @@ -845,13 +849,27 @@ const device_t compaq_ati28800_device = { .init = ati28800_init, .close = ati28800_close, .reset = NULL, - { .available = compaq_ati28800_available }, + .available = compaq_ati28800_available, .speed_changed = ati28800_speed_changed, .force_redraw = ati28800_force_redraw, .config = ati28800_config }; -#if defined(DEV_BRANCH) && defined(USE_XL24) +const device_t ati28800_wonder1024d_xl_plus_device = { + .name = "ATI 28800-6 (ATI VGA Wonder 1024D XL Plus)", + .internal_name = "ati28800_wonder1024d_xl_plus", + .flags = DEVICE_ISA, + .local = VGAWONDERXLPLUS, + .init = ati28800_init, + .close = ati28800_close, + .reset = NULL, + .available = ati28800_wonder1024d_xl_plus_available, + .speed_changed = ati28800_speed_changed, + .force_redraw = ati28800_force_redraw, + .config = NULL +}; + +#ifdef USE_XL24 const device_t ati28800_wonderxl24_device = { .name = "ATI-28800 (VGA Wonder XL24)", .internal_name = "ati28800w", @@ -860,9 +878,9 @@ const device_t ati28800_wonderxl24_device = { .init = ati28800_init, .close = ati28800_close, .reset = NULL, - { .available = ati28800_wonderxl24_available }, + .available = ati28800_wonderxl24_available, .speed_changed = ati28800_speed_changed, .force_redraw = ati28800_force_redraw, .config = ati28800_wonderxl_config }; -#endif +#endif /* USE_XL24 */ diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index ac2a0f7cb..bb5ccbf31 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -74,16 +74,16 @@ ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) switch (addr) { case 0: - svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, val, svga); + svga_out((dev && dev->on) ? 0x2ec : 0x3c8, val, svga); break; case 1: - svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, val, svga); + svga_out((dev && dev->on) ? 0x2ed : 0x3c9, val, svga); break; case 2: - svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, val, svga); + svga_out((dev && dev->on) ? 0x2ea : 0x3c6, val, svga); break; case 3: - svga_out((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, val, svga); + svga_out((dev && dev->on) ? 0x2eb : 0x3c7, val, svga); break; default: ramdac->regs[addr & 0xf] = val; @@ -181,16 +181,16 @@ ati68860_ramdac_in(uint16_t addr, void *priv, svga_t *svga) switch (addr) { case 0: - temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ec : 0x3c8, svga); + temp = svga_in((dev && dev->on) ? 0x2ec : 0x3c8, svga); break; case 1: - temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ed : 0x3c9, svga); + temp = svga_in((dev && dev->on) ? 0x2ed : 0x3c9, svga); break; case 2: - temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2ea : 0x3c6, svga); + temp = svga_in((dev && dev->on) ? 0x2ea : 0x3c6, svga); break; case 3: - temp = svga_in((dev && (dev->on[0] || dev->on[1])) ? 0x2eb : 0x3c7, svga); + temp = svga_in((dev && dev->on) ? 0x2eb : 0x3c7, svga); break; case 4: case 8: @@ -314,7 +314,7 @@ const device_t ati68860_ramdac_device = { .init = ati68860_ramdac_init, .close = ati68860_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_ati68875_ramdac.c b/src/video/vid_ati68875_ramdac.c index 447a8eca8..5d573a282 100644 --- a/src/video/vid_ati68875_ramdac.c +++ b/src/video/vid_ati68875_ramdac.c @@ -160,7 +160,7 @@ const device_t ati68875_ramdac_device = { .init = ati68875_ramdac_init, .close = ati68875_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 054d83d36..a057f1f39 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -43,11 +43,12 @@ ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) } if (fread(eeprom->data, 1, size, fp) != size) memset(eeprom->data, 0, size); + fclose(fp); } void -ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn) +ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn, int mca) { FILE *fp; int size; @@ -55,14 +56,43 @@ ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn) strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); fp = nvr_fopen(eeprom->fn, "rb"); size = 128; - if (!fp) { /*The ATI Graphics Ultra bios expects an immediate write to nvram if none is present at boot time otherwise + if (!fp) { + if (mca) { + (void) fseek(fp, 2L, SEEK_SET); + memset(eeprom->data + 2, 0xff, size - 2); + fp = nvr_fopen(eeprom->fn, "wb"); + fwrite(eeprom->data, 1, size, fp); + fclose(fp); + } else + memset(eeprom->data, 0xff, size); + return; + } + if (fread(eeprom->data, 1, size, fp) != size) + memset(eeprom->data, 0, size); + + fclose(fp); +} + +void +ati_eeprom_load_mach8_vga(ati_eeprom_t *eeprom, char *fn) +{ + FILE *fp; + int size; + eeprom->type = 0; + strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); + fp = nvr_fopen(eeprom->fn, "rb"); + size = 128; + if (!fp) { /*The ATI Graphics Ultra bios expects a fresh nvram zero'ed at boot time otherwise it would hang the machine.*/ memset(eeprom->data, 0, size); fp = nvr_fopen(eeprom->fn, "wb"); fwrite(eeprom->data, 1, size, fp); + fclose(fp); + return; } if (fread(eeprom->data, 1, size, fp) != size) memset(eeprom->data, 0, size); + fclose(fp); } @@ -79,9 +109,9 @@ ati_eeprom_save(ati_eeprom_t *eeprom) void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) { - if (!ena) { + if (!ena) eeprom->out = 1; - } + if (clk && !eeprom->oldclk) { if (ena && !eeprom->oldena) { eeprom->state = EEPROM_WAIT; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 04d497f28..9499f4ecc 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -248,12 +248,12 @@ typedef struct mach64_t { fifo_entry_t fifo[FIFO_SIZE]; atomic_int fifo_read_idx; atomic_int fifo_write_idx; + atomic_int blitter_busy; thread_t *fifo_thread; event_t *wake_fifo_thread; event_t *fifo_not_full_event; - int blitter_busy; uint64_t blitter_time; uint64_t status_time; @@ -333,7 +333,8 @@ enum { enum { SRC_PATT_EN = 1, SRC_PATT_ROT_EN = 2, - SRC_LINEAR_EN = 4 + SRC_LINEAR_EN = 4, + SRC_BYTE_ALIGN = 8 }; enum { @@ -538,7 +539,7 @@ mach64_recalctimings(svga_t *svga) break; case BPP_8: if (mach64->type != MACH64_GX) - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_clone_highres; svga->hdisp <<= 3; svga->rowoffset >>= 1; break; @@ -649,9 +650,8 @@ mach64_updatemapping(mach64_t *mach64) static void mach64_update_irqs(mach64_t *mach64) { - if (!mach64->pci) { + if (!mach64->pci) return; - } if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) pci_set_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state); @@ -659,7 +659,6 @@ mach64_update_irqs(mach64_t *mach64) pci_clear_irq(mach64->pci_slot, PCI_INTA, &mach64->irq_state); } -#if 0 static __inline void wake_fifo_thread(mach64_t *mach64) { @@ -674,7 +673,6 @@ mach64_wait_fifo_idle(mach64_t *mach64) thread_wait_event(mach64->fifo_not_full_event, 1); } } -#endif #define READ8(addr, var) \ switch ((addr) &3) { \ @@ -1174,7 +1172,6 @@ mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) } } -#if 0 static void fifo_thread(void *param) { @@ -1222,11 +1219,53 @@ static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; + int limit = 0; - if (FIFO_FULL) { - thread_reset_event(mach64->fifo_not_full_event); + switch (type) { + case FIFO_WRITE_BYTE: + switch (addr & 0x3ff) { + case 0x11b: + limit = 1; + break; + default: + break; + } + break; + case FIFO_WRITE_WORD: + switch (addr & 0x3fe) { + case 0x11a: + limit = 1; + break; + default: + break; + } + break; + case FIFO_WRITE_DWORD: + switch (addr & 0x3fc) { + case 0x118: + limit = 1; + break; + default: + break; + } + break; + default: + break; + } + + if (limit) { + if (FIFO_ENTRIES >= 16) { + thread_reset_event(mach64->fifo_not_full_event); + if (FIFO_ENTRIES >= 16) { + thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } + } else { if (FIFO_FULL) { - thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + thread_reset_event(mach64->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } } } @@ -1238,11 +1277,18 @@ mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) wake_fifo_thread(mach64); } -#endif void mach64_start_fill(mach64_t *mach64) { + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; + + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; + mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; + mach64->accel.dst_x = 0; mach64->accel.dst_y = 0; @@ -1256,7 +1302,8 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; - if (((mach64->dp_src >> 16) & 7) == MONO_SRC_BLITSRC) { + if ((((mach64->dp_src >> 16) & 7) == MONO_SRC_BLITSRC) && + ((mach64->src_cntl & (SRC_LINEAR_EN | SRC_BYTE_ALIGN)) == (SRC_LINEAR_EN | SRC_BYTE_ALIGN))) { if (mach64->accel.dst_width & 7) mach64->accel.dst_width = (mach64->accel.dst_width & ~7) + 8; } @@ -1308,14 +1355,6 @@ mach64_start_fill(mach64_t *mach64) mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - if (mach64->accel.src_size == WIDTH_1BIT) mach64->accel.src_offset <<= 3; else @@ -1469,16 +1508,16 @@ mach64_start_line(mach64_t *mach64) mach64->accel.op = OP_LINE; } -#define READ(addr, dat, width) \ - if (width == 0) \ - dat = svga->vram[((addr)) & mach64->vram_mask]; \ - else if (width == 1) \ - dat = *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask]; \ - else if (width == 2) \ - dat = *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask]; \ - else if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) &7)) & 1; \ - else \ +#define READ(addr, dat, width) \ + if (width == 0) \ + dat = svga->vram[((addr)) & mach64->vram_mask]; \ + else if (width == 1) \ + dat = *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask]; \ + else if (width == 2) \ + dat = *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask]; \ + else if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ + dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) &7)) & 1; \ + else \ dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> (7 - ((addr) &7))) & 1; #define MIX \ @@ -1536,29 +1575,29 @@ mach64_start_line(mach64_t *mach64) break; \ } -#define WRITE(addr, width) \ - if (width == 0) { \ - svga->vram[(addr) &mach64->vram_mask] = dest_dat; \ - svga->changedvram[((addr) &mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if (width == 1) { \ - *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if (width == 2) { \ - *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else { \ - if (dest_dat & 1) { \ - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) &7); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << (7 - ((addr) &7)); \ - } else { \ - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) &7)); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \ - } \ - svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ +#define WRITE(addr, width) \ + if (width == 0) { \ + svga->vram[(addr) &mach64->vram_mask] = dest_dat; \ + svga->changedvram[((addr) &mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ + } else if (width == 1) { \ + *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ + } else if (width == 2) { \ + *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ + } else { \ + if (dest_dat & 1) { \ + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ + svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) &7); \ + else \ + svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << (7 - ((addr) &7)); \ + } else { \ + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ + svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) &7)); \ + else \ + svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \ + } \ + svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } void @@ -1824,6 +1863,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) cpu_dat >>= (count & 7); else cpu_dat <<= (count & 7); + count &= ~7; } } @@ -2538,26 +2578,26 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x101: case 0x102: case 0x103: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_off_pitch); break; case 0x104: case 0x105: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; case 0x108: case 0x109: case 0x11c: case 0x11d: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->dst_y_x); break; case 0x10c: case 0x10d: case 0x10e: case 0x10f: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; case 0x110: @@ -2572,7 +2612,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x11b: case 0x11e: case 0x11f: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_height_width); break; @@ -2580,28 +2620,28 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x121: case 0x122: case 0x123: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_lnth); break; case 0x124: case 0x125: case 0x126: case 0x127: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_err); break; case 0x128: case 0x129: case 0x12a: case 0x12b: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_inc); break; case 0x12c: case 0x12d: case 0x12e: case 0x12f: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_dec); break; @@ -2609,7 +2649,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x131: case 0x132: case 0x133: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; @@ -2617,75 +2657,75 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x181: case 0x182: case 0x183: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_off_pitch); break; case 0x184: case 0x185: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; case 0x188: case 0x189: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x); break; case 0x18c: case 0x18d: case 0x18e: case 0x18f: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; case 0x190: case 0x191: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height1_width1); break; case 0x194: case 0x195: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; case 0x198: case 0x199: case 0x19a: case 0x19b: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; case 0x19c: case 0x19d: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; case 0x1a0: case 0x1a1: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x_start); break; case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; case 0x1a8: case 0x1a9: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height2_width2); break; case 0x1ac: case 0x1ad: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; @@ -2693,7 +2733,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x1b5: case 0x1b6: case 0x1b7: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_cntl); break; @@ -2701,7 +2741,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x241: case 0x242: case 0x243: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->host_cntl); break; @@ -2709,14 +2749,14 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x281: case 0x282: case 0x283: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg0); break; case 0x284: case 0x285: case 0x286: case 0x287: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg1); break; @@ -2724,7 +2764,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x289: case 0x28a: case 0x28b: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_cntl); break; @@ -2732,7 +2772,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2a1: case 0x2a8: case 0x2a9: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; case 0x2a4: @@ -2741,7 +2781,7 @@ mach64_ext_readb(uint32_t addr, void *priv) fallthrough; case 0x2aa: case 0x2ab: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; @@ -2749,7 +2789,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2ad: case 0x2b4: case 0x2b5: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; case 0x2b0: @@ -2758,7 +2798,7 @@ mach64_ext_readb(uint32_t addr, void *priv) fallthrough; case 0x2b6: case 0x2b7: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; @@ -2766,14 +2806,14 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2c1: case 0x2c2: case 0x2c3: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_bkgd_clr); break; case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_frgd_clr); break; @@ -2781,7 +2821,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2c9: case 0x2ca: case 0x2cb: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->write_mask); break; @@ -2789,7 +2829,7 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2cd: case 0x2ce: case 0x2cf: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->chain_mask); break; @@ -2797,21 +2837,21 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x2d1: case 0x2d2: case 0x2d3: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_pix_width); break; case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_mix); break; case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_src); break; @@ -2819,53 +2859,61 @@ mach64_ext_readb(uint32_t addr, void *priv) case 0x301: case 0x302: case 0x303: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_clr); break; case 0x304: case 0x305: case 0x306: case 0x307: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_mask); break; case 0x308: case 0x309: case 0x30a: case 0x30b: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_cntl); break; case 0x310: case 0x311: + if (!mach64->blitter_busy) + wake_fifo_thread(mach64); + ret = 0; + if (FIFO_FULL) + ret = 0xff; break; case 0x320: case 0x321: case 0x322: case 0x323: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->context_mask); break; case 0x330: case 0x331: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; case 0x332: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr - 2, mach64->src_cntl); break; case 0x333: - //mach64_wait_fifo_idle(mach64); + mach64_wait_fifo_idle(mach64); READ8(addr - 3, mach64->pat_cntl); break; case 0x338: - ret = 0; + if (!mach64->blitter_busy) + wake_fifo_thread(mach64); + + ret = FIFO_EMPTY ? 0 : 1; break; default: @@ -2884,7 +2932,7 @@ mach64_ext_readw(uint32_t addr, void *priv) uint16_t ret; if (!(addr & 0x400)) { - mach64_log("nmach64_ext_readw: addr=%04x\n", addr); + mach64_log("mach64_ext_readw: addr=%04x\n", addr); ret = 0xffff; } else switch (addr & 0x3ff) { @@ -3048,9 +3096,9 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv) break; } - mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); + mach64_log("mach64_ext_writeb: addr=%04x val=%02x\n", addr, val); } else if (addr & 0x300) { - mach64_accel_write_fifo(mach64, addr & 0x3ff, val); + mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); } else { switch (addr & 0x3ff) { case 0x00: @@ -3293,14 +3341,11 @@ mach64_ext_writew(uint32_t addr, uint16_t val, void *priv) mach64_ext_writeb(addr, val, priv); mach64_ext_writeb(addr + 1, val >> 8, priv); } else if (addr & 0x300) { - mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val); - } else - switch (addr & 0x3fe) { - default: - mach64_ext_writeb(addr, val, priv); - mach64_ext_writeb(addr + 1, val >> 8, priv); - break; - } + mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + } else { + mach64_ext_writeb(addr, val, priv); + mach64_ext_writeb(addr + 1, val >> 8, priv); + } } void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) @@ -3314,14 +3359,11 @@ mach64_ext_writel(uint32_t addr, uint32_t val, void *priv) mach64_ext_writew(addr, val, priv); mach64_ext_writew(addr + 2, val >> 16, priv); } else if (addr & 0x300) { - mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val); - } else - switch (addr & 0x3fc) { - default: - mach64_ext_writew(addr, val, priv); - mach64_ext_writew(addr + 2, val >> 16, priv); - break; - } + mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + } else { + mach64_ext_writew(addr, val, priv); + mach64_ext_writew(addr + 2, val >> 16, priv); + } } uint8_t @@ -3527,12 +3569,10 @@ uint16_t mach64_ext_inw(uint16_t port, void *priv) { uint16_t ret; - switch (port) { - default: - ret = mach64_ext_inb(port, priv); - ret |= (mach64_ext_inb(port + 1, priv) << 8); - break; - } + + ret = mach64_ext_inb(port, priv); + ret |= (mach64_ext_inb(port + 1, priv) << 8); + mach64_log("mach64_ext_inw : port %04X ret %04X\n", port, ret); return ret; } @@ -3540,6 +3580,7 @@ uint32_t mach64_ext_inl(uint16_t port, void *priv) { uint32_t ret; + switch (port) { case 0x56ec: ret = mach64_ext_readl(0x400 | 0xb4, priv); @@ -3737,23 +3778,15 @@ void mach64_ext_outw(uint16_t port, uint16_t val, void *priv) { mach64_log("mach64_ext_outw : port %04X val %04X\n", port, val); - switch (port) { - default: - mach64_ext_outb(port, val, priv); - mach64_ext_outb(port + 1, val >> 8, priv); - break; - } + mach64_ext_outb(port, val, priv); + mach64_ext_outb(port + 1, val >> 8, priv); } void mach64_ext_outl(uint16_t port, uint32_t val, void *priv) { mach64_log("mach64_ext_outl : port %04X val %08X\n", port, val); - switch (port) { - default: - mach64_ext_outw(port, val, priv); - mach64_ext_outw(port + 2, val >> 16, priv); - break; - } + mach64_ext_outw(port, val, priv); + mach64_ext_outw(port + 2, val >> 16, priv); } static uint8_t @@ -4546,6 +4579,11 @@ mach64_common_init(const device_t *info) mach64->dst_cntl = 3; + mach64->thread_run = 1; + mach64->wake_fifo_thread = thread_create_event(); + mach64->fifo_not_full_event = thread_create_event(); + mach64->fifo_thread = thread_create(fifo_thread, mach64); + mach64->i2c = i2c_gpio_init("ddc_ati_mach64"); mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c)); @@ -4640,6 +4678,12 @@ mach64_close(void *priv) { mach64_t *mach64 = (mach64_t *) priv; + mach64->thread_run = 0; + thread_set_event(mach64->wake_fifo_thread); + thread_wait(mach64->fifo_thread); + thread_destroy_event(mach64->fifo_not_full_event); + thread_destroy_event(mach64->wake_fifo_thread); + svga_close(&mach64->svga); ddc_close(mach64->ddc); @@ -4667,68 +4711,53 @@ mach64_force_redraw(void *priv) // clang-format off static const device_config_t mach64gx_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t mach64vt2_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on const device_t mach64gx_isa_device = { .name = "ATI Mach64GX ISA", .internal_name = "mach64gx_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = 0, .init = mach64gx_init, .close = mach64_close, .reset = NULL, - { .available = mach64gx_isa_available }, + .available = mach64gx_isa_available, .speed_changed = mach64_speed_changed, .force_redraw = mach64_force_redraw, .config = mach64gx_config @@ -4742,7 +4771,7 @@ const device_t mach64gx_vlb_device = { .init = mach64gx_init, .close = mach64_close, .reset = NULL, - { .available = mach64gx_vlb_available }, + .available = mach64gx_vlb_available, .speed_changed = mach64_speed_changed, .force_redraw = mach64_force_redraw, .config = mach64gx_config @@ -4756,7 +4785,7 @@ const device_t mach64gx_pci_device = { .init = mach64gx_init, .close = mach64_close, .reset = NULL, - { .available = mach64gx_available }, + .available = mach64gx_available, .speed_changed = mach64_speed_changed, .force_redraw = mach64_force_redraw, .config = mach64gx_config @@ -4770,7 +4799,7 @@ const device_t mach64vt2_device = { .init = mach64vt2_init, .close = mach64_close, .reset = NULL, - { .available = mach64vt2_available }, + .available = mach64vt2_available, .speed_changed = mach64_speed_changed, .force_redraw = mach64_force_redraw, .config = mach64vt2_config diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index b170ae205..06a60449f 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -37,6 +37,7 @@ #include <86box/i2c.h> #include <86box/vid_ddc.h> #include <86box/vid_8514a.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/vid_ati_eeprom.h> @@ -48,26 +49,24 @@ #define BIOS_MACH32_MCA_ROM_PATH "roms/video/mach32/MACH32MCA_Olivetti.BIN" #define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/intelopt_00000.rom" -static video_timings_t timing_gfxultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; -static video_timings_t timing_mach32_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; -static video_timings_t timing_mach32_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; -static video_timings_t timing_mach32_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_gfxultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_mach32_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_mach32_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_mach32_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; static void mach_accel_outb(uint16_t port, uint8_t val, void *priv); static void mach_accel_outw(uint16_t port, uint16_t val, void *priv); +static void mach_accel_outl(uint16_t port, uint32_t val, void *priv); static uint8_t mach_accel_inb(uint16_t port, void *priv); static uint16_t mach_accel_inw(uint16_t port, void *priv); -static uint8_t mach_in(uint16_t addr, void *priv); +static uint32_t mach_accel_inl(uint16_t port, void *priv); -#ifdef ATI_8514_ULTRA static void ati8514_accel_outb(uint16_t port, uint8_t val, void *priv); static void ati8514_accel_outw(uint16_t port, uint16_t val, void *priv); static void ati8514_accel_outl(uint16_t port, uint32_t val, void *priv); static uint8_t ati8514_accel_inb(uint16_t port, void *priv); static uint16_t ati8514_accel_inw(uint16_t port, void *priv); static uint32_t ati8514_accel_inl(uint16_t port, void *priv); -#endif - static void mach32_updatemapping(mach_t *mach, svga_t *svga); @@ -89,14 +88,14 @@ mach_log(const char *fmt, ...) # define mach_log(fmt, ...) #endif -#define WRITE8(addr, var, val) \ - switch ((addr) & 1) { \ - case 0: \ - var = (var & 0xff00) | (val); \ - break; \ - case 1: \ - var = (var & 0x00ff) | ((val) << 8); \ - break; \ +#define WRITE8(addr, var, val) \ + switch ((addr) & 1) { \ + case 0: \ + var = (var & 0xff00) | (val); \ + break; \ + case 1: \ + var = (var & 0x00ff) | ((val) << 8); \ + break; \ } #define READ8(addr, var) \ @@ -111,156 +110,164 @@ mach_log(const char *fmt, ...) #define READ_PIXTRANS_BYTE_IO(cx, n) \ if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ - if (dev->bpp) { \ - if (n == 0) \ + if (dev->bpp) { \ + if (n == 0) \ mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] & 0xff; \ - else \ - mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] >> 8; \ - } else { \ - mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ - } \ + else \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (dev->vram_mask >> 1)] >> 8; \ + } else \ + mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ } -#define READ_PIXTRANS_WORD(cx, n) \ - if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ - if (dev->bpp) \ - temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ - else { \ - temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ - } else if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ - if (dev->bpp) \ - temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ - else { \ - temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ - } else if ((mach->accel.cmd_type == 3) || (mach->accel.cmd_type == 4)) { \ - if (dev->bpp) \ - temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ - else { \ - temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ +#define READ_PIXTRANS_WORD(cx, n) \ + if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ + if (dev->bpp) \ + temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ + temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ + if (dev->bpp) \ + temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ + temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((mach->accel.cmd_type == 3) || (mach->accel.cmd_type == 4)) { \ + if (dev->bpp) \ + temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (dev->vram_mask >> 1)]; \ + else { \ + temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ temp |= (dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } \ + } \ } -#define READ(addr, dat) \ - if (dev->bpp) \ - dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ - else \ - dat = dev->vram[(addr) & (dev->vram_mask)]; +#define READ(addr, dat) \ + if (dev->bpp) \ + dat = vram_w[(addr) & (dev->vram_mask >> 1)]; \ + else \ + dat = (dev->vram[(addr) & (dev->vram_mask)]); -#define MIX(mixmode, dest_dat, src_dat) \ - { \ - switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ - case 0x00: \ - dest_dat = ~dest_dat; \ - break; \ - case 0x01: \ - dest_dat = 0; \ - break; \ - case 0x02: \ - dest_dat = ~0; \ - break; \ - case 0x03: \ - dest_dat = dest_dat; \ - break; \ - case 0x04: \ - dest_dat = ~src_dat; \ - break; \ - case 0x05: \ - dest_dat = src_dat ^ dest_dat; \ - break; \ - case 0x06: \ - dest_dat = ~(src_dat ^ dest_dat); \ - break; \ - case 0x07: \ - dest_dat = src_dat; \ - break; \ - case 0x08: \ - dest_dat = ~(src_dat & dest_dat); \ - break; \ - case 0x09: \ - dest_dat = ~src_dat | dest_dat; \ - break; \ - case 0x0a: \ - dest_dat = src_dat | ~dest_dat; \ - break; \ - case 0x0b: \ - dest_dat = src_dat | dest_dat; \ - break; \ - case 0x0c: \ - dest_dat = src_dat & dest_dat; \ - break; \ - case 0x0d: \ - dest_dat = src_dat & ~dest_dat; \ - break; \ - case 0x0e: \ - dest_dat = ~src_dat & dest_dat; \ - break; \ - case 0x0f: \ - dest_dat = ~(src_dat | dest_dat); \ - break; \ - case 0x10: \ - dest_dat = MIN(src_dat, dest_dat); \ - break; \ - case 0x11: \ - dest_dat = dest_dat - src_dat; \ - break; \ - case 0x12: \ - dest_dat = src_dat - dest_dat; \ - break; \ - case 0x13: \ - dest_dat = src_dat + dest_dat; \ - break; \ - case 0x14: \ - dest_dat = MAX(src_dat, dest_dat); \ - break; \ - case 0x15: \ - dest_dat = (dest_dat - src_dat) / 2; \ - break; \ - case 0x16: \ - dest_dat = (src_dat - dest_dat) / 2; \ - break; \ - case 0x17: \ - dest_dat = (dest_dat + src_dat) / 2; \ - break; \ - case 0x18: \ - dest_dat = MAX(0, (dest_dat - src_dat)); \ - break; \ - case 0x19: \ - dest_dat = MAX(0, (dest_dat - src_dat)); \ - break; \ - case 0x1a: \ - dest_dat = MAX(0, (src_dat - dest_dat)); \ - break; \ - case 0x1b: \ - dest_dat = MIN(0xff, (dest_dat + src_dat)); \ - break; \ - case 0x1c: \ - dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ - break; \ - case 0x1d: \ - dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ - break; \ - case 0x1e: \ - dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ - break; \ - case 0x1f: \ - dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ - break; \ - } \ +#define READ_HIGH(addr, dat) \ + dat |= (dev->vram[(addr) & (dev->vram_mask)] << 8); + +#define MIX(mixmode, dest_dat, src_dat) \ + { \ + switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ + case 0x00: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x01: \ + dest_dat = 0; \ + break; \ + case 0x02: \ + dest_dat = ~0; \ + break; \ + case 0x03: \ + dest_dat = dest_dat; \ + break; \ + case 0x04: \ + dest_dat = ~src_dat; \ + break; \ + case 0x05: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x06: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x07: \ + dest_dat = src_dat; \ + break; \ + case 0x08: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x09: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0x0a: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0x0b: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0x0c: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0x0d: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0x0e: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0x0f: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + case 0x10: \ + dest_dat = MIN(src_dat, dest_dat); \ + break; \ + case 0x11: \ + dest_dat = dest_dat - src_dat; \ + break; \ + case 0x12: \ + dest_dat = src_dat - dest_dat; \ + break; \ + case 0x13: \ + dest_dat = src_dat + dest_dat; \ + break; \ + case 0x14: \ + dest_dat = MAX(src_dat, dest_dat); \ + break; \ + case 0x15: \ + dest_dat = (dest_dat - src_dat) / 2; \ + break; \ + case 0x16: \ + dest_dat = (src_dat - dest_dat) / 2; \ + break; \ + case 0x17: \ + dest_dat = (dest_dat + src_dat) / 2; \ + break; \ + case 0x18: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x19: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x1a: \ + dest_dat = MAX(0, (src_dat - dest_dat)); \ + break; \ + case 0x1b: \ + if (dev->bpp) \ + dest_dat = MIN(0xffff, (dest_dat + src_dat)); \ + else \ + dest_dat = MIN(0xff, (dest_dat + src_dat)); \ + break; \ + case 0x1c: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1d: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1e: \ + dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ + break; \ + case 0x1f: \ + if (dev->bpp) \ + dest_dat = (0xffff < (src_dat + dest_dat)) ? 0xffff : ((src_dat + dest_dat) / 2); \ + else \ + dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ + break; \ + } \ } -#define WRITE(addr, dat) \ - if (dev->bpp) { \ - vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ +#define WRITE(addr, dat) \ + if (dev->bpp) { \ + vram_w[((addr)) & (dev->vram_mask >> 1)] = dat; \ dev->changedvram[(((addr)) & (dev->vram_mask >> 1)) >> 11] = changeframecount; \ - } else { \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ } static int @@ -282,7 +289,7 @@ mach_pixel_read(mach_t *mach) } static void -mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, mach_t *mach, ibm8514_t *dev) +mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, UNUSED(svga_t *svga), mach_t *mach, ibm8514_t *dev) { int compare_mode; uint16_t poly_src = 0; @@ -298,12 +305,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 uint16_t old_dest_dat; uint16_t *vram_w = (uint16_t *) dev->vram; uint16_t mix = 0; - int16_t clip_l = dev->accel.clip_left & 0x7ff; - int16_t clip_t = dev->accel.clip_top & 0x7ff; - int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; - int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; uint32_t mono_dat0 = 0; uint32_t mono_dat1 = 0; + int16_t clip_t = dev->accel.clip_top; + int16_t clip_l = dev->accel.clip_left; + int16_t clip_b = dev->accel.clip_bottom; + int16_t clip_r = dev->accel.clip_right; if (!dev->bpp) { rd_mask &= 0xff; @@ -323,17 +330,15 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (cpu_input) { if (dev->bpp) { - if ((mach->accel.dp_config & 0x200) && (count == 2)) { + if ((mach->accel.dp_config & 0x200) && (count == 2)) count >>= 1; - } } } - if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) { - if ((cmd_type == 2) && cpu_input) { - mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); - } - } + if ((dev->accel_bpp == 8) || (dev->accel_bpp == 15) || (dev->accel_bpp == 16) || (dev->accel_bpp == 24)) + mach_log("RdMask=%04x, DPCONFIG=%04x, Clipping: l=%d, r=%d, t=%d, b=%d, LineDrawOpt=%04x, BPP=%d, CMDType = %d, offs=%08x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, d(%d,%d), dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", + dev->accel.rd_mask, mach->accel.dp_config, clip_l, clip_r, clip_t, clip_b, mach->accel.linedraw_opt, dev->accel_bpp, cmd_type, mach->accel.ge_offset, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, dev->accel.cur_y, + mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); switch (cmd_type) { case 1: /*Extended Raw Linedraw from bres_count register (0x96ee)*/ @@ -341,6 +346,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.dx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) dev->accel.dx |= ~0x5ff; + dev->accel.dy = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) dev->accel.dy |= ~0x5ff; @@ -348,6 +354,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.cx = dev->accel.destx_distp; if (dev->accel.destx_distp >= 0x600) dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.desty_axstp; if (dev->accel.desty_axstp >= 0x600) dev->accel.cy |= ~0x5ff; @@ -356,12 +363,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.sx = 0; mach->accel.poly_fill = 0; - mach->accel.color_pattern_idx = ((dev->accel.cx + (dev->accel.cy << 3)) & mach->accel.patt_len); - mach->accel.stepx = (mach->accel.linedraw_opt & 0x20) ? 1 : -1; mach->accel.stepy = (mach->accel.linedraw_opt & 0x80) ? 1 : -1; - mach_log("Extended bresenham, CUR(%d,%d), DEST(%d,%d), width = %d, options = %04x, dpconfig = %04x, opt_ena = %03x.\n", dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.linedraw_opt, mach->accel.dp_config, mach->accel.max_waitstates & 0x100); + mach_log("Extended bresenham, CUR(%d,%d), DEST(%d,%d), width = %d, options = %04x, dpconfig = %04x, opt_ena = %03x.\n", + dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.linedraw_opt, + mach->accel.dp_config, mach->accel.max_waitstates & 0x100); if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { if (mach_pixel_write(mach)) { @@ -376,19 +383,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if (frgd_sel == 5) { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; - } - - /*The destination coordinates should match the pattern index.*/ - if (mach->accel.color_pattern_idx != mach->accel.patt_idx) - mach->accel.color_pattern_idx = mach->accel.patt_idx; - } - if (mono_src == 1) { - count = mach->accel.width; - mix_dat = mach->accel.patt_data[0x10]; + count = mach->accel.width; + mix_dat = mach->accel.mono_pattern_normal[0]; dev->accel.temp_cnt = 8; } @@ -403,7 +400,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 dev->accel.temp_cnt = 8; mix_dat >>= 8; } - mix = (mix_dat & 0x80); + mix = !!(mix_dat & 0x80); dev->accel.temp_cnt--; mix_dat <<= 1; mix_dat |= 1; @@ -414,10 +411,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 mix_dat <<= 1; } else { if (mach->accel.dp_config & 0x200) { - mix = mix_dat & 1; + mix = mix_dat & 0x01; mix_dat >>= 1; } else { - mix = mix_dat & 0x80; + mix = !!(mix_dat & 0x80); mix_dat <<= 1; mix_dat |= 1; } @@ -436,7 +433,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -452,20 +452,18 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 src_dat = cpu_dat; else { if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + READ((mach->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat); } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), src_dat); + READ((mach->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat); } - if (mono_src == 3) { + if (mono_src == 3) src_dat = (src_dat & rd_mask) == rd_mask; - } } break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: @@ -545,16 +543,27 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if ((mono_src == 1) && !count) + if ((mono_src == 1) && !count) { + dev->accel.cmd_back = 1; break; - else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) + } else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) { + dev->accel.cmd_back = 1; break; + } if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else + mach->accel.color_pattern_idx++; + + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + switch (mach->accel.linedraw_opt & 0xe0) { case 0x00: dev->accel.cx++; @@ -647,7 +656,10 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 break; } - if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -673,10 +685,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: @@ -756,16 +767,27 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 } } - if ((mono_src == 1) && !count) + if ((mono_src == 1) && !count) { + dev->accel.cmd_back = 1; break; - else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) + } else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) { + dev->accel.cmd_back = 1; break; + } if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else + mach->accel.color_pattern_idx++; + + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + if (mach->accel.linedraw_opt & 0x40) { dev->accel.dy += mach->accel.stepy; if ((frgd_sel == 3) || (bkgd_sel == 3)) @@ -815,20 +837,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.cur_y >= 0x600) dev->accel.dy |= ~0x5ff; - if (mach->accel.dp_config == 0x5211) { - if (mach->accel.dest_x_end == 1024) { - goto skip_dx; - } - } /*Destination Width*/ - if (mach->accel.dest_x_start != dev->accel.dx) - mach->accel.dest_x_start = dev->accel.dx; - -skip_dx: mach->accel.dx_start = mach->accel.dest_x_start; if (mach->accel.dest_x_start >= 0x600) mach->accel.dx_start |= ~0x5ff; + mach_log("DXStart=%d, CURX=%d.\n", mach->accel.dx_start, dev->accel.dx); mach->accel.dx_end = mach->accel.dest_x_end; if (mach->accel.dest_x_end >= 0x600) mach->accel.dx_end |= ~0x5ff; @@ -841,26 +855,24 @@ skip_dx: 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); + 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); + mach_log("BitBLT: Dst Indeterminate X, dpconfig = %04x, destxend = %d, destxstart = %d.\n", + mach->accel.dp_config, mach->accel.dest_x_end, mach->accel.dest_x_start); } - dev->accel.sx = 0; - mach->accel.poly_fill = 0; - mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); - if ((dev->accel_bpp == 24) && (mono_src != 1)) { - if (mach->accel.color_pattern_idx == mach->accel.patt_len) - mach->accel.color_pattern_idx = mach->accel.patt_data_idx; - } else if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mono_src == 1) && (mach->accel.patt_len_reg & 0x4000)) - mach->accel.color_pattern_idx = 0; + dev->accel.sx = 0; + mach->accel.poly_fill = 0; /*Height*/ mach->accel.dy_start = dev->accel.cur_y; if (dev->accel.cur_y >= 0x600) mach->accel.dy_start |= ~0x5ff; + mach->accel.dy_end = mach->accel.dest_y_end; if (mach->accel.dest_y_end >= 0x600) mach->accel.dy_end |= ~0x5ff; @@ -877,13 +889,16 @@ skip_dx: } dev->accel.sy = 0; - if (dev->bpp) - dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); - else - dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + if (mach->accel.dp_config & 0x02) + dev->accel.dest = (dev->accel.dy * dev->pitch); + else { + if (dev->bpp) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); + } mach->accel.src_stepx = 0; - /*Source Width*/ dev->accel.cx = mach->accel.src_x; if (mach->accel.src_x >= 0x600) @@ -904,40 +919,47 @@ skip_dx: if (mach->accel.sx_end > mach->accel.sx_start) { mach->accel.src_width = (mach->accel.sx_end - mach->accel.sx_start); mach->accel.src_stepx = 1; - mach_log("BitBLT: Src Positive X: wh(%d,%d), srcwidth = %d, coordinates: %d,%d px, start: %d, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_start, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + mach_log("BitBLT: Src Positive X: wh(%d,%d), srcwidth = %d, coordinates: %d,%d px, start: %d, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", + mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_start, mach->accel.src_x_end, + mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); } else if (mach->accel.sx_end < mach->accel.sx_start) { mach->accel.src_width = (mach->accel.sx_start - mach->accel.sx_end); mach->accel.src_stepx = -1; if (dev->accel.cx > 0) dev->accel.cx--; - mach_log("BitBLT: Src Negative X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + mach_log("BitBLT: Src Negative X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", + mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config + mach->accel.src_width & 1); } else { mach->accel.src_stepx = 1; mach->accel.src_width = 0; - mach_log("BitBLT: Src Indeterminate X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + mach_log("BitBLT: Src Indeterminate X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", + mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, + mach->accel.dp_config, mach->accel.src_width & 1); } mach->accel.sx = 0; - if (dev->bpp) - dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + if (mach->accel.patt_data_idx < 16) + mach->accel.color_pattern_idx = mach->accel.patt_idx; else - dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + mach->accel.color_pattern_idx = 0; - if ((dev->accel_bpp == 24) && (frgd_sel == 5)) - mach_log("BitBLT=%04x, WH(%d,%d), SRCWidth=%d, c(%d,%d), s(%d,%d).\n", mach->accel.dp_config, mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy); - else if (mach->accel.dp_config & 0x02) - mach_log("BitBLT=%04x, Pitch=%d, C(%d,%d), D(%d,%d), SRCWidth=%d, SRCXStep=%d, WH(%d,%d), clipt=%d, clipb=%d, geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, mach->accel.src_x, mach->accel.src_y, dev->accel.cur_x, dev->accel.cur_y, mach->accel.src_width, mach->accel.src_stepx, mach->accel.width, mach->accel.height, clip_t, clip_b, (mach->accel.ge_offset << 2)); + if (dev->bpp) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); if (mono_src == 1) { - if ((mach->accel.mono_pattern_enable) && !(mach->accel.patt_len_reg & 0x4000)) { - mono_dat0 = mach->accel.patt_data[0x10]; - mono_dat0 |= (mach->accel.patt_data[0x11] << 8); - mono_dat0 |= (mach->accel.patt_data[0x12] << 16); - mono_dat0 |= (mach->accel.patt_data[0x13] << 24); - mono_dat1 = mach->accel.patt_data[0x14]; - mono_dat1 |= (mach->accel.patt_data[0x15] << 8); - mono_dat1 |= (mach->accel.patt_data[0x16] << 16); - mono_dat1 |= (mach->accel.patt_data[0x17] << 24); + if (mach->accel.mono_pattern_enable || mach->accel.block_write_mono_pattern_enable) { + mono_dat0 = mach->accel.mono_pattern_normal[0]; + mono_dat0 |= (mach->accel.mono_pattern_normal[1] << 8); + mono_dat0 |= (mach->accel.mono_pattern_normal[2] << 16); + mono_dat0 |= (mach->accel.mono_pattern_normal[3] << 24); + mono_dat1 = mach->accel.mono_pattern_normal[4]; + mono_dat1 |= (mach->accel.mono_pattern_normal[5] << 8); + mono_dat1 |= (mach->accel.mono_pattern_normal[6] << 16); + mono_dat1 |= (mach->accel.mono_pattern_normal[7] << 24); + mach_log("MonoData0=%x, MonoData1=%x.\n", mono_dat0, mono_dat1); for (uint8_t y = 0; y < 8; y++) { for (uint8_t x = 0; x < 8; x++) { uint32_t temp = (y & 4) ? mono_dat1 : mono_dat0; @@ -961,78 +983,59 @@ skip_dx: } if (mono_src == 1) { - if (!mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { - count = mach->accel.width; - mix_dat = mach->accel.patt_data[0x10] ^ ((mach->accel.patt_idx & 1) ? 0xff : 0); - dev->accel.temp_cnt = 8; - } - } - - if (frgd_sel == 5) { - if (dev->bpp) { - for (int x = 0; x <= mach->accel.patt_len; x += 2) { - mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] = (mach->accel.patt_data[x & mach->accel.patt_len] & 0xff); - mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] |= (mach->accel.patt_data[(x + 1) & mach->accel.patt_len] << 8); - } - } else { - if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern[x] = mach->accel.patt_data[x]; - mach_log("BITBLT: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); - } - } else { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; - } + if (!mach->accel.mono_pattern_enable && !mach->accel.block_write_mono_pattern_enable) { + if (((dev->accel_bpp == 24) && (frgd_sel != 5)) || (dev->accel_bpp != 24)) { + mix_dat = mach->accel.mono_pattern_normal[0] ^ ((mach->accel.patt_idx & 0x01) ? 0xff : 0); + dev->accel.temp_cnt = 8; } } - - /*The destination coordinates should match the pattern index.*/ - if (mach->accel.color_pattern_idx != mach->accel.patt_idx) - mach->accel.color_pattern_idx = mach->accel.patt_idx; } if (mach->accel.dy_end == mach->accel.dy_start) { mach_log("No DEST.\n"); + dev->accel.cmd_back = 1; return; } if ((mono_src == 3) || (bkgd_sel == 3) || (frgd_sel == 3)) { if (mach->accel.sx_end == mach->accel.sx_start) { mach_log("No SRC.\n"); + dev->accel.cmd_back = 1; return; } } if (cpu_input) { if (mach->accel.dp_config == 0x3251) { - mach_log("DPCONFIG 3251: monosrc=%d, frgdsel=%d, bkgdsel=%d, pitch=%d.\n", mono_src, frgd_sel, bkgd_sel, dev->pitch); - if (dev->accel.sy == mach->accel.height) + mach_log("DPCONFIG 3251: monosrc=%d, frgdsel=%d, bkgdsel=%d, pitch=%d.\n", + mono_src, frgd_sel, bkgd_sel, dev->pitch); + if (dev->accel.sy == mach->accel.height) { + mach_log("No Blit on DPCONFIG=3251.\n"); + dev->accel.cmd_back = 1; return; + } } } while (count--) { switch (mono_src) { case 0: - mix = 1; + mix = 0x01; break; case 1: - if (mach->accel.mono_pattern_enable) + if (mach->accel.mono_pattern_enable || mach->accel.block_write_mono_pattern_enable) mix = mach->accel.mono_pattern[dev->accel.dy & 7][dev->accel.dx & 7]; + else if ((dev->accel_bpp == 24) && (frgd_sel == 5)) + mix = 0x01; else { - if ((dev->accel_bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) - mix = 1; - else { - if (!dev->accel.temp_cnt) { - dev->accel.temp_cnt = 8; - mix_dat >>= 8; - } - mix = (mix_dat & 0x80); - dev->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; } + mix = !!(mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; } break; case 2: @@ -1041,10 +1044,10 @@ skip_dx: mix_dat <<= 1; } else { if (mach->accel.dp_config & 0x200) { - mix = mix_dat & 1; + mix = mix_dat & 0x01; mix_dat >>= 1; } else { - mix = mix_dat & 0x80; + mix = !!(mix_dat & 0x80); mix_dat <<= 1; mix_dat |= 1; } @@ -1059,15 +1062,18 @@ skip_dx: break; } - if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { - if ((mach->accel.dp_config & 0x02) || (mach->accel.linedraw_opt & 0x02)) { + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { + if (mach->accel.dp_config & 0x02) { READ(dev->accel.src + dev->accel.cx, poly_src); poly_src = ((poly_src & rd_mask) == rd_mask); if (poly_src) mach->accel.poly_fill ^= 1; } - if (mach->accel.poly_fill || !(mach->accel.dp_config & 0x02) || !(mach->accel.linedraw_opt & 0x02)) { + if (mach->accel.poly_fill || !(mach->accel.dp_config & 0x02)) { switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -1088,22 +1094,18 @@ skip_dx: } break; case 5: - if (mix) { - if (dev->bpp) - src_dat = mach->accel.color_pattern_word[mach->accel.color_pattern_idx]; - else - src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: break; } - if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && !mach->accel.mono_pattern_enable) { if (dev->accel.sy & 1) { - READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + READ(dev->accel.dest + dev->accel.dx - dev->pitch, dest_dat); } else { READ(dev->accel.dest + dev->accel.dx, dest_dat); } @@ -1147,9 +1149,9 @@ skip_dx: } if (mach->accel.dp_config & 0x10) { - if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if ((dev->accel_bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && !mach->accel.mono_pattern_enable) { if (dev->accel.sy & 1) { - WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat); + WRITE(dev->accel.dest + dev->accel.dx - dev->pitch, dest_dat); } else { WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } @@ -1165,54 +1167,48 @@ skip_dx: else cpu_dat >>= 8; + if (mach->accel.dp_config == 0x2071 || (mach->accel.dp_config == 0x2011)) + mach_log("FontBlit: SX=%d, C(%d,%d), SRCWidth=%d, frgdmix=%d, bkgdmix=%d, rdmask=%04x, D(%d,%d), geoffset=%x, addr=%08x,.\n", + mach->accel.sx, dev->accel.cx, dev->accel.cy, mach->accel.src_width, dev->accel.frgd_mix & 0x1f, + dev->accel.bkgd_mix & 0x1f, rd_mask, dev->accel.dx, dev->accel.dy, dev->accel.ge_offset, + (dev->accel.src + dev->accel.cx) & dev->vram_mask); + if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02)) { dev->accel.cx += mach->accel.src_stepx; mach->accel.sx++; if (mach->accel.sx >= mach->accel.src_width) { mach->accel.sx = 0; - if (mach->accel.src_stepx == -1) + if (mach->accel.src_stepx < 0) dev->accel.cx += mach->accel.src_width; else dev->accel.cx -= mach->accel.src_width; dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); if (dev->bpp) - dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * dev->pitch); else - dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); } } - dev->accel.dx += mach->accel.stepx; - - if ((dev->accel_bpp == 8) || ((dev->accel_bpp == 24) && (mach->accel.patt_len >= 3) && (mono_src != 1))) - mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - - if ((dev->accel_bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mach->accel.patt_len >= 3) && (mono_src != 1)) { - mach->accel.color_pattern_idx = mach->accel.patt_data_idx; - } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { - if (mach->accel.patt_len == 2) { - mach->accel.color_pattern_idx++; - if (mach->accel.color_pattern_idx == 3) - mach->accel.color_pattern_idx = 0; - } else - mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - - } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000) && (frgd_sel == 5)) { + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else mach->accel.color_pattern_idx++; - if (mach->accel.color_pattern_idx == 3) + + if ((mono_src == 1) && !mach->accel.mono_pattern_enable && !mach->accel.block_write_mono_pattern_enable && (frgd_sel == 5) && (dev->accel_bpp == 24)) { + if (mach->accel.color_pattern_idx > 2) + mach->accel.color_pattern_idx = 0; + } else { + if (mach->accel.color_pattern_idx > mach->accel.patt_len) mach->accel.color_pattern_idx = 0; } - if (dev->bpp) { - mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; - } - + dev->accel.dx += mach->accel.stepx; dev->accel.sx++; if ((dev->accel.sx >= mach->accel.width) || (dev->accel.dx >= 0x600)) { dev->accel.sx = 0; - if (mach->accel.stepx == -1) + if (mach->accel.stepx < 0) dev->accel.dx += mach->accel.width; else dev->accel.dx -= mach->accel.width; @@ -1221,27 +1217,20 @@ skip_dx: dev->accel.sy++; mach->accel.poly_fill = 0; - if (dev->bpp) - dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); - else - dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); - - if ((mono_src == 1) && (dev->accel_bpp == 24) && (frgd_sel == 5)) - mach->accel.color_pattern_idx = 0; - else - mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); - - if ((dev->accel_bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mono_src != 1)) - mach->accel.color_pattern_idx = 0; - if ((mono_src == 1) && !mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { - dev->accel.cur_x = dev->accel.dx; - dev->accel.cur_y = dev->accel.dy; - return; + if (mach->accel.dp_config & 0x02) + dev->accel.dest = (dev->accel.dy * dev->pitch); + else { + if (dev->bpp) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); } + if (dev->accel.sy >= mach->accel.height) { - if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02) || (mach->accel.linedraw_opt & 0x02)) + dev->accel.cmd_back = 1; + if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3) || (mach->accel.dp_config & 0x02)) return; - if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) + if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24)) return; dev->accel.cur_x = dev->accel.dx; dev->accel.cur_y = dev->accel.dy; @@ -1274,14 +1263,18 @@ skip_dx: dev->accel.sx = 0; - mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%d), bounds: l=%d, r=%d, t=%d, b=%d.\n", dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, mach->accel.cy_end_line, mach->accel.bleft, mach->accel.bright, mach->accel.btop, mach->accel.bbottom); + mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%d), bounds: l=%d, r=%d, t=%d, b=%d.\n", + dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, + mach->accel.cy_end_line, mach->accel.bleft, mach->accel.bright, mach->accel.btop, mach->accel.bbottom); if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { if (mach_pixel_write(mach)) { + mach_log("Write PIXTRANS.\n"); dev->data_available = 0; dev->data_available2 = 0; return; } else if (mach_pixel_read(mach)) { + mach_log("Read PIXTRANS.\n"); dev->data_available = 1; dev->data_available2 = 1; return; @@ -1289,18 +1282,12 @@ skip_dx: } } - if (frgd_sel == 5) { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; - } - } - if (mono_src == 1) { - mix_dat = mach->accel.patt_data[0x10]; + mix_dat = mach->accel.mono_pattern_normal[0]; dev->accel.temp_cnt = 8; } - count = (dev->accel.dx > dev->accel.dy) ? (dev->accel.dx >> 1) : (dev->accel.dy >> 1); + count = (dev->accel.dx > dev->accel.dy) ? (dev->accel.dx >> 1) : (dev->accel.dy >> 1); mach->accel.width = count; if (dev->accel.dx > dev->accel.dy) { @@ -1316,7 +1303,10 @@ skip_dx: mix_dat <<= 1; mix_dat |= 1; - if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; switch (mix ? frgd_sel : bkgd_sel) { case 0: @@ -1335,10 +1325,9 @@ skip_dx: src_dat = 0; break; case 5: - if (mix) - src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; - else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: @@ -1395,14 +1384,24 @@ skip_dx: } else mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); - if (!count) + if (!count) { + dev->accel.cmd_back = 1; break; + } if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else + mach->accel.color_pattern_idx++; + + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + if (mach->accel.err >= 0) { dev->accel.cy += mach->accel.stepy; mach->accel.err -= dev->accel.dx; @@ -1437,12 +1436,19 @@ skip_dx: break; } - if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; if (mach->accel.linedraw_opt & 0x02) { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src); + } if (poly_src) - mach->accel.poly_fill = !mach->accel.poly_fill; + mach->accel.poly_fill ^= 1; } switch (mix ? frgd_sel : bkgd_sel) { @@ -1463,20 +1469,23 @@ skip_dx: } break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: break; } - if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + if (mach->accel.linedraw_opt & 0x02) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + READ(((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1519,31 +1528,49 @@ skip_dx: if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { + if (mach->accel.linedraw_opt & 0x02) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } else { + WRITE(((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } + } else { + if (mach->accel.linedraw_opt & 0x02) { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } - } - } else { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + WRITE(((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } } else mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); - if (dev->accel.sx >= mach->accel.width) + if (dev->accel.sx >= mach->accel.width) { + dev->accel.cmd_back = 1; break; + } if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else + mach->accel.color_pattern_idx++; + + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + if (mach->accel.err >= 0) { dev->accel.cy += mach->accel.stepy; mach->accel.err -= dev->accel.dx; @@ -1567,7 +1594,10 @@ skip_dx: mix_dat <<= 1; mix_dat |= 1; - if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; switch (mix ? frgd_sel : bkgd_sel) { case 0: @@ -1587,10 +1617,9 @@ skip_dx: } break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: @@ -1647,14 +1676,24 @@ skip_dx: } else mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); - if (!count) + if (!count) { + dev->accel.cmd_back = 1; break; + } if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else + mach->accel.color_pattern_idx++; + + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + if (mach->accel.err >= 0) { dev->accel.cx += mach->accel.stepx; mach->accel.err -= dev->accel.dy; @@ -1689,9 +1728,11 @@ skip_dx: break; } - if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { mach->accel.clip_overrun = 0; - switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -1710,20 +1751,23 @@ skip_dx: } break; case 5: - if (mix) { - src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: break; } - if (dev->bpp) { - READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + if (mach->accel.linedraw_opt & 0x02) { + if (dev->bpp) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } } else { - READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + READ(((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } switch (compare_mode) { @@ -1764,31 +1808,49 @@ skip_dx: if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { if (mach->accel.linedraw_opt & 0x04) { if (dev->accel.sx < mach->accel.width) { + if (mach->accel.linedraw_opt & 0x02) { + if (dev->bpp) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + } + } else { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } + } + } else { + if (mach->accel.linedraw_opt & 0x02) { if (dev->bpp) { WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } - } - } else { - if (dev->bpp) { - WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } else { - WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); + WRITE(((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat); } } } } else mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); - if (dev->accel.sx >= mach->accel.width) + if (dev->accel.sx >= mach->accel.width) { + dev->accel.cmd_back = 1; break; + } if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else + mach->accel.color_pattern_idx++; + + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + if (mach->accel.err >= 0) { dev->accel.cx += mach->accel.stepx; mach->accel.err -= dev->accel.dy; @@ -1841,8 +1903,6 @@ skip_dx: } dev->accel.sx = 0; - if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 0x17)) - mach->accel.color_pattern_idx = 0; /*Step Y*/ mach->accel.dy_start = dev->accel.cur_y; @@ -1852,13 +1912,12 @@ skip_dx: if (mach->accel.dest_y_end >= 0x600) mach->accel.dy_end |= ~0x5ff; - if (mach->accel.dy_end > mach->accel.dy_start) { + if (mach->accel.dy_end > mach->accel.dy_start) mach->accel.stepy = 1; - } else if (mach->accel.dy_end < mach->accel.dy_start) { + else if (mach->accel.dy_end < mach->accel.dy_start) mach->accel.stepy = -1; - } else { + else mach->accel.stepy = 0; - } if (dev->bpp) dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); @@ -1902,22 +1961,9 @@ skip_dx: else dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); - if ((dev->accel_bpp == 24) && (frgd_sel == 5)) { - if (mach->accel.patt_len == 0x17) - mach->accel.color_pattern_idx = 0; - dev->accel.x1 = dev->accel.dx + mach->accel.width; - if (dev->accel.x1 == dev->pitch) { - dev->accel.x2 = mach->accel.width & 1; - } else if ((dev->accel.x1 == mach->accel.width) && (dev->accel.dy & 1) && !dev->accel.y1 && dev->accel.x2) { - if (mach->accel.patt_len == 0x17) - mach->accel.color_pattern_idx = 3; - dev->accel.x3 = 1; - } else - dev->accel.x3 = 0; - } else - mach_log("ScanToX=%04x, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, mach->accel.width, mach->accel.height, (mach->accel.ge_offset << 1)); - - dev->accel.y1 = 0; + mach_log("ScanToX=%04x, MonoSRC=%d, FrgdSel=%d, BkgdSel=%d, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), colorpattidx=%d, pattlen=%d.\n", + mach->accel.dp_config, mono_src, frgd_sel, bkgd_sel, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, + mach->accel.width, mach->accel.height, mach->accel.color_pattern_idx, mach->accel.patt_len); if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { if (mach_pixel_write(mach)) { @@ -1934,30 +1980,10 @@ skip_dx: if (mono_src == 1) { count = mach->accel.width; - mix_dat = mach->accel.patt_data[0x10]; + mix_dat = mach->accel.mono_pattern_normal[0]; dev->accel.temp_cnt = 8; } - if (frgd_sel == 5) { - if (dev->accel_bpp != 24) { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; - } - } else { - if (mach->accel.patt_len == 0x17) { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern_full[x] = mach->accel.patt_data[x]; - mach_log("ScanToX: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern_full[x], mach->accel.patt_data_idx, mach->accel.patt_len); - } - } else { - for (int x = 0; x <= mach->accel.patt_len; x++) { - mach->accel.color_pattern[x] = mach->accel.patt_data[x]; - mach_log("ScanToX: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); - } - } - } - } - while (count--) { switch (mono_src) { case 0: @@ -1997,7 +2023,10 @@ skip_dx: break; } - if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) { + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) { switch (mix ? frgd_sel : bkgd_sel) { case 0: src_dat = dev->accel.bkgd_color; @@ -2018,16 +2047,9 @@ skip_dx: } break; case 5: - if (mix) { - if (dev->accel_bpp == 24) { - if (mach->accel.patt_len == 0x17) - src_dat = mach->accel.color_pattern_full[mach->accel.color_pattern_idx]; - else - src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; - } else - src_dat = mach->accel.color_pattern[(dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len]; - } else - src_dat = 0; + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + if (dev->bpp) + src_dat |= (mach->accel.color_pattern[mach->accel.color_pattern_idx + 1] << 8); break; default: @@ -2072,7 +2094,7 @@ skip_dx: } if (mach->accel.dp_config & 0x10) { - WRITE(dev->accel.dest + (dev->accel.dx), dest_dat); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } @@ -2096,35 +2118,28 @@ skip_dx: dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); } - dev->accel.dx += mach->accel.stepx; - if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17)) { + if (dev->bpp) + mach->accel.color_pattern_idx += 2; + else mach->accel.color_pattern_idx++; - if (dev->accel.x3) { - if (mach->accel.color_pattern_idx == 9) - mach->accel.color_pattern_idx = 3; - } else { - if (mach->accel.color_pattern_idx == 6) - mach->accel.color_pattern_idx = 0; - } - } else if ((dev->accel_bpp == 24) && (mach->accel.patt_len < 3)) { - mach->accel.color_pattern_idx++; - if (mach->accel.color_pattern_idx == 3) - mach->accel.color_pattern_idx = 0; - } else - mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + if (mach->accel.color_pattern_idx > mach->accel.patt_len) + mach->accel.color_pattern_idx = 0; + + dev->accel.dx += mach->accel.stepx; dev->accel.sx++; if (dev->accel.sx >= mach->accel.width) { dev->accel.sx = 0; dev->accel.dy += mach->accel.stepy; if (dev->bpp) - dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * dev->pitch); else - dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * dev->pitch); if (mach->accel.line_idx == 2) { mach->accel.line_array[0] = dev->accel.dx; mach->accel.line_array[4] = dev->accel.dx; } + dev->accel.cmd_back = 1; return; } } @@ -2136,42 +2151,49 @@ skip_dx: } static void -mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t val) +mach_accel_out_pixtrans(svga_t *svga, mach_t *mach, ibm8514_t *dev, uint16_t val) { int frgd_sel; int bkgd_sel; int mono_src; + int swap = 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; - if ((mach->accel.dp_config & 4) && (mach->accel.cmd_type != 5)) { + if ((mach->accel.dp_config & 0x04) && (mach->accel.cmd_type != 5)) { + mach_log("Read Host Monochrome Data.\n"); val = (val >> 8) | (val << 8); + swap = 1; } switch (mach->accel.dp_config & 0x200) { case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if (mach->accel.dp_config & 0x1000) + if ((mach->accel.dp_config & 0x1000) && !swap) { + mach_log("8-bit bus size swap.\n"); val = (val >> 8) | (val << 8); - mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev); + } + mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), svga, mach, dev); break; case 0x200: /*16-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if (mach->accel.dp_config & 0x1000) + if ((mach->accel.dp_config & 0x1000) && !swap) { + mach_log("16-bit bus size swap.\n"); val = (val >> 8) | (val << 8); - mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, mach, dev); + } + mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), svga, mach, dev); break; default: @@ -2184,7 +2206,7 @@ mach_out(uint16_t addr, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; svga_t *svga = &mach->svga; - const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t old; uint8_t rs2; uint8_t rs3; @@ -2192,6 +2214,15 @@ mach_out(uint16_t addr, uint8_t val, void *priv) if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((dev->disp_cntl & 0x60) == 0x20) && ((dev->local & 0xff) >= 0x02)) { + if ((addr >= 0x3c6) && (addr <= 0x3c9)) { + mach_log("VGA DAC write regs=%03x, on=%d, display control=%02x, on1=%x, clocksel=%02x.\n", + addr, dev->on, dev->disp_cntl & 0x60, dev->accel.advfunc_cntl & 0x01, mach->accel.clock_sel & 0x01); + } else if ((addr >= 0x2ea) && (addr <= 0x2ed)) + mach_log("8514/A DAC write regs=%03x, on=%d, display control=%02x, on1=%x, clocksel=%02x.\n", + addr, dev->on, dev->disp_cntl & 0x60, dev->accel.advfunc_cntl & 0x01, mach->accel.clock_sel & 0x01); + } + switch (addr) { case 0x1ce: mach->index = val; @@ -2199,25 +2230,33 @@ mach_out(uint16_t addr, uint8_t val, void *priv) case 0x1cf: old = mach->regs[mach->index]; mach->regs[mach->index] = val; - mach_log("ATI VGA write reg=0x%02X, val=0x%02X\n", mach->index, val); + mach_log("ATI VGA write reg=%02x, val=%02x.\n", mach->index, val); switch (mach->index) { case 0xa3: - if ((old ^ val) & 0x10) + if ((old ^ val) & 0x10) { + mach_log("ATI A3 bit 7.\n"); svga_recalctimings(svga); + } break; case 0xa7: - if ((old ^ val) & 0x80) + if ((old ^ val) & 0x80) { + mach_log("ATI A7 bit 7.\n"); svga_recalctimings(svga); + } break; case 0xad: if ((dev->local & 0xff) >= 0x02) { - if ((old ^ val) & 0x0c) + if ((old ^ val) & 0x0c) { + mach_log("ATI AD bits 2-3.\n"); svga_recalctimings(svga); + } } break; case 0xb0: - if ((old ^ val) & 0x60) + if ((old ^ val) & 0x60) { + mach_log("ATI B0 bits 5-6: old=%02x, val=%02x.\n", old & 0x60, val & 0x60); svga_recalctimings(svga); + } break; case 0xae: case 0xb2: @@ -2230,49 +2269,56 @@ mach_out(uint16_t addr, uint8_t val, void *priv) mach->bank_r |= ((mach->regs[0xae] & 0x0c) << 2); mach->bank_w |= ((mach->regs[0xae] & 3) << 4); } - if (dev->on[0] || dev->on[1]) + if (dev->on) mach_log("Separate B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); } else { /* Single bank mode */ mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); - if ((dev->local & 0xff) >= 0x02) { + if ((dev->local & 0xff) >= 0x02) mach->bank_w |= ((mach->regs[0xae] & 3) << 4); - } + mach->bank_r = mach->bank_w; - if (dev->on[0] || dev->on[1]) + if (dev->on) mach_log("Single B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); } svga->read_bank = mach->bank_r << 16; svga->write_bank = mach->bank_w << 16; if (mach->index == 0xbe) { - if ((old ^ val) & 0x10) + if ((old ^ val) & 0x10) { + mach_log("ATI BE bit 4.\n"); svga_recalctimings(svga); + } } break; case 0xbd: - if ((old ^ val) & 4) { + if ((old ^ val) & 0x04) mach32_updatemapping(mach, svga); - } break; case 0xb3: - ati_eeprom_write(&mach->eeprom, val & 8, val & 2, val & 1); + ati_eeprom_write(&mach->eeprom, val & 0x08, val & 0x02, val & 0x01); break; case 0xb6: - if ((old ^ val) & 0x10) + if ((old ^ val) & 0x10) { + mach_log("ATI B6 bit 4.\n"); svga_recalctimings(svga); + } break; case 0xb8: if ((dev->local & 0xff) >= 0x02) { - if ((old ^ val) & 0x40) + if ((old ^ val) & 0x40) { + mach_log("ATI B8 bit 6.\n"); svga_recalctimings(svga); + } } else { if ((old ^ val) & 0xc0) svga_recalctimings(svga); } break; case 0xb9: - if ((old ^ val) & 2) + if ((old ^ val) & 0x02) { + mach_log("ATI B9 bit 1.\n"); svga_recalctimings(svga); + } break; default: @@ -2287,8 +2333,15 @@ mach_out(uint16_t addr, uint8_t val, void *priv) rs2 = !!(mach->accel.ext_ge_config & 0x1000); rs3 = !!(mach->accel.ext_ge_config & 0x2000); if ((dev->local & 0xff) >= 0x02) { + if (mach->regs[0xb0] & 0x20) { /*ATI extended 8514/A mode.*/ + mach_log("Extended 8514/A mode.\n"); + dev->vendor_mode = 1; + dev->on |= 0x01; + svga_recalctimings(svga); + mach32_updatemapping(mach, svga); + } if (mach->pci_bus && !mach->ramdac_type) - ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); + ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); else ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else @@ -2302,14 +2355,33 @@ mach_out(uint16_t addr, uint8_t val, void *priv) rs2 = !!(mach->regs[0xa0] & 0x20); rs3 = !!(mach->regs[0xa0] & 0x40); if ((dev->local & 0xff) >= 0x02) { + if (svga->attrregs[0x10] & 0x40) { + mach_log("VGA mode.\n"); + dev->vendor_mode = 0; + dev->on &= ~0x01; + svga_recalctimings(svga); + mach32_updatemapping(mach, svga); + } if (mach->pci_bus && !mach->ramdac_type) - ati68860_ramdac_out((addr & 3) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); + ati68860_ramdac_out((addr & 0x03) | (rs2 << 2) | (rs3 << 3), val, svga->ramdac, svga); else ati68875_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else svga_out(addr, val, svga); return; + case 0x3CF: + if (svga->gdcaddr == 6) { + uint8_t old_val = svga->gdcreg[6]; + svga->gdcreg[6] = val; + if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) { + mach_log("GDCREG6=%02x.\n", svga->gdcreg[6] & 0xc); + mach32_updatemapping(mach, svga); + } + return; + } + break; + case 0x3D4: svga->crtcreg = val & 0x3f; return; @@ -2347,7 +2419,7 @@ mach_in(uint16_t addr, void *priv) { mach_t *mach = (mach_t *) priv; svga_t *svga = &mach->svga; - const ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t temp = 0xff; uint8_t rs2; uint8_t rs3; @@ -2355,8 +2427,11 @@ mach_in(uint16_t addr, void *priv) if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; - if ((addr >= 0x3c6) && (addr <= 0x3c9) && (dev->on[0] || dev->on[1])) + if ((addr >= 0x3c6) && (addr <= 0x3c9) && dev->on) { addr -= 0xdc; + mach_log("VGA DAC read regs=%03x.\n", addr); + } else if ((addr >= 0x2ea) && (addr <= 0x2ed)) + mach_log("8514/A DAC read regs=%03x.\n", addr); switch (addr) { case 0x1ce: @@ -2430,16 +2505,15 @@ mach_in(uint16_t addr, void *priv) return temp; } - -#ifdef ATI_8514_ULTRA -static void +void ati8514_out(uint16_t addr, uint8_t val, void *priv) { mach_log("[%04X:%08X]: ADDON OUT addr=%03x, val=%02x.\n", CS, cpu_state.pc, addr, val); + svga_out(addr, val, priv); } -static uint8_t +uint8_t ati8514_in(uint16_t addr, void *priv) { uint8_t temp = 0xff; @@ -2450,65 +2524,157 @@ ati8514_in(uint16_t addr, void *priv) return temp; } +static void +ati_render_24bpp(svga_t *svga) +{ + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + 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]); + p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + p[x + 1] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + p[x + 2] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + p[x + 3] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + dev->ma += 12; + } + } 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]); + p[x] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 3) & dev->vram_mask]); + p[x + 1] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 6) & dev->vram_mask]); + p[x + 2] = dat & 0xffffff; + + dat = *(uint32_t *) (&dev->vram[(dev->ma + 9) & dev->vram_mask]); + p[x + 3] = dat & 0xffffff; + + dev->ma += 12; + } + } + dev->ma &= dev->vram_mask; + } +} + +static void +ati_render_32bpp(svga_t *svga) +{ + mach_t *mach = (mach_t *) svga->priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + int x; + uint32_t *p; + uint32_t dat; + + if ((dev->displine + svga->y_add) < 0) + return; + + if (dev->changedvram[dev->ma >> 12] || dev->changedvram[(dev->ma >> 12) + 1] || dev->changedvram[(dev->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[dev->displine + svga->y_add][svga->x_add]; + + if (dev->firstline_draw == 2000) + dev->firstline_draw = dev->displine; + dev->lastline_draw = dev->displine; + + 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]); + *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]); + *p++ = ((dat & 0xffffff00) >> 8); + } + } + dev->ma += (x * 4); + dev->ma &= dev->vram_mask; + } +} + void ati8514_recalctimings(svga_t *svga) { mach_t *mach = (mach_t *) svga->ext8514; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - mach_log("ON0=%d, ON1=%d, vgahdisp=%d.\n", dev->on[0], dev->on[1], svga->hdisp); - if (dev->on[0] || dev->on[1]) { + mach_log("ON=%d, vgahdisp=%d.\n", dev->on, svga->hdisp); + if (dev->on) { mach_log("8514/A ON.\n"); + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; dev->h_total = dev->htotal + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); mach->accel.ge_offset = dev->accel.ge_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 & 0x04, mach->accel.clock_sel & 0xfe); - if (dev->accel.advfunc_cntl & 0x01) { + 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); + + if (mach->accel.clock_sel & 0x01) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { if (dev->accel.advfunc_cntl & 0x04) { - dev->h_disp = dev->hdisp; - dev->dispend = dev->vdisp; + if (dev->hdisp == 640) { + dev->h_disp = 1024; + dev->dispend = 768; + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } } else { dev->h_disp = 640; dev->dispend = 480; } - } else { - dev->h_disp = dev->hdisp; - dev->dispend = dev->vdisp; } - if (dev->accel.advfunc_cntl & 0x04) { + if (dev->accel.advfunc_cntl & 0x04) svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { + else svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } - if (dev->dispend == 766) - dev->dispend += 2; + if (dev->interlace) + dev->dispend >>= 1; - if (dev->dispend == 598) - dev->dispend += 2; - - if (dev->dispend == 478) - dev->dispend += 2; - - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); - svga->map8 = dev->pallook; - svga->render8514 = ibm8514_render_8bpp; - } else { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { /*40 column*/ - svga->render = svga_render_text_40; + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", + dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, + mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); + if (dev->vram_512k_8514) { + if (dev->h_disp == 640) { + dev->ext_pitch = 640; + dev->pitch = dev->ext_pitch; } else { - svga->render = svga_render_text_80; + dev->ext_pitch = 1024; + dev->pitch = dev->ext_pitch; } } + dev->accel_bpp = 8; + svga->render8514 = ibm8514_render_8bpp; } } -#endif static void mach_recalctimings(svga_t *svga) @@ -2541,11 +2707,9 @@ mach_recalctimings(svga_t *svga) svga->htotal <<= 1; svga->dots_per_clock <<= 1; svga->rowoffset <<= 1; - svga->gdcreg[5] &= ~0x40; } if (mach->regs[0xb0] & 0x20) { - svga->gdcreg[5] |= 0x40; if ((mach->regs[0xb6] & 0x18) >= 0x10) svga->packed_4bpp = 1; else @@ -2554,7 +2718,7 @@ mach_recalctimings(svga_t *svga) svga->packed_4bpp = 0; if ((dev->local & 0xff) < 0x02) { - if ((mach->regs[0xb6] & 0x18) == 8) { + if ((mach->regs[0xb6] & 0x18) == 0x08) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->dots_per_clock <<= 1; @@ -2563,18 +2727,47 @@ mach_recalctimings(svga_t *svga) svga->ati_4color = 0; } - svga->render8514 = ibm8514_render_blank; - mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); - if (dev->on[0] || dev->on[1]) { - mach_log("8514/A ON.\n"); + mach_log("ON?=%d, override=%d.\n", dev->on, svga->override); + if (dev->on) { + mach_log("8514/A ON, extpitch=%d, devma=%x, vgamalatch=%x.\n", dev->ext_pitch, dev->ma, svga->ma_latch); + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; dev->h_total = dev->htotal + 1; dev->rowcount = !!(dev->disp_cntl & 0x08); dev->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); mach->accel.ge_offset = dev->accel.ge_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 & 0x04, mach->accel.clock_sel & 0xfe); - if (!dev->bpp) { - if (dev->accel.advfunc_cntl & 0x01) { + mach_log("HDISP=%d, VDISP=%d, shadowset=%x, 8514/A mode=%x, clocksel=%02x, interlace=%x.\n", + dev->hdisp, dev->vdisp, mach->shadow_set & 0x03, dev->accel.advfunc_cntl & 0x04, + mach->accel.clock_sel & 0xfe, dev->interlace); + if ((dev->local & 0xff) >= 0x02) { + if (dev->bpp || ((mach->accel.ext_ge_config & 0x30) == 0x30) || (mach->accel.clock_sel & 0x01)) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + if (dev->interlace) { /*Interlaced displays are only for 800x600 and up.*/ + if (dev->accel.advfunc_cntl & 0x04) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { + dev->h_disp = 640; + dev->dispend = 480; + } + } else { + if (((mach->shadow_set & 0x03) == 0x00) && ((dev->hdisp2 == 640) || (dev->hdisp2 == 1280)) && (dev->hdisp != 800)) { + dev->h_disp = dev->hdisp2; + dev->dispend = dev->vdisp2; + } else { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } + } + } + } else { + if (mach->accel.clock_sel & 0x01) { + dev->h_disp = dev->hdisp; + dev->dispend = dev->vdisp; + } else { if (dev->accel.advfunc_cntl & 0x04) { dev->h_disp = dev->hdisp; dev->dispend = dev->vdisp; @@ -2582,36 +2775,18 @@ mach_recalctimings(svga_t *svga) dev->h_disp = 640; dev->dispend = 480; } - } else { - dev->h_disp = dev->hdisp; - dev->dispend = dev->vdisp; } - } else { - dev->h_disp = dev->hdisp; - dev->dispend = dev->vdisp; } svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); + if (mach->accel.clock_sel & 0x40) + svga->clock8514 *= 2; if (dev->interlace) dev->dispend >>= 1; - if (dev->dispend == 478) - dev->dispend += 2; - - if (dev->dispend == 598) - dev->dispend += 2; - - if (dev->dispend == 766) - dev->dispend += 2; - - if (dev->dispend == 1022) - dev->dispend += 2; - if ((dev->local & 0xff) >= 0x02) { - mach_log("HDISP=%d.\n", dev->h_disp); - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; + mach_log("HDISP=%d, mask=%02x.\n", dev->h_disp, dev->dac_mask); if ((mach->accel.ext_ge_config & 0x800) || (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800))) { if ((mach->accel.ext_ge_config & 0x30) == 0x20) { if ((mach->accel.ext_ge_config & 0xc0) == 0x40) @@ -2623,10 +2798,25 @@ mach_recalctimings(svga_t *svga) dev->accel_bpp = 32; else dev->accel_bpp = 24; - } else + } else if ((mach->accel.ext_ge_config & 0x30) == 0x10) dev->accel_bpp = 8; + else { + if (dev->vram_512k_8514) { + if (dev->h_disp == 640) { + dev->ext_pitch = 640; + dev->pitch = dev->ext_pitch; + } else { + dev->ext_pitch = 1024; + dev->pitch = dev->ext_pitch; + } + } + dev->accel_bpp = 8; + } - mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d, shadow=%x, vgahdisp=%d.\n", dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, dev->accel_bpp, mach->shadow_set & 3, svga->hdisp); + svga->render8514 = ibm8514_render_blank; + mach_log("hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, bpp=%d, shadow=%x, vgahdisp=%d.\n", + dev->h_disp, dev->dispend, dev->pitch, dev->ext_crt_pitch, mach->accel.ext_ge_config & 0xcec0, + dev->accel_bpp, mach->shadow_set & 3, svga->hdisp); switch (dev->accel_bpp) { case 8: svga->render8514 = ibm8514_render_8bpp; @@ -2639,17 +2829,11 @@ mach_recalctimings(svga_t *svga) break; case 24: mach_log("GEConfig24bpp: %03x.\n", mach->accel.ext_ge_config & 0x600); - if (mach->accel.ext_ge_config & 0x400) - svga->render8514 = ibm8514_render_BGR; - else - svga->render8514 = ibm8514_render_24bpp; + svga->render8514 = ati_render_24bpp; break; case 32: mach_log("GEConfig32bpp: %03x.\n", mach->accel.ext_ge_config & 0x600); - if (mach->accel.ext_ge_config & 0x400) - svga->render8514 = ibm8514_render_ABGR8888; - else - svga->render8514 = ibm8514_render_32bpp; + svga->render8514 = ati_render_32bpp; break; default: @@ -2657,72 +2841,61 @@ mach_recalctimings(svga_t *svga) } } } else { - dev->pitch = dev->ext_pitch; - dev->rowoffset = dev->ext_crt_pitch; - mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); - svga->map8 = dev->pallook; - svga->render8514 = ibm8514_render_8bpp; - } - } - - if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if (((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); - mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); - if ((dev->local & 0xff) >= 0x02) { - if (mach->regs[0xb8] & 0x40) - svga->clock *= 2; - } else { - switch (mach->regs[0xb8] & 0xc0) { - case 0x40: - svga->clock *= 2; - break; - case 0x80: - svga->clock *= 3; - break; - case 0xc0: - svga->clock *= 4; - break; - - default: - break; + svga->render8514 = ibm8514_render_blank; + mach_log("cntl=%d, hv(%d,%d), pitch=%d, rowoffset=%d, gextconfig=%03x, shadow=%x interlace=%d.\n", + dev->accel.advfunc_cntl & 0x04, dev->h_disp, dev->dispend, dev->pitch, dev->rowoffset, + mach->accel.ext_ge_config & 0xcec0, mach->shadow_set & 3, dev->interlace); + if (dev->vram_512k_8514) { + if (dev->h_disp == 640) { + dev->ext_pitch = 640; + dev->pitch = dev->ext_pitch; + } else { + dev->ext_pitch = 1024; + dev->pitch = dev->ext_pitch; } } - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: /*256+ colours*/ - switch (svga->bpp) { - default: - case 8: - svga->map8 = svga->pallook; - mach_log("Lowres=%x, seqreg[1]bit3=%x.\n", svga->lowres, svga->seqregs[1] & 8); - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - if (!svga->packed_4bpp) { - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; - } - } - break; - } - break; + dev->accel_bpp = 8; + svga->render8514 = ibm8514_render_8bpp; + } + } else { + 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); + if ((svga->gdcreg[6] & 0x01) || (svga->attrregs[0x10] & 0x01)) { + if ((svga->gdcreg[5] & 0x40) || (svga->attrregs[0x10] & 0x40) || (mach->regs[0xb0] & 0x20)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + mach_log("VGA clock=%02x.\n", mach->regs[0xa7] & 0x80); + if ((dev->local & 0xff) >= 0x02) { + if (mach->regs[0xb8] & 0x40) + svga->clock *= 2; + } else { + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock *= 2; + break; + case 0x80: + svga->clock *= 3; + break; + case 0xc0: + svga->clock *= 4; + break; - default: - break; + default: + break; + } + } + svga->map8 = svga->pallook; + mach_log("Lowres=%x, seqreg[1]bit3=%x.\n", svga->lowres, svga->seqregs[1] & 8); + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + } + } } } } @@ -2739,464 +2912,265 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u switch (port) { case 0x82e8: - case 0x82e9: case 0x86e8: - case 0x86e9: case 0xc2e8: - case 0xc2e9: case 0xc6e8: - case 0xc6e9: + dev->ext_fifo_idx++; ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xf6ee: - ibm8514_accel_out_fifo(svga, 0x82e8, val, len); - break; - case 0xf6ef: - ibm8514_accel_out_fifo(svga, 0x82e9, val, len); + dev->ext_fifo_idx++; + if (len == 2) + dev->accel.cur_y = val & 0x7ff; break; case 0x8ae8: case 0xcae8: + dev->ext_fifo_idx++; ibm8514_accel_out_fifo(svga, port, val, len); - if (len != 1) - mach->accel.src_y = val; - break; - case 0x8ae9: - case 0x8ee9: - case 0xcae9: - case 0xcee9: - ibm8514_accel_out_fifo(svga, port, val, len); + if (len == 2) { + mach_log("SRCY=%d.\n", val & 0x07ff); + mach->accel.src_y = val & 0x07ff; + } break; case 0x8ee8: case 0xcee8: + dev->ext_fifo_idx++; ibm8514_accel_out_fifo(svga, port, val, len); - if (len != 1) - mach->accel.src_x = val; + if (len == 2) { + mach_log("SRCX=%d.\n", val & 0x07ff); + mach->accel.src_x = val & 0x07ff; + } break; case 0x92e8: - case 0x92e9: - case 0x96e9: case 0xd2e8: - case 0xd2e9: - case 0xd6e9: + dev->ext_fifo_idx++; ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x96e8: case 0xd6e8: + dev->ext_fifo_idx++; ibm8514_accel_out_fifo(svga, port, val, len); - if (len != 1) + if (len == 2) mach->accel.test = val & 0x1fff; break; case 0x9ae8: case 0xdae8: - dev->accel.ssv_state = 0; - if (len == 1) - dev->accel.cmd = (dev->accel.cmd & 0xff00) | val; - else { - dev->data_available = 0; - dev->data_available2 = 0; - dev->accel.cmd = val; - mach_log("CMD8514=%04x, len=%d, pixcntl=%02x.\n", val, len, dev->accel.multifunc[0x0a]); - mach->accel.cmd_type = -1; - if (port == 0xdae8) { - if (dev->accel.cmd & 0x100) - dev->accel.cmd_back = 0; - } - ibm8514_accel_start(-1, 0, -1, 0, svga, len); - } - break; - case 0x9ae9: - case 0xdae9: - if (len == 1) { - dev->data_available = 0; - dev->data_available2 = 0; - dev->accel.cmd = (dev->accel.cmd & 0xff) | (val << 8); - mach->accel.cmd_type = -1; - if (port == 0xdae9) { - if (dev->accel.cmd & 0x100) - dev->accel.cmd_back = 0; - } - ibm8514_accel_start(-1, 0, -1, 0, svga, len); - } + dev->ext_fifo_idx++; + mach->accel.cmd_type = -1; + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0x9ee8: case 0xdee8: - dev->accel.ssv_state = 1; - if (len == 1) - dev->accel.short_stroke = (dev->accel.short_stroke & 0xff00) | val; - else { - dev->accel.short_stroke = val; - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - - if (dev->accel.cur_x >= 0x600) - dev->accel.cx |= ~0x5ff; - - if (dev->accel.cur_y >= 0x600) - dev->accel.cy |= ~0x5ff; - - if (dev->accel.cmd & 0x1000) { - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); - } else { - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); - } - } - break; - case 0x9ee9: - case 0xdee9: - if (len == 1) { - dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - - if (dev->accel.cur_x >= 0x600) { - dev->accel.cx |= ~0x5ff; - } - if (dev->accel.cur_y >= 0x600) { - dev->accel.cy |= ~0x5ff; - } - - if (dev->accel.cmd & 0x1000) { - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); - } else { - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); - ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); - } - } + dev->ext_fifo_idx++; + ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xa2e8: case 0xe2e8: + dev->ext_fifo_idx++; + dev->fifo_idx++; if (port == 0xe2e8) { - if (dev->accel.cmd_back) { - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; - else + if (len == 2) { + if (dev->accel.cmd_back) { dev->accel.bkgd_color = val; - } else { - if (len == 1) { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; - mach->accel.pix_trans[1] = val; - } + mach_log("CMDBack BKGDCOLOR, sy=%d, height=%d, val=%04x.\n", dev->accel.sy, mach->accel.height, val); } else { if (mach->accel.cmd_type >= 0) { if (mach_pixel_read(mach)) break; - mach_accel_out_pixtrans(mach, dev, val); + mach_accel_out_pixtrans(svga, mach, dev, val); } else { if (ibm8514_cpu_dest(svga)) break; ibm8514_accel_out_pixtrans(svga, port, val, len); } } - } - } else { - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; - else - dev->accel.bkgd_color = val; - } - break; - case 0xa2e9: - case 0xe2e9: - if (port == 0xe2e9) { - if (dev->accel.cmd_back) { - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); } else { - if (len == 1) { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; - mach->accel.pix_trans[0] = val; - frgd_sel = (mach->accel.dp_config >> 13) & 7; - bkgd_sel = (mach->accel.dp_config >> 7) & 3; - mono_src = (mach->accel.dp_config >> 5) & 3; - - switch (mach->accel.dp_config & 0x200) { - case 0x000: /*8-bit size*/ - if (mono_src == 2) { - if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - break; - case 0x200: /*16-bit size*/ - if (mono_src == 2) { - if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); - else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - break; - - default: - break; - } - } + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[1] = val; } } } else { - if (len == 1) - dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); + if (len == 2) + dev->accel.bkgd_color = val; } break; case 0xa6e8: case 0xe6e8: + dev->ext_fifo_idx++; + dev->fifo_idx++; if (port == 0xe6e8) { - if (dev->accel.cmd_back) { - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; - else + if (len == 2) { + if (dev->accel.cmd_back) dev->accel.frgd_color = val; - } else { - if (len == 1) { + else { if (mach->accel.cmd_type >= 0) { if (mach_pixel_read(mach)) break; - mach->accel.pix_trans[1] = val; - } - } else { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; - mach_accel_out_pixtrans(mach, dev, val); + mach_accel_out_pixtrans(svga, mach, dev, val); } else { if (ibm8514_cpu_dest(svga)) break; ibm8514_accel_out_pixtrans(svga, port, val, len); } } - } - } else { - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; - else - dev->accel.frgd_color = val; - } - break; - case 0xa6e9: - case 0xe6e9: - if (port == 0xe6e9) { - if (dev->accel.cmd_back) { - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); } else { - if (len == 1) { - if (mach->accel.cmd_type >= 0) { - if (mach_pixel_read(mach)) - break; - mach->accel.pix_trans[0] = val; - frgd_sel = (mach->accel.dp_config >> 13) & 7; - bkgd_sel = (mach->accel.dp_config >> 7) & 3; - mono_src = (mach->accel.dp_config >> 5) & 3; - - switch (mach->accel.dp_config & 0x200) { - case 0x000: /*8-bit size*/ - if (mono_src == 2) { - if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - break; - case 0x200: /*16-bit size*/ - if (mono_src == 2) { - if ((frgd_sel != 2) && (bkgd_sel != 2)) { - if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); - else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); - break; - - default: - break; - } - } + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[1] = val; } } } else { - if (len == 1) - dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); + if (len == 2) + dev->accel.frgd_color = val; } break; + case 0xe2e9: + case 0xe6e9: + dev->ext_fifo_idx++; + dev->fifo_idx++; + mach_log("Write PORT=%04x, 8514/A=%x, val=%04x, len=%d.\n", port, dev->accel.cmd_back, val, len); + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[0] = val; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, svga, mach, dev); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); + break; + + default: + break; + } + } + } + mach_log("Write Port=%04x, Busy=%02x.\n", port, dev->force_busy2); + break; + case 0xaae8: - case 0xaae9: case 0xaee8: - case 0xaee9: case 0xb2e8: - case 0xb2e9: case 0xb6e8: case 0xbae8: case 0xeae8: - case 0xeae9: case 0xeee8: - case 0xeee9: case 0xf2e8: - case 0xf2e9: case 0xf6e8: case 0xfae8: + dev->ext_fifo_idx++; ibm8514_accel_out_fifo(svga, port, val, len); break; case 0xbee8: case 0xfee8: - if (len == 1) - dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff00) | val; - else { - dev->accel.multifunc_cntl = val; - dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) - dev->accel.clip_top = val & 0x7ff; - - if ((dev->accel.multifunc_cntl >> 12) == 2) - dev->accel.clip_left = val & 0x7ff; - - if ((dev->accel.multifunc_cntl >> 12) == 3) - dev->accel.multifunc[3] = val & 0x7ff; - - if ((dev->accel.multifunc_cntl >> 12) == 4) - dev->accel.multifunc[4] = val & 0x7ff; - - mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], dev->accel_bpp, dev->pitch); + dev->ext_fifo_idx++; + ibm8514_accel_out_fifo(svga, port, val, len); + if (len == 2) { if ((dev->accel.multifunc_cntl >> 12) == 5) { if ((dev->local & 0xff) < 0x02) dev->ext_crt_pitch = 128; } - if (port == 0xfee8) - dev->accel.cmd_back = 1; - else - dev->accel.cmd_back = 0; - } - break; - case 0xbee9: - case 0xfee9: - if (len == 1) { - dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); - dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; - if ((dev->accel.multifunc_cntl >> 12) == 1) - dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; - - if ((dev->accel.multifunc_cntl >> 12) == 2) - dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; - - if ((dev->accel.multifunc_cntl >> 12) == 5) { - if ((dev->local & 0xff) < 0x02) - dev->ext_crt_pitch = 128; - } - if (port == 0xfee9) - dev->accel.cmd_back = 1; - else - dev->accel.cmd_back = 0; } break; /*ATI Mach8/32 specific registers*/ case 0x82ee: - mach->accel.patt_data_idx = val & 0x1f; - mach_log("Pattern Data Index = %d.\n", val & 0x1f); + dev->ext_fifo_idx++; + mach->accel.patt_data_idx_reg = val & 0x1f; + mach->accel.patt_data_idx = mach->accel.patt_data_idx_reg; + + if (mach->accel.patt_data_idx_reg < 0x10) + mach->accel.color_pattern_idx = mach->accel.patt_idx; + else + mach->accel.color_pattern_idx = 0; + + mach_log("Write Port 82ee: Pattern Data Index=%d.\n", val & 0x1f); break; case 0x8eee: - if (len == 1) - mach->accel.patt_data[mach->accel.patt_data_idx] = val; - else { - mach->accel.patt_data[mach->accel.patt_data_idx] = val & 0xff; - mach->accel.patt_data[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; - if (mach->accel.mono_pattern_enable) - mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 0x17; - else { - frgd_sel = (mach->accel.dp_config >> 13) & 7; - mono_src = (mach->accel.dp_config >> 5) & 3; - if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { - mach->accel.patt_data_idx += 2; - dev->accel.y1 = 1; - } else { - if (dev->accel_bpp == 24) - mach->accel.patt_data_idx += 2; - else - mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; - } - mach_log("ExtCONFIG = %04x, Pattern Mono = %04x, selidx = %d, dataidx = %d, bit 0 = %02x len = %d.\n", mach->accel.ext_ge_config, val, mach->accel.patt_idx, mach->accel.patt_data_idx, val & 1, mach->accel.patt_len); - } - } - break; - case 0x8eef: - if (len == 1) { - mach->accel.patt_data[mach->accel.patt_data_idx + 1] = val; - if (mach->accel.mono_pattern_enable) - mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 7; - else { - frgd_sel = (mach->accel.dp_config >> 13) & 7; - if ((dev->accel_bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { - mach->accel.patt_data_idx += 2; - dev->accel.y1 = 1; - } else - mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; + dev->ext_fifo_idx++; + if (len == 2) { + if (mach->accel.patt_data_idx_reg < 0x10) { + mach->accel.color_pattern[mach->accel.patt_data_idx] = val & 0xff; + mach->accel.color_pattern[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; + mach_log("Write Port 8eee: Color Pattern Word Data[%d]=%04x.\n", mach->accel.patt_data_idx, val); + } else { + mach->accel.mono_pattern_normal[mach->accel.patt_data_idx - 0x10] = val & 0xff; + mach->accel.mono_pattern_normal[(mach->accel.patt_data_idx + 1) - 0x10] = (val >> 8) & 0xff; + mach_log("Write Port 8eee: Mono Pattern Word Data[%d]=%04x.\n", mach->accel.patt_data_idx - 0x10, val); } + mach->accel.patt_data_idx += 2; } break; case 0x96ee: - if (len == 1) - mach->accel.bres_count = (mach->accel.bres_count & 0x700) | val; - else { + dev->ext_fifo_idx++; + if (len == 2) { mach->accel.bres_count = val & 0x7ff; - mach_log("BresenhamDraw = %04x.\n", mach->accel.dp_config); - dev->data_available = 0; + mach_log("BresenhamDraw=%04x.\n", mach->accel.dp_config); + dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 1; - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); - } - break; - case 0x96ef: - if (len == 1) { - mach->accel.bres_count = (mach->accel.bres_count & 0xff) | ((val & 0x07) << 8); - mach_log("96EE (2) line draw.\n"); - dev->data_available = 0; - dev->data_available2 = 0; - mach->accel.cmd_type = 1; - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + dev->accel.cmd_back = 1; + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) + dev->accel.cmd_back = 0; + + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, svga, mach, dev); } break; case 0x9aee: + dev->ext_fifo_idx++; mach->accel.line_idx = val & 0x07; break; case 0xa2ee: - mach_log("Line OPT = %04x\n", val); - if (len == 1) - mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0xff00) | val; - else { + dev->ext_fifo_idx++; + mach_log("Line OPT=%04x.\n", val); + if (len == 2) { mach->accel.linedraw_opt = val; - mach->accel.bbottom = dev->accel.multifunc[3] & 0x7ff; - mach->accel.btop = dev->accel.clip_top & 0x7ff; - mach->accel.bleft = dev->accel.clip_left & 0x7ff; - mach->accel.bright = dev->accel.multifunc[4] & 0x7ff; + mach->accel.bbottom = dev->accel.clip_bottom; + mach->accel.btop = dev->accel.clip_top; + mach->accel.bleft = dev->accel.clip_left; + mach->accel.bright = dev->accel.clip_right; if (mach->accel.linedraw_opt & 0x100) { mach->accel.bbottom = 2047; mach->accel.btop = 0; @@ -3205,102 +3179,90 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } } break; - case 0xa2ef: - if (len == 1) - mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0x00ff) | (val << 8); - break; case 0xa6ee: - if (len == 1) - mach->accel.dest_x_start = (mach->accel.dest_x_start & 0x700) | val; - else + dev->ext_fifo_idx++; + if (len == 2) mach->accel.dest_x_start = val & 0x7ff; break; - case 0xa6ef: - if (len == 1) - mach->accel.dest_x_start = (mach->accel.dest_x_start & 0x0ff) | ((val & 0x07) << 8); - break; case 0xaaee: - if (len == 1) - mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x700) | val; - else + dev->ext_fifo_idx++; + if (len == 2) mach->accel.dest_x_end = val & 0x7ff; break; - case 0xaaef: - if (len == 1) - mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x0ff) | ((val & 0x07) << 8); - break; case 0xaeee: - if (len == 1) - mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x700) | val; - else { + dev->ext_fifo_idx++; + if (len == 2) { mach->accel.dest_y_end = val & 0x7ff; if ((val + 1) == 0x10000) { - mach_log("Dest_Y_end overflow val = %04x\n", val); + mach_log("Dest_Y_end overflow val=%04x, DPCONFIG=%04x\n", val, mach->accel.dp_config); mach->accel.dest_y_end = 0; } dev->data_available = 0; dev->data_available2 = 0; - mach_log("BitBLT = %04x.\n", mach->accel.dp_config); + mach_log("BitBLT=%04x.\n", mach->accel.dp_config); + mach_log(".\n"); mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); - } - break; - case 0xaeef: - if (len == 1) { - mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x0ff) | ((val & 0x07) << 8); - dev->data_available = 0; - dev->data_available2 = 0; - mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + dev->accel.cmd_back = 1; + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) + dev->accel.cmd_back = 0; + + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, svga, mach, dev); } break; case 0xb2ee: - if (len == 1) - mach->accel.src_x_start = (mach->accel.src_x_start & 0x700) | val; - else + dev->ext_fifo_idx++; + if (len == 2) mach->accel.src_x_start = val & 0x7ff; break; - case 0xb2ef: - if (len == 1) - mach->accel.src_x_start = (mach->accel.src_x_start & 0x0ff) | ((val & 0x07) << 8); - break; case 0xb6ee: + dev->ext_fifo_idx++; dev->accel.bkgd_mix = val & 0xff; break; case 0xbaee: + dev->ext_fifo_idx++; dev->accel.frgd_mix = val & 0xff; break; case 0xbeee: - if (len == 1) - mach->accel.src_x_end = (mach->accel.src_x_end & 0x700) | val; - else + dev->ext_fifo_idx++; + if (len == 2) mach->accel.src_x_end = val & 0x7ff; break; - case 0xbeef: - if (len == 1) - mach->accel.src_x_end = (mach->accel.src_x_end & 0x0ff) | ((val & 0x07) << 8); - break; case 0xc2ee: + dev->ext_fifo_idx++; mach->accel.src_y_dir = val & 1; break; case 0xc6ee: - mach->accel.cmd_type = 0; - mach_log("TODO: Short Stroke.\n"); + dev->ext_fifo_idx++; + if (len == 2) { + mach->accel.cmd_type = 0; + mach_log("TODO: Short Stroke.\n"); + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + dev->accel.cmd_back = 1; + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) + dev->accel.cmd_back = 0; + } break; case 0xcaee: - if (len == 1) - mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x700) | val; - else { + dev->ext_fifo_idx++; + if (len == 2) { mach->accel.scan_to_x = (val & 0x7ff); if ((val + 1) == 0x10000) { mach_log("Scan_to_X overflow val = %04x\n", val); @@ -3309,128 +3271,110 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u dev->data_available = 0; dev->data_available2 = 0; mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ - mach_log("ScanToX = %04x.\n", mach->accel.dp_config); - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); - } - break; - case 0xcaef: - if (len == 1) { - mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x0ff) | ((val & 0x07) << 8); - dev->data_available = 0; - dev->data_available2 = 0; - mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + mach_log("ScanToX=%04x.\n", mach->accel.dp_config); + mach_log(".\n"); + + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + dev->accel.cmd_back = 1; + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) + dev->accel.cmd_back = 0; + + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, svga, mach, dev); } break; case 0xceee: + dev->ext_fifo_idx++; mach_log("CEEE write val = %04x.\n", val); - if (len == 1) - mach->accel.dp_config = (mach->accel.dp_config & 0xff00) | val; - else { + if (len == 2) { dev->data_available = 0; dev->data_available2 = 0; mach->accel.dp_config = val; } break; - case 0xceef: - if (len == 1) - mach->accel.dp_config = (mach->accel.dp_config & 0x00ff) | (val << 8); - break; case 0xd2ee: + dev->ext_fifo_idx++; mach->accel.patt_len = val & 0x1f; - mach_log("Pattern Length = %d, val = %04x.\n", val & 0x1f, val); + mach_log("Write Port d2ee: Pattern Length=%d, val=%04x.\n", val & 0x1f, val); mach->accel.mono_pattern_enable = !!(val & 0x80); - if (len != 1) + if (len == 2) { + mach->accel.block_write_mono_pattern_enable = !!(val & 0x8000); mach->accel.patt_len_reg = val; - else - mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0xff00) | val; - break; - case 0xd2ef: - if (len == 1) - mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0x00ff) | (val << 8); + } break; case 0xd6ee: + dev->ext_fifo_idx++; mach->accel.patt_idx = val & 0x1f; - mach_log("Pattern Index = %d, val = %02x.\n", val & 0x1f, val); + mach_log("Write Port d6ee: Pattern Index=%d.\n", val & 0x1f); break; case 0xdaee: - mach_log("DAEE (extclipl) write val = %d\n", val); - if (len == 1) - dev->accel.clip_left = (dev->accel.clip_left & 0x700) | val; - else - dev->accel.clip_left = val & 0x7ff; - break; - case 0xdaef: - if (len == 1) - dev->accel.clip_left = (dev->accel.clip_left & 0x0ff) | ((val & 0x07) << 8); + dev->ext_fifo_idx++; + if (len == 2) { + dev->accel.multifunc[2] = val & 0x7ff; + dev->accel.clip_left = dev->accel.multifunc[2]; + if (val & 0x800) + dev->accel.clip_left |= ~0x7ff; + } + mach_log("DAEE (extclipl) write val=%d, left=%d.\n", val, dev->accel.clip_left); break; case 0xdeee: + dev->ext_fifo_idx++; + if (len == 2) { + dev->accel.multifunc[1] = val & 0x7ff; + dev->accel.clip_top = dev->accel.multifunc[1]; + if (val & 0x800) { + dev->accel.clip_top |= ~0x7ff; + } + } mach_log("DEEE (extclipt) write val = %d\n", val); - if (len == 1) - dev->accel.clip_top = (dev->accel.clip_top & 0x700) | val; - else - dev->accel.clip_top = val & 0x7ff; - break; - case 0xdeef: - if (len == 1) - dev->accel.clip_top = (dev->accel.clip_top & 0x0ff) | ((val & 0x07) << 8); break; case 0xe2ee: - mach_log("E2EE (extclipr) write val = %d\n", val); - if (len == 1) - dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x700) | val; - else + dev->ext_fifo_idx++; + if (len == 2) { dev->accel.multifunc[4] = val & 0x7ff; - break; - case 0xe2ef: - if (len == 1) - dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x0ff) | ((val & 0x07) << 8); + dev->accel.clip_right = dev->accel.multifunc[4]; + if (val & 0x800) + dev->accel.clip_right |= ~0x7ff; + } + mach_log("E2EE (extclipr) write val = %d\n", val); break; case 0xe6ee: - mach_log("E6EE (extclipb) write val = %d\n", val); - if (len == 1) - dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x700) | val; - else + dev->ext_fifo_idx++; + if (len == 2) { dev->accel.multifunc[3] = val & 0x7ff; - break; - case 0xe6ef: - if (len == 1) - dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x0ff) | ((val & 0x07) << 8); + dev->accel.clip_bottom = dev->accel.multifunc[3]; + if (val & 0x800) + dev->accel.clip_bottom |= ~0x7ff; + } + mach_log("E6EE (extclipb) write val = %d\n", val); break; case 0xeeee: - if (len == 1) - mach->accel.dest_cmp_fn = (mach->accel.dest_cmp_fn & 0xff00) | val; - else + dev->ext_fifo_idx++; + if (len == 2) mach->accel.dest_cmp_fn = val; break; - case 0xeeef: - if (len == 1) - mach->accel.dest_cmp_fn = (mach->accel.dest_cmp_fn & 0x00ff) | (val << 8); - break; case 0xf2ee: + dev->ext_fifo_idx++; mach_log("F2EE.\n"); - if (len == 1) - mach->accel.dst_clr_cmp_mask = (mach->accel.dst_clr_cmp_mask & 0xff00) | val; - else + if (len == 2) mach->accel.dst_clr_cmp_mask = val; break; - case 0xf2ef: - if (len == 1) - mach->accel.dst_clr_cmp_mask = (mach->accel.dst_clr_cmp_mask & 0x00ff) | (val << 8); - break; case 0xfeee: - mach_log("LineDraw = %04x.\n", mach->accel.dp_config); - if (len != 1) { + dev->ext_fifo_idx++; + mach_log("LineDraw=%04x.\n", mach->accel.dp_config); + if (len == 2) { mach->accel.line_array[mach->accel.line_idx] = val; dev->accel.cur_x = mach->accel.line_array[(mach->accel.line_idx == 4) ? 4 : 0]; dev->accel.cur_y = mach->accel.line_array[(mach->accel.line_idx == 5) ? 5 : 1]; @@ -3438,7 +3382,15 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u mach->accel.cy_end_line = mach->accel.line_array[3]; if ((mach->accel.line_idx == 3) || (mach->accel.line_idx == 5)) { mach->accel.cmd_type = (mach->accel.line_idx == 5) ? 4 : 3; - mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev); + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + dev->accel.cmd_back = 1; + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) + dev->accel.cmd_back = 0; + + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, svga, mach, dev); mach->accel.line_idx = (mach->accel.line_idx == 5) ? 4 : 2; break; } @@ -3454,7 +3406,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u static void mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9 && port != 0x46e8 && port != 0x46e9) + if (port != 0x42e8 && port != 0x42e9) mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); switch (port) { @@ -3462,23 +3414,45 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x6e9: case 0xae8: case 0xee8: - case 0x12e8: - case 0x12e9: - case 0x1ae8: - case 0x1ae9: case 0x1ee8: case 0x1ee9: - case 0x22e8: case 0x42e8: + ibm8514_accel_out(port, val, svga, 2); + break; case 0x42e9: ibm8514_accel_out(port, val, svga, 2); + if ((val & 0xc0) == 0xc0) { + dev->ext_fifo_idx = 0; + mach->force_busy = 0; + } break; case 0x6e8: /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { - dev->hdisped = val; - dev->hdisp = (dev->hdisped + 1) << 3; + if (!(mach->shadow_cntl & 0x08)) { + if ((mach->shadow_set & 0x03) || (mach->accel.clock_sel & 0x01)) { + dev->hdisped = val; + dev->hdisp = (val + 1) << 3; + } else if (((mach->shadow_set & 0x03) == 0x00) && !(mach->accel.clock_sel & 0x01)) + dev->hdisp2 = (val + 1) << 3; + } + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): hdisp=0x%02x, shadowcntl=%02x, shadowset=%02x.\n", + CS, cpu_state.pc, port, val, mach->shadow_cntl & 0x08, mach->shadow_set & 0x03); + svga_recalctimings(svga); + break; + + case 0x12e8: + case 0x12e9: + /*In preparation to switch from VGA to 8514/A mode*/ + if (!(mach->shadow_cntl & 0x10)) { + if ((mach->shadow_set & 0x03) || (mach->accel.clock_sel & 0x01) || + (((mach->shadow_set & 0x03) == 0x00) && !(mach->accel.clock_sel & 0x01))) { + WRITE8(port, dev->v_total_reg, val); + dev->v_total_reg &= 0x1fff; + dev->v_total = dev->v_total_reg + 1; + if (dev->interlace) + dev->v_total >>= 1; + } } mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): hdisp=0x%02x.\n", CS, cpu_state.pc, port, val); svga_recalctimings(svga); @@ -3487,32 +3461,74 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x16e8: case 0x16e9: /*In preparation to switch from VGA to 8514/A mode*/ - if (!dev->on[0] || !dev->on[1] || (mach->accel.clock_sel & 0x01)) { - WRITE8(port, dev->v_disp, val); - dev->v_disp &= 0x1fff; - dev->vdisp = (dev->v_disp + 1) >> 1; + if (!(mach->shadow_cntl & 0x20)) { + if ((mach->shadow_set & 0x03) || (mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_disp, val); + dev->v_disp &= 0x1fff; + dev->vdisp = (dev->v_disp + 1) >> 1; + if ((dev->vdisp == 478) || (dev->vdisp == 598) || (dev->vdisp == 766) || (dev->vdisp == 1022)) + dev->vdisp += 2; + } else if (((mach->shadow_set & 0x03) == 0x00) && !(mach->accel.clock_sel & 0x01)) { + WRITE8(port, dev->v_disp2, val); + dev->v_disp2 &= 0x1fff; + dev->vdisp2 = (dev->v_disp2 + 1) >> 1; + if ((dev->vdisp2 == 478) || (dev->vdisp2 == 598) || (dev->vdisp2 == 766) || (dev->vdisp2 == 1022)) + dev->vdisp2 += 2; + } } - mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->v_disp); + 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); svga_recalctimings(svga); break; - case 0x4ae8: - case 0x4ae9: - WRITE8(port, dev->accel.advfunc_cntl, val); - dev->on[port & 1] = dev->accel.advfunc_cntl & 0x01; - if ((dev->local & 0xff) < 0x02) - dev->ext_crt_pitch = 128; - - vga_on = !dev->on[port & 1]; - mach->ext_on[port & 1] = dev->on[port & 1]; - mach32_updatemapping(mach, svga); - dev->vendor_mode[port & 1] = 0; - mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", CS, cpu_state.pc, port, dev->on[port & 1], dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); - mach_log("IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); + case 0x1ae8: + case 0x1ae9: + /*In preparation to switch from VGA to 8514/A mode*/ + if (!(mach->shadow_cntl & 0x10)) { + if ((mach->shadow_set & 0x03) || (mach->accel.clock_sel & 0x01) || + (((mach->shadow_set & 0x03) == 0x00) && !(mach->accel.clock_sel & 0x01))) { + WRITE8(port, dev->v_sync_start, val); + dev->v_sync_start &= 0x1fff; + dev->v_syncstart = dev->v_sync_start + 1; + if (dev->interlace) + dev->v_syncstart >>= 1; + } + } + 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); svga_recalctimings(svga); break; + case 0x22e8: + if (!(mach->shadow_cntl & 0x03)) { + if ((mach->shadow_set & 0x03) || (mach->accel.clock_sel & 0x01) || + (((mach->shadow_set & 0x03) == 0x00) && !(mach->accel.clock_sel & 0x01))) { + dev->disp_cntl = val; + dev->interlace = !!(dev->disp_cntl & 0x10); + } + } + mach_log("ATI 8514/A: DISP_CNTL write %04x=%02x, written=%02x, interlace=%d.\n", + port, val & 0x70, dev->disp_cntl & 0x70, dev->interlace); + svga_recalctimings(svga); + break; + + case 0x4ae8: + dev->accel.advfunc_cntl = val; + dev->on = dev->accel.advfunc_cntl & 0x01; + dev->vendor_mode = 0; + mach_log("[%04X:%08X]: ATI 8514/A: (0x%04x): ON=%d, shadow crt=%x, hdisp=%d, vdisp=%d.\n", + CS, cpu_state.pc, port, val & 0x01, dev->accel.advfunc_cntl & 0x04, dev->hdisp, dev->vdisp); + + if ((dev->local & 0xff) < 0x02) { + dev->ext_crt_pitch = 128; + svga_recalctimings(svga); + } else { + svga_recalctimings(svga); + mach32_updatemapping(mach, svga); + } + mach_log("Vendor IBM mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); + break; + /*ATI Mach8/32 specific registers*/ case 0x2ee: mach_log("2EE write val = %02x.\n", val); @@ -3532,14 +3548,16 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0xaef: WRITE8(port, mach->cursor_offset_lo_reg, val); mach->cursor_offset_lo = mach->cursor_offset_lo_reg; + dev->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2); break; case 0xeee: case 0xeef: WRITE8(port, mach->cursor_offset_hi_reg, val); mach->cursor_offset_hi = mach->cursor_offset_hi_reg & 0x0f; - dev->hwcursor.addr = (mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2; + dev->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16)) << 2); dev->hwcursor.ena = !!(mach->cursor_offset_hi_reg & 0x8000); + mach_log("HWCursorEnabled=%x.\n", dev->hwcursor.ena); break; case 0x12ee: @@ -3571,6 +3589,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x22ee: if (mach->pci_bus) { mach->pci_cntl_reg = val; + mach_log("PCI Control Reg=%02x.\n", val); mach32_updatemapping(mach, svga); } break; @@ -3587,21 +3606,31 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 else dev->ext_crt_pitch <<= 1; } - mach_log("ATI 8514/A: (0x%04x) val=0x%02x.\n", port, val); + if ((dev->local & 0xff) >= 0x02) { + dev->on |= 0x01; + dev->vendor_mode = 1; + } svga_recalctimings(svga); + if ((dev->local & 0xff) >= 0x01) + mach32_updatemapping(mach, svga); + + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, extended 8514/A mode=%02x.\n", port, val, mach->regs[0xb0] & 0x20); break; case 0x32ee: case 0x32ef: WRITE8(port, mach->local_cntl, val); - mach32_updatemapping(mach, svga); + if ((dev->local & 0xff) >= 0x01) + mach32_updatemapping(mach, svga); break; case 0x36ee: case 0x36ef: mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - WRITE8(port, mach->misc, val); - mach->misc &= 0xfff0; + if ((dev->local & 0xff) >= 0x02) { + WRITE8(port, mach->misc, val); + mach->misc &= 0xfff0; + } break; case 0x3aee: @@ -3620,7 +3649,7 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x42ee: case 0x42ef: - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + mach_log("ATI 8514/A: (0x%04x) val=%04x.\n", port, val); WRITE8(port, mach->accel.test2, val); break; @@ -3633,13 +3662,15 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x4aee: case 0x4aef: WRITE8(port, mach->accel.clock_sel, val); - dev->on[port & 1] = mach->accel.clock_sel & 0x01; - mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d, val=0x%02x.\n", port, dev->on[port & 1], val, dev->hdisp, dev->vdisp, val & 0xfe); - mach_log("ATI mode set %s resolution.\n", (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); - mach->ext_on[port & 1] = dev->on[port & 1]; - vga_on = !dev->on[port & 1]; - dev->vendor_mode[port & 1] = 1; + dev->on = mach->accel.clock_sel & 0x01; + dev->vendor_mode = 1; + mach_log("ATI 8514/A: (0x%04x): ON=%d, val=%04x, hdisp=%d, vdisp=%d.\n", + port, mach->accel.clock_sel & 0x01, val, dev->hdisp, dev->vdisp); + mach_log("Vendor ATI mode set %s resolution.\n", + (dev->accel.advfunc_cntl & 0x04) ? "2: 1024x768" : "1: 640x480"); svga_recalctimings(svga); + if ((dev->local & 0xff) >= 0x01) + mach32_updatemapping(mach, svga); break; case 0x52ee: @@ -3673,7 +3704,8 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if (!mach->pci_bus) mach->linear_base = (mach->memory_aperture & 0xff00) << 12; - mach32_updatemapping(mach, svga); + if ((dev->local & 0xff) >= 0x01) + mach32_updatemapping(mach, svga); break; case 0x62ee: @@ -3693,13 +3725,14 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 case 0x6eef: WRITE8(port, mach->accel.ge_offset_lo, val); svga_recalctimings(svga); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, geoffset=%04x.\n", port, val, dev->accel.ge_offset); break; case 0x72ee: case 0x72ef: WRITE8(port, mach->accel.ge_offset_hi, val); - mach_log("ATI 8514/A: (0x%04x) val=0x%02x, geoffset=%04x.\n", port, val, dev->accel.ge_offset); svga_recalctimings(svga); + mach_log("ATI 8514/A: (0x%04x) val=0x%02x, geoffset=%04x.\n", port, val, dev->accel.ge_offset); break; case 0x76ee: @@ -3716,8 +3749,9 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 if ((dev->local & 0xff) >= 0x02) { if (mach->accel.crt_pitch & 0xff) dev->ext_crt_pitch = mach->accel.crt_pitch & 0xff; + switch (mach->accel.ext_ge_config & 0x30) { - case 0: + case 0x00: case 0x10: dev->bpp = 0; break; @@ -3737,20 +3771,10 @@ mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8 break; } svga_set_ramdac_type(svga, !!(mach->accel.ext_ge_config & 0x4000)); - dev->vendor_mode[port & 1] = 1; - mach32_updatemapping(mach, svga); mach_log("ATI 8514/A: (0x%04x) val=%02x.\n", port, val); svga_recalctimings(svga); - } else { - ati_eeprom_write(&mach->eeprom, !!(mach->accel.ext_ge_config & 0x4040), !!(mach->accel.ext_ge_config & 0x2020), !!(mach->accel.ext_ge_config & 0x1010)); - } - break; - - case 0x7eee: - case 0x7eef: - WRITE8(port, mach->accel.eeprom_control, val); - ati_eeprom_write(&mach->eeprom, !!(mach->accel.eeprom_control & 8), !!(mach->accel.eeprom_control & 2), !!(mach->accel.eeprom_control & 1)); - mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); + } else + ati_eeprom_write(&mach->eeprom, !!(mach->accel.ext_ge_config & 0x4000), !!(mach->accel.ext_ge_config & 0x2000), !!(mach->accel.ext_ge_config & 0x1000)); break; default: @@ -3772,7 +3796,7 @@ static uint16_t mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, int len) { const uint16_t *vram_w = (uint16_t *) dev->vram; - uint16_t temp = 0; + uint16_t temp = 0x0000; int cmd; int frgd_sel; int bkgd_sel; @@ -3790,9 +3814,15 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0x9ae8: case 0xdae8: - if (len != 1) { + if ((dev->fifo_idx >= 1) && (dev->fifo_idx <= 8)) { + temp |= (1 << (dev->fifo_idx - 1)); + dev->fifo_idx = 0; + } + + if (len == 2) { if (dev->force_busy) temp |= 0x200; /*Hardware busy*/ + dev->force_busy = 0; if (dev->data_available) { temp |= 0x100; /*Read Data available*/ @@ -3812,8 +3842,19 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in break; } } else { - if (dev->accel.sy < 0) - dev->data_available = 0; + switch (dev->accel.cmd >> 13) { + case 2: + case 3: + case 4: + case 6: + if (dev->accel.sy < 0) + dev->data_available = 0; + break; + default: + if (!dev->accel.sy) + dev->data_available = 0; + break; + } } } } @@ -3823,10 +3864,11 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0xdae9: if (len == 1) { if (dev->force_busy2) - temp |= 2; /*Hardware busy*/ + temp |= 0x02; /*Hardware busy*/ + dev->force_busy2 = 0; if (dev->data_available2) { - temp |= 1; /*Read Data available*/ + temp |= 0x01; /*Read Data available*/ if (mach->accel.cmd_type >= 0) { switch (mach->accel.cmd_type) { case 2: @@ -3865,24 +3907,29 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in } else { READ_PIXTRANS_WORD(dev->accel.dx, 0) } - mach_accel_out_pixtrans(mach, dev, temp); + mach_accel_out_pixtrans(svga, mach, dev, temp); } } } else { if (ibm8514_cpu_dest(svga)) { cmd = (dev->accel.cmd >> 13); - if (len != 1) { + if (len == 2) { READ_PIXTRANS_WORD(dev->accel.cx, 0) - if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { - temp &= ~0xff00; - temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); - } - if (dev->subsys_stat & 1) { + if (dev->subsys_stat & 0x01) { dev->force_busy = 1; dev->data_available = 1; } + if (dev->accel.input) { + ibm8514_accel_out_pixtrans(svga, port, temp & 0xff, len); + if (dev->accel.odd_in) { /*WORDs on odd destination scan lengths.*/ + dev->accel.odd_in = 0; + temp &= ~0xff00; + READ_HIGH(dev->accel.dest + dev->accel.cx, temp); + } + ibm8514_accel_out_pixtrans(svga, port, (temp >> 8) & 0xff, len); + } else + ibm8514_accel_out_pixtrans(svga, port, temp, len); } - ibm8514_accel_out_pixtrans(svga, port, temp, len); } } break; @@ -3904,23 +3951,23 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in case 0x000: /*8-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { - mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); break; case 0x200: /*16-bit size*/ if (mono_src == 2) { if ((frgd_sel != 2) && (bkgd_sel != 2)) { if (mach->accel.dp_config & 0x1000) - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, svga, mach, dev); else - mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); } else - mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev); + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), svga, mach, dev); break; default: @@ -3931,47 +3978,9 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in } break; - case 0xbee8: - case 0xfee8: - if (len != 1) { - mach_log("Multifunc_cntl = %d.\n", dev->accel.multifunc_cntl >> 12); - switch ((dev->accel.multifunc_cntl >> 12) & 0x0f) { - case 0: - temp = dev->accel.multifunc[0]; - break; - case 1: - temp = dev->accel.clip_top; - break; - case 2: - temp = dev->accel.clip_left; - break; - case 3: - temp = dev->accel.multifunc[3]; - break; - case 4: - temp = dev->accel.multifunc[4]; - break; - case 5: - temp = dev->accel.multifunc[5]; - break; - case 8: - temp = dev->accel.multifunc[8]; - break; - case 9: - temp = dev->accel.multifunc[9]; - break; - case 0x0a: - temp = dev->accel.multifunc[0x0a]; - break; - - default: - break; - } - } - break; - case 0x82ee: - temp = mach->accel.patt_data_idx; + if (len == 2) + temp = mach->accel.patt_data_idx; break; case 0x86ee: @@ -4018,6 +4027,15 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in temp = mach->accel.test >> 8; break; + case 0x9aee: + if (len == 2) { + if ((dev->ext_fifo_idx >= 1) && (dev->ext_fifo_idx <= 16)) { + temp |= (1 << (dev->ext_fifo_idx - 1)); + dev->ext_fifo_idx = 0; + } + } + break; + case 0xa2ee: if (len == 1) temp = mach->accel.linedraw_opt & 0xff; @@ -4089,44 +4107,50 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in break; case 0xceee: + mach_log("CEEE read=%d.\n", len); if (len == 1) temp = dev->vc & 0xff; else temp = dev->vc & 0x7ff; break; case 0xceef: + mach_log("CEEF read=%d.\n", len); if (len == 1) - temp = (dev->vc >> 8) & 7; + temp = (dev->vc >> 8) & 0x07; break; case 0xdaee: - if (len != 1) { - temp = mach->accel.src_x; + if (len == 2) { if ((dev->local & 0xff) >= 0x02) - temp &= 0x7ff; - } else - temp = mach->accel.src_x & 0xff; + temp = mach->accel.src_x; + } else { + if ((dev->local & 0xff) >= 0x02) + temp = mach->accel.src_x & 0xff; + } break; case 0xdaef: - if (len == 1) - temp = mach->accel.src_x >> 8; + if (len == 1) { + if ((dev->local & 0xff) >= 0x02) + temp = mach->accel.src_x >> 8; + } break; case 0xdeee: - if (len != 1) { - temp = mach->accel.src_y; + if (len == 2) { if ((dev->local & 0xff) >= 0x02) - temp &= 0x7ff; + temp = mach->accel.src_y; } else temp = mach->accel.src_y & 0xff; break; case 0xdeef: - if (len == 1) - temp = mach->accel.src_y >> 8; + if (len == 1) { + if ((dev->local & 0xff) >= 0x02) + temp = mach->accel.src_y >> 8; + } break; case 0xfaee: - if (len != 1) { + if (len == 2) { if ((dev->local & 0xff) >= 0x02) { if (mach->pci_bus) temp = 0x0017; @@ -4165,14 +4189,14 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in static uint8_t mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - uint8_t temp = 0; - uint16_t clip_b_ibm = dev->accel.multifunc[3]; - uint16_t clip_r_ibm = dev->accel.multifunc[4]; - int16_t clip_l = dev->accel.clip_left & 0x7ff; - int16_t clip_t = dev->accel.clip_top & 0x7ff; - int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; - int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; - int cmd = (dev->accel.cmd >> 13); + uint8_t temp = 0; + int16_t clip_t = dev->accel.clip_top; + int16_t clip_l = dev->accel.clip_left; + int16_t clip_b = dev->accel.clip_bottom; + int16_t clip_r = dev->accel.clip_right; + uint16_t clip_b_ibm = dev->accel.clip_bottom; + uint16_t clip_r_ibm = dev->accel.clip_right; + int cmd = dev->accel.cmd >> 13; switch (port) { case 0x2e8: @@ -4188,28 +4212,54 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) case 0x42e8: case 0x42e9: if (dev->vc == dev->v_syncstart) - dev->subsys_stat |= 1; + temp |= 0x01; - if (mach->accel.cmd_type >= 0) { - if (((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b)) - temp |= 2; - } else { + if (mach->accel.cmd_type == -1) { if (cmd == 6) { - if (((dev->accel.dx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.dy) >= dev->accel.clip_top) && ((dev->accel.dy) <= clip_b_ibm)) - temp |= 2; + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r_ibm) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b_ibm)) + temp |= 0x02; } else { - if (((dev->accel.cx) >= dev->accel.clip_left) && ((dev->accel.dx) <= clip_r_ibm) && ((dev->accel.cy) >= dev->accel.clip_top) && ((dev->accel.cy) <= clip_b_ibm)) - temp |= 2; + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r_ibm) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b_ibm)) + temp |= 0x02; + } + } else { + switch (mach->accel.cmd_type) { + case 1: + case 2: + case 5: + if ((dev->accel.dx >= clip_l) && + (dev->accel.dx <= clip_r) && + (dev->accel.dy >= clip_t) && + (dev->accel.dy <= clip_b)) + temp |= 0x02; + break; + case 3: + case 4: + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) + temp |= 0x02; + break; + default: + break; } } - if (!dev->force_busy) - temp |= 8; - + if ((!dev->fifo_idx || !dev->ext_fifo_idx)) { + if ((!dev->force_busy && !dev->force_busy2) || !mach->force_busy) + temp |= 0x08; + } if (port & 1) - temp = 0x80; + temp = dev->vram_512k_8514 ? 0x00 : 0x80; else { - temp |= (dev->subsys_stat | 0x80); + temp |= (dev->subsys_stat | (dev->vram_512k_8514 ? 0x00 : 0x80)); if (mach->accel.ext_ge_config & 0x08) temp |= ((mach->accel.ext_ge_config & 0x07) << 4); else @@ -4246,25 +4296,25 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) case 0x36ee: case 0x36ef: - READ8(port, mach->misc); + if ((dev->local & 0xff) >= 0x02) { + READ8(port, mach->misc); - if (!(port & 1)) { - temp &= ~0x0c; - switch (mach->memory) { - case 1024: - temp |= 0x04; - break; - case 2048: - temp |= 0x08; - break; - case 4096: - temp |= 0x0c; - break; - - default: - if ((dev->local & 0xff) < 0x02) + if (!(port & 1)) { + temp &= ~0x0c; + switch (dev->vram_amount) { + case 1024: temp |= 0x04; - break; + break; + case 2048: + temp |= 0x08; + break; + case 4096: + temp |= 0x0c; + break; + + default: + break; + } } } break; @@ -4287,26 +4337,13 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) case 0x52ee: case 0x52ef: READ8(port, mach->accel.scratch0); -#ifdef ATI_8514_ULTRA if (mach->mca_bus) { - if (!(port & 1)) { - if (svga->ext8514 != NULL) - temp = dev->pos_regs[4]; - } else { - if (svga->ext8514 != NULL) - temp = dev->pos_regs[5]; - } - } else { if (svga->ext8514 != NULL) { - temp = ((dev->bios_addr >> 7) - 0x1000) >> 4; - if (port & 1) { - temp &= ~0x80; + temp = (((dev->bios_rom.mapping.base >> 7) - 0x1000) >> 4); + if (port & 1) temp |= 0x01; - } - } else - temp = 0x00; + } } -#endif break; case 0x56ee: @@ -4365,13 +4402,11 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) default: break; } - if (port != 0x62ee && port != 0x62ef && port != 0x42e8 && port != 0x42e9) - mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); + mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); return temp; } -#ifdef ATI_8514_ULTRA static void ati8514_accel_out(uint16_t port, uint8_t val, svga_t *svga) { @@ -4422,7 +4457,6 @@ ati8514_accel_outl(uint16_t port, uint32_t val, void *priv) ati8514_accel_out(port + 3, (val >> 24), svga); } } -#endif static void mach_accel_outb(uint16_t port, uint8_t val, void *priv) @@ -4467,7 +4501,6 @@ mach_accel_outl(uint16_t port, uint32_t val, void *priv) } } -#ifdef ATI_8514_ULTRA static uint8_t ati8514_accel_in(uint16_t port, svga_t *svga) { @@ -4523,7 +4556,6 @@ ati8514_accel_inl(uint16_t port, void *priv) } return temp; } -#endif static uint8_t mach_accel_in(uint16_t port, mach_t *mach) @@ -4582,43 +4614,6 @@ mach_accel_inl(uint16_t port, void *priv) return temp; } -static uint32_t -mach32_decode_addr(svga_t *svga, uint32_t addr, int write) -{ - int memory_map_mode = (svga->gdcreg[6] >> 2) & 3; - - addr &= 0x1ffff; - - switch (memory_map_mode) { - case 0: - break; - case 1: - if (addr >= 0x10000) - return 0xffffffff; - break; - case 2: - addr -= 0x10000; - if (addr >= 0x8000) - return 0xffffffff; - break; - default: - case 3: - addr -= 0x18000; - if (addr >= 0x8000) - return 0xffffffff; - break; - } - - if (memory_map_mode <= 1) { - if (write) - addr = (addr & svga->banked_mask) + svga->write_bank; - else - addr = (addr & svga->banked_mask) + svga->read_bank; - } - - return addr; -} - static __inline void mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t *svga) { @@ -4627,39 +4622,51 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t int reset_wm = 0; latch8514_t vall; uint8_t wm = svga->writemask; - uint8_t count; uint8_t i; cycles -= svga->monitor->mon_video_timing_write_b; if (linear) { - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) + addr <<= 1; + addr &= dev->vram_mask; dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - dev->vram[addr] = val; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + switch (addr & 0x06) { + case 0x00: + case 0x06: + dev->vram[addr] = val & 0x0f; + dev->vram[addr + 1] = (val >> 4) & 0x0f; + break; + case 0x02: + dev->vram[addr + 2] = val & 0x0f; + dev->vram[addr + 3] = (val >> 4) & 0x0f; + break; + case 0x04: + dev->vram[addr - 2] = val & 0x0f; + dev->vram[addr - 1] = (val >> 4) & 0x0f; + break; + default: + break; + } + } else + dev->vram[addr] = val; + return; - } else { - addr = mach32_decode_addr(svga, addr, 1); - if (addr == 0xffffffff) - return; } if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; - if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { + if (svga->chain4) { writemask2 = 1 << (addr & 3); addr &= ~3; - } else if (svga->chain4 && (svga->writemode < 4)) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_write) { writemask2 &= ~0xa; if (addr & 1) writemask2 <<= 1; + addr &= ~1; addr &= dev->vram_mask; } else { @@ -4669,26 +4676,25 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t } addr &= svga->decode_mask; - if (addr >= dev->vram_size) + if (addr >= dev->vram_size) { + mach_log("WriteOver! %x.\n", addr); return; + } addr &= dev->vram_mask; - dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - count = 4; - switch (svga->writemode) { case 0: val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = val; } return; } else { - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (svga->gdcreg[1] & (1 << i)) vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; else @@ -4697,17 +4703,17 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t } break; case 1: - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = dev->latch.b[i]; } return; case 2: - for (i = 0; i < count; i++) + for (i = 0; i < 4; i++) vall.b[i] = !!(val & (1 << i)) * 0xff; if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (dev->latch.b[i] & ~svga->gdcreg[8]); } @@ -4719,7 +4725,7 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t wm = svga->gdcreg[8]; svga->gdcreg[8] &= val; - for (i = 0; i < count; i++) + for (i = 0; i < 4; i++) vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; reset_wm = 1; @@ -4730,25 +4736,25 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t switch (svga->gdcreg[3] & 0x18) { case 0x00: /* Set */ - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (dev->latch.b[i] & ~svga->gdcreg[8]); } break; case 0x08: /* AND */ - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & dev->latch.b[i]; } break; case 0x10: /* OR */ - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | dev->latch.b[i]; } break; case 0x18: /* XOR */ - for (i = 0; i < count; i++) { + for (i = 0; i < 4; i++) { if (writemask2 & (1 << i)) dev->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ dev->latch.b[i]; } @@ -4762,59 +4768,94 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t svga->gdcreg[8] = wm; } -#ifdef ATI_8514_ULTRA -static void -ati8514_write(uint32_t addr, uint8_t val, void *priv) -{ - svga_t *svga = (svga_t *) priv; - mach_t *mach = (mach_t *) svga->ext8514; - mach32_write_common(addr, val, 0, mach, svga); -} - -static void -ati8514_writew(uint32_t addr, uint16_t val, void *priv) -{ - svga_t *svga = (svga_t *) priv; - mach_t *mach = (mach_t *) svga->ext8514; - mach32_write_common(addr, val & 0xff, 0, mach, svga); - mach32_write_common(addr + 1, val >> 8, 0, mach, svga); -} - -static void -ati8514_writel(uint32_t addr, uint32_t val, void *priv) -{ - svga_t *svga = (svga_t *) priv; - mach_t *mach = (mach_t *) svga->ext8514; - mach32_write_common(addr, val & 0xff, 0, mach, svga); - mach32_write_common(addr + 1, val >> 8, 0, mach, svga); - mach32_write_common(addr + 2, val >> 16, 0, mach, svga); - mach32_write_common(addr + 3, val >> 24, 0, mach, svga); -} -#endif - static void mach32_write(uint32_t addr, uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val, 0, mach, &mach->svga); + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + xga_write_test(addr, val, svga); + addr = (addr & svga->banked_mask) + svga->write_bank; + + if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + switch (addr & 0x06) { + case 0x00: + case 0x06: + mach32_write_common(addr, val & 0x0f, 0, mach, svga); + mach32_write_common(addr + 1, (val >> 4) & 0x0f, 0, mach, svga); + break; + case 0x02: + mach32_write_common(addr + 2, val & 0x0f, 0, mach, svga); + mach32_write_common(addr + 3, (val >> 4) & 0x0f, 0, mach, svga); + break; + case 0x04: + mach32_write_common(addr - 2, val & 0x0f, 0, mach, svga); + mach32_write_common(addr - 1, (val >> 4) & 0x0f, 0, mach, svga); + break; + default: + break; + } + } else + mach32_write_common(addr, val, 0, mach, svga); } static void mach32_writew(uint32_t addr, uint16_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga); - mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga); + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + xga_write_test(addr, val, svga); + addr = (addr & svga->banked_mask) + svga->write_bank; + + if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + if (addr & 0x04) { + mach32_write_common(addr - 2, val & 0x0f, 0, mach, svga); + mach32_write_common(addr - 1, (val >> 4) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 2, (val >> 8) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 3, (val >> 12) & 0x0f, 0, mach, svga); + } else { + mach32_write_common(addr, val & 0x0f, 0, mach, svga); + mach32_write_common(addr + 1, (val >> 4) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 4, (val >> 8) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 5, (val >> 12) & 0x0f, 0, mach, svga); + } + } else { + mach32_write_common(addr, val & 0xff, 0, mach, svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, svga); + } } static void mach32_writel(uint32_t addr, uint32_t val, void *priv) { mach_t *mach = (mach_t *) priv; - mach32_write_common(addr, val & 0xff, 0, mach, &mach->svga); - mach32_write_common(addr + 1, val >> 8, 0, mach, &mach->svga); - mach32_write_common(addr + 2, val >> 16, 0, mach, &mach->svga); - mach32_write_common(addr + 3, val >> 24, 0, mach, &mach->svga); + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + + xga_write_test(addr, val, svga); + addr = (addr & svga->banked_mask) + svga->write_bank; + + if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + mach32_write_common(addr, val & 0x0f, 0, mach, svga); + mach32_write_common(addr + 1, (val >> 4) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 4, (val >> 8) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 5, (val >> 12) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 2, (val >> 16) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 3, (val >> 20) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 6, (val >> 24) & 0x0f, 0, mach, svga); + mach32_write_common(addr + 7, (val >> 28) & 0x0f, 0, mach, svga); + } else { + mach32_write_common(addr, val & 0xff, 0, mach, svga); + mach32_write_common(addr + 1, val >> 8, 0, mach, svga); + mach32_write_common(addr + 2, val >> 16, 0, mach, svga); + mach32_write_common(addr + 3, val >> 24, 0, mach, svga); + } } static __inline void @@ -4824,13 +4865,25 @@ mach32_writew_linear(uint32_t addr, uint16_t val, mach_t *mach) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; cycles -= svga->monitor->mon_video_timing_write_w; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) + addr <<= 1; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return; addr &= dev->vram_mask; dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - *(uint16_t *) &dev->vram[addr] = val; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + if (addr & 0x04) { + dev->vram[addr - 2] = val & 0x0f; + dev->vram[addr - 1] = (val >> 4) & 0x0f; + dev->vram[addr + 2] = (val >> 8) & 0x0f; + dev->vram[addr + 3] = (val >> 12) & 0x0f; + } else { + dev->vram[addr] = val & 0x0f; + dev->vram[addr + 1] = (val >> 4) & 0x0f; + dev->vram[addr + 4] = (val >> 8) & 0x0f; + dev->vram[addr + 5] = (val >> 12) & 0x0f; + } + } else + *(uint16_t *) &dev->vram[addr] = val; } static __inline void @@ -4841,12 +4894,22 @@ mach32_writel_linear(uint32_t addr, uint32_t val, mach_t *mach) cycles -= svga->monitor->mon_video_timing_write_l; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) + addr <<= 1; + addr &= dev->vram_mask; dev->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - *(uint32_t *) &dev->vram[addr] = val; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + dev->vram[addr] = val & 0x0f; + dev->vram[addr + 1] = (val >> 4) & 0x0f; + dev->vram[addr + 4] = (val >> 8) & 0x0f; + dev->vram[addr + 5] = (val >> 12) & 0x0f; + dev->vram[addr + 2] = (val >> 16) & 0x0f; + dev->vram[addr + 3] = (val >> 20) & 0x0f; + dev->vram[addr + 6] = (val >> 24) & 0x0f; + dev->vram[addr + 7] = (val >> 28) & 0x0f; + } else + *(uint32_t *) &dev->vram[addr] = val; } static __inline uint8_t @@ -4857,20 +4920,37 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) int readplane = svga->readplane; uint8_t count; uint8_t temp; - uint8_t ret; + uint8_t ret = 0x00; cycles -= svga->monitor->mon_video_timing_read_b; if (linear) { - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return 0xff; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) + addr <<= 1; - return dev->vram[addr & dev->vram_mask]; - } else { - addr = mach32_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) - return 0xff; + addr &= dev->vram_mask; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + switch (addr & 0x06) { + case 0x00: + case 0x06: + ret = dev->vram[addr] & 0x0f; + ret |= (dev->vram[addr + 1] << 4); + break; + case 0x02: + ret = dev->vram[addr + 2] & 0x0f; + ret |= (dev->vram[addr + 3] << 4); + break; + case 0x04: + ret = dev->vram[addr - 2] & 0x0f; + ret |= (dev->vram[addr - 1] << 4); + break; + default: + break; + } + } else + ret = dev->vram[addr]; + + return ret; } count = 2; @@ -4878,28 +4958,31 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) latch_addr = (addr << count) & svga->decode_mask; count = (1 << count); - if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { + if (svga->chain4) { addr &= svga->decode_mask; - if (addr >= dev->vram_size) + if (addr >= dev->vram_size) { + mach_log("ReadOver! (chain4) %x.\n", addr); return 0xff; + } latch_addr = (addr & dev->vram_mask) & ~3; for (uint8_t i = 0; i < count; i++) dev->latch.b[i] = dev->vram[latch_addr | i]; return dev->vram[addr & dev->vram_mask]; - } else if (svga->chain4 && !svga->force_old_addr) { - readplane = addr & 3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); addr &= ~1; addr &= dev->vram_mask; } else { addr &= svga->decode_mask; - if (addr >= dev->vram_size) + if (addr >= dev->vram_size) { + mach_log("ReadOver! (normal) %x.\n", addr); return 0xff; + } latch_addr = (addr & dev->vram_mask) & ~3; for (uint8_t i = 0; i < count; i++) dev->latch.b[i] = dev->vram[latch_addr | i]; + + mach_log("Read (normal) addr=%06x, ret=%02x.\n", addr, dev->vram[addr & dev->vram_mask]); return dev->vram[addr & dev->vram_mask]; } @@ -4907,6 +4990,7 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) /* standard VGA latched access */ if (latch_addr >= dev->vram_size) { + mach_log("Over VRAM Latch addr=%x.\n", latch_addr); for (uint8_t i = 0; i < count; i++) dev->latch.b[i] = 0xff; } else { @@ -4916,8 +5000,10 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) dev->latch.b[i] = dev->vram[latch_addr | i]; } - if (addr >= dev->vram_size) + if (addr >= dev->vram_size) { + mach_log("ReadOver! (chain2) %x.\n", addr); return 0xff; + } addr &= dev->vram_mask; @@ -4938,55 +5024,43 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) } else ret = dev->vram[addr | readplane]; + mach_log("ReadMode=%02x, addr=%06x, ret=%02x.\n", svga->readmode, addr, ret); return ret; } -#ifdef ATI_8514_ULTRA -static uint8_t -ati8514_read(uint32_t addr, void *priv) -{ - svga_t *svga = (svga_t *) priv; - mach_t *mach = (mach_t *) svga->ext8514; - uint8_t ret; - - ret = mach32_read_common(addr, 0, mach, svga); - return ret; -} - -static uint16_t -ati8514_readw(uint32_t addr, void *priv) -{ - svga_t *svga = (svga_t *) priv; - mach_t *mach = (mach_t *) svga->ext8514; - uint16_t ret; - - ret = mach32_read_common(addr, 0, mach, svga); - ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); - return ret; -} - -static uint32_t -ati8514_readl(uint32_t addr, void *priv) -{ - svga_t *svga = (svga_t *) priv; - mach_t *mach = (mach_t *) svga->ext8514; - uint32_t ret; - - ret = mach32_read_common(addr, 0, mach, svga); - ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); - ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 16); - ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 24); - return ret; -} -#endif - static uint8_t mach32_read(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; - uint8_t ret; + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint8_t ret = 0x00; + + (void) xga_read_test(addr, svga); + addr = (addr & svga->banked_mask) + svga->read_bank; + + if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + switch (addr & 0x06) { + case 0x00: + case 0x06: + ret = mach32_read_common(addr, 0, mach, svga) & 0x0f; + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 4); + break; + case 0x02: + ret = mach32_read_common(addr + 2, 0, mach, svga) & 0x0f; + ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 4); + break; + case 0x04: + ret = mach32_read_common(addr - 2, 0, mach, svga) & 0x0f; + ret |= (mach32_read_common(addr - 1, 0, mach, svga) << 4); + break; + default: + break; + } + } else + ret = mach32_read_common(addr, 0, mach, svga); - ret = mach32_read_common(addr, 0, mach, &mach->svga); return ret; } @@ -4994,10 +5068,30 @@ static uint16_t mach32_readw(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; - uint16_t ret; + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t ret; - ret = mach32_read_common(addr, 0, mach, &mach->svga); - ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8); + (void) xga_read_test(addr, svga); + addr = (addr & svga->banked_mask) + svga->read_bank; + + if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + if (addr & 0x04) { + ret = mach32_read_common(addr - 2, 0, mach, svga) & 0x0f; + ret |= (mach32_read_common(addr - 1, 0, mach, svga) << 4); + ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 8); + ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 12); + } else { + ret = mach32_read_common(addr, 0, mach, svga) & 0x0f; + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 4); + ret |= (mach32_read_common(addr + 4, 0, mach, svga) << 8); + ret |= (mach32_read_common(addr + 5, 0, mach, svga) << 12); + } + } else { + ret = mach32_read_common(addr, 0, mach, svga); + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); + } return ret; } @@ -5005,12 +5099,29 @@ static uint32_t mach32_readl(uint32_t addr, void *priv) { mach_t *mach = (mach_t *) priv; - uint32_t ret; + svga_t *svga = &mach->svga; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t ret; - ret = mach32_read_common(addr, 0, mach, &mach->svga); - ret |= (mach32_read_common(addr + 1, 0, mach, &mach->svga) << 8); - ret |= (mach32_read_common(addr + 2, 0, mach, &mach->svga) << 16); - ret |= (mach32_read_common(addr + 3, 0, mach, &mach->svga) << 24); + (void) xga_read_test(addr, svga); + addr = (addr & svga->banked_mask) + svga->read_bank; + + if ((((dev->local & 0xff) >= 0x02) && !dev->vram_512k_8514) && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + ret = mach32_read_common(addr, 0, mach, svga) & 0x0f; + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 4); + ret |= (mach32_read_common(addr + 4, 0, mach, svga) << 8); + ret |= (mach32_read_common(addr + 5, 0, mach, svga) << 12); + ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 20); + ret |= (mach32_read_common(addr + 6, 0, mach, svga) << 24); + ret |= (mach32_read_common(addr + 7, 0, mach, svga) << 28); + } else { + ret = mach32_read_common(addr, 0, mach, svga); + ret |= (mach32_read_common(addr + 1, 0, mach, svga) << 8); + ret |= (mach32_read_common(addr + 2, 0, mach, svga) << 16); + ret |= (mach32_read_common(addr + 3, 0, mach, svga) << 24); + } return ret; } @@ -5019,14 +5130,27 @@ mach32_readw_linear(uint32_t addr, mach_t *mach) { svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint16_t ret; cycles -= svga->monitor->mon_video_timing_read_w; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + addr &= dev->vram_mask; + if (addr & 0x04) { + ret = dev->vram[addr - 2] & 0x0f; + ret |= (dev->vram[addr - 1] << 4); + ret |= (dev->vram[addr + 2] << 8); + ret |= (dev->vram[addr + 3] << 12); + } else { + ret = dev->vram[addr] & 0x0f; + ret |= (dev->vram[addr + 1] << 4); + ret |= (dev->vram[addr + 4] << 8); + ret |= (dev->vram[addr + 5] << 12); + } + } else + ret = *(uint16_t *) &dev->vram[addr & dev->vram_mask]; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return 0xffff; - - return *(uint16_t *) &dev->vram[addr & dev->vram_mask]; + return ret; } static __inline uint32_t @@ -5034,14 +5158,24 @@ mach32_readl_linear(uint32_t addr, mach_t *mach) { svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + uint32_t ret; cycles -= svga->monitor->mon_video_timing_read_l; + if (!dev->vram_512k_8514 && ((mach->accel.ext_ge_config & 0x30) == 0x00)) { + addr <<= 1; + addr &= dev->vram_mask; + ret = dev->vram[addr] & 0x0f; + ret |= (dev->vram[addr + 1] << 4); + ret |= (dev->vram[addr + 4] << 8); + ret |= (dev->vram[addr + 5] << 12); + ret |= (dev->vram[addr + 2] << 16); + ret |= (dev->vram[addr + 3] << 20); + ret |= (dev->vram[addr + 6] << 24); + ret |= (dev->vram[addr + 7] << 28); + } else + ret = *(uint32_t *) &dev->vram[addr & dev->vram_mask]; - addr &= svga->decode_mask; - if (addr >= dev->vram_size) - return 0xffffffff; - - return *(uint32_t *) &dev->vram[addr & dev->vram_mask]; + return ret; } static void @@ -5062,8 +5196,9 @@ mach32_ap_writeb(uint32_t addr, uint8_t val, void *priv) mach_accel_outb(0x02e8 + (addr & 1) + (port_dword << 8), val, mach); } } else { - mach_log("Linear WORDB Write=%08x, val=%02x.\n", addr, val); - if (dev->on[0] || dev->on[1]) + mach_log("Linear WORDB Write=%08x, val=%02x, ON=%x, dpconfig=%04x, apsize=%08x.\n", + addr & dev->vram_mask, val, dev->on, mach->accel.dp_config, mach->ap_size << 20); + if (dev->on) mach32_write_common(addr, val, 1, mach, svga); else svga_write_linear(addr, val, svga); @@ -5088,10 +5223,11 @@ mach32_ap_writew(uint32_t addr, uint16_t val, void *priv) mach_accel_outw(0x02e8 + (port_dword << 8), val, mach); } } else { - mach_log("Linear WORDW Write=%08x, val=%04x.\n", addr, val); - if (dev->on[0] || dev->on[1]) { + mach_log("Linear WORDW Write=%08x, val=%04x, ON=%x, dpconfig=%04x, apsize=%08x.\n", + addr & dev->vram_mask, val, dev->on, mach->accel.dp_config, mach->ap_size << 20); + if (dev->on) mach32_writew_linear(addr, val, mach); - } else + else svga_writew_linear(addr, val, svga); } } @@ -5116,10 +5252,11 @@ mach32_ap_writel(uint32_t addr, uint32_t val, void *priv) mach_accel_outw(0x02e8 + (port_dword << 8) + 4, val >> 16, mach); } } else { - mach_log("Linear WORDL Write=%08x, val=%08x.\n", addr, val); - if (dev->on[0] || dev->on[1]) { + mach_log("Linear WORDL Write=%08x, val=%08x, ON=%x, dpconfig=%04x, apsize=%08x.\n", + addr & dev->vram_mask, val, dev->on, mach->accel.dp_config, mach->ap_size << 20); + if (dev->on) mach32_writel_linear(addr, val, mach); - } else + else svga_writel_linear(addr, val, svga); } } @@ -5140,7 +5277,7 @@ mach32_ap_readb(uint32_t addr, void *priv) else temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); } else { - if (dev->on[0] || dev->on[1]) + if (dev->on) temp = mach32_read_common(addr, 1, mach, svga); else temp = svga_read_linear(addr, svga); @@ -5167,9 +5304,9 @@ mach32_ap_readw(uint32_t addr, void *priv) else temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); } else { - if (dev->on[0] || dev->on[1]) { + if (dev->on) temp = mach32_readw_linear(addr, mach); - } else + else temp = svga_readw_linear(addr, svga); mach_log("Linear WORDW Read=%08x, ret=%04x.\n", addr, temp); @@ -5197,12 +5334,12 @@ mach32_ap_readl(uint32_t addr, void *priv) temp |= (mach_accel_inw(0x02e8 + (port_dword << 8) + 4, mach) << 8); } } else { - if (dev->on[0] || dev->on[1]) { + if (dev->on) temp = mach32_readl_linear(addr, mach); - } else + else temp = svga_readl_linear(addr, svga); - mach_log("Linear WORDL Read=%08x, ret=%08x, ON0=%d, ON1=%d.\n", addr, temp, dev->on[0], dev->on[1]); + mach_log("Linear WORDL Read=%08x, ret=%08x, ON%d.\n", addr, temp, dev->on); } return temp; @@ -5214,12 +5351,13 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; if (mach->pci_bus && (!(mach->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { + mach_log("No Mapping.\n"); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&mach->mmio_linear_mapping); return; } - if (mach->regs[0xbd] & 4) { + if (mach->regs[0xbd] & 0x04) { mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; } else { @@ -5239,6 +5377,15 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) case 0xC: /*32k at B8000*/ mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; + if (((dev->local & 0xff) >= 0x02) && !(dev->accel.advfunc_cntl & 0x01) && !(mach->accel.clock_sel & 0x01)) { + if ((svga->gdcreg[6] & 0x01) || (svga->attrregs[0x10] & 0x01)) { + if (svga->attrregs[0x10] & 0x40) { + dev->vendor_mode = 0; + dev->on &= ~0x01; + svga_recalctimings(svga); + } + } + } break; default: @@ -5246,35 +5393,37 @@ mach32_updatemapping(mach_t *mach, svga_t *svga) } } - mach_log("Linear base = %08x, aperture = %04x, localcntl = %02x svgagdc = %x.\n", mach->linear_base, mach->memory_aperture, mach->local_cntl, svga->gdcreg[6] & 0x0c); + mach_log("Linear base = %08x, aperture = %04x, localcntl = %02x svgagdc = %x.\n", + mach->linear_base, mach->memory_aperture, mach->local_cntl, svga->gdcreg[6] & 0x0c); if (mach->linear_base) { if (((mach->memory_aperture & 3) == 1) && !mach->pci_bus) { /*1 MB aperture*/ mach->ap_size = 1; + mach_log("Linear Enabled APSIZE=1.\n"); mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); } else { /*4 MB aperture*/ mach->ap_size = 4; + mach_log("Linear Enabled APSIZE=4.\n"); mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); } } else { mach->ap_size = 4; + mach_log("Linear Disabled APSIZE=4.\n"); mem_mapping_disable(&mach->mmio_linear_mapping); } - if ((dev->on[0] || dev->on[1]) && (mach->ext_on[0] || mach->ext_on[1]) && (dev->vendor_mode[0] || dev->vendor_mode[1])) { - mach_log("ExtON.\n"); -#ifdef ATI_8514_ULTRA - if (svga->ext8514 != NULL) { - mem_mapping_set_handler(&svga->mapping, ati8514_read, ati8514_readw, ati8514_readl, ati8514_write, ati8514_writew, ati8514_writel); - mem_mapping_set_p(&svga->mapping, svga); - } else -#endif - { + if ((dev->local & 0xff) >= 0x02) { + if (dev->on && dev->vendor_mode) { + mach_log("Mach32 banked mapping.\n"); mem_mapping_set_handler(&svga->mapping, mach32_read, mach32_readw, mach32_readl, mach32_write, mach32_writew, mach32_writel); mem_mapping_set_p(&svga->mapping, mach); + } else { + mach_log("IBM compatible banked mapping.\n"); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&svga->mapping, svga); } } else { - mach_log("ExtOFF.\n"); + mach_log("IBM compatible banked mapping.\n"); mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); mem_mapping_set_p(&svga->mapping, svga); } @@ -5287,19 +5436,22 @@ mach32_hwcursor_draw(svga_t *svga, int displine) ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint16_t dat; int comb; - int offset = dev->hwcursor_latch.x - dev->hwcursor_latch.xoff; + int offset; uint32_t color0; uint32_t color1; uint32_t *p; int x_pos; int y_pos; - mach_log("BPP=%d.\n", dev->accel_bpp); + offset = dev->hwcursor_latch.x - dev->hwcursor_latch.xoff; + + mach_log("BPP=%d, displine=%d.\n", dev->accel_bpp, displine); switch (dev->accel_bpp) { default: case 8: color0 = dev->pallook[mach->cursor_col_0]; color1 = dev->pallook[mach->cursor_col_1]; + mach_log("4/8BPP: Color0=%08x, Color1=%08x.\n", color0, color1); break; case 15: color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; @@ -5321,6 +5473,7 @@ mach32_hwcursor_draw(svga_t *svga, int displine) for (int x = 0; x < 64; x += 8) { dat = dev->vram[dev->hwcursor_latch.addr & dev->vram_mask] | (dev->vram[(dev->hwcursor_latch.addr + 1) & dev->vram_mask] << 8); + for (int xx = 0; xx < 8; xx++) { comb = (dat >> (xx << 1)) & 0x03; @@ -5349,11 +5502,11 @@ mach32_hwcursor_draw(svga_t *svga, int displine) } dev->hwcursor_latch.addr += 2; } + if (dev->interlace && !dev->hwcursor_oddeven) dev->hwcursor_latch.addr += 16; } -#ifdef ATI_8514_ULTRA static void ati8514_io_set(svga_t *svga) { @@ -5369,7 +5522,6 @@ ati8514_io_set(svga_t *svga) io_sethandler(0x26e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x2ee8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x42e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); - io_sethandler(0x46e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x4ae8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x52e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0x56e8, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); @@ -5469,7 +5621,122 @@ ati8514_io_set(svga_t *svga) io_sethandler(0xf6ee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); io_sethandler(0xfeee, 0x0002, ati8514_accel_inb, ati8514_accel_inw, ati8514_accel_inl, ati8514_accel_outb, ati8514_accel_outw, ati8514_accel_outl, svga); } -#endif + +static void +mach_io_remove(mach_t *mach) +{ + io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + + io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + + io_removehandler(0x02ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x22ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x86ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); +} static void mach_io_set(mach_t *mach) @@ -5486,7 +5753,6 @@ mach_io_set(mach_t *mach) io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); - io_sethandler(0x46e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); @@ -5606,7 +5872,8 @@ mach_mca_write(int port, uint8_t val, void *priv) return; mach->pos_regs[port & 7] = val; - mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", CS, port & 7, mach->pos_regs[port & 7], (((mach->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); + mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", + CS, port & 7, mach->pos_regs[port & 7], (((mach->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); mem_mapping_disable(&mach->bios_rom.mapping); mem_mapping_disable(&mach->bios_rom2.mapping); if (mach->pos_regs[2] & 0x01) { @@ -5631,16 +5898,12 @@ mach_mca_reset(void *priv) svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - mem_mapping_disable(&mach->bios_rom.mapping); - mem_mapping_disable(&mach->bios_rom2.mapping); mach_log("MCA reset.\n"); - dev->on[0] = 0; - dev->on[1] = 0; - vga_on = 1; + dev->on = 0; mach_mca_write(0x102, 0, mach); + svga_set_poll(svga); } -#ifdef ATI_8514_ULTRA uint8_t ati8514_mca_read(int port, void *priv) { @@ -5660,7 +5923,8 @@ ati8514_mca_write(int port, uint8_t val, void *priv) return; dev->pos_regs[port & 7] = val; - mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", CS, port & 7, dev->pos_regs[port & 7], (((dev->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); + mach_log("[%04X]: MCA write port = %x, val = %02x, biosaddr = %05x.\n", + CS, port & 7, dev->pos_regs[port & 7], (((dev->pos_regs[3] & 0x3e) << 0x0c) >> 1) + 0xc0000); mem_mapping_disable(&dev->bios_rom.mapping); if (dev->pos_regs[2] & 0x01) @@ -5672,7 +5936,6 @@ ati8514_pos_write(uint16_t port, uint8_t val, void *priv) { ati8514_mca_write(port, val, priv); } -#endif static uint8_t mach32_pci_read(UNUSED(int func), int addr, void *priv) @@ -5764,13 +6027,21 @@ mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case PCI_REG_COMMAND: mach->pci_regs[PCI_REG_COMMAND] = val & 0x27; if (val & PCI_COMMAND_IO) { + mach_log("Remove and set handlers.\n"); + io_removehandler(0x01ce, 2, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_removehandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mach_io_remove(mach); + io_sethandler(0x01ce, 2, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mach_io_set(mach); } else { + mach_log("Remove handlers.\n"); + io_removehandler(0x01ce, 2, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_removehandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_removehandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + mach_io_remove(mach); } mach32_updatemapping(mach, &mach->svga); break; @@ -5827,8 +6098,9 @@ mach8_init(const device_t *info) dev->type = info->flags; dev->local = info->local & 0xff; mach->has_bios = !(info->local & 0xff00); - mach->memory = device_get_config_int("memory"); mach->ramdac_type = mach->pci_bus ? device_get_config_int("ramdac") : 1; + dev->vram_amount = device_get_config_int("memory"); + dev->vram_512k_8514 = dev->vram_amount == 512; if ((dev->local & 0xff) >= 0x02) { if (mach->pci_bus) { @@ -5866,12 +6138,12 @@ mach8_init(const device_t *info) 0, MEM_MAPPING_EXTERNAL); if ((dev->local & 0xff) >= 0x02) { - svga_init(info, svga, mach, mach->memory << 10, /*default: 2MB for Mach32*/ + svga_init(info, svga, mach, dev->vram_amount << 10, /*default: 2MB for Mach32*/ mach_recalctimings, mach_in, mach_out, mach32_hwcursor_draw, NULL); - dev->vram_size = mach->memory << 10; + dev->vram_size = dev->vram_amount << 10; dev->vram = calloc(dev->vram_size, 1); dev->changedvram = calloc((dev->vram_size >> 12) + 1, 1); dev->vram_mask = dev->vram_size - 1; @@ -5888,7 +6160,7 @@ mach8_init(const device_t *info) else mach->config1 |= 0x0c; mach->config1 |= 0x0400; - svga->clock_gen = device_add(&ati18811_0_device); + svga->clock_gen = device_add(&ati18811_1_device); } else if (mach->mca_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_mca); if (is286 && !is386) @@ -5905,11 +6177,11 @@ mach8_init(const device_t *info) else mach->config1 |= 0x0a00; mach->config2 |= 0x2000; - svga->clock_gen = device_add(&ati18811_0_device); + svga->clock_gen = device_add(&ati18811_1_device); } else { video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); mach->config1 |= 0x0400; - svga->clock_gen = device_add(&ati18811_0_device); + svga->clock_gen = device_add(&ati18811_1_device); } mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach); mem_mapping_disable(&mach->mmio_linear_mapping); @@ -5919,20 +6191,22 @@ mach8_init(const device_t *info) mach_in, mach_out, NULL, NULL); - dev->vram_size = (1024 << 10); + dev->vram_size = (dev->vram_amount << 10); dev->vram = calloc(dev->vram_size, 1); dev->changedvram = calloc((dev->vram_size >> 12) + 1, 1); dev->vram_mask = dev->vram_size - 1; video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); - mach->config1 = 0x01 | 0x02 | 0x20 | 0x08 | 0x80; + mach->config1 = 0x01 | 0x02 | 0x08 | 0x80; + if (dev->vram_amount >= 1024) + mach->config1 |= 0x20; + mach->config2 = 0x02; - svga->clock_gen = device_add(&ati18810_device); + svga->clock_gen = device_add(&ati18811_0_device); } dev->bpp = 0; svga->getclock = ics2494_getclock; - dev->on[0] = 0; - dev->on[1] = 0; + dev->on = 0; dev->ext_pitch = 1024; dev->ext_crt_pitch = 0x80; dev->accel_bpp = 8; @@ -5945,6 +6219,7 @@ mach8_init(const device_t *info) io_sethandler(0x03c0, 32, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); io_sethandler(0x02ea, 4, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); mach_io_set(mach); + mach->accel.cmd_type = -2; if ((dev->local & 0xff) >= 0x02) { svga->decode_mask = (4 << 20) - 1; @@ -5968,27 +6243,25 @@ mach8_init(const device_t *info) } else pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach, &mach->pci_slot); - mach->pci_regs[PCI_REG_COMMAND] = 0x83; + mach->pci_regs[PCI_REG_COMMAND] = 0x87; mach->pci_regs[0x30] = 0x00; mach->pci_regs[0x32] = 0x0c; mach->pci_regs[0x33] = 0x00; } else ati_eeprom_load(&mach->eeprom, "mach32.nvr", 1); } else - ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); + ati_eeprom_load_mach8_vga(&mach->eeprom, "mach8.nvr"); return mach; } -#ifdef ATI_8514_ULTRA void ati8514_init(svga_t *svga, void *ext8514, void *dev8514) { mach_t *mach = (mach_t *) ext8514; ibm8514_t *dev = (ibm8514_t *) dev8514; - dev->on[0] = 0; - dev->on[1] = 0; + dev->on = 0; dev->ext_pitch = 1024; dev->ext_crt_pitch = 0x80; dev->accel_bpp = 8; @@ -6000,14 +6273,16 @@ ati8514_init(svga_t *svga, void *ext8514, void *dev8514) ati8514_io_set(svga); mach->mca_bus = !!(dev->type & DEVICE_MCA); + mach->config1 = 0x02 | 0x08 | 0x80; + if (mach->mca_bus) - mach->config1 = 0x02 | 0x04 | 0x08 | 0x20 | 0x80; - else - mach->config1 = 0x02 | 0x08 | 0x20 | 0x80; + mach->config1 |= 0x04; + + if (dev->vram_amount >= 1024) + mach->config1 |= 0x20; mach->config2 = 0x01 | 0x02; } -#endif static int mach8_vga_available(void) @@ -6076,173 +6351,163 @@ mach_force_redraw(void *priv) } // clang-format off +static const device_config_t mach8_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1024, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + static const device_config_t mach32_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2048, - .selection = { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "4 MB", - .value = 4096 - }, - { - .description = "" - } - } + .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 = "4 MB", .value = 4096 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format off static const device_config_t mach32_pci_config[] = { { - .name = "ramdac", - .description = "RAMDAC type", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "ATI 68860", - .value = 0 - }, - { - .description = "ATI 68875", - .value = 1 - }, - { - .description = "" - } - } + .name = "ramdac", + .description = "RAMDAC type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "ATI 68860", .value = 0 }, + { .description = "ATI 68875", .value = 1 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2048, - .selection = { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "4 MB", - .value = 4096 - }, - { - .description = "" - } - } + .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 = "4 MB", .value = 4096 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; +// clang-format on const device_t mach8_vga_isa_device = { - .name = "ATI Mach8 (ATI Graphics Ultra) (ISA)", + .name = "ATI Mach8 (ATI Graphics Ultra) (ISA)", .internal_name = "mach8_vga_isa", - .flags = DEVICE_ISA, - .local = 1, - .init = mach8_init, - .close = mach_close, - .reset = NULL, - { .available = mach8_vga_available }, + .flags = DEVICE_ISA, + .local = 1, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + .available = mach8_vga_available, .speed_changed = mach_speed_changed, - .force_redraw = mach_force_redraw, - .config = NULL + .force_redraw = mach_force_redraw, + .config = mach8_config }; const device_t mach32_isa_device = { - .name = "ATI Mach32 (ISA)", + .name = "ATI Mach32 (ISA)", .internal_name = "mach32_isa", - .flags = DEVICE_ISA, - .local = 2, - .init = mach8_init, - .close = mach_close, - .reset = NULL, - { .available = mach32_isa_available }, + .flags = DEVICE_ISA, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + .available = mach32_isa_available, .speed_changed = mach_speed_changed, - .force_redraw = mach_force_redraw, - .config = mach32_config + .force_redraw = mach_force_redraw, + .config = mach32_config }; const device_t mach32_vlb_device = { - .name = "ATI Mach32 (VLB)", + .name = "ATI Mach32 (VLB)", .internal_name = "mach32_vlb", - .flags = DEVICE_VLB, - .local = 2, - .init = mach8_init, - .close = mach_close, - .reset = NULL, - { .available = mach32_vlb_available }, + .flags = DEVICE_VLB, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + .available = mach32_vlb_available, .speed_changed = mach_speed_changed, - .force_redraw = mach_force_redraw, - .config = mach32_config + .force_redraw = mach_force_redraw, + .config = mach32_config }; const device_t mach32_mca_device = { - .name = "ATI Mach32 (MCA)", + .name = "ATI Mach32 (MCA)", .internal_name = "mach32_mca", - .flags = DEVICE_MCA, - .local = 2, - .init = mach8_init, - .close = mach_close, - .reset = NULL, - { .available = mach32_mca_available }, + .flags = DEVICE_MCA, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + .available = mach32_mca_available, .speed_changed = mach_speed_changed, - .force_redraw = mach_force_redraw, - .config = mach32_config + .force_redraw = mach_force_redraw, + .config = mach32_config }; const device_t mach32_pci_device = { - .name = "ATI Mach32 (PCI)", + .name = "ATI Mach32 (PCI)", .internal_name = "mach32_pci", - .flags = DEVICE_PCI, - .local = 2, - .init = mach8_init, - .close = mach_close, - .reset = NULL, - { .available = mach32_pci_available }, + .flags = DEVICE_PCI, + .local = 2, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + .available = mach32_pci_available, .speed_changed = mach_speed_changed, - .force_redraw = mach_force_redraw, - .config = mach32_pci_config + .force_redraw = mach_force_redraw, + .config = mach32_pci_config }; const device_t mach32_onboard_pci_device = { - .name = "ATI Mach32 (PCI) On-Board", + .name = "ATI Mach32 (PCI) On-Board", .internal_name = "mach32_pci_onboard", - .flags = DEVICE_PCI, - .local = 2 | 0x100, - .init = mach8_init, - .close = mach_close, - .reset = NULL, - { .available = NULL }, + .flags = DEVICE_PCI, + .local = 2 | 0x100, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + .available = NULL, .speed_changed = mach_speed_changed, - .force_redraw = mach_force_redraw, - .config = mach32_pci_config + .force_redraw = mach_force_redraw, + .config = mach32_pci_config }; - diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index f13740d34..7815f79be 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -182,7 +182,7 @@ const device_t att490_ramdac_device = { .init = att49x_ramdac_init, .close = att49x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -196,7 +196,7 @@ const device_t att491_ramdac_device = { .init = att49x_ramdac_init, .close = att49x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -210,7 +210,7 @@ const device_t att492_ramdac_device = { .init = att49x_ramdac_init, .close = att49x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c index 47eebccae..f52b1432f 100644 --- a/src/video/vid_att2xc498_ramdac.c +++ b/src/video/vid_att2xc498_ramdac.c @@ -183,7 +183,7 @@ const device_t att498_ramdac_device = { .init = att498_ramdac_init, .close = att498_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_av9194.c b/src/video/vid_av9194.c index e7cf75dee..951f3519c 100644 --- a/src/video/vid_av9194.c +++ b/src/video/vid_av9194.c @@ -103,7 +103,7 @@ const device_t av9194_device = { .init = av9194_init, .close = NULL, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index a4459ce4c..84fb110c6 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -921,50 +921,37 @@ bochs_vbe_force_redraw(void *priv) static const device_config_t bochs_vbe_config[] = { // clang-format off { - .name = "revision", - .description = "Revision", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "VirtualBox", - .value = VBE_DISPI_ID4 - }, - { - .description = "Bochs latest", - .value = VBE_DISPI_ID5 - }, - { - .description = "" - } + .name = "revision", + .description = "Revision", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = VBE_DISPI_ID5, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "VirtualBox", .value = VBE_DISPI_ID4 }, + { .description = "Bochs latest", .value = VBE_DISPI_ID5 }, + { .description = "" } }, - .default_int = VBE_DISPI_ID5 + .bios = { { 0 } } }, { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 16, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "4 MB", .value = 4 }, + { .description = "8 MB", .value = 8 }, + { .description = "16 MB", .value = 16 }, + { .description = "" } }, - .default_int = 16 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -976,7 +963,7 @@ const device_t bochs_svga_device = { .init = bochs_vbe_init, .close = bochs_vbe_close, .reset = bochs_vbe_reset, - { .available = bochs_vbe_available }, + .available = bochs_vbe_available, .speed_changed = bochs_vbe_speed_changed, .force_redraw = bochs_vbe_force_redraw, .config = bochs_vbe_config diff --git a/src/video/vid_bt481_ramdac.c b/src/video/vid_bt481_ramdac.c new file mode 100644 index 000000000..1b81e2dc7 --- /dev/null +++ b/src/video/vid_bt481_ramdac.c @@ -0,0 +1,161 @@ +/* + * 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 Brooktree BT481 true colour RAMDAC + * family. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2024 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> +#include <86box/plat_unused.h> + +typedef struct bt481_ramdac_t { + int state; + uint8_t cmd; +} bt481_ramdac_t; + +static void +bt481_ramdac_command(uint8_t val, void *priv, svga_t *svga) +{ + bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv; + ramdac->cmd = val; + pclog("RAMDAC CMD=%02x.\n", val); + switch ((ramdac->cmd >> 4) & 0x0f) { + default: + case 0x00: + svga->bpp = 8; + break; + case 0x08: + case 0x0a: + svga->bpp = 15; + break; + case 0x09: + case 0x0c: + svga->bpp = 16; + break; + case 0x0e: + case 0x0f: + svga->bpp = 24; + break; + } + svga_recalctimings(svga); +} + +void +bt481_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) +{ + bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv; + uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); + + switch (rs) { + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + ramdac->state = 0; + break; + case 0x02: + pclog("RAMDAC Write State=%x.\n", ramdac->state); + switch (ramdac->state) { + case 4: + bt481_ramdac_command(val, ramdac, svga); + break; + default: + svga_out(addr, val, svga); + break; + } + break; + case 0x06: + bt481_ramdac_command(val, ramdac, svga); + ramdac->state = 0; + break; + + default: + break; + } +} + +uint8_t +bt481_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) +{ + bt481_ramdac_t * ramdac = (bt481_ramdac_t *) priv; + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); + + switch (rs) { + case 0x02: + case 0x06: + switch (ramdac->state) { + case 4: + temp = ramdac->cmd; + break; + default: + temp = svga_in(addr, svga); + ramdac->state++; + break; + } + break; + + default: + temp = svga_in(addr, svga); + ramdac->state = 0; + break; + } + + pclog("RAMDAC IN=%02x, ret=%02x.\n", rs, temp); + return temp; +} + +static void * +bt481_ramdac_init(UNUSED(const device_t *info)) +{ + bt481_ramdac_t *ramdac = (bt481_ramdac_t *) malloc(sizeof(bt481_ramdac_t)); + memset(ramdac, 0, sizeof(bt481_ramdac_t)); + + return ramdac; +} + +static void +bt481_ramdac_close(void *priv) +{ + bt481_ramdac_t *ramdac = (bt481_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + +const device_t bt481_ramdac_device = { + .name = "Brooktree Bt481 RAMDAC", + .internal_name = "bt481_ramdac", + .flags = 0, + .local = 0, + .init = bt481_ramdac_init, + .close = bt481_ramdac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index 6b0ec300b..d608750e3 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -538,7 +538,7 @@ const device_t bt484_ramdac_device = { .init = bt48x_ramdac_init, .close = bt48x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -552,7 +552,7 @@ const device_t att20c504_ramdac_device = { .init = bt48x_ramdac_init, .close = bt48x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -566,7 +566,7 @@ const device_t bt485_ramdac_device = { .init = bt48x_ramdac_init, .close = bt48x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -580,7 +580,7 @@ const device_t att20c505_ramdac_device = { .init = bt48x_ramdac_init, .close = bt48x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -594,7 +594,7 @@ const device_t bt485a_ramdac_device = { .init = bt48x_ramdac_init, .close = bt48x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 2ea07c346..f439cb1d8 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -70,6 +70,15 @@ static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w void cga_recalctimings(cga_t *cga); +static void +cga_update_latch(cga_t *cga) +{ + uint32_t lp_latch = cga->displine * cga->crtc[1]; + + cga->crtc[0x10] = (lp_latch >> 8) & 0x3f; + cga->crtc[0x11] = lp_latch & 0xff; +} + void cga_out(uint16_t addr, uint8_t val, void *priv) { @@ -87,7 +96,7 @@ cga_out(uint16_t addr, uint8_t val, void *priv) old = cga->crtc[cga->crtcreg]; cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; if (old != val) { - if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) { + if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x11)) { cga->fullchange = changeframecount; cga_recalctimings(cga); } @@ -111,6 +120,17 @@ cga_out(uint16_t addr, uint8_t val, void *priv) cga_recalctimings(cga); return; + case 0x3DB: + if (cga->lp_strobe == 1) + cga->lp_strobe = 0; + return; + case 0x3DC: + if (cga->lp_strobe == 0) { + cga->lp_strobe = 1; + cga_update_latch(cga); + } + return; + default: break; } @@ -119,8 +139,7 @@ cga_out(uint16_t addr, uint8_t val, void *priv) uint8_t cga_in(uint16_t addr, void *priv) { - const cga_t *cga = (cga_t *) priv; - + cga_t *cga = (cga_t *) priv; uint8_t ret = 0xff; if ((addr >= 0x3d0) && (addr <= 0x3d7)) @@ -137,6 +156,17 @@ cga_in(uint16_t addr, void *priv) ret = cga->cgastat; break; + case 0x3DB: + if (cga->lp_strobe == 1) + cga->lp_strobe = 0; + break; + case 0x3DC: + if (cga->lp_strobe == 0) { + cga->lp_strobe = 1; + cga_update_latch(cga); + } + break; + default: break; } @@ -418,7 +448,7 @@ cga_interpolate_linear(uint8_t co1, uint8_t co2, double fraction) } static color_t -cga_interpolate_lookup(cga_t *cga, color_t color1, color_t color2, double fraction) +cga_interpolate_lookup(cga_t *cga, color_t color1, color_t color2, UNUSED(double fraction)) { color_t ret; uint8_t dt = cga->double_type - DOUBLE_INTERPOLATE_SRGB; @@ -779,114 +809,83 @@ cga_speed_changed(void *priv) // clang-format off const device_config_t cga_config[] = { { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_int = CGA_RGB, - .selection = { - { - .description = "RGB", - .value = CGA_RGB - }, - { - .description = "Composite", - .value = CGA_COMPOSITE - }, - { - .description = "" - } - } + .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_int = COMPOSITE_OLD, - .selection = { - { - .description = "Old", - .value = COMPOSITE_OLD - }, - { - .description = "New", - .value = COMPOSITE_NEW - }, - { - .description = "" - } - } + .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_int = 5, - .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 = "" - } - } + .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_int = DOUBLE_NONE, - .selection = { - { - .description = "None", - .value = DOUBLE_NONE - }, - { - .description = "Simple doubling", - .value = DOUBLE_SIMPLE - }, - { - .description = "sRGB interpolation", - .value = DOUBLE_INTERPOLATE_SRGB - }, - { - .description = "Linear interpolation", - .value = DOUBLE_INTERPOLATE_LINEAR - }, - { - .description = "" - } - } + .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 = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "snow_enabled", + .description = "Snow emulation", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on @@ -898,7 +897,7 @@ const device_t cga_device = { .init = cga_standalone_init, .close = cga_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = cga_speed_changed, .force_redraw = NULL, .config = cga_config @@ -912,7 +911,7 @@ const device_t cga_pravetz_device = { .init = cga_pravetz_init, .close = cga_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = cga_speed_changed, .force_redraw = NULL, .config = cga_config diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index d580f0c06..6ad6a6b0a 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -44,22 +44,22 @@ static const double tau = 6.28318531; /* == 2*pi */ static unsigned char chroma_multiplexer[256] = { // clang-format off - 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, - 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, - 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, - 140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135, - 32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77, - 177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192, - 4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117, - 147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193, - 72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1, - 248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130, - 1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2, - 162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112, - 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, - 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, - 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, - 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 + 2, 2, 2, 2, 114, 174, 4, 3, 2, 1, 133, 135, 2, 113, 150, 4, + 133, 2, 1, 99, 151, 152, 2, 1, 3, 2, 96, 136, 151, 152, 151, 152, + 2, 56, 62, 4, 111, 250, 118, 4, 0, 51, 207, 137, 1, 171, 209, 5, + 140, 50, 54, 100, 133, 202, 57, 4, 2, 50, 153, 149, 128, 198, 198, 135, + 32, 1, 36, 81, 147, 158, 1, 42, 33, 1, 210, 254, 34, 109, 169, 77, + 177, 2, 0, 165, 189, 154, 3, 44, 33, 0, 91, 197, 178, 142, 144, 192, + 4, 2, 61, 67, 117, 151, 112, 83, 4, 0, 249, 255, 3, 107, 249, 117, + 147, 1, 50, 162, 143, 141, 52, 54, 3, 0, 145, 206, 124, 123, 192, 193, + 72, 78, 2, 0, 159, 208, 4, 0, 53, 58, 164, 159, 37, 159, 171, 1, + 248, 117, 4, 98, 212, 218, 5, 2, 54, 59, 93, 121, 176, 181, 134, 130, + 1, 61, 31, 0, 160, 255, 34, 1, 1, 58, 197, 166, 0, 177, 194, 2, + 162, 111, 34, 96, 205, 253, 32, 1, 1, 57, 123, 125, 119, 188, 150, 112, + 78, 4, 0, 75, 166, 180, 20, 38, 78, 1, 143, 246, 42, 113, 156, 37, + 252, 4, 1, 188, 175, 129, 1, 37, 118, 4, 88, 249, 202, 150, 145, 200, + 61, 59, 60, 60, 228, 252, 117, 77, 60, 58, 248, 251, 81, 212, 254, 107, + 198, 59, 58, 169, 250, 251, 81, 80, 100, 58, 154, 250, 251, 252, 252, 252 // clang-format on }; diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index 5d41dc4a7..012a16348 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -166,12 +166,12 @@ static chips_69000_t *reset_state = NULL; /* TODO: Probe timings on real hardware. */ static video_timings_t timing_chips = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; -uint8_t chips_69000_readb_linear(uint32_t addr, void *p); -uint16_t chips_69000_readw_linear(uint32_t addr, void *p); -uint32_t chips_69000_readl_linear(uint32_t addr, void *p); -void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p); -void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p); -void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p); +uint8_t chips_69000_readb_linear(uint32_t addr, void *priv); +uint16_t chips_69000_readw_linear(uint32_t addr, void *priv); +uint32_t chips_69000_readl_linear(uint32_t addr, void *priv); +void chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *priv); +void chips_69000_writew_linear(uint32_t addr, uint16_t val, void *priv); +void chips_69000_writel_linear(uint32_t addr, uint32_t val, void *priv); /* Multimedia handling. */ uint8_t @@ -1643,9 +1643,9 @@ chips_69000_write_ext_reg(chips_69000_t* chips, uint8_t val) } void -chips_69000_out(uint16_t addr, uint8_t val, void *p) +chips_69000_out(uint16_t addr, uint8_t val, void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; svga_t *svga = &chips->svga; uint8_t old, index; @@ -1750,9 +1750,9 @@ chips_69000_out(uint16_t addr, uint8_t val, void *p) } uint8_t -chips_69000_in(uint16_t addr, void *p) +chips_69000_in(uint16_t addr, void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; svga_t *svga = &chips->svga; uint8_t temp = 0, index; @@ -1828,9 +1828,9 @@ chips_69000_in(uint16_t addr, void *p) } static uint8_t -chips_69000_pci_read(int func, int addr, void *p) +chips_69000_pci_read(UNUSED(int func), int addr, void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; { switch (addr) { @@ -1885,9 +1885,9 @@ chips_69000_pci_read(int func, int addr, void *p) } static void -chips_69000_pci_write(int func, int addr, uint8_t val, void *p) +chips_69000_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; { switch (addr) { @@ -2193,71 +2193,71 @@ chips_69000_writel_mmio(uint32_t addr, uint32_t val, chips_69000_t* chips) } uint8_t -chips_69000_readb_linear(uint32_t addr, void *p) +chips_69000_readb_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_readb_mmio(addr, chips); - return svga_readb_linear(addr & 0x1FFFFF, p); + return svga_readb_linear(addr & 0x1FFFFF, priv); } uint16_t -chips_69000_readw_linear(uint32_t addr, void *p) +chips_69000_readw_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x800000) { if (addr & 0x400000) return bswap16(chips_69000_readw_mmio(addr, chips)); - return bswap16(svga_readw_linear(addr & 0x1FFFFF, p)); + return bswap16(svga_readw_linear(addr & 0x1FFFFF, priv)); } if (addr & 0x400000) return chips_69000_readw_mmio(addr, chips); - return svga_readw_linear(addr & 0x1FFFFF, p); + return svga_readw_linear(addr & 0x1FFFFF, priv); } uint32_t -chips_69000_readl_linear(uint32_t addr, void *p) +chips_69000_readl_linear(uint32_t addr, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x800000) { if (addr & 0x400000) return bswap32(chips_69000_readl_mmio(addr, chips)); - return bswap32(svga_readl_linear(addr & 0x1FFFFF, p)); + return bswap32(svga_readl_linear(addr & 0x1FFFFF, priv)); } if (addr & 0x400000) return chips_69000_readl_mmio(addr, chips); - return svga_readl_linear(addr & 0x1FFFFF, p); + return svga_readl_linear(addr & 0x1FFFFF, priv); } void -chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *p) +chips_69000_writeb_linear(uint32_t addr, uint8_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x400000) return chips_69000_writeb_mmio(addr, val, chips); - svga_writeb_linear(addr & 0x1FFFFF, val, p); + svga_writeb_linear(addr & 0x1FFFFF, val, priv); } void -chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) +chips_69000_writew_linear(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x800000) @@ -2266,13 +2266,13 @@ chips_69000_writew_linear(uint32_t addr, uint16_t val, void *p) if (addr & 0x400000) return chips_69000_writew_mmio(addr, val, chips); - svga_writew_linear(addr & 0x1FFFFF, val, p); + svga_writew_linear(addr & 0x1FFFFF, val, priv); } void -chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) +chips_69000_writel_linear(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) p; + svga_t *svga = (svga_t *) priv; chips_69000_t *chips = (chips_69000_t *) svga->priv; if (addr & 0x800000) @@ -2281,7 +2281,7 @@ chips_69000_writel_linear(uint32_t addr, uint32_t val, void *p) if (addr & 0x400000) return chips_69000_writel_mmio(addr, val, chips); - svga_writel_linear(addr & 0x1FFFFF, val, p); + svga_writel_linear(addr & 0x1FFFFF, val, priv); } void @@ -2526,9 +2526,9 @@ chips_69000_available(void) } void -chips_69000_close(void *p) +chips_69000_close(void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; chips->quit = 1; // thread_set_event(chips->fifo_event); @@ -2544,17 +2544,17 @@ chips_69000_close(void *p) } void -chips_69000_speed_changed(void *p) +chips_69000_speed_changed(void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; svga_recalctimings(&chips->svga); } void -chips_69000_force_redraw(void *p) +chips_69000_force_redraw(void *priv) { - chips_69000_t *chips = (chips_69000_t *) p; + chips_69000_t *chips = (chips_69000_t *) priv; chips->svga.fullchange = chips->svga.monitor->mon_changeframecount; } @@ -2567,7 +2567,7 @@ const device_t chips_69000_device = { .init = chips_69000_init, .close = chips_69000_close, .reset = chips_69000_reset, - { .available = chips_69000_available }, + .available = chips_69000_available, .speed_changed = chips_69000_speed_changed, .force_redraw = chips_69000_force_redraw, .config = NULL @@ -2581,7 +2581,7 @@ const device_t chips_69000_onboard_device = { .init = chips_69000_init, .close = chips_69000_close, .reset = chips_69000_reset, - { .available = chips_69000_available }, + .available = chips_69000_available, .speed_changed = chips_69000_speed_changed, .force_redraw = chips_69000_force_redraw, .config = NULL diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index bf27a700a..73be7cd76 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.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/plat_fallthrough.h> @@ -248,6 +249,7 @@ typedef struct gd54xx_t { uint8_t status; uint8_t extensions; uint8_t crtcreg_mask; + uint8_t aperture_mask; uint8_t fc; /* Feature Connector */ @@ -270,9 +272,15 @@ typedef struct gd54xx_t { void *ddc; } gd54xx_t; -static video_timings_t timing_gd54xx_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; -static video_timings_t timing_gd54xx_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 8, .read_b = 10, .read_w = 10, .read_l = 20 }; -static video_timings_t timing_gd54xx_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 8, .read_b = 10, .read_w = 10, .read_l = 20 }; +static video_timings_t timing_gd54xx_isa = { .type = VIDEO_ISA, + .write_b = 3, .write_w = 3, .write_l = 6, + .read_b = 8, .read_w = 8, .read_l = 12 }; +static video_timings_t timing_gd54xx_vlb = { .type = VIDEO_BUS, + .write_b = 4, .write_w = 4, .write_l = 8, + .read_b = 10, .read_w = 10, .read_l = 20 }; +static video_timings_t timing_gd54xx_pci = { .type = VIDEO_PCI, .write_b = 4, + .write_w = 4, .write_l = 8, .read_b = 10, + .read_w = 10, .read_l = 20 }; static void gd543x_mmio_write(uint32_t addr, uint8_t val, void *priv); @@ -511,7 +519,8 @@ gd54xx_interrupt_enabled(gd54xx_t *gd54xx) static int gd54xx_vga_vsync_enabled(gd54xx_t *gd54xx) { - if (!(gd54xx->svga.crtc[0x11] & 0x20) && (gd54xx->svga.crtc[0x11] & 0x10) && gd54xx_interrupt_enabled(gd54xx)) + if (!(gd54xx->svga.crtc[0x11] & 0x20) && (gd54xx->svga.crtc[0x11] & 0x10) && + gd54xx_interrupt_enabled(gd54xx)) return 1; return 0; } @@ -572,7 +581,8 @@ gd54xx_overlay_draw(svga_t *svga, int displine) OVERLAY_SAMPLE(); - for (int x = 0; (x < gd54xx->overlay.region2size) && ((x + gd54xx->overlay.region1size) < svga->hdisp); x++) { + for (int x = 0; (x < gd54xx->overlay.region2size) && + ((x + gd54xx->overlay.region1size) < svga->hdisp); x++) { if (gd54xx->overlay.occlusion) { occl = 1; ckval = gd54xx->overlay.ck; @@ -614,8 +624,10 @@ gd54xx_update_overlay(gd54xx_t *gd54xx) int bpp = svga->bpp; svga->overlay.cur_ysize = gd54xx->overlay.wve - gd54xx->overlay.wvs + 1; - gd54xx->overlay.region1size = 32 * gd54xx->overlay.r1sz / bpp + (gd54xx->overlay.r1adjust * 8 / bpp); - gd54xx->overlay.region2size = 32 * gd54xx->overlay.r2sz / bpp + (gd54xx->overlay.r2adjust * 8 / bpp); + gd54xx->overlay.region1size = 32 * gd54xx->overlay.r1sz / bpp + + (gd54xx->overlay.r1adjust * 8 / bpp); + gd54xx->overlay.region2size = 32 * gd54xx->overlay.r2sz / bpp + + (gd54xx->overlay.r2adjust * 8 / bpp); gd54xx->overlay.occlusion = (svga->crtc[0x3e] & 0x80) != 0 && svga->bpp <= 16; @@ -623,7 +635,8 @@ gd54xx_update_overlay(gd54xx_t *gd54xx) if (gd54xx->overlay.colorkeymode == 0) gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare; else if (gd54xx->overlay.colorkeymode == 1) - gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare | (gd54xx->overlay.colorkeycomparemask << 8); + gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare | + (gd54xx->overlay.colorkeycomparemask << 8); else gd54xx->overlay.occlusion = 0; } @@ -632,7 +645,8 @@ gd54xx_update_overlay(gd54xx_t *gd54xx) static int gd54xx_has_transp(svga_t *svga, int mask) { - if (((svga->crtc[0x27] == CIRRUS_ID_CLGD5446) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5480)) && !mask) + if (((svga->crtc[0x27] == CIRRUS_ID_CLGD5446) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5480)) && + !mask) return 1; /* 5446 and 5480 have mask but not transparency. */ if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5426) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5428)) return 1; /* 5426 and 5428 have both. */ @@ -698,12 +712,17 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { for (uint8_t c = 0; c < 16; c++) { if (svga->attrregs[0x10] & 0x80) - svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + svga->egapal[c] = (svga->attrregs[c] & 0xf) | + ((svga->attrregs[0x14] & 0xf) << 4); else - svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + svga->egapal[c] = (svga->attrregs[c] & 0x3f) | + ((svga->attrregs[0x14] & 0xc) << 4); } } - /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ + /* + Recalculate timings on change of attribute register + 0x11 (overscan border color) too. + */ if (svga->attraddr == 0x10) { if (o != val) svga_recalctimings(svga); @@ -793,20 +812,28 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga_recalctimings(svga); svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) ? 64 : 32; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = + ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) && + (val & CIRRUS_CURSOR_LARGE)) ? 64 : 32; else svga->hwcursor.cur_xsize = 32; - if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) && + (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE)) + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + + ((svga->seqregs[0x13] & 0x3c) * 256)); else - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + + ((svga->seqregs[0x13] & 0x3f) * 256)); break; case 0x13: - if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3c) * 256)); + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) && + (svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE)) + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + + ((val & 0x3c) * 256)); else - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256)); + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + + ((val & 0x3f) * 256)); break; case 0x07: svga->packed_chain4 = svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA; @@ -868,7 +895,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) gd54xx->extpal[index].r = svga->dac_r; gd54xx->extpal[index].g = svga->dac_g; gd54xx->extpal[index].b = val; - gd54xx->extpallook[index] = makecol32(video_6to8[gd54xx->extpal[index].r & 0x3f], video_6to8[gd54xx->extpal[index].g & 0x3f], video_6to8[gd54xx->extpal[index].b & 0x3f]); + gd54xx->extpallook[index] = makecol32(video_6to8[gd54xx->extpal[index].r & 0x3f], + video_6to8[gd54xx->extpal[index].g & 0x3f], + video_6to8[gd54xx->extpal[index].b & 0x3f]); if (svga->ext_overscan && (index == 2)) { o32 = svga->overscan_color; svga->overscan_color = gd54xx->extpallook[2]; @@ -879,7 +908,9 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; svga->vgapal[index].b = val; - svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); + svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], + video_6to8[svga->vgapal[index].g & 0x3f], + video_6to8[svga->vgapal[index].b & 0x3f]); } svga->dac_addr = (svga->dac_addr + 1) & 255; svga->dac_pos = 0; @@ -894,7 +925,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->gdcaddr = val /* & 0x3f*/; return; case 0x3cf: - if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) + if (((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) && + (svga->gdcaddr > 0x1f)) return; o = svga->gdcreg[svga->gdcaddr]; @@ -940,7 +972,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) gd54xx_set_svga_fast(gd54xx); - if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || ((svga->gdcaddr == 6) && ((val ^ o) & 1))) + if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || + ((svga->gdcaddr == 6) && ((val ^ o) & 1))) svga_recalctimings(svga); } else { switch (svga->gdcaddr) { @@ -1101,7 +1134,10 @@ gd54xx_out(uint16_t addr, uint8_t val, void *priv) svga->crtcreg = val & gd54xx->crtcreg_mask; return; case 0x3d5: - if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && !gd54xx->unlocked) + if (!gd54xx->unlocked && + ((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || + (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || + (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27))) return; if ((svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) return; @@ -1216,7 +1252,8 @@ 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->crtc[8] & 0x60) >> 5); + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + + ((svga->crtc[8] & 0x60) >> 5); } else { svga->fullchange = changeframecount; svga_recalctimings(svga); @@ -1282,7 +1319,8 @@ gd54xx_in(uint16_t addr, void *priv) ret |= 0x80; } break; - case 0x0a: /*Scratch Pad 1 (Memory size for 5402/542x)*/ + case 0x0a: + /* Scratch Pad 1 (Memory size for 5402/542x) */ ret = svga->seqregs[0x0a] & ~0x1a; if (svga->crtc[0x27] == CIRRUS_ID_CLGD5402) { ret |= 0x01; /*512K of memory*/ @@ -1309,17 +1347,21 @@ gd54xx_in(uint16_t addr, void *priv) case 0x0e: ret = gd54xx->vclk_n[svga->seqaddr - 0x0b]; break; - case 0x0f: /*DRAM control*/ + case 0x0f: /* DRAM control */ ret = svga->seqregs[0x0f] & ~0x98; switch (gd54xx->vram_size >> 10) { case 512: - ret |= 0x08; /*16-bit DRAM data bus width*/ + ret |= 0x08; /* 16-bit DRAM data bus width */ break; case 1024: - ret |= 0x10; /*32-bit DRAM data bus width for 1M of memory*/ + ret |= 0x10; /* 32-bit DRAM data bus width for 1M of memory */ break; case 2048: - ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18; /*32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width for 2M of memory*/ + /* + 32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width + for 2M of memory + */ + ret |= 0x18; break; case 4096: ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ @@ -1351,7 +1393,8 @@ gd54xx_in(uint16_t addr, void *priv) case 0x17: ret = svga->seqregs[0x17] & ~(7 << 3); if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || + (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { if (gd54xx->vlb) ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3); else if (gd54xx->mca) @@ -1452,7 +1495,9 @@ gd54xx_in(uint16_t addr, void *priv) if (svga->gdcaddr >= 0x10) { if ((svga->gdcaddr > 8) && !gd54xx->unlocked) ret = 0xff; - else if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) + else if (((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || + (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) && + (svga->gdcaddr > 0x1f)) ret = 0xff; else switch (svga->gdcaddr) { @@ -1582,7 +1627,10 @@ gd54xx_in(uint16_t addr, void *priv) break; case 0x3d5: ret = svga->crtc[svga->crtcreg]; - if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && !gd54xx->unlocked) + if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || + (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || + (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && + !gd54xx->unlocked) ret = 0xff; else switch (svga->crtcreg) { @@ -1600,7 +1648,8 @@ gd54xx_in(uint16_t addr, void *priv) ret = svga->crtc[0x27]; /*GD542x/GD543x*/ break; case 0x28: /*Class ID*/ - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || + (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) ret = 0xff; /*Standard CL-GD5430/40*/ break; @@ -1629,13 +1678,15 @@ gd54xx_recalc_banking(gd54xx_t *gd54xx) else svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } else { - if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424) && + (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K)) svga->extra_banks[0] = svga->gdcreg[0x09] << 14; else svga->extra_banks[0] = svga->gdcreg[0x09] << 12; if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { - if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424) && + (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K)) svga->extra_banks[1] = svga->gdcreg[0x0a] << 14; else svga->extra_banks[1] = svga->gdcreg[0x0a] << 12; @@ -1651,6 +1702,8 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) uint32_t base; uint32_t size; + gd54xx->aperture_mask = 0x00; + if (gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) { mem_mapping_disable(&svga->mapping); mem_mapping_disable(&gd54xx->linear_mapping); @@ -1660,7 +1713,8 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) gd54xx->mmio_vram_overlap = 0; - if (!gd54xx_is_5422(svga) || !(svga->seqregs[0x07] & 0xf0) || !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { + if (!gd54xx_is_5422(svga) || !(svga->seqregs[0x07] & 0xf0) || + !(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { mem_mapping_disable(&gd54xx->linear_mapping); mem_mapping_disable(&gd54xx->aperture2_mapping); switch (svga->gdcreg[6] & 0x0c) { @@ -1686,7 +1740,8 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) break; } - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) && (svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && + (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { if (gd54xx->mmio_vram_overlap) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); @@ -1722,19 +1777,28 @@ gd543x_recalc_mapping(gd54xx_t *gd54xx) size = 4 * 1024 * 1024; } + if (size >= (16 * 1024 * 1024)) + gd54xx->aperture_mask = 0x03; + mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && + (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) - mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ + /* MMIO is handled in the linear read/write functions */ + mem_mapping_disable(&gd54xx->mmio_mapping); else mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); } else mem_mapping_disable(&gd54xx->mmio_mapping); - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_APERTURE2) && ((gd54xx->blt.mode & (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC)) == (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC))) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && + (gd54xx->blt.status & CIRRUS_BLT_APERTURE2) && + ((gd54xx->blt.mode & (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC)) == + (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC))) { if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - mem_mapping_set_addr(&gd54xx->aperture2_mapping, gd54xx->lfb_base + 16777216, 16777216); + mem_mapping_set_addr(&gd54xx->aperture2_mapping, + gd54xx->lfb_base + 16777216, 16777216); else mem_mapping_set_addr(&gd54xx->aperture2_mapping, 0xbc000, 0x04000); } else @@ -1753,10 +1817,14 @@ gd54xx_recalctimings(svga_t *svga) svga->hblankstart = svga->crtc[2]; if (svga->crtc[0x1b] & ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5424) ? 0xa0 : 0x20)) { - /* Special blanking mode: the blank start and end become components of the window generator, - and the actual blanking comes from the display enable signal. */ - /* This means blanking during overscan, we already calculate it that way, so just use the - same calculation and force otvercan to 0. */ + /* + Special blanking mode: the blank start and end become components + of the window generator, and the actual blanking comes from the + display enable signal. + + This means blanking during overscan, we already calculate it that + way, so just use the same calculation and force otvercan to 0. + */ svga->hblank_end_val = (svga->crtc[3] & 0x1f) | ((svga->crtc[5] & 0x80) ? 0x20 : 0x00) | (((svga->crtc[0x1a] >> 4) & 3) << 6); @@ -1894,7 +1962,8 @@ gd54xx_recalctimings(svga_t *svga) break; case CIRRUS_SR7_BPP_16: - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || + (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { svga->bpp = 16; if (linedbl) svga->render = svga_render_16bpp_lowres; @@ -1946,7 +2015,8 @@ gd54xx_recalctimings(svga_t *svga) clocksel = (svga->miscout >> 2) & 3; if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) - svga->clock = (cpuclock * (float) (1ULL << 32)) / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); + svga->clock = (cpuclock * (float) (1ULL << 32)) / + ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); else { int n = gd54xx->vclk_n[clocksel] & 0x7f; int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; @@ -2111,10 +2181,10 @@ gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) } static uint8_t -gd54xx_get_aperture(uint32_t addr) +gd54xx_get_aperture(gd54xx_t *gd54xx, uint32_t addr) { uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); + return (uint8_t) (ap & gd54xx->aperture_mask); } static uint32_t @@ -2190,11 +2260,14 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } + xga_write_test(addr, val, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; svga_write_linear(addr, val, svga); @@ -2206,12 +2279,19 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + val = (val >> 8) | (val << 8); + gd54xx_write(addr, val, gd54xx); gd54xx_write(addr + 1, val >> 8, gd54xx); return; } + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2229,7 +2309,11 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + gd54xx_write(addr, val, gd54xx); gd54xx_write(addr + 1, val >> 8, gd54xx); gd54xx_write(addr + 2, val >> 16, gd54xx); @@ -2237,6 +2321,11 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) return; } + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + xga_write_test(addr + 2, val >> 16, svga); + xga_write_test(addr + 3, val >> 24, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2286,8 +2375,10 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) for (i = 0; i < 8; i++) { j = (0x80 >> i); if (svga->seqregs[2] & j) { - svga->vram[addr + (i << 1)] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + (i << 1) + 1] = (val & j) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + svga->vram[addr + (i << 1)] = (val & j) ? + svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + (i << 1) + 1] = (val & j) ? + svga->gdcreg[0x11] : svga->gdcreg[0x10]; } } } else { @@ -2332,19 +2423,24 @@ gd54xx_readb_linear(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); addr &= 0x003fffff; /* 4 MB mask */ if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_read_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && + (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) return gd543x_mmio_read(addr & 0x000000ff, gd54xx); } - /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + /* + Do mem sys dest reads here if the blitter is neither paused, + nor is there a second aperture. + */ + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, ap); switch (ap) { @@ -2373,7 +2469,7 @@ gd54xx_readw_linear(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint32_t old_addr = addr; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); uint16_t temp; addr &= 0x003fffff; /* 4 MB mask */ @@ -2388,8 +2484,12 @@ gd54xx_readw_linear(uint32_t addr, void *priv) } } - /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + /* + Do mem sys dest reads here if the blitter is neither paused, + nor is there a second aperture. + */ + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { temp = gd54xx_readb_linear(old_addr, priv); temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; return temp; @@ -2423,7 +2523,7 @@ gd54xx_readl_linear(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint32_t old_addr = addr; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); uint32_t temp; addr &= 0x003fffff; /* 4 MB mask */ @@ -2438,8 +2538,12 @@ gd54xx_readl_linear(uint32_t addr, void *priv) } } - /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + /* + Do mem sys dest reads here if the blitter is neither paused, + nor is there a second aperture. + */ + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { temp = gd54xx_readb_linear(old_addr, priv); temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; temp |= gd54xx_readb_linear(old_addr + 2, priv) << 16; @@ -2480,7 +2584,7 @@ static uint8_t gd5436_aperture2_readb(UNUSED(uint32_t addr), void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) @@ -2527,7 +2631,7 @@ static void gd5436_aperture2_writeb(UNUSED(uint32_t addr), uint8_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) @@ -2566,7 +2670,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_write_linear(addr, val, svga); @@ -2576,14 +2680,19 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) addr &= 0x003fffff; /* 4 MB mask */ if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && + (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); return; } } - /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + /* + Do mem sys src writes here if the blitter is neither paused, + nor is there a second aperture. + */ + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd54xx_mem_sys_src_write(gd54xx, val, ap); return; } @@ -2613,7 +2722,7 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint32_t old_addr = addr; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writew_linear(addr, val, svga); @@ -2623,14 +2732,19 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) addr &= 0x003fffff; /* 4 MB mask */ if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && + (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { gd543x_mmio_writew(addr & 0x000000ff, val, gd54xx); return; } } - /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + /* + Do mem sys src writes here if the blitter is neither paused, + nor is there a second aperture. + */ + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd54xx_writeb_linear(old_addr, val, gd54xx); gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); return; @@ -2680,7 +2794,7 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; uint32_t old_addr = addr; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(gd54xx, addr); if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writel_linear(addr, val, svga); @@ -2690,14 +2804,19 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) addr &= 0x003fffff; /* 4 MB mask */ if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && + (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { gd543x_mmio_writel(addr & 0x000000ff, val, gd54xx); return; } } - /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + /* + Do mem sys src writes here if the blitter is neither paused, + nor is there a second aperture. + */ + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd54xx_writeb_linear(old_addr, val, gd54xx); gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); gd54xx_writeb_linear(old_addr + 2, val >> 16, gd54xx); @@ -2759,9 +2878,12 @@ gd54xx_read(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, 0); + (void) xga_read_test(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); @@ -2774,12 +2896,16 @@ gd54xx_readw(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint16_t ret; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, priv); ret |= gd54xx_read(addr + 1, priv) << 8; return ret; } + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); @@ -2792,7 +2918,8 @@ gd54xx_readl(uint32_t addr, void *priv) svga_t *svga = &gd54xx->svga; uint32_t ret; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, priv); ret |= gd54xx_read(addr + 1, priv) << 8; ret |= gd54xx_read(addr + 2, priv) << 16; @@ -2800,6 +2927,11 @@ gd54xx_readl(uint32_t addr, void *priv) return ret; } + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + (void) xga_read_test(addr + 2, svga); + (void) xga_read_test(addr + 3, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); @@ -2913,7 +3045,9 @@ gd543x_mmio_write(uint32_t addr, uint8_t val, void *priv) else gd54xx->blt.dst_addr &= 0x1fffff; - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART) && !(gd54xx->blt.status & CIRRUS_BLT_BUSY)) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && + (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART) && + !(gd54xx->blt.status & CIRRUS_BLT_BUSY)) { gd54xx->blt.status |= CIRRUS_BLT_BUSY; gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); } @@ -2989,7 +3123,8 @@ gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && gd54xx->countminusone && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && gd54xx->countminusone && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } @@ -3007,7 +3142,8 @@ gd543x_mmio_writew(uint32_t addr, uint16_t val, void *priv) gd543x_mmio_write(addr, val & 0xff, gd54xx); gd543x_mmio_write(addr + 1, val >> 8, gd54xx); } else if (gd54xx->mmio_vram_overlap) { - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd543x_mmio_write(addr, val & 0xff, gd54xx); gd543x_mmio_write(addr + 1, val >> 8, gd54xx); } else { @@ -3029,7 +3165,8 @@ gd543x_mmio_writel(uint32_t addr, uint32_t val, void *priv) gd543x_mmio_write(addr + 2, val >> 16, gd54xx); gd543x_mmio_write(addr + 3, val >> 24, gd54xx); } else if (gd54xx->mmio_vram_overlap) { - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd543x_mmio_write(addr, val & 0xff, gd54xx); gd543x_mmio_write(addr + 1, val >> 8, gd54xx); gd543x_mmio_write(addr + 2, val >> 16, gd54xx); @@ -3178,9 +3315,9 @@ gd543x_mmio_read(uint32_t addr, void *priv) } } else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx); - else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) ret = gd54xx_mem_sys_dest_read(gd54xx, 0); - } return ret; } @@ -3196,7 +3333,8 @@ gd543x_mmio_readw(uint32_t addr, void *priv) ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr + 1, gd54xx) << 8); else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8); - else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd543x_mmio_read(addr, priv); ret |= gd543x_mmio_read(addr + 1, priv) << 8; return ret; @@ -3213,10 +3351,14 @@ gd543x_mmio_readl(uint32_t addr, void *priv) uint32_t ret = 0xffffffff; if (gd543x_do_mmio(svga, addr)) - ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr + 1, gd54xx) << 8) | (gd543x_mmio_read(addr + 2, gd54xx) << 16) | (gd543x_mmio_read(addr + 3, gd54xx) << 24); + ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr + 1, gd54xx) << 8) | + (gd543x_mmio_read(addr + 2, gd54xx) << 16) | + (gd543x_mmio_read(addr + 3, gd54xx) << 24); else if (gd54xx->mmio_vram_overlap) - ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8) | (gd54xx_read(addr + 2, gd54xx) << 16) | (gd54xx_read(addr + 3, gd54xx) << 24); - else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8) | + (gd54xx_read(addr + 2, gd54xx) << 16) | (gd54xx_read(addr + 3, gd54xx) << 24); + else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd543x_mmio_read(addr, priv); ret |= gd543x_mmio_read(addr + 1, priv) << 8; ret |= gd543x_mmio_read(addr + 2, priv) << 16; @@ -3358,20 +3500,25 @@ gd54xx_blit(gd54xx_t *gd54xx, uint8_t mask, uint8_t *dst, uint8_t target, int sk int is_transp; int is_bgonly; - /* skip indicates whether or not it is a pixel to be skipped (used for left skip); + /* + skip indicates whether or not it is a pixel to be skipped (used for left skip); mask indicates transparency or not (only when transparent comparison is enabled): - color expand: direct pattern bit; 1 = write, 0 = do not write - (the other way around in inverse mode); - normal 8-bpp or 16-bpp: does not match transparent color = write, - matches transparent color = do not write */ + color expand: direct pattern bit; 1 = write, 0 = do not write + (the other way around in inverse mode); + normal 8-bpp or 16-bpp: does not match transparent color = write, + matches transparent color = do not write + */ /* Make sure to always ignore transparency and skip in case of mem sys dest. */ - is_transp = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : (gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP); - is_bgonly = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_BACKGROUNDONLY); + is_transp = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? + 0 : (gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP); + is_bgonly = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? + 0 : (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_BACKGROUNDONLY); skip = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : skip; if (is_transp) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) mask = !mask; /* If mask is 1 and it is not a pixel to be skipped, write it. */ @@ -3510,9 +3657,9 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) gd54xx->countminusone = 1; gd54xx->blt.sys_src32 = 0x00000000; gd54xx->blt.sys_cnt = 0; - return; } else if (gd54xx->countminusone) { - if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) || (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) || + (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { if (!gd54xx->blt.xx_count && !gd54xx->blt.x_count) byte_pos = (((gd54xx->blt.mask >> 5) & 3) << 3); else @@ -3536,7 +3683,8 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) target = *dst; gd54xx_rop(gd54xx, &target, &target, &exp); if ((gd54xx->blt.pixel_width == 3) && (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) - gd54xx_blit(gd54xx, bitmask, dst, target, ((gd54xx->blt.x_count + gd54xx->blt.xx_count) < gd54xx->blt.pattern_x)); + gd54xx_blit(gd54xx, bitmask, dst, target, + ((gd54xx->blt.x_count + gd54xx->blt.xx_count) < gd54xx->blt.pattern_x)); else gd54xx_blit(gd54xx, bitmask, dst, target, (gd54xx->blt.x_count < gd54xx->blt.pattern_x)); @@ -3564,13 +3712,14 @@ gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) if (!gd54xx->blt.x_count) { gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) % (gd54xx->blt.height + 1); if (gd54xx->blt.y_count) - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); - else { + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + + (gd54xx->blt.dst_pitch * gd54xx->blt.y_count * + gd54xx->blt.dir); + else /* If we're here, the blit is over, reset. */ gd54xx_reset_blit(gd54xx); - } /* Stop blitting and request new data if end of line reached. */ - return; + break; } } } @@ -3621,12 +3770,15 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) mask = !mask; /* This handles 8bpp and 16bpp non-color-expanding transparent comparisons. */ - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) <= CIRRUS_BLTMODE_PIXELWIDTH16) && (src != ((gd54xx->blt.trans_mask >> (shift << 3)) & 0xff))) + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && + !(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) <= CIRRUS_BLTMODE_PIXELWIDTH16) && + (src != ((gd54xx->blt.trans_mask >> (shift << 3)) & 0xff))) mask = 0; - if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) { + if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && + !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) svga->vram[dst_addr & gd54xx->vram_mask] = dst; - } dst_addr += gd54xx->blt.dir; gd54xx->blt.x_count++; @@ -3640,14 +3792,16 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) width--; if (width == 0xffff) { width = gd54xx->blt.width; - dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + (gd54xx->blt.dst_pitch * gd54xx->blt.dir); + dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + + (gd54xx->blt.dst_pitch * gd54xx->blt.dir); gd54xx->blt.y_count = (gd54xx->blt.y_count + gd54xx->blt.dir) & 7; if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { if (gd54xx->blt.x_count != 0) src_addr++; } else - src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + (gd54xx->blt.src_pitch * gd54xx->blt.dir); + src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + + (gd54xx->blt.src_pitch * gd54xx->blt.dir); dst_addr &= gd54xx->vram_mask; gd54xx->blt.dst_addr_backup &= gd54xx->vram_mask; @@ -3658,8 +3812,7 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.height_internal--; if (gd54xx->blt.height_internal == 0xffff) { - gd54xx_reset_blit(gd54xx); - return; + break; } } } @@ -3693,7 +3846,8 @@ gd54xx_mem_sys_dest(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.msd_buf_pos = 0; while (gd54xx->blt.msd_buf_pos < 32) { - gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & gd54xx->vram_mask]; + gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & + gd54xx->vram_mask]; gd54xx->blt.src_addr_backup += gd54xx->blt.dir; gd54xx->blt.msd_buf_pos++; @@ -3703,17 +3857,21 @@ gd54xx_mem_sys_dest(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) % (gd54xx->blt.height + 1); if (gd54xx->blt.y_count) - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr + (gd54xx->blt.src_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); + gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr + + (gd54xx->blt.src_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); else gd54xx->countminusone = 2; /* Signal end of blit. */ /* End of line reached, stop and notify regardless of how much we already transferred. */ - goto request_more_data; + break; } } - /* End of while. */ -request_more_data: - /* If the byte count we have blitted are not divisible by 4, round them up. */ + /* + End of while. + + If the byte count we have blitted are not divisible by 4, + round them up. + */ if (gd54xx->blt.msd_buf_pos & 3) gd54xx->blt.msd_buf_cnt = (gd54xx->blt.msd_buf_pos & ~3) + 4; else @@ -3726,7 +3884,9 @@ request_more_data: static void gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *svga) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) && !(gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) && !(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP)) + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) && + !(gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) && + !(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP)) gd54xx->blt.dir = -1; else gd54xx->blt.dir = 1; @@ -3737,7 +3897,8 @@ gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *sv if (gd54xx->blt.pixel_width == 3) gd54xx->blt.pattern_x = gd54xx->blt.mask & 0x1f; /* (Mask & 0x1f) bytes. */ else - gd54xx->blt.pattern_x = (gd54xx->blt.mask & 0x07) * gd54xx->blt.pixel_width; /* (Mask & 0x07) pixels. */ + /* (Mask & 0x07) pixels. */ + gd54xx->blt.pattern_x = (gd54xx->blt.mask & 0x07) * gd54xx->blt.pixel_width; } else gd54xx->blt.pattern_x = 0; /* No skip in normal blit mode. */ @@ -3777,7 +3938,8 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) break; case PCI_REG_COMMAND: - ret = gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + /* Respond to IO and memory accesses */ + ret = gd54xx->pci_regs[PCI_REG_COMMAND]; break; case 0x07: @@ -3826,6 +3988,16 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 24) & 0xff) : 0x00; break; + case 0x2c: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? gd54xx->bios_rom.rom[0x7ffc] : 0x00; + break; + case 0x2d: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? gd54xx->bios_rom.rom[0x7ffd] : 0x00; + break; + case 0x2e: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? gd54xx->bios_rom.rom[0x7ffe] : 0x00; + break; + case 0x30: ret = (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ break; @@ -3881,8 +4053,10 @@ cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x13: - /* 5480, like 5446 rev. B, has a 32 MB aperture, with the second set used for - BitBLT transfers. */ + /* + 5480, like 5446 rev. B, has a 32 MB aperture, with the second set used for + BitBLT transfers. + */ if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) val &= 0xfe; gd54xx->lfb_base = val << 24; @@ -3900,7 +4074,8 @@ cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) val &= 0xf0; gd54xx->vgablt_base |= (val << byte); mem_mapping_disable(&gd54xx->vgablt_mapping); - if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->vgablt_base != 0x00000000) && (gd54xx->vgablt_base < 0xfff00000)) + if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && + (gd54xx->vgablt_base != 0x00000000) && (gd54xx->vgablt_base < 0xfff00000)) mem_mapping_set_addr(&gd54xx->vgablt_mapping, gd54xx->vgablt_base, 0x1000); break; @@ -4228,8 +4403,15 @@ gd54xx_init(const device_t *info) if ((vram == 1) || (vram >= 256 && vram <= 1024)) svga->decode_mask = gd54xx->vram_mask; + svga->read = gd54xx_read; + svga->readw = gd54xx_readw; + svga->write = gd54xx_write; + svga->writew = gd54xx_writew; if (gd54xx->bit32) { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); + svga->readl = gd54xx_readl; + svga->writel = gd54xx_writel; + mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, + gd54xx_write, gd54xx_writew, gd54xx_writel); mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, @@ -4247,7 +4429,10 @@ gd54xx_init(const device_t *info) gd5480_vgablt_write, gd5480_vgablt_writew, gd5480_vgablt_writel, NULL, MEM_MAPPING_EXTERNAL, gd54xx); } else { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, NULL, gd54xx_write, gd54xx_writew, NULL); + svga->readl = NULL; + svga->writel = NULL; + mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, NULL, + gd54xx_write, gd54xx_writew, NULL); mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, gd543x_mmio_readw, NULL, gd543x_mmio_writeb, gd543x_mmio_writew, NULL, @@ -4275,6 +4460,9 @@ gd54xx_init(const device_t *info) mem_mapping_disable(&gd54xx->bios_rom.mapping); } + if ((id <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) + mem_mapping_set_base_ignore(&gd54xx->linear_mapping, 0xff000000); + mem_mapping_set_p(&svga->mapping, gd54xx); mem_mapping_disable(&gd54xx->mmio_mapping); mem_mapping_disable(&gd54xx->linear_mapping); @@ -4513,218 +4701,158 @@ gd54xx_force_redraw(void *priv) // clang-format off static const device_config_t gd542x_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 512, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 512 }, + { .description = "1 MB", .value = 1024 }, + { .description = "" } }, - .default_int = 512 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5426_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "" - } + .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 = "" } }, - .default_int = 2048 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5428_onboard_config[] = { { - .name = "memory", - .description = "Onboard memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "" - } + .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 = "" } }, - .default_int = 2048 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5429_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5440_onboard_config[] = { { - .name = "memory", - .description = "Onboard memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5434_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } }, - .default_int = 4 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5434_onboard_config[] = { { - .name = "memory", - .description = "Onboard memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } }, - .default_int = 4 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t gd5480_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } }, - .default_int = 4 + .bios = { { 0 } } }, - { - .type = -1 - } + { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on @@ -4736,7 +4864,7 @@ const device_t gd5401_isa_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5401_available }, + .available = gd5401_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = NULL, @@ -4750,7 +4878,7 @@ const device_t gd5402_isa_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5402_available }, + .available = gd5402_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = NULL, @@ -4759,12 +4887,12 @@ const device_t gd5402_isa_device = { const device_t gd5402_onboard_device = { .name = "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2) (On-Board)", .internal_name = "cl_gd5402_onboard", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5402 | 0x200, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = NULL, @@ -4773,12 +4901,12 @@ const device_t gd5402_onboard_device = { const device_t gd5420_isa_device = { .name = "Cirrus Logic GD5420 (ISA)", .internal_name = "cl_gd5420_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5420, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5420_available }, + .available = gd5420_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd542x_config, @@ -4787,12 +4915,12 @@ const device_t gd5420_isa_device = { const device_t gd5422_isa_device = { .name = "Cirrus Logic GD5422 (ISA)", .internal_name = "cl_gd5422_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5422, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5422_available }, /* Common BIOS between 5422 and 5424 */ + .available = gd5422_available, /* Common BIOS between 5422 and 5424 */ .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd542x_config, @@ -4806,7 +4934,7 @@ const device_t gd5424_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5422_available }, /* Common BIOS between 5422 and 5424 */ + .available = gd5422_available, /* Common BIOS between 5422 and 5424 */ .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd542x_config, @@ -4815,12 +4943,12 @@ const device_t gd5424_vlb_device = { const device_t gd5426_isa_device = { .name = "Cirrus Logic GD5426 (ISA)", .internal_name = "cl_gd5426_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5426, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_isa_available }, + .available = gd5428_isa_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4830,12 +4958,12 @@ const device_t gd5426_isa_device = { const device_t gd5426_diamond_speedstar_pro_a1_isa_device = { .name = "Cirrus Logic GD5426 (ISA) (Diamond SpeedStar Pro Rev. A1)", .internal_name = "cl_gd5426_diamond_a1_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5426 | 0x100, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5426_diamond_a1_available }, + .available = gd5426_diamond_a1_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4849,7 +4977,7 @@ const device_t gd5426_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_available }, + .available = gd5428_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4863,7 +4991,7 @@ const device_t gd5426_onboard_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = NULL @@ -4872,12 +5000,12 @@ const device_t gd5426_onboard_device = { const device_t gd5428_isa_device = { .name = "Cirrus Logic GD5428 (ISA)", .internal_name = "cl_gd5428_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5428, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_isa_available }, + .available = gd5428_isa_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4891,7 +5019,7 @@ const device_t gd5428_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_available }, + .available = gd5428_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4906,7 +5034,7 @@ const device_t gd5428_diamond_speedstar_pro_b1_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_diamond_b1_available }, + .available = gd5428_diamond_b1_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4915,12 +5043,12 @@ const device_t gd5428_diamond_speedstar_pro_b1_vlb_device = { const device_t gd5428_boca_isa_device = { .name = "Cirrus Logic GD5428 (ISA) (BOCA Research 4610)", .internal_name = "cl_gd5428_boca_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5428 | 0x100, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_boca_isa_available }, + .available = gd5428_boca_isa_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4934,7 +5062,7 @@ const device_t gd5428_mca_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_mca_available }, + .available = gd5428_mca_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = NULL @@ -4948,7 +5076,7 @@ const device_t gd5426_mca_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5426_mca_available }, + .available = gd5426_mca_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5426_config @@ -4957,12 +5085,12 @@ const device_t gd5426_mca_device = { const device_t gd5428_onboard_device = { .name = "Cirrus Logic GD5428 (ISA) (On-Board)", .internal_name = "cl_gd5428_onboard", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5428, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5428_isa_available }, + .available = gd5428_isa_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5428_onboard_config @@ -4976,7 +5104,7 @@ const device_t gd5428_vlb_onboard_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5428_onboard_config @@ -4985,12 +5113,12 @@ const device_t gd5428_vlb_onboard_device = { const device_t gd5429_isa_device = { .name = "Cirrus Logic GD5429 (ISA)", .internal_name = "cl_gd5429_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5429, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5429_available }, + .available = gd5429_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5004,7 +5132,7 @@ const device_t gd5429_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5429_available }, + .available = gd5429_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5019,7 +5147,7 @@ const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5430_diamond_a8_available }, + .available = gd5430_diamond_a8_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5033,7 +5161,7 @@ const device_t gd5430_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5430_orchid_vlb_available }, + .available = gd5430_orchid_vlb_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5047,7 +5175,7 @@ const device_t gd5430_onboard_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5061,7 +5189,7 @@ const device_t gd5430_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5430_available }, + .available = gd5430_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5075,7 +5203,7 @@ const device_t gd5430_onboard_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5084,12 +5212,12 @@ const device_t gd5430_onboard_pci_device = { const device_t gd5434_isa_device = { .name = "Cirrus Logic GD5434 (ISA)", .internal_name = "cl_gd5434_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5434, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5434_isa_available }, + .available = gd5434_isa_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5099,12 +5227,12 @@ const device_t gd5434_isa_device = { const device_t gd5434_diamond_speedstar_64_a3_isa_device = { .name = "Cirrus Logic GD5434 (ISA) (Diamond SpeedStar 64 Rev. A3)", .internal_name = "cl_gd5434_diamond_a3_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = CIRRUS_ID_CLGD5434 | 0x100, .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5434_diamond_a3_available }, + .available = gd5434_diamond_a3_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5118,7 +5246,7 @@ const device_t gd5434_onboard_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_onboard_config @@ -5132,7 +5260,7 @@ const device_t gd5434_vlb_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5430_orchid_vlb_available }, + .available = gd5430_orchid_vlb_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5146,7 +5274,7 @@ const device_t gd5434_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5434_available }, + .available = gd5434_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5160,7 +5288,7 @@ const device_t gd5436_onboard_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5174,7 +5302,7 @@ const device_t gd5436_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5436_available }, + .available = gd5436_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5188,7 +5316,7 @@ const device_t gd5440_onboard_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = NULL }, + .available = NULL, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5440_onboard_config @@ -5202,7 +5330,7 @@ const device_t gd5440_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5440_available }, + .available = gd5440_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5429_config @@ -5216,7 +5344,7 @@ const device_t gd5446_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5446_available }, + .available = gd5446_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5230,7 +5358,7 @@ const device_t gd5446_stb_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5446_stb_available }, + .available = gd5446_stb_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5434_config @@ -5244,7 +5372,7 @@ const device_t gd5480_pci_device = { .init = gd54xx_init, .close = gd54xx_close, .reset = gd54xx_reset, - { .available = gd5480_available }, + .available = gd5480_available, .speed_changed = gd54xx_speed_changed, .force_redraw = gd54xx_force_redraw, .config = gd5480_config diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index dcc72a76b..6c66175c1 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -14,7 +14,7 @@ * Miran Grca, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -357,7 +357,7 @@ 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_init(0x3BC); + lpt3_setup(LPT_MDA_ADDR); return colorplus; } @@ -382,52 +382,47 @@ colorplus_speed_changed(void *priv) static const device_config_t colorplus_config[] = { // clang-format off { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_int = CGA_RGB, - .selection = { - { - .description = "RGB", - .value = CGA_RGB - }, - { - .description = "Composite", - .value = CGA_COMPOSITE - }, - { - .description = "" - } - } + .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_int = COMPOSITE_OLD, - .selection = { - { - .description = "Old", - .value = COMPOSITE_OLD - }, - { - .description = "New", - .value = COMPOSITE_NEW - }, - { - .description = "" - } - } + .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 = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "snow_enabled", + .description = "Snow emulation", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -439,7 +434,7 @@ const device_t colorplus_device = { .init = colorplus_standalone_init, .close = colorplus_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = colorplus_speed_changed, .force_redraw = NULL, .config = colorplus_config diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 430c7a64d..13fc399eb 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -481,7 +481,7 @@ const device_t compaq_cga_device = { .init = compaq_cga_init, .close = compaq_cga_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = compaq_cga_speed_changed, .force_redraw = NULL, .config = cga_config @@ -495,7 +495,7 @@ const device_t compaq_cga_2_device = { .init = compaq_cga_init, .close = compaq_cga_close, .reset = NULL, - { .available = 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 a472f2e57..10df85c79 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -156,7 +156,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) if (!(val & 1)) io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); ega_recalctimings(ega); - if ((ega_type == 2) && !(val & 0x02)) + if ((ega_type == EGA_TYPE_COMPAQ) && !(val & 0x02)) mem_mapping_disable(&ega->mapping); else switch (ega->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ @@ -227,7 +227,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->chain2_read = val & 0x10; break; case 6: - if ((ega_type == 2) && !(ega->miscout & 0x02)) + if ((ega_type == EGA_TYPE_COMPAQ) && !(ega->miscout & 0x02)) mem_mapping_disable(&ega->mapping); else switch (val & 0xc) { case 0x0: /*128k at A0000*/ @@ -615,7 +615,7 @@ ega_recalctimings(ega_t *ega) if (ega->dispofftime < TIMER_USEC) ega->dispofftime = TIMER_USEC; - if (ega_type == 2) { + if (ega_type == EGA_TYPE_COMPAQ) { ega->dot_time = (uint64_t) (ega->dot_clock); if (ega->dot_time < TIMER_USEC) ega->dot_time = TIMER_USEC; @@ -1313,7 +1313,7 @@ ega_read(uint32_t addr, void *priv) return ~(temp | temp2 | temp3 | temp4); } - if ((ega_type == 2) && (ega->gdcreg[4] & 0x04)) + if ((ega_type == EGA_TYPE_COMPAQ) && (ega->gdcreg[4] & 0x04)) return 0xff; return ega->vram[addr | readplane]; @@ -1504,7 +1504,7 @@ ega_standalone_init(const device_t *info) ega->vrammask = ega->vram_limit - 1; mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); - if (ega_type == 2) + if (ega_type == EGA_TYPE_COMPAQ) mem_mapping_disable(&ega->mapping); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1590,74 +1590,43 @@ ega_speed_changed(void *priv) static const device_config_t ega_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 256, - .selection = { - { - .description = "32 kB", - .value = 32 - }, - { - .description = "64 kB", - .value = 64 - }, - { - .description = "128 kB", - .value = 128 - }, - { - .description = "256 kB", - .value = 256 - }, - { - .description = "" - } - } - }, - { - .name = "monitor_type", - .description = "Monitor type", - .type = CONFIG_SELECTION, - .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 = "" - } + .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 = "" } }, - .default_int = 9 + .bios = { { 0 } } }, { - .type = CONFIG_END - } + .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 } } + }, + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -1669,7 +1638,7 @@ const device_t ega_device = { .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = ega_standalone_available }, + .available = ega_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config @@ -1683,7 +1652,7 @@ const device_t cpqega_device = { .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = cpqega_standalone_available }, + .available = cpqega_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config @@ -1697,7 +1666,7 @@ const device_t sega_device = { .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = sega_standalone_available }, + .available = sega_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config @@ -1711,7 +1680,7 @@ const device_t atiega800p_device = { .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = atiega800p_standalone_available }, + .available = atiega800p_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config @@ -1725,7 +1694,7 @@ const device_t iskra_ega_device = { .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = iskra_ega_standalone_available }, + .available = iskra_ega_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config @@ -1739,7 +1708,7 @@ const device_t et2000_device = { .init = ega_standalone_init, .close = ega_close, .reset = NULL, - { .available = et2000_standalone_available }, + .available = et2000_standalone_available, .speed_changed = ega_speed_changed, .force_redraw = NULL, .config = ega_config diff --git a/src/video/vid_et3000.c b/src/video/vid_et3000.c index a7d2a749f..193fed3c7 100644 --- a/src/video/vid_et3000.c +++ b/src/video/vid_et3000.c @@ -548,17 +548,24 @@ et3000_available(void) } static const device_config_t et3000_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { .description = "256 KB", - .value = 256 }, - { .description = "512 KB", - .value = 512 }, - { .description = "" } } }, - { .type = CONFIG_END } + // clang-format 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 = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on }; const device_t et3000_isa_device = { @@ -569,7 +576,7 @@ const device_t et3000_isa_device = { .init = et3000_init, .close = et3000_close, .reset = NULL, - { .available = et3000_available }, + .available = et3000_available, .speed_changed = et3000_speed_changed, .force_redraw = et3000_force_redraw, .config = et3000_config diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index c223d37ba..064d79230 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -82,8 +82,8 @@ typedef struct { rom_t bios_rom; uint8_t banking; - uint32_t vram_size, - vram_mask; + uint32_t vram_size; + uint32_t vram_mask; uint8_t port_22cb_val; uint8_t port_32cb_val; @@ -125,15 +125,6 @@ et4000_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { - case 0x3c2: - if (dev->type == ET4000_TYPE_MCA) { - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) - return 0; - else - return 0x10; - } - break; - case 0x3c5: if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4; @@ -770,12 +761,16 @@ et4000_mca_write(int port, uint8_t val, void *priv) /* Save the MCA register value. */ et4000->pos_regs[port & 7] = val; + mem_mapping_disable(&et4000->bios_rom.mapping); + if (et4000->pos_regs[2] & 1) + mem_mapping_enable(&et4000->bios_rom.mapping); } static uint8_t et4000_mca_feedb(UNUSED(void *priv)) { - return 1; + et4000_t *et4000 = (et4000_t *) priv; + return et4000->pos_regs[2] & 1; } static void * @@ -889,7 +884,10 @@ et4000_init(const device_t *info) dev->vram_mask = dev->vram_size - 1; rom_init(&dev->bios_rom, fn, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + if (dev->type == ET4000_TYPE_MCA) + mem_mapping_disable(&dev->bios_rom.mapping); dev->svga.translate_address = get_et4000_addr; @@ -945,125 +943,128 @@ et4000_kasan_available(void) static const device_config_t et4000_tc6058af_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { + .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", + .type = CONFIG_BIOS, + .default_string = "v1_10", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { - .description = "256 KB", - .value = 256 + .name = "Version 1.10", + .internal_name = "v1_10", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { TC6058AF_BIOS_ROM_PATH, "" } }, { - .description = "512 KB", - .value = 512 + .name = "Version 1.21", + .internal_name = "v1_21", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { V1_21_BIOS_ROM_PATH, "" } }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } + { .files_no = 0 } } }, - { - .name = "bios_ver", - .description = "BIOS Version", - .type = CONFIG_BIOS, - .default_string = "v1_10", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .bios = { - { .name = "Version 1.10", .internal_name = "v1_10", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 32768, .files = { TC6058AF_BIOS_ROM_PATH, "" } }, - { .name = "Version 1.21", .internal_name = "v1_21", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 32768, .files = { V1_21_BIOS_ROM_PATH, "" } }, - { .files_no = 0 } - }, - }, - { - .type = CONFIG_END - } + { .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_int = 1024, - .selection = { + .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 = "bios_ver", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v8_01", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { - .description = "256 KB", - .value = 256 + .name = "Version 8.01", + .internal_name = "v8_01", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { BIOS_ROM_PATH, "" } }, { - .description = "512 KB", - .value = 512 + .name = "Version 8.06", + .internal_name = "v8_06", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { V8_06_BIOS_ROM_PATH, "" } }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } + { .files_no = 0 } } }, - { - .name = "bios_ver", - .description = "BIOS Version", - .type = CONFIG_BIOS, - .default_string = "v8_01", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, /*W1*/ - .bios = { - { .name = "Version 8.01", .internal_name = "v8_01", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 32768, .files = { BIOS_ROM_PATH, "" } }, - { .name = "Version 8.06", .internal_name = "v8_06", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 32768, .files = { V8_06_BIOS_ROM_PATH, "" } }, - { .files_no = 0 } - }, - }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_config_t et4000_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1024, - .selection = { - { - .description = "256 KB", - .value = 256 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -1075,7 +1076,7 @@ const device_t et4000_tc6058af_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_tc6058af_config @@ -1089,7 +1090,7 @@ const device_t et4000_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_bios_config @@ -1103,7 +1104,7 @@ const device_t et4000_mca_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000_available }, + .available = et4000_available, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_config @@ -1117,7 +1118,7 @@ const device_t et4000k_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000k_available }, + .available = et4000k_available, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_config @@ -1131,7 +1132,7 @@ const device_t et4000k_tg286_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000k_available }, + .available = et4000k_available, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_config @@ -1145,7 +1146,7 @@ const device_t et4000_kasan_isa_device = { .init = et4000_init, .close = et4000_close, .reset = NULL, - { .available = et4000_kasan_available }, + .available = et4000_kasan_available, .speed_changed = et4000_speed_changed, .force_redraw = et4000_force_redraw, .config = et4000_config diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 2f086f3c7..246decb9c 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2943,39 +2943,33 @@ et4000w32p_force_redraw(void *priv) static const device_config_t et4000w32p_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; const device_t et4000w32_device = { .name = "Tseng Labs ET4000/w32 ISA", .internal_name = "et4000w32", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = ET4000W32, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32_available }, + .available = et4000w32_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = NULL @@ -2984,12 +2978,12 @@ const device_t et4000w32_device = { const device_t et4000w32_onboard_device = { .name = "Tseng Labs ET4000/w32 (ISA) (On-Board)", .internal_name = "et4000w32_onboard", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = ET4000W32, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32_available }, + .available = et4000w32_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = NULL @@ -2998,12 +2992,12 @@ const device_t et4000w32_onboard_device = { const device_t et4000w32i_isa_device = { .name = "Tseng Labs ET4000/w32i Rev. B ISA", .internal_name = "et4000w32i", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = ET4000W32I, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32i_isa_available }, + .available = et4000w32i_isa_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = NULL @@ -3017,7 +3011,7 @@ const device_t et4000w32i_vlb_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32i_vlb_available }, + .available = et4000w32i_vlb_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3031,7 +3025,7 @@ const device_t et4000w32p_videomagic_revb_vlb_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_videomagic_revb_vlb_available }, + .available = et4000w32p_videomagic_revb_vlb_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3045,7 +3039,7 @@ const device_t et4000w32p_videomagic_revb_pci_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_videomagic_revb_vlb_available }, + .available = et4000w32p_videomagic_revb_vlb_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3059,7 +3053,7 @@ const device_t et4000w32p_revc_vlb_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_revc_available }, + .available = et4000w32p_revc_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3073,7 +3067,7 @@ const device_t et4000w32p_revc_pci_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_revc_available }, + .available = et4000w32p_revc_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3087,7 +3081,7 @@ const device_t et4000w32p_noncardex_vlb_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_noncardex_available }, + .available = et4000w32p_noncardex_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3101,7 +3095,7 @@ const device_t et4000w32p_noncardex_pci_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_noncardex_available }, + .available = et4000w32p_noncardex_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3115,7 +3109,7 @@ const device_t et4000w32p_cardex_vlb_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_cardex_available }, + .available = et4000w32p_cardex_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3129,7 +3123,7 @@ const device_t et4000w32p_cardex_pci_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_cardex_available }, + .available = et4000w32p_cardex_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3143,7 +3137,7 @@ const device_t et4000w32p_vlb_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_available }, + .available = et4000w32p_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config @@ -3157,7 +3151,7 @@ const device_t et4000w32p_pci_device = { .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - { .available = et4000w32p_available }, + .available = et4000w32p_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index 772926e1e..c607cda14 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -631,7 +631,7 @@ const device_t f82c425_video_device = { .init = f82c425_init, .close = f82c425_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = f82c425_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index 4ae8e6fd1..c7a91aac6 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -826,7 +826,7 @@ const device_t genius_device = { .init = genius_init, .close = genius_close, .reset = NULL, - { .available = genius_available }, + .available = genius_available, .speed_changed = genius_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 2a725488d..00374d08f 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -14,7 +14,7 @@ * Miran Grca, * * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -585,7 +585,7 @@ hercules_init(UNUSED(const device_t *info)) video_inform(VIDEO_FLAG_TYPE_MDA, &timing_hercules); /* Force the LPT3 port to be enabled. */ - lpt3_init(0x3BC); + lpt3_setup(LPT_MDA_ADDR); return dev; } @@ -615,41 +615,34 @@ speed_changed(void *priv) static const device_config_t hercules_config[] = { // clang-format off { - .name = "rgb_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "Default", - .value = 0 - }, - { - .description = "Green", - .value = 1 - }, - { - .description = "Amber", - .value = 2 - }, - { - .description = "Gray", - .value = 3 - }, - { - .description = "" - } - } + .name = "rgb_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .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 = "" } + }, + .bios = { { 0 } } }, { - .name = "blend", - .description = "Blend", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "blend", + .description = "Blend", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -661,7 +654,7 @@ const device_t hercules_device = { .init = hercules_init, .close = hercules_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = speed_changed, .force_redraw = NULL, .config = hercules_config diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 429632f19..fb42c3022 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -14,7 +14,7 @@ * Miran Grca, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -23,8 +23,8 @@ #include #include <86box/86box.h> #include <86box/io.h> -#include <86box/lpt.h> #include <86box/timer.h> +#include <86box/lpt.h> #include <86box/pit.h> #include <86box/mem.h> #include <86box/rom.h> @@ -670,7 +670,7 @@ herculesplus_init(UNUSED(const device_t *info)) video_inform(VIDEO_FLAG_TYPE_MDA, &timing_herculesplus); /* Force the LPT3 port to be enabled. */ - lpt3_init(0x3BC); + lpt3_setup(LPT_MDA_ADDR); return dev; } @@ -700,41 +700,34 @@ speed_changed(void *priv) static const device_config_t herculesplus_config[] = { // clang-format off { - .name = "rgb_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "Default", - .value = 0 - }, - { - .description = "Green", - .value = 1 - }, - { - .description = "Amber", - .value = 2 - }, - { - .description = "Gray", - .value = 3 - }, - { - .description = "" - } - } + .name = "rgb_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .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 = "" } + }, + .bios = { { 0 } } }, { - .name = "blend", - .description = "Blend", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "blend", + .description = "Blend", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -746,7 +739,7 @@ const device_t herculesplus_device = { .init = herculesplus_init, .close = herculesplus_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = speed_changed, .force_redraw = NULL, .config = herculesplus_config diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 213cf9ed4..57b0f303c 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -33,8 +33,12 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/vid_8514a.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_ati_eeprom.h> +#include <86box/vid_ati_mach8.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> @@ -424,9 +428,8 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) svga->banked_mask = 0xffff; } - if (svga->gdcaddr <= 8) { + if (svga->gdcaddr <= 8) svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4; - } break; case 0x3D4: @@ -624,7 +627,9 @@ ht216_remap(ht216_t *ht216) void ht216_recalctimings(svga_t *svga) { - ht216_t *ht216 = (ht216_t *) svga->priv; + ht216_t *ht216 = (ht216_t *) svga->priv; + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + mach_t *mach = (mach_t *) svga->ext8514; int high_res_256 = 0; @@ -671,10 +676,16 @@ ht216_recalctimings(svga_t *svga) if (!svga->scrblank && svga->attr_palette_enable) { if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) /*40 column*/ { + if (svga->seqregs[1] & 8) /*40 column*/ svga->render = svga_render_text_40; - } else { + else svga->render = svga_render_text_80; + + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (svga->ext8514 != NULL) { + if (!(dev->accel.advfunc_cntl & 0x01) && !(mach->accel.clock_sel & 0x01)) /*FIXME: Possibly a BIOS bug within the V7 chips when it's used with a 8514/A card?*/ + dev->on &= ~0x01; + } } } else { if (svga->crtc[0x17] == 0xeb) { @@ -1217,6 +1228,8 @@ ht216_write(uint32_t addr, uint8_t val, void *priv) svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + xga_write_test(addr, val, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; @@ -1238,6 +1251,9 @@ ht216_writew(uint32_t addr, uint16_t val, void *priv) svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; @@ -1261,6 +1277,11 @@ ht216_writel(uint32_t addr, uint32_t val, void *priv) svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + xga_write_test(addr + 2, val >> 16, svga); + xga_write_test(addr + 3, val >> 24, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; @@ -1422,9 +1443,11 @@ static uint8_t ht216_read(uint32_t addr, void *priv) { ht216_t *ht216 = (ht216_t *) priv; - const svga_t *svga = &ht216->svga; + svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + (void) xga_read_test(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->read_banks[(addr >> 15) & 1]; @@ -1563,10 +1586,17 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) if (has_rom == 4) svga->ramdac = device_add(&sc11484_nors2_ramdac_device); + svga->read = ht216_read; + svga->readw = NULL; + svga->readl = NULL; + svga->write = ht216_write; + svga->writew = ht216_writew; if ((info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) { + svga->writel = ht216_writel; mem_mapping_set_handler(&svga->mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, ht216_writel); mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); } else { + svga->writel = NULL; mem_mapping_set_handler(&svga->mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, NULL); mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, NULL, NULL, MEM_MAPPING_EXTERNAL, svga); } @@ -1688,52 +1718,45 @@ ht216_force_redraw(void *priv) ht216->svga.fullchange = changeframecount; } +// clang-format off static const device_config_t v7_vga_1024i_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { .description = "256 kB", - .value = 256 }, - { .description = "512 kB", - .value = 512 }, - { .description = "" } } }, - { .type = CONFIG_END } + { + .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 = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; -// clang-format off static const device_config_t ht216_32_standalone_config[] = { { - .name = "monitor_type", - .description = "Monitor type", - .type = CONFIG_SELECTION, - .default_int = 0x18, - .selection = { - { - .description = "Mono Interlaced", - .value = 0x00 - }, - { - .description = "Mono Non-Interlaced", - .value = 0x08 - }, - { - .description = "Color Interlaced", - .value = 0x10 - }, - { - .description = "Color Non-Interlaced", - .value = 0x18 - }, - { - .description = "" - } - } + .name = "monitor_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0x18, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Mono Interlaced", .value = 0x00 }, + { .description = "Mono Non-Interlaced", .value = 0x08 }, + { .description = "Color Interlaced", .value = 0x10 }, + { .description = "Color Non-Interlaced", .value = 0x18 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on @@ -1745,7 +1768,7 @@ const device_t g2_gc205_device = { .init = g2_gc205_init, .close = ht216_close, .reset = NULL, - { .available = g2_gc205_available }, + .available = g2_gc205_available, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, .config = NULL @@ -1759,7 +1782,7 @@ const device_t v7_vga_1024i_device = { .init = v7_vga_1024i_init, .close = ht216_close, .reset = NULL, - { .available = v7_vga_1024i_available }, + .available = v7_vga_1024i_available, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, .config = v7_vga_1024i_config @@ -1773,7 +1796,7 @@ const device_t ht216_32_pb410a_device = { .init = ht216_pb410a_init, .close = ht216_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, .config = NULL @@ -1787,7 +1810,7 @@ const device_t ht216_32_standalone_device = { .init = ht216_standalone_init, .close = ht216_close, .reset = NULL, - { .available = ht216_standalone_available }, + .available = ht216_standalone_available, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, .config = ht216_32_standalone_config @@ -1796,12 +1819,12 @@ const device_t ht216_32_standalone_device = { const device_t radius_svga_multiview_isa_device = { .name = "Radius SVGA Multiview ISA (HT209)", .internal_name = "radius_isa", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0x7152, /*HT209*/ .init = radius_svga_multiview_init, .close = ht216_close, .reset = NULL, - { .available = radius_svga_multiview_available }, + .available = radius_svga_multiview_available, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, .config = NULL @@ -1815,7 +1838,7 @@ const device_t radius_svga_multiview_mca_device = { .init = radius_svga_multiview_init, .close = ht216_close, .reset = NULL, - { .available = radius_svga_multiview_available }, + .available = radius_svga_multiview_available, .speed_changed = ht216_speed_changed, .force_redraw = ht216_force_redraw, .config = NULL diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index 1b19a3a0f..dcdbbb25b 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -982,7 +982,7 @@ const device_t ibm_rgb528_ramdac_device = { .init = ibm_rgb528_ramdac_init, .close = ibm_rgb528_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 4c23d6ec5..7b80a5484 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -179,7 +179,7 @@ const device_t icd2061_device = { .init = icd2061_init, .close = icd2061_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -193,7 +193,7 @@ const device_t ics9161_device = { .init = icd2061_init, .close = icd2061_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index e85b4539e..350a490cc 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -168,7 +168,7 @@ const device_t ics2494an_305_device = { .init = ics2494_init, .close = ics2494_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -182,7 +182,7 @@ const device_t ati18810_device = { .init = ics2494_init, .close = ics2494_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -196,7 +196,7 @@ const device_t ati18811_0_device = { .init = ics2494_init, .close = ics2494_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -210,7 +210,7 @@ const device_t ati18811_1_device = { .init = ics2494_init, .close = ics2494_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index ecb414f2b..b5da3d7e2 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -129,7 +129,7 @@ const device_t ics2595_device = { .init = ics2595_init, .close = ics2595_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index c7602ffd0..a77ad09c3 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -1090,7 +1090,7 @@ const device_t im1024_device = { .init = im1024_init, .close = im1024_close, .reset = NULL, - { .available = im1024_available }, + .available = im1024_available, .speed_changed = im1024_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index e3f37ec65..d9b48f43a 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -14,7 +14,7 @@ * Miran Grca, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -1018,7 +1018,7 @@ incolor_init(UNUSED(const device_t *info)) video_inform(VIDEO_FLAG_TYPE_MDA, &timing_incolor); /* Force the LPT3 port to be enabled. */ - lpt3_init(0x3BC); + lpt3_setup(LPT_MDA_ADDR); return dev; } @@ -1053,7 +1053,7 @@ const device_t incolor_device = { .init = incolor_init, .close = incolor_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 702fb7e32..66a0fbb71 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -14,7 +14,7 @@ * Miran Grca, * * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. + * Copyright 2016-2025 Miran Grca. */ #include #include @@ -322,7 +322,7 @@ mda_standalone_init(UNUSED(const device_t *info)) mda_init(mda); - lpt3_init(0x3BC); + lpt3_setup(LPT_MDA_ADDR); return mda; } @@ -353,35 +353,23 @@ mda_speed_changed(void *priv) static const device_config_t mda_config[] = { // clang-format off { - .name = "rgb_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "Default", - .value = 0 - }, - { - .description = "Green", - .value = 1 - }, - { - .description = "Amber", - .value = 2 - }, - { - .description = "Gray", - .value = 3 - }, - { - .description = "" - } - } + .name = "rgb_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .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 = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -393,7 +381,7 @@ const device_t mda_device = { .init = mda_standalone_init, .close = mda_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = mda_speed_changed, .force_redraw = NULL, .config = mda_config diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 1bdbecdf6..3937c2a7d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -427,8 +427,7 @@ enum { DMA_STATE_SEC }; -typedef struct -{ +typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; @@ -484,13 +483,11 @@ typedef struct mystique_t { event_t *wake_fifo_thread, *fifo_not_full_event; - struct - { + struct { int m, n, p, s; } xpixpll[3]; - struct - { + struct { uint8_t funcnt : 7, stylelen, dmamod; @@ -521,27 +518,23 @@ typedef struct mystique_t { uint64_t extended_dr[4]; - struct - { + struct { int sdydxl, scanleft, sdxl, sdy, sdxr; } sgn; } dwgreg; - struct - { + struct { uint8_t r, g, b; } lut[256]; - struct - { + struct { uint16_t pos_x, pos_y, addr; uint32_t col[3]; } cursor; - struct - { + struct { atomic_int pri_state, sec_state, iload_state, state; atomic_uint primaddress, primend, secaddress, secend, @@ -5558,6 +5551,7 @@ blit_bitblt(mystique_t *mystique) mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; src_addr = mystique->dwgreg.ar[3]; + break; } else src_addr += x_dir; @@ -5670,6 +5664,7 @@ blit_bitblt(mystique_t *mystique) mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; src_addr = mystique->dwgreg.ar[3]; + break; } else src_addr += x_dir; @@ -5756,6 +5751,7 @@ blit_bitblt(mystique_t *mystique) mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; src_addr = mystique->dwgreg.ar[3]; + break; } else src_addr += x_dir; @@ -5852,6 +5848,7 @@ blit_bitblt(mystique_t *mystique) mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; src_addr = mystique->dwgreg.ar[3]; + break; } else src_addr += x_dir; @@ -6170,7 +6167,7 @@ mystique_hwcursor_draw(svga_t *svga, int displine) } static uint8_t -mystique_tvp3026_gpio_read(uint8_t cntl, void *priv) +mystique_tvp3026_gpio_read(UNUSED(uint8_t cntl), void *priv) { mystique_t *mystique = (mystique_t *) priv; @@ -6521,6 +6518,7 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) mystique->pci_regs[addr] = val; if (addr == 0x30) mystique->pci_regs[addr] &= 1; + if (mystique->pci_regs[0x30] & 0x01) { uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); @@ -6533,26 +6531,24 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) return; case 0x40: - mystique->pci_regs[addr] = val & 0x3f; + mystique->pci_regs[0x40] = val & 0x3f; break; case 0x41: - mystique->pci_regs[addr] = val; + mystique->pci_regs[0x41] = val; break; case 0x42: - mystique->pci_regs[addr] = val & 0x1f; + mystique->pci_regs[0x42] = val & 0x1f; break; case 0x43: - mystique->pci_regs[addr] = val; - if (addr == 0x43) { - if (val & 0x40) { - if (mystique->pci_regs[0x30] & 0x01) { - uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); - } else - mem_mapping_disable(&mystique->bios_rom.mapping); + mystique->pci_regs[0x43] = val; + if (val & 0x40) { + if (mystique->pci_regs[0x30] & 0x01) { + uint32_t biosaddr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, biosaddr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else - mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); - } + mem_mapping_disable(&mystique->bios_rom.mapping); + } else + mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); break; case 0x4c: @@ -6580,17 +6576,17 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) mystique_ctrl_write_b(addr, val, mystique); break; - case 0xf8: - mystique->pci_regs[0xf8] = val & 0x7; - break; + case 0xf8: + mystique->pci_regs[0xf8] = val & 0x7; + break; - case 0xf9: - mystique->pci_regs[0xf9] = val & 0x3; - break; + case 0xf9: + mystique->pci_regs[0xf9] = val & 0x3; + break; - case 0xfb: - mystique->pci_regs[0xfb] = val; - break; + case 0xfb: + mystique->pci_regs[0xfb] = val; + break; default: break; @@ -6677,6 +6673,7 @@ mystique_init(const device_t *info) mystique->svga.conv_16to32 = tvp3026_conv_16to32; if (mystique->type == MGA_2164W) mystique->svga.decode_mask = 0xffffff; + tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); @@ -6848,64 +6845,44 @@ mystique_force_redraw(void *priv) static const device_config_t mystique_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 8, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "8 MB", .value = 8 }, + { .description = "" } }, - .default_int = 8 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_config_t millennium_ii_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 8, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "4 MB", .value = 4 }, + { .description = "8 MB", .value = 8 }, + { .description = "16 MB", .value = 16 }, + { .description = "" } }, - .default_int = 8 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -6917,7 +6894,7 @@ const device_t millennium_device = { .init = mystique_init, .close = mystique_close, .reset = NULL, - { .available = millennium_available }, + .available = millennium_available, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, .config = mystique_config @@ -6931,7 +6908,7 @@ const device_t mystique_device = { .init = mystique_init, .close = mystique_close, .reset = NULL, - { .available = mystique_available }, + .available = mystique_available, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, .config = mystique_config @@ -6945,7 +6922,7 @@ const device_t mystique_220_device = { .init = mystique_init, .close = mystique_close, .reset = NULL, - { .available = mystique_220_available }, + .available = mystique_220_available, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, .config = mystique_config @@ -6959,7 +6936,7 @@ const device_t millennium_ii_device = { .init = mystique_init, .close = mystique_close, .reset = NULL, - { .available = millennium_ii_available }, + .available = millennium_ii_available, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, .config = millennium_ii_config @@ -6974,7 +6951,7 @@ const device_t productiva_g100_device = { .init = mystique_init, .close = mystique_close, .reset = NULL, - { .available = matrox_g100_available }, + .available = matrox_g100_available, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, .config = millennium_ii_config diff --git a/src/video/vid_nga.c b/src/video/vid_nga.c index 32c103a8b..3640e5106 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_nga.c @@ -600,91 +600,67 @@ nga_init(UNUSED(const device_t *info)) const device_config_t nga_config[] = { // clang-format off { - .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "Color", - .value = 0 - }, - { - .description = "Green Monochrome", - .value = 1 - }, - { - .description = "Amber Monochrome", - .value = 2 - }, - { - .description = "Gray Monochrome", - .value = 3 - }, - { - .description = "Color (no brown)", - .value = 4 - }, - { - .description = "" - } - } + .name = "rgb_type", + .description = "RGB type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Color", .value = 0 }, + { .description = "Green Monochrome", .value = 1 }, + { .description = "Amber Monochrome", .value = 2 }, + { .description = "Gray Monochrome", .value = 3 }, + { .description = "Color (no brown)", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "snow_enabled", + .description = "Snow emulation", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 64, - .selection = { - { - .description = "32 KB", - .value = 32 - }, - { - .description = "64 KB", - .value = 64 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 64, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "32 KB", .value = 32 }, + { .description = "64 KB", .value = 64 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "charset", - .description = "Character set", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "U.S. English", - .value = 0 - }, - { - .description = "Scandinavian", - .value = 1 - }, - { - .description = "Other languages", - .value = 2 - }, - { - .description = "E.F. Hutton", - .value = 3 - }, - { - .description = "" - } - } + .name = "charset", + .description = "Character set", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "U.S. English", .value = 0 }, + { .description = "Scandinavian", .value = 1 }, + { .description = "Other languages", .value = 2 }, + { .description = "E.F. Hutton", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -696,7 +672,7 @@ const device_t nga_device = { .init = nga_init, .close = nga_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = nga_speed_changed, .force_redraw = NULL, .config = nga_config diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index f21e9d66c..ce44ef890 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -571,110 +571,80 @@ oti067_m300_available(void) // clang-format off static const device_config_t oti067_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "" - } - } + .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 = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t oti067_ama932j_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 256, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 256, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "256 KB", .value = 256 }, + { .description = "512 KB", .value = 512 }, + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t oti077_acer100t_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t oti077_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1024, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on @@ -686,7 +656,7 @@ const device_t oti037c_device = { .init = oti_init, .close = oti_close, .reset = NULL, - { .available = oti037c_available }, + .available = oti037c_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, .config = NULL @@ -700,7 +670,7 @@ const device_t oti067_device = { .init = oti_init, .close = oti_close, .reset = NULL, - { .available = oti067_077_available }, + .available = oti067_077_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, .config = oti067_config @@ -714,7 +684,7 @@ const device_t oti067_m300_device = { .init = oti_init, .close = oti_close, .reset = NULL, - { .available = oti067_m300_available }, + .available = oti067_m300_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, .config = oti067_config @@ -728,7 +698,7 @@ const device_t oti067_ama932j_device = { .init = oti_init, .close = oti_close, .reset = NULL, - { .available = oti067_ama932j_available }, + .available = oti067_ama932j_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, .config = oti067_ama932j_config @@ -742,7 +712,7 @@ const device_t oti077_acer100t_device = { .init = oti_init, .close = oti_close, .reset = NULL, - { .available = oti077_acer100t_available }, + .available = oti077_acer100t_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, .config = oti077_acer100t_config @@ -757,7 +727,7 @@ const device_t oti077_device = { .init = oti_init, .close = oti_close, .reset = NULL, - { .available = oti067_077_available }, + .available = oti067_077_available, .speed_changed = oti_speed_changed, .force_redraw = oti_force_redraw, .config = oti077_config diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index c3073898d..7fe5fbbeb 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -97,11 +97,14 @@ ogc_out(uint16_t addr, uint8_t val, void *priv) cga_out(addr, val, &ogc->cga); break; + case 0x3db: case 0x3de: - /* set control register */ - ogc->ctrl_3de = val; - /* select 1st or 2nd 16k vram block to be used */ - ogc->base = (val & 0x08) ? 0x4000 : 0; + if (addr == ogc->ctrl_addr) { + /* set control register */ + ogc->ctrl_3de = val; + /* select 1st or 2nd 16k vram block to be used */ + ogc->base = (val & 0x08) ? 0x4000 : 0; + } break; default: @@ -622,6 +625,8 @@ ogc_init(UNUSED(const device_t *info)) else ogc->mono_display = 1; + ogc->ctrl_addr = 0x3de; + return ogc; } @@ -629,41 +634,34 @@ const device_config_t ogc_m24_config[] = { // clang-format off { /* Olivetti / ATT compatible displays */ - .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, - .default_int = CGA_RGB, - .selection = { - { - .description = "Color", - .value = 0 - }, - { - .description = "Green Monochrome", - .value = 1 - }, - { - .description = "Amber Monochrome", - .value = 2 - }, - { - .description = "Gray Monochrome", - .value = 3 - }, - { - .description = "" - } - } + .name = "rgb_type", + .description = "RGB type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = CGA_RGB, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Color", .value = 0 }, + { .description = "Green Monochrome", .value = 1 }, + { .description = "Amber Monochrome", .value = 2 }, + { .description = "Gray Monochrome", .value = 3 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1, + .name = "snow_enabled", + .description = "Snow emulation", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -675,7 +673,7 @@ const device_t ogc_m24_device = { .init = ogc_init, .close = ogc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = ogc_speed_changed, .force_redraw = NULL, .config = ogc_m24_config @@ -689,7 +687,7 @@ const device_t ogc_device = { .init = ogc_init, .close = ogc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = ogc_speed_changed, .force_redraw = NULL, .config = cga_config diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 70f90d6d8..d0acaf276 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -68,7 +68,7 @@ typedef struct paradise_t { } paradise_t; static video_timings_t timing_paradise_pvga1a = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; -static video_timings_t timing_paradise_wd90c = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_paradise_wd90c = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; void paradise_remap(paradise_t *paradise); @@ -204,6 +204,14 @@ paradise_out(uint16_t addr, uint8_t val, void *priv) return; case 0x0b: svga->gdcreg[0x0b] = val; + svga->gdcreg[0x0b] &= ~0xc0; + if (paradise->memory == 1024) + svga->gdcreg[0x0b] |= 0xc0; + else if (paradise->memory == 512) + svga->gdcreg[0x0b] |= 0x80; + else + svga->gdcreg[0x0b] |= 0x40; + paradise_remap(paradise); return; case 0x0e: @@ -282,6 +290,7 @@ paradise_remap(paradise_t *paradise) paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } + /*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; @@ -294,7 +303,7 @@ paradise_remap(paradise_t *paradise) void paradise_recalctimings(svga_t *svga) { - const paradise_t *paradise = (paradise_t *) svga->priv; + paradise_t *paradise = (paradise_t *) svga->priv; svga->lowres = !(svga->gdcreg[0x0e] & 0x01); @@ -328,15 +337,11 @@ paradise_recalctimings(svga_t *svga) svga->hdisp >>= 1; if (svga->hdisp == 788) svga->hdisp += 12; - if (svga->hdisp == 800) - svga->ma_latch -= 3; } else if (svga->bpp == 15) { svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; if (svga->hdisp == 788) svga->hdisp += 12; - if (svga->hdisp == 800) - svga->ma_latch -= 3; } else svga->render = svga_render_8bpp_highres; @@ -482,7 +487,7 @@ paradise_readw(uint32_t addr, void *priv) } void * -paradise_init(const device_t *info, uint32_t memsize) +paradise_init(const device_t *info, uint32_t memory) { paradise_t *paradise = malloc(sizeof(paradise_t)); svga_t *svga = ¶dise->svga; @@ -493,35 +498,35 @@ paradise_init(const device_t *info, uint32_t memsize) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_paradise_wd90c); - paradise->memory = memsize >> 10; + paradise->memory = memory; switch (info->local) { case PVGA1A: - svga_init(info, svga, paradise, memsize, /*256kb*/ + svga_init(info, svga, paradise, (memory << 10), /*256kb default*/ paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - paradise->vram_mask = memsize - 1; - svga->decode_mask = memsize - 1; + paradise->vram_mask = (memory << 10) - 1; + svga->decode_mask = (memory << 10) - 1; break; case WD90C11: - svga_init(info, svga, paradise, 1 << 19, /*512kb*/ + svga_init(info, svga, paradise, (memory << 10), /*512kb default*/ paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - paradise->vram_mask = (1 << 19) - 1; - svga->decode_mask = (1 << 19) - 1; + paradise->vram_mask = (memory << 10) - 1; + svga->decode_mask = (memory << 10) - 1; break; case WD90C30: - svga_init(info, svga, paradise, memsize, + svga_init(info, svga, paradise, (memory << 10), paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - paradise->vram_mask = memsize - 1; - svga->decode_mask = memsize - 1; + paradise->vram_mask = (memory << 10) - 1; + svga->decode_mask = (memory << 10) - 1; svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ break; @@ -529,6 +534,12 @@ paradise_init(const device_t *info, uint32_t memsize) break; } + svga->read = paradise_read; + svga->readw = paradise_readw; + svga->readl = NULL; + svga->write = paradise_write; + svga->writew = paradise_writew; + svga->writel = NULL; mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); mem_mapping_set_p(&svga->mapping, paradise); @@ -566,7 +577,7 @@ paradise_init(const device_t *info, uint32_t memsize) static void * paradise_pvga1a_ncr3302_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 256); if (paradise) rom_init(¶dise->bios_rom, "roms/machines/3302/c000-wd_1987-1989-740011-003058-019c.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -577,7 +588,7 @@ paradise_pvga1a_ncr3302_init(const device_t *info) static void * paradise_pvga1a_pc2086_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 256); if (paradise) rom_init(¶dise->bios_rom, "roms/machines/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -588,7 +599,7 @@ paradise_pvga1a_pc2086_init(const device_t *info) static void * paradise_pvga1a_pc3086_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 256); if (paradise) rom_init(¶dise->bios_rom, "roms/machines/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -600,12 +611,9 @@ static void * paradise_pvga1a_standalone_init(const device_t *info) { paradise_t *paradise; - uint32_t memory = 512; + uint32_t memsize = device_get_config_int("memory"); - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_init(info, memory); + paradise = paradise_init(info, memsize); if (paradise) rom_init(¶dise->bios_rom, "roms/video/pvga1a/BIOS.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -622,7 +630,7 @@ paradise_pvga1a_standalone_available(void) static void * paradise_wd90c11_megapc_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 0); + paradise_t *paradise = paradise_init(info, 512); if (paradise) rom_init_interleaved(¶dise->bios_rom, @@ -636,7 +644,7 @@ paradise_wd90c11_megapc_init(const device_t *info) static void * paradise_wd90c11_standalone_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 0); + paradise_t *paradise = paradise_init(info, 512); if (paradise) rom_init(¶dise->bios_rom, "roms/video/wd90c11/WD90C11.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -654,12 +662,9 @@ static void * paradise_wd90c30_standalone_init(const device_t *info) { paradise_t *paradise; - uint32_t memory = 512; + uint32_t memsize = device_get_config_int("memory"); - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_init(info, memory); + paradise = paradise_init(info, memsize); if (paradise) rom_init(¶dise->bios_rom, "roms/video/wd90c30/90C30-LR.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -707,7 +712,7 @@ const device_t paradise_pvga1a_pc2086_device = { .init = paradise_pvga1a_pc2086_init, .close = paradise_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = NULL @@ -721,7 +726,7 @@ const device_t paradise_pvga1a_pc3086_device = { .init = paradise_pvga1a_pc3086_init, .close = paradise_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = NULL @@ -730,27 +735,21 @@ const device_t paradise_pvga1a_pc3086_device = { static const device_config_t paradise_pvga1a_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "" - } - } + .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 = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -762,7 +761,7 @@ const device_t paradise_pvga1a_ncr3302_device = { .init = paradise_pvga1a_ncr3302_init, .close = paradise_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = paradise_pvga1a_config @@ -776,7 +775,7 @@ const device_t paradise_pvga1a_device = { .init = paradise_pvga1a_standalone_init, .close = paradise_close, .reset = NULL, - { .available = paradise_pvga1a_standalone_available }, + .available = paradise_pvga1a_standalone_available, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = paradise_pvga1a_config @@ -790,7 +789,7 @@ const device_t paradise_wd90c11_megapc_device = { .init = paradise_wd90c11_megapc_init, .close = paradise_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = NULL @@ -804,7 +803,7 @@ const device_t paradise_wd90c11_device = { .init = paradise_wd90c11_standalone_init, .close = paradise_close, .reset = NULL, - { .available = paradise_wd90c11_standalone_available }, + .available = paradise_wd90c11_standalone_available, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = NULL @@ -813,27 +812,22 @@ const device_t paradise_wd90c11_device = { static const device_config_t paradise_wd90c30_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1024, - .selection = { - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -845,7 +839,7 @@ const device_t paradise_wd90c30_device = { .init = paradise_wd90c30_standalone_init, .close = paradise_close, .reset = NULL, - { .available = paradise_wd90c30_standalone_available }, + .available = paradise_wd90c30_standalone_available, .speed_changed = paradise_speed_changed, .force_redraw = paradise_force_redraw, .config = paradise_wd90c30_config diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 354c7e265..5cb35dc4e 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2743,7 +2743,7 @@ const device_t pgc_device = { .init = pgc_standalone_init, .close = pgc_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = pgc_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index e82763d15..ae9475d96 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -387,58 +387,43 @@ rtg3106_available(void) static const device_config_t rtg3105_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 KB", - .value = 256 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "" - } - } + .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 = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_config_t rtg3106_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1024, - .selection = { - { - .description = "256 KB", - .value = 256 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - { - .description = "" - } - } + .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 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -450,7 +435,7 @@ const device_t realtek_rtg3105_device = { .init = rtg_init, .close = rtg_close, .reset = NULL, - { .available = rtg3105_available }, + .available = rtg3105_available, .speed_changed = rtg_speed_changed, .force_redraw = rtg_force_redraw, .config = rtg3105_config @@ -464,7 +449,7 @@ const device_t realtek_rtg3106_device = { .init = rtg_init, .close = rtg_close, .reset = NULL, - { .available = rtg3106_available }, + .available = rtg3106_available, .speed_changed = rtg_speed_changed, .force_redraw = rtg_force_redraw, .config = rtg3106_config diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 2ad525892..769cd0001 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -253,6 +253,7 @@ typedef struct s3_t { uint16_t multifunc_cntl; uint16_t multifunc[16]; uint8_t pix_trans[4]; + uint16_t pix_trans_val; int ssv_state; int16_t cx, cy; @@ -272,20 +273,15 @@ typedef struct s3_t { int dat_count; int b2e8_pix, temp_cnt; int ssv_len; + int ssv_len_back; uint8_t ssv_dir; uint8_t ssv_draw; uint8_t dat_buf_16bit; uint8_t frgd_color_actual[2]; uint8_t bkgd_color_actual[2]; uint8_t wrt_mask_actual[2]; - uint8_t rd_mask_actual[2]; - uint8_t *pix_trans_ptr; - int pix_trans_ptr_cnt; - int pix_trans_x_count; - int pix_trans_x_count2; int color_16bit_check; - int color_16bit_check_rectfill; - uint16_t minus, srcminus; + int16_t minus; /*For non-threaded FIFO*/ int setup_fifo_slot; @@ -365,7 +361,7 @@ typedef struct s3_t { event_t *wake_fifo_thread; event_t *fifo_not_full_event; - int blitter_busy; + atomic_int blitter_busy; uint64_t blitter_time; uint64_t status_time; @@ -412,6 +408,7 @@ static uint32_t s3_accel_read_l(uint32_t addr, void *priv); static void s3_out(uint16_t addr, uint8_t val, void *priv); static uint8_t s3_in(uint16_t addr, void *priv); +static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val); static void s3_accel_out(uint16_t port, uint8_t val, void *priv); static void s3_accel_out_w(uint16_t port, uint16_t val, void *priv); static void s3_accel_out_l(uint16_t port, uint32_t val, void *priv); @@ -508,15 +505,14 @@ s3_update_irqs(s3_t *s3) if (!s3->pci) return; - if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) { + if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) pci_set_irq(s3->pci_slot, PCI_INTA, &s3->irq_state); - } else { + else pci_clear_irq(s3->pci_slot, PCI_INTA, &s3->irq_state); - } } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv); -void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); +void s3_short_stroke_start(s3_t *s3, uint8_t ssv); static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); #define WRITE8(addr, var, val) \ @@ -536,21 +532,20 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); } #define READ_PIXTRANS_BYTE_IO(n) \ - s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n - s3->accel.minus)) & s3->vram_mask]; + s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus + n)) & s3->vram_mask]; #define READ_PIXTRANS_BYTE_MM \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; -#define READ_PIXTRANS_WORD \ - if ((s3->bpp == 0) && !s3->color_16bit) { \ - temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ - temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ - } else { \ - temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus)) & (s3->vram_mask >> 1)]; \ - } +#define READ_PIXTRANS_WORD \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ + temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ + temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ + } else \ + temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus)) & (s3->vram_mask >> 1)]; #define READ_PIXTRANS_LONG \ - if ((s3->bpp == 0) && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ @@ -612,111 +607,62 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.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) val = (val >> 8) | (val << 8); s3->accel_start(8, 1, val | (val << 16), 0, s3); + } else { + if ((s3->bpp == 0) && s3->color_16bit) + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + else + s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + } + } else { + if ((s3->bpp == 0) && s3->color_16bit) { + if (s3->accel.cur_x & 0x400) + val = (val >> 8) | (val << 8); + + s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } else s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - } else { - if (s3->accel.color_16bit_check_rectfill) { - if (s3->accel.color_16bit_check) { - if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - s3_log("Word: CPU data CMD=%04x, byte write=%02x, " - "cnt=%d, check=%d.\n", s3->accel.cmd, val & 0xff, - s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; - s3->accel.pix_trans_x_count += 2; - } - } - break; - } - s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x200: - 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) val = (val >> 8) | (val << 8); + s3->accel_start(16, 1, val | (val << 16), 0, s3); } else s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } else { - if (s3->accel.color_16bit_check_rectfill) { - if (s3->accel.color_16bit_check) { - if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - s3_log("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, " - "totalptrcnt=%d.\n", s3->accel.cmd, val, - s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, - s3->accel.pix_trans_ptr_cnt); - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val & 0xff; - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count + 1] = val >> 8; - s3->accel.pix_trans_x_count += 2; - s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; - } - } else { - if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - s3_log("Word: CPU data CMD=%04x, word write=%04x, cnt=%d, check=%d, " - "totalptrcnt=%d.\n", s3->accel.cmd, val, - s3->accel.pix_trans_x_count, s3->accel.color_16bit_check, - s3->accel.pix_trans_ptr_cnt); - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val & 0xff; - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2 + 1] = val >> 8; - s3->accel.pix_trans_x_count += 2; - } - if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { - for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { - s3_log("Transferring write count=%d, bytes=%08x.\n", i, - s3->accel.pix_trans_ptr[i] | - (s3->accel.pix_trans_ptr[i + 1] << 8) | - (s3->accel.pix_trans_ptr[i + 2] << 16) | - (s3->accel.pix_trans_ptr[i + 3] << 24)); - s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | - (s3->accel.pix_trans_ptr[i + 1] << 8), s3); - } - - s3->accel.pix_trans_x_count2 = 0; - s3->accel.color_16bit_check_rectfill = 0; - if (s3->accel.pix_trans_ptr != NULL) { - free(s3->accel.pix_trans_ptr); - s3->accel.pix_trans_ptr = NULL; - } - } - } - break; + if ((s3->bpp == 0) && s3->color_16bit) { + if (s3->accel.cur_x & 0x400) + val = (val >> 8) | (val << 8); } s3->accel_start(2, 1, 0xffffffff, val | (val << 16), s3); } break; case 0x400: - if (svga->crtc[0x53] & 0x08) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); + 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) + val = (val >> 8) | (val << 8); + + if (svga->crtc[0x53] & 0x08) s3->accel_start(32, 1, val | (val << 16), 0, s3); - } else - s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } else - s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } else { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); + else s3->accel_start(16, 1, val | (val << 16), 0, s3); - } else - s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); } else s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } + } else + s3->accel_start(4, 1, 0xffffffff, val | (val << 16), s3); break; case 0x600: if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.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) val = (val >> 8) | (val << 8); @@ -805,7 +751,7 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { - const svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; switch (port) { case 0x8148: @@ -840,6 +786,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 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); break; case 0x854a: case 0x86ea: @@ -950,6 +897,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x9ae9: s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); s3->accel.ssv_state = 0; + if (s3->bpp == 3) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] &= ~0x10; + } + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port - 1, s3->accel.cmd); s3->accel_start(-1, 0, 0xffffffff, 0, s3); break; @@ -975,30 +927,62 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.cy = s3->accel.cur_y & 0xfff; if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); } else { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); } break; case 0xa148: case 0xa2e8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else + s3_log("[%04X:%08X] OUT PORTB=%04x (Background Color), val=%02x.\n", CS, cpu_state.pc, port, val); + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } + } else s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; break; case 0xa149: case 0xa2e9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + s3_log("[%04X:%08X] OUT PORTB=%04x (Background Color), val=%02x.\n", CS, cpu_state.pc, port, val); + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) + s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->chip >= S3_VISION964) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } if (s3->accel.color_16bit_check) s3->accel.bkgd_color_actual[1] = s3->accel.bkgd_color & 0xff; else @@ -1006,44 +990,81 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa14a: case 0xa2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } } break; case 0xa14b: case 0xa2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + + s3->accel.multifunc[0xe] ^= 0x10; + } } break; case 0xa548: case 0xa6e8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else + s3_log("[%04X:%08X] OUT PORTB=%04x (Foreground Color), val=%02x.\n", CS, cpu_state.pc, port, val); + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } + } else s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; break; case 0xa549: case 0xa6e9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + s3_log("[%04X:%08X] OUT PORTB=%04x (Foreground Color), val=%02x.\n", CS, cpu_state.pc, port, val); + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) + s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->chip >= S3_VISION964) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } if (s3->accel.color_16bit_check) s3->accel.frgd_color_actual[1] = s3->accel.frgd_color & 0xff; else @@ -1051,44 +1072,81 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa54a: case 0xa6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + else if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } } break; case 0xa54b: case 0xa6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + + s3->accel.multifunc[0xe] ^= 0x10; + } } break; case 0xa948: case 0xaae8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else + s3_log("[%04X:%08X] OUT PORTB=%04x (Write Mask), val=%02x.\n", CS, cpu_state.pc, port, val); + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } + } else s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; break; case 0xa949: case 0xaae9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + s3_log("[%04X:%08X] OUT PORTB=%04x (Write Mask), val=%02x.\n", CS, cpu_state.pc, port, val); + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) + s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->chip >= S3_VISION964) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } if (s3->accel.color_16bit_check) s3->accel.wrt_mask_actual[1] = s3->accel.wrt_mask & 0xff; else @@ -1096,83 +1154,258 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa94a: case 0xaaea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } } break; case 0xa94b: case 0xaaeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + + s3->accel.multifunc[0xe] ^= 0x10; + } } break; case 0xad48: case 0xaee8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } + } else s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; break; case 0xad49: case 0xaee9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + + s3->accel.multifunc[0xe] ^= 0x10; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) + s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->chip >= S3_VISION964) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } break; case 0xad4a: case 0xaeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } } break; case 0xad4b: case 0xaeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) + if (s3->chip >= S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x200) s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + + s3->accel.multifunc[0xe] ^= 0x10; + } } break; case 0xb148: case 0xb2e8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + 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) { + s3->accel.b2e8_pix = 0; + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } + } else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } else { + s3->accel.b2e8_pix = 1; + if (s3_cpu_dest(s3)) + break; + s3->accel.pix_trans[0] = val; + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + break; + + default: + break; + } + } + } break; case 0xb149: case 0xb2e9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + 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) { + s3->accel.b2e8_pix = 0; + if (s3->bpp == 3) { + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + + s3->accel.multifunc[0xe] ^= 0x10; + } else if (s3->chip >= S3_VISION964) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + + if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) + s3->accel.multifunc[0xe] ^= 0x10; + else if (s3->chip >= S3_VISION964) { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } + } else { + s3->accel.b2e8_pix = 1; + if (s3_cpu_dest(s3)) + break; + s3->accel.pix_trans[1] = val; + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || + ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3->accel_start(8, 1, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), 0, s3); + else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); + } else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || + ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + s3->accel_start(16, 1, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3->accel_start(16, 1, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), 0, s3); + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); + } + } else { + if (s3->accel.cmd & 0x1000) + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | + (s3->accel.pix_trans[0] << 8), s3); + else + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | + (s3->accel.pix_trans[1] << 8), s3); + } + break; + case 0x400: + if (svga->crtc[0x53] & 0x08) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3->accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + else + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } else + s3->accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + break; + case 0x600: + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3->accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + } + } + } + break; + + default: + break; + } + + } + } break; case 0xb14a: case 0xb2ea: @@ -1194,6 +1427,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); else s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; } break; @@ -1228,17 +1462,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe548: case 0xe6e8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + } else s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; break; case 0xe549: case 0xe6e9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + } else s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; @@ -1262,6 +1503,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; } break; @@ -1283,17 +1525,24 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed48: case 0xeee8: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + } else s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; break; case 0xed49: case 0xeee9: - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + } else s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; @@ -1317,12 +1566,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; } break; case 0xe148: case 0xe2e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d), WRTMASK=%04x.\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y, s3->accel.wrt_mask); + s3_log(".\n"); s3->accel.b2e8_pix = 0; if (s3_cpu_dest(s3)) break; @@ -1336,46 +1588,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) else s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else { - if (s3->accel.color_16bit_check_rectfill) { - if (s3->accel.color_16bit_check) { - if (s3->accel.pix_trans_x_count < s3->accel.pix_trans_ptr_cnt) { - s3_log("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, " - "check=%d.\n", s3->accel.cmd, val, - s3->accel.pix_trans_x_count, s3->accel.color_16bit_check); - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count] = val; - s3->accel.pix_trans_x_count++; - s3->accel.pix_trans_x_count2 = s3->accel.pix_trans_x_count; - } + if ((s3->bpp == 0) && s3->color_16bit) { + s3->accel.pix_trans[1] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus)) & s3->vram_mask]; + if (s3->accel.cur_x & 0x400) { + s3_log("Last Pixel Written=%02x (1024).\n", s3->accel.pix_trans[1]); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); } else { - if (s3->accel.pix_trans_x_count2 < s3->accel.pix_trans_ptr_cnt) { - s3_log("Byte: CPU data CMD=%04x, byte write=%02x, cnt=%d, " - "check=%d.\n", s3->accel.cmd, val, - s3->accel.pix_trans_x_count2, s3->accel.color_16bit_check); - s3->accel.pix_trans_ptr[s3->accel.pix_trans_x_count2] = val; - s3->accel.pix_trans_x_count2++; - } - s3_log("WriteCNT=%d, TotalCNT=%d.\n", s3->accel.pix_trans_x_count2, - s3->accel.pix_trans_ptr_cnt); - if (s3->accel.pix_trans_x_count2 == s3->accel.pix_trans_ptr_cnt) { - for (int i = 0; i < s3->accel.pix_trans_ptr_cnt; i += 2) { - s3_log("Transferring write count=%d, bytes=%04x.\n", i, - s3->accel.pix_trans_ptr[i] | - (s3->accel.pix_trans_ptr[i + 1] << 8)); - s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans_ptr[i] | - (s3->accel.pix_trans_ptr[i + 1] << 8), s3); - } - - s3->accel.pix_trans_x_count2 = 0; - s3->accel.color_16bit_check_rectfill = 0; - if (s3->accel.pix_trans_ptr != NULL) { - free(s3->accel.pix_trans_ptr); - s3->accel.pix_trans_ptr = NULL; - } - } + s3_log("Last Pixel Written=%02x (0).\n", s3->accel.pix_trans[1]); + s3->accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } - break; - } - s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else + s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } break; @@ -1386,14 +1609,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe149: case 0xe2e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d), WRTMASK=%04x.\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y, s3->accel.wrt_mask); + s3_log(".\n"); s3->accel.b2e8_pix = 0; if (s3_cpu_dest(s3)) break; s3->accel.pix_trans[1] = val; if (s3->accel.cmd & 0x100) { - s3_log("S3 PIXTRANS_B write (E2E9): cmd=%03x, pixelcntl=%02x, frgdmix=%02x, " - "bkgdmix=%02x, curx=%d, val=%04x.\n", s3->accel.cmd, s3->accel.multifunc[0x0a], - s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.cur_x, val); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -1541,13 +1763,27 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if (port != 0x9ee8 && port != 0x9d48) { - if (port == 0xb2e8 || port == 0xb148) { - s3->accel.b2e8_pix = 1; + if ((port != 0x9ee8) && (port != 0x9d48)) { + s3_log("[%04X:%08X] OUT PORTW=%04x, val=%04x, CMD=%04x, C(%d,%d), WRTMASK=%04x.\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y, s3->accel.wrt_mask); + s3_log(".\n"); + if ((port == 0xb2e8) || (port == 0xb148)) { + if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_86C928)) { + s3->accel.b2e8_pix = 0; + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + } else { + s3->accel.b2e8_pix = 1; + s3_accel_out_pixtrans_w(s3, val); + } } else { s3->accel.b2e8_pix = 0; + if ((port == 0xe2e8) || (port == 0xe2ea) || (port == 0xe148) || (port == 0xe14a)) + s3_accel_out_pixtrans_w(s3, val); + else { + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + } } - s3_accel_out_pixtrans_w(s3, val); } else { s3->accel.short_stroke = val; s3->accel.ssv_state = 1; @@ -1556,11 +1792,11 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.cy = s3->accel.cur_y & 0xfff; if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); } else { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); } } } @@ -1568,12 +1804,29 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (port == 0xb2e8 || port == 0xb148) - s3->accel.b2e8_pix = 1; - else + if ((port == 0xb2e8) || (port == 0xb148)) { + s3_log("[%04X:%08X] OUT PORTL=%04x, val=%08x, 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) || (s3->chip >= S3_86C928)) { + s3->accel.b2e8_pix = 0; + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + s3_accel_out_fifo(s3, port + 2, val >> 16); + s3_accel_out_fifo(s3, port + 3, val >> 24); + } else { + s3->accel.b2e8_pix = 1; + s3_accel_out_pixtrans_l(s3, val); + } + } else { s3->accel.b2e8_pix = 0; - - s3_accel_out_pixtrans_l(s3, val); + if ((port == 0xe2e8) || (port == 0xe148)) + s3_accel_out_pixtrans_l(s3, val); + else { + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + s3_accel_out_fifo(s3, port + 2, val >> 16); + s3_accel_out_fifo(s3, port + 3, val >> 24); + } + } } static void @@ -1749,77 +2002,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) s3->accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); } } else { - switch (addr & 0x1ffff) { - case 0x83b0: - case 0x83b1: - case 0x83b2: - case 0x83b3: - case 0x83b4: - case 0x83b5: - case 0x83b6: - case 0x83b7: - case 0x83b8: - case 0x83b9: - case 0x83ba: - case 0x83bb: - case 0x83bc: - case 0x83bd: - case 0x83be: - case 0x83bf: - case 0x83c0: - case 0x83c1: - case 0x83c2: - case 0x83c3: - case 0x83c4: - case 0x83c5: - case 0x83c6: - case 0x83c7: - case 0x83c8: - case 0x83c9: - case 0x83ca: - case 0x83cb: - case 0x83cc: - case 0x83cd: - case 0x83ce: - case 0x83cf: - case 0x83d0: - case 0x83d1: - case 0x83d2: - case 0x83d3: - case 0x83d4: - case 0x83d5: - case 0x83d6: - case 0x83d7: - case 0x83d8: - case 0x83d9: - case 0x83da: - case 0x83db: - case 0x83dc: - case 0x83dd: - case 0x83de: - case 0x83df: - s3_out(addr & 0x3ff, val, s3); - break; - case 0x8504: - s3->subsys_stat &= ~val; - s3_update_irqs(s3); - break; - case 0x8505: - s3->subsys_cntl = val; - s3_update_irqs(s3); - break; - case 0x850c: - s3->accel.advfunc_cntl = val; - s3_updatemapping(s3); - break; - case 0xff20: - s3->serialport = val; - i2c_gpio_set(s3->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); - break; - default: - s3_accel_out_fifo(s3, addr & 0xffff, val); - break; - } + s3_accel_out_fifo(s3, addr & 0xffff, val); } } else { if (addr & 0x8000) { @@ -1858,45 +2041,21 @@ mmio_byte_write: static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { - const svga_t *svga = &s3->svga; - - if (svga->crtc[0x53] & 0x08) { - if ((addr & 0x1fffe) < 0x8000) { - s3_accel_out_pixtrans_w(s3, val); - } else { - switch (addr & 0x1fffe) { - default: - case 0x83d4: - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - break; - case 0xff20: - s3_accel_write_fifo(s3, addr, val); - break; - case 0x811c: - s3_accel_out_fifo_w(s3, 0x9ee8, val); - break; - } - } - } else { - if (addr & 0x8000) { - if (addr == 0x811c) - s3_accel_out_fifo_w(s3, 0x9ee8, val); + if ((addr & 0x1fffe) < 0x8000) { + s3_accel_out_pixtrans_w(s3, val); + } else if ((addr & 0x1fffe) == 0x811c) { + s3_accel_out_fifo_w(s3, 0x9ee8, val); + } else if (((addr & 0x1fffe) >= 0x8000) && (addr & 0x1fffe) < 0x10000) { + if (((addr & 0x1fffe) == 0xe2e8) || ((addr & 0x1fffe) == 0xe2ea)) { + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) + s3_accel_out_pixtrans_w(s3, val); else { - if ((addr == 0xe2e8) || (addr == 0xe2ea)) { - if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) - s3_accel_out_pixtrans_w(s3, val); - else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } - } else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); } } else { - s3_accel_out_pixtrans_w(s3, val); + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); } } } @@ -1904,221 +2063,78 @@ s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { - svga_t *svga = &s3->svga; + if ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000) { + s3_visionx68_video_engine_op(val, s3); + } else if ((addr & 0x1fffc) < 0x8000) { + s3_accel_out_pixtrans_l(s3, val); + } else if ((addr & 0x1fffc) >= 0x18000) { + switch (addr & 0x1fffc) { + case 0x18080: + s3->videoengine.nop = 1; + break; - if (svga->crtc[0x53] & 0x08) { - if ((addr & 0x1fffc) < 0x8000 || ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000)) { - if ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000) { - s3_visionx68_video_engine_op(val, s3); - } else if ((addr & 0x1fffc) < 0x8000) { - s3_accel_out_pixtrans_l(s3, val); - } - } else { - switch (addr & 0x1fffc) { - case 0x8180: - s3->streams.pri_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x8184: - s3->streams.chroma_ctrl = val; - break; - case 0x8190: - s3->streams.sec_ctrl = val; - s3->streams.dda_horiz_accumulator = val & 0xfff; - if (val & (1 << 11)) - s3->streams.dda_horiz_accumulator |= 0xfffff800; - s3->streams.sdif = (val >> 24) & 7; - break; - case 0x8194: - s3->streams.chroma_upper_bound = val; - break; - case 0x8198: - s3->streams.sec_filter = val; - s3->streams.k1_horiz_scale = val & 0x7ff; - if (val & (1 << 10)) - s3->streams.k1_horiz_scale |= 0xfffff800; - s3->streams.k2_horiz_scale = (val >> 16) & 0x7ff; - if ((val >> 16) & (1 << 10)) - s3->streams.k2_horiz_scale |= 0xfffff800; - break; - case 0x81a0: - s3->streams.blend_ctrl = val; - break; - case 0x81c0: - s3->streams.pri_fb0 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81c4: - s3->streams.pri_fb1 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81c8: - s3->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81cc: - s3->streams.buffer_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81d0: - s3->streams.sec_fb0 = val; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81d4: - s3->streams.sec_fb1 = val; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81d8: - s3->streams.sec_stride = val; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81dc: - s3->streams.overlay_ctrl = val; - break; - case 0x81e0: - s3->streams.k1_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - s3->streams.k1_vert_scale |= 0xfffff800; - break; - case 0x81e4: - s3->streams.k2_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - s3->streams.k2_vert_scale |= 0xfffff800; - break; - case 0x81e8: - s3->streams.dda_vert_accumulator = val & 0xfff; - if (val & (1 << 11)) - s3->streams.dda_vert_accumulator |= 0xfffff800; - break; - case 0x81ec: - s3->streams.fifo_ctrl = val; - break; - case 0x81f0: - s3->streams.pri_start = val; - s3->streams.pri_x = (val >> 16) & 0x7ff; - s3->streams.pri_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81f4: - s3->streams.pri_size = val; - s3->streams.pri_w = (val >> 16) & 0x7ff; - s3->streams.pri_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81f8: - s3->streams.sec_start = val; - s3->streams.sec_x = (val >> 16) & 0x7ff; - s3->streams.sec_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; - case 0x81fc: - s3->streams.sec_size = val; - s3->streams.sec_w = (val >> 16) & 0x7ff; - s3->streams.sec_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = svga->monitor->mon_changeframecount; - break; + case 0x18088: + s3->videoengine.cntl = val; + s3->videoengine.dda_init_accumulator = val & 0xfff; + s3->videoengine.odf = (val >> 16) & 7; + s3->videoengine.yuv = !!(val & (1 << 19)); + s3->videoengine.idf = (val >> 20) & 7; + s3->videoengine.dither = !!(val & (1 << 29)); + s3->videoengine.dm_index = (val >> 23) & 7; + break; - case 0x8504: - s3->subsys_stat &= ~(val & 0xff); - s3->subsys_cntl = (val >> 8); - s3_update_irqs(s3); - break; + case 0x1808c: + s3->videoengine.stretch_filt_const = val; + s3->videoengine.k2 = val & 0x7ff; + s3->videoengine.k1 = (val >> 16) & 0x7ff; + s3->videoengine.host_data = !!(val & (1 << 30)); + s3->videoengine.scale_down = !!(val & (1 << 31)); + break; - case 0x850c: - s3->accel.advfunc_cntl = val & 0xff; - s3_updatemapping(s3); - break; + case 0x18090: + s3->videoengine.src_dst_step = val; + s3->videoengine.dst_step = val & 0x1fff; + s3->videoengine.src_step = (val >> 16) & 0x1fff; + break; - case 0xff20: - s3_accel_write_fifo(s3, addr, val); - break; + case 0x18094: + s3->videoengine.crop = val; + s3->videoengine.len = val & 0xfff; + s3->videoengine.start = (val >> 16) & 0xfff; + s3->videoengine.input = 1; + break; - case 0x18080: - s3->videoengine.nop = 1; - break; + case 0x18098: + s3->videoengine.src_base = val & 0xffffff; + break; - case 0x18088: - s3->videoengine.cntl = val; - s3->videoengine.dda_init_accumulator = val & 0xfff; - s3->videoengine.odf = (val >> 16) & 7; - s3->videoengine.yuv = !!(val & (1 << 19)); - s3->videoengine.idf = (val >> 20) & 7; - s3->videoengine.dither = !!(val & (1 << 29)); - s3->videoengine.dm_index = (val >> 23) & 7; - break; + case 0x1809c: + s3->videoengine.dest_base = val & 0xffffff; + break; - case 0x1808c: - s3->videoengine.stretch_filt_const = val; - s3->videoengine.k2 = val & 0x7ff; - s3->videoengine.k1 = (val >> 16) & 0x7ff; - s3->videoengine.host_data = !!(val & (1 << 30)); - s3->videoengine.scale_down = !!(val & (1 << 31)); - break; - - case 0x18090: - s3->videoengine.src_dst_step = val; - s3->videoengine.dst_step = val & 0x1fff; - s3->videoengine.src_step = (val >> 16) & 0x1fff; - break; - - case 0x18094: - s3->videoengine.crop = val; - s3->videoengine.len = val & 0xfff; - s3->videoengine.start = (val >> 16) & 0xfff; - s3->videoengine.input = 1; - break; - - case 0x18098: - s3->videoengine.src_base = val & 0xffffff; - break; - - case 0x1809c: - s3->videoengine.dest_base = val & 0xffffff; - break; - - default: - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - break; - } + default: + break; } - } else { - if (addr & 0x8000) { - if (addr == 0xe2e8) { - if ((s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) - s3_accel_out_pixtrans_l(s3, val); - else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - } else { + } else if (((addr & 0x1fffc) >= 0x8000) && ((addr & 0x1fffc) < 0x10000)) { + if ((addr & 0x1fffc) == 0xe2e8) { + if ((s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) + s3_accel_out_pixtrans_l(s3, val); + else { s3_accel_write_fifo(s3, addr, val); s3_accel_write_fifo(s3, addr + 1, val >> 8); s3_accel_write_fifo(s3, addr + 2, val >> 16); s3_accel_write_fifo(s3, addr + 3, val >> 24); } } else { - s3_accel_out_pixtrans_l(s3, val); + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); } } } + static void s3_vblank_start(svga_t *svga) { @@ -2148,7 +2164,7 @@ s3_hwcursor_draw(svga_t *svga, int displine) const s3_t *s3 = (s3_t *) svga->priv; int shift = 1; int width = 16; - uint16_t dat[2]; + uint16_t dat[2] = { 0, 0 }; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; uint32_t fg; @@ -2481,7 +2497,6 @@ s3_trio64v_overlay_draw(svga_t *svga, int displine) { const s3_t *s3 = (s3_t *) svga->priv; int offset = (s3->streams.sec_x - s3->streams.pri_x) + 1; - int h_acc = s3->streams.dda_horiz_accumulator; int r[8]; int g[8]; int b[8]; @@ -2491,7 +2506,7 @@ s3_trio64v_overlay_draw(svga_t *svga, int displine) uint32_t *p; uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - p = &(buffer32->line[displine][offset + svga->x_add]); + p = &((uint32_t *)buffer32->line[displine])[offset + svga->x_add]; if ((offset + s3->streams.sec_w) > s3->streams.pri_w) x_size = (s3->streams.pri_w - s3->streams.sec_x) + 1; @@ -2503,13 +2518,14 @@ s3_trio64v_overlay_draw(svga_t *svga, int displine) for (int x = 0; x < x_size; x++) { *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - h_acc += s3->streams.k1_horiz_scale; - if (h_acc >= 0) { + svga->overlay_latch.h_acc += s3->streams.k1_horiz_scale; + if (svga->overlay_latch.h_acc >= 0) { if ((x_read ^ (x_read + 1)) & ~3) OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; - h_acc += (s3->streams.k2_horiz_scale - s3->streams.k1_horiz_scale); + svga->overlay_latch.h_acc += (s3->streams.k2_horiz_scale - s3->streams.k1_horiz_scale); } } @@ -2731,16 +2747,24 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { - svga->seqregs[svga->seqaddr] = val; - switch (svga->seqaddr) { - case 0x12: - case 0x13: - svga_recalctimings(svga); - return; + if (s3->chip == S3_TRIO64V2) { + if (svga->seqaddr >= 0x10) { + svga->seqregs[svga->seqaddr] = val; + svga_recalctimings(svga); + return; + } + } else { + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { + svga->seqregs[svga->seqaddr] = val; + switch (svga->seqaddr) { + case 0x12: + case 0x13: + svga_recalctimings(svga); + return; - default: - break; + default: + break; + } } } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ @@ -2749,19 +2773,21 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; + + svga_recalctimings(svga); } else if (svga->seqaddr == 9) { - svga->seqregs[svga->seqaddr] = val & 0x80; + svga->seqregs[9] = val & 0x80; s3_io_set(s3); return; } else if (svga->seqaddr == 0xa) { - svga->seqregs[svga->seqaddr] = val & 0x80; + svga->seqregs[0xa] = val & 0x80; return; } else if (s3->chip >= S3_VISION964) { - if (svga->seqaddr == 0x08) { - svga->seqregs[svga->seqaddr] = val & 0x0f; + if (svga->seqaddr == 8) { + svga->seqregs[8] = val & 0x0f; return; - } else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) { - svga->seqregs[svga->seqaddr] = val; + } else if ((svga->seqaddr == 0xd) && (svga->seqregs[8] == 0x06)) { + svga->seqregs[0xd] = val; svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20)); svga_recalctimings(svga); return; @@ -2813,8 +2839,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) return; if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) return; - if ((s3->chip == S3_TRIO64V2) && (svga->crtcreg >= 0x80)) - return; if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50)) return; @@ -2833,6 +2857,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x50: s3->bpp = (svga->crtc[0x50] >> 4) & 3; + s3_log("S3 BPP=%d.\n", s3->bpp); if (s3->bpp == 3) { if (!(s3->accel.multifunc[0xe] & 0x200)) /*On True Color mode change, reset bit 4 of Misc Index register*/ s3->accel.multifunc[0xe] &= ~0x10; @@ -2862,6 +2887,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; + + s3_log("CRTC35 Chain4=%x, Bank=%02x.\n", svga->chain4, s3->bank); break; case 0x51: @@ -2988,21 +3015,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x43: if (s3->chip < S3_VISION964) { - if (s3->chip <= S3_86C805) { - s3->color_16bit = !!(val & 8); - if (s3->color_16bit) { - s3->width = 1024; - } else { - if (s3->chip <= S3_86C924) - s3->width = 1024; - else { - if (s3->accel.advfunc_cntl & 4) - s3->width = 1024; - else - s3->width = 640; - } - } - } + if (s3->chip <= S3_86C805) + svga_recalctimings(svga); + s3_io_remove_alt(s3); s3->translate = !!(val & 0x10); s3_io_set_alt(s3); @@ -3084,7 +3099,7 @@ s3_in(uint16_t addr, void *priv) break; case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { + if ((svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) && (s3->chip < S3_TRIO64V2)) { temp = svga->seqregs[svga->seqaddr]; /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not get stuck in an infinite loop. */ @@ -3093,6 +3108,8 @@ s3_in(uint16_t addr, void *priv) (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; + } if ((svga->seqaddr >= 0x10) && (s3->chip >= S3_TRIO64V2)) { + return svga->seqregs[svga->seqaddr]; } else if ((svga->seqaddr >= 5) && (svga->seqaddr < 8)) return 0xff; else @@ -3131,6 +3148,7 @@ s3_in(uint16_t addr, void *priv) return sc1502x_ramdac_in(addr, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); + break; case 0x3d4: return svga->crtcreg; @@ -3161,7 +3179,7 @@ s3_in(uint16_t addr, void *priv) case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x5c: /* General Output Port Register */ - temp = svga->crtc[svga->crtcreg] & 0xa0; + temp = svga->crtc[0x5c] & 0xa0; if (((svga->miscout >> 2) & 3) == 3) temp |= svga->crtc[0x42] & 0x0f; else @@ -3182,20 +3200,19 @@ s3_in(uint16_t addr, void *priv) case 0x6b: s3_log("[%04X:%08X]: Read CRTC6b=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6b]); if (s3->chip != S3_TRIO64V2) { - if (svga->crtc[0x53] & 0x08) { + if (svga->crtc[0x53] & 0x08) return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); - } else { + else return svga->crtc[0x59]; - } } else return svga->crtc[0x6b]; break; case 0x6c: s3_log("[%04X:%08X]: Read CRTC6c=%02x.\n", CS, cpu_state.pc, svga->crtc[0x6c]); if (s3->chip != S3_TRIO64V2) { - if (svga->crtc[0x53] & 0x08) { + if (svga->crtc[0x53] & 0x08) return 0x00; - } else + else return (svga->crtc[0x5a] & 0x80); } else return svga->crtc[0x6c]; @@ -3212,6 +3229,140 @@ s3_in(uint16_t addr, void *priv) return svga_in(addr, svga); } +uint32_t +s3_decode_addr(svga_t *svga, uint32_t addr, int write) +{ + int memory_map_mode = (svga->gdcreg[6] >> 2) & 3; + + s3_log("CRTC31 bit 3=%x, map=%x, write=%x, wrtbank=%x, chain4=%x, vrammask=%08x.\n", svga->crtc[0x31] & 0x08, memory_map_mode, write, svga->write_bank, svga->chain4, svga->vram_display_mask); + + if (svga->crtc[0x31] & 0x08) + memory_map_mode = 1; + + addr &= 0x1ffff; + + switch (memory_map_mode) { + case 0: + break; + case 1: + if (addr >= 0x10000) + return 0xffffffff; + break; + case 2: + addr -= 0x10000; + if (addr >= 0x8000) + return 0xffffffff; + break; + default: + case 3: + addr -= 0x18000; + if (addr >= 0x8000) + return 0xffffffff; + break; + } + + if (memory_map_mode <= 1) { + if (write) + addr += svga->write_bank; + else + addr += svga->read_bank; + } + + return addr; +} + +static void +s3_write(uint32_t addr, uint8_t val, void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + xga_write_test(addr, val, svga); + addr = s3_decode_addr(svga, addr, 1); + if (addr == 0xffffffff) + return; + + svga_write_linear(addr, val, svga); +} + +static void +s3_writew(uint32_t addr, uint16_t val, void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + addr = s3_decode_addr(svga, addr, 1); + if (addr == 0xffffffff) + return; + + svga_writew_linear(addr, val, svga); +} + +static void +s3_writel(uint32_t addr, uint32_t val, void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + xga_write_test(addr + 2, val >> 16, svga); + xga_write_test(addr + 3, val >> 24, svga); + addr = s3_decode_addr(svga, addr, 1); + if (addr == 0xffffffff) + return; + + svga_writel_linear(addr, val, svga); +} + +static uint8_t +s3_read(uint32_t addr, void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + (void) xga_read_test(addr, svga); + addr = s3_decode_addr(svga, addr, 0); + if (addr == 0xffffffff) + return 0xff; + + return svga_read_linear(addr, svga); +} + +static uint16_t +s3_readw(uint32_t addr, void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + addr = s3_decode_addr(svga, addr, 0); + if (addr == 0xffffffff) + return 0xffff; + + return svga_readw_linear(addr, svga); +} + +static uint32_t +s3_readl(uint32_t addr, void *priv) +{ + s3_t *s3 = (s3_t *) priv; + svga_t *svga = &s3->svga; + + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + (void) xga_read_test(addr + 2, svga); + (void) xga_read_test(addr + 3, svga); + addr = s3_decode_addr(svga, addr, 0); + if (addr == 0xffffffff) + return 0xffffffff; + + return svga_readl_linear(addr, svga); +} + static void s3_recalctimings(svga_t *svga) { @@ -3233,6 +3384,8 @@ s3_recalctimings(svga_t *svga) svga->hdisp = svga->hdisp_old; svga->ma_latch |= (s3->ma_ext << 16); + svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); + if (s3->chip >= S3_86C928) { if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; @@ -3246,8 +3399,8 @@ s3_recalctimings(svga_t *svga) svga->dispend |= 0x400; if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; - else - svga->vblankstart = svga->dispend; + else if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) + svga->vblankstart = svga->dispend; /*Applies only to Enhanced modes*/ if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; if (svga->crtc[0x5e] & 0x40) @@ -3294,35 +3447,48 @@ s3_recalctimings(svga_t *svga) break; } - svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); + if (s3->chip <= S3_86C805) { + s3->color_16bit = !!(svga->crtc[0x43] & 0x08); + if (svga->bpp == 24) + s3->color_16bit = 0; - if (s3->chip != S3_86C801) - mask |= 0x01; - switch (svga->crtc[0x50] & mask) { - case 0x00: - if (s3->color_16bit) + if (s3->color_16bit) + s3->width = 1024; + else { + if (s3->chip <= S3_86C924) s3->width = 1024; - else - s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; - break; - case 0x01: - s3->width = 1152; - break; - case 0x40: - s3->width = 640; - break; - case 0x80: - s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; - break; - case 0x81: - s3->width = 1600; - break; - case 0xc0: - s3->width = 1280; - break; + } + } - default: - break; + if (s3->chip >= S3_86C928) { + if (s3->chip != S3_86C801) + mask |= 0x01; + + switch (svga->crtc[0x50] & mask) { + case 0x00: + s3->width = (svga->crtc[0x31] & 0x02) ? 2048 : 1024; + if (s3->color_16bit) + s3->width = 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 0x04)) ? 1600 : 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + + default: + break; + } } if (svga->crtc[0x33] & 0x20) { @@ -3382,7 +3548,6 @@ s3_recalctimings(svga_t *svga) #endif if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { - svga->vram_display_mask = s3->vram_mask; s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, " "attr=%02x, hdisp=%d.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, @@ -3965,6 +4130,17 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; break; + case S3_VISION968: + switch (s3->card_type) { + case S3_MIROVIDEO40SV_ERGO_968: + svga->hdisp = (svga->hdisp / 3) << 2; + svga->dots_per_clock = (svga->hdisp / 3) << 2; + break; + default: + break; + } + break; + case S3_TRIO64: case S3_TRIO32: svga->hdisp /= 3; @@ -4133,23 +4309,27 @@ s3_recalctimings(svga_t *svga) default: break; } + svga->vram_display_mask = s3->vram_mask; } else { - svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; - if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x31] & 0x08) { - svga->vram_display_mask = s3->vram_mask; - if (svga->bpp == 8) { - /*Enhanced 4bpp mode, just like the 8bpp mode per the spec. */ - svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - } - } + if (svga->crtc[0x31] & 0x08) { + if (!(svga->crtc[0x5e] & 0x04)) + svga->vblankstart = svga->dispend; /*Applies only to Enhanced modes*/ + + /*Enhanced 4bpp mode, just like the 8bpp mode per the spec. */ + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; + svga->vram_display_mask = s3->vram_mask; + } else { + svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; + s3_log("CRTC31 bit 0=%x, CRTC32 bit 6=%02x.\n", (svga->crtc[0x31] & 0x01), svga->crtc[0x32] & 0x40); + if (!(svga->crtc[0x31] & 0x01)) { /*Bank Enable bit*/ + svga->write_bank = 0; + svga->read_bank = 0; } } } - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864)) + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) svga->hoverride = 1; else svga->hoverride = 0; @@ -4258,7 +4438,6 @@ s3_trio64v_recalctimings(svga_t *svga) svga->lowres = (!!(svga->attrregs[0x10] & 0x40) && !(svga->crtc[0x3a] & 0x10)); if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { - svga->vram_display_mask = s3->vram_mask; switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -4285,9 +4464,14 @@ s3_trio64v_recalctimings(svga_t *svga) default: break; } - } else + svga->vram_display_mask = s3->vram_mask; + } else { svga->vram_display_mask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : s3->vram_mask; - + if (!(svga->crtc[0x31] & 0x01)) { /*Bank Enable bit*/ + svga->write_bank = 0; + svga->read_bank = 0; + } + } } else /*Streams mode*/ { if (s3->streams.buffer_ctrl & 1) @@ -4309,20 +4493,22 @@ s3_trio64v_recalctimings(svga_t *svga) svga->overlay.addr = s3->streams.sec_fb0; svga->overlay.ena = (svga->overlay.x >= 0); + svga->overlay.h_acc = s3->streams.dda_horiz_accumulator; svga->overlay.v_acc = s3->streams.dda_vert_accumulator; svga->rowoffset = s3->streams.pri_stride >> 3; - svga->vram_display_mask = s3->vram_mask; + if (svga->overlay.ena) { + svga->overlay.ena = (((s3->streams.blend_ctrl >> 24) & 7) == 0b000) || + (((s3->streams.blend_ctrl >> 24) & 7) == 0b101); + } switch ((s3->streams.pri_ctrl >> 24) & 0x7) { case 0: /*RGB-8 (CLUT)*/ svga->render = svga_render_8bpp_highres; break; case 3: /*KRGB-16 (1.5.5.5)*/ - svga->multiplier = 0.5; svga->render = svga_render_15bpp_highres; break; case 5: /*RGB-16 (5.6.5)*/ - svga->multiplier = 0.5; svga->render = svga_render_16bpp_highres; break; case 6: /*RGB-24 (8.8.8)*/ @@ -4335,6 +4521,7 @@ s3_trio64v_recalctimings(svga_t *svga) default: break; } + svga->vram_display_mask = s3->vram_mask; } svga->hoverride = 1; @@ -4397,8 +4584,6 @@ s3_updatemapping(s3_t *s3) else s3->linear_base &= 0x00ffffff; } - - s3_log("LinearBase=%x, crtc58bits=%x.\n", s3->linear_base, svga->crtc[0x58] & 0x13); if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); @@ -4457,6 +4642,7 @@ s3_updatemapping(s3_t *s3) } /* Memory mapped I/O. */ + s3_log("CRTC53=%02x, SEQREG9=%02x.\n", svga->crtc[0x53] & 0x18, svga->seqregs[9] & 0x80); if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) { mem_mapping_disable(&svga->mapping); if (s3->chip >= S3_TRIO64V) { @@ -4464,8 +4650,8 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); else mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } - mem_mapping_enable(&s3->mmio_mapping); + } else + mem_mapping_enable(&s3->mmio_mapping); } else { mem_mapping_disable(&s3->mmio_mapping); } @@ -4476,8 +4662,7 @@ s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); else mem_mapping_disable(&s3->new_mmio_mapping); - } - else + } else mem_mapping_disable(&s3->new_mmio_mapping); } } @@ -4522,11 +4707,12 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) case 0x4148: case 0x42e8: s3->subsys_stat &= ~val; + s3->accel.subsys_cntl = (s3->accel.subsys_cntl & 0xff00) | val; s3_update_irqs(s3); break; case 0x4149: case 0x42e9: - s3->subsys_cntl = val; + s3->accel.subsys_cntl = (s3->accel.subsys_cntl & 0xff) | (val << 8); s3_update_irqs(s3); break; case 0x4548: @@ -4587,7 +4773,7 @@ s3_accel_in(uint16_t port, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; int temp; - uint8_t temp2; + uint8_t temp2 = 0x00; if (!s3->enable_8514) return 0xff; @@ -4598,7 +4784,7 @@ s3_accel_in(uint16_t port, void *priv) return s3->subsys_stat; case 0x4149: case 0x42e9: - return s3->subsys_cntl; + return s3->accel.subsys_cntl >> 8; case 0x8148: case 0x82e8: @@ -4670,6 +4856,8 @@ s3_accel_in(uint16_t port, void *priv) case 0x9548: case 0x96e8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.maj_axis_pcnt & 0xff; } break; @@ -4773,9 +4961,20 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.bkgd_color >> 16; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.bkgd_color >> 16; + else + temp2 = s3->accel.bkgd_color & 0xff; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 16; + else + temp2 = s3->accel.bkgd_color & 0xff; + } + } else temp2 = s3->accel.bkgd_color & 0xff; return temp2; @@ -4786,13 +4985,34 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.bkgd_color >> 24; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.bkgd_color >> 24; + else + temp2 = s3->accel.bkgd_color >> 8; + + s3->accel.multifunc[0xe] ^= 0x10; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 24; + else + temp2 = s3->accel.bkgd_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { temp2 = s3->accel.bkgd_color >> 8; - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + if (s3->chip < S3_VISION964) + s3->accel.multifunc[0xe] ^= 0x10; + else { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } return temp2; } break; @@ -4800,32 +5020,51 @@ s3_accel_in(uint16_t port, void *priv) case 0xa2ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.bkgd_color & 0xff; - else - temp2 = s3->accel.bkgd_color >> 16; + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.bkgd_color >> 16; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.bkgd_color & 0xff; + else + temp2 = s3->accel.bkgd_color >> 16; + } return temp2; case 0xa14b: case 0xa2eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.bkgd_color >> 8; - else - temp2 = s3->accel.bkgd_color >> 24; - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.bkgd_color >> 24; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.bkgd_color >> 8; + else + temp2 = s3->accel.bkgd_color >> 24; + s3->accel.multifunc[0xe] ^= 0x10; + } return temp2; case 0xa548: case 0xa6e8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.frgd_color >> 16; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.frgd_color >> 16; + else + temp2 = s3->accel.frgd_color & 0xff; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 16; + else + temp2 = s3->accel.frgd_color & 0xff; + } + } else temp2 = s3->accel.frgd_color & 0xff; return temp2; @@ -4836,13 +5075,34 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.frgd_color >> 24; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.frgd_color >> 24; + else + temp2 = s3->accel.frgd_color >> 8; + + s3->accel.multifunc[0xe] ^= 0x10; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 24; + else + temp2 = s3->accel.frgd_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { temp2 = s3->accel.frgd_color >> 8; - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + if (s3->chip < S3_VISION964) + s3->accel.multifunc[0xe] ^= 0x10; + else { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } return temp2; } break; @@ -4850,23 +5110,31 @@ s3_accel_in(uint16_t port, void *priv) case 0xa6ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.frgd_color & 0xff; - else - temp2 = s3->accel.frgd_color >> 16; + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.frgd_color >> 16; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.frgd_color & 0xff; + else + temp2 = s3->accel.frgd_color >> 16; + } return temp2; case 0xa54b: case 0xa6eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.frgd_color >> 8; - else - temp2 = s3->accel.frgd_color >> 24; - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.frgd_color >> 24; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.frgd_color >> 8; + else + temp2 = s3->accel.frgd_color >> 24; + s3->accel.multifunc[0xe] ^= 0x10; + } return temp2; case 0xa948: @@ -4874,9 +5142,20 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.wrt_mask >> 16; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.wrt_mask >> 16; + else + temp2 = s3->accel.wrt_mask & 0xff; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 16; + else + temp2 = s3->accel.wrt_mask & 0xff; + } + } else temp2 = s3->accel.wrt_mask & 0xff; return temp2; @@ -4887,13 +5166,34 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.wrt_mask >> 24; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.wrt_mask >> 24; + else + temp2 = s3->accel.wrt_mask >> 8; + + s3->accel.multifunc[0xe] ^= 0x10; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 24; + else + temp2 = s3->accel.wrt_mask >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { temp2 = s3->accel.wrt_mask >> 8; - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + if (s3->chip < S3_VISION964) + s3->accel.multifunc[0xe] ^= 0x10; + else { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } return temp2; } break; @@ -4901,23 +5201,31 @@ s3_accel_in(uint16_t port, void *priv) case 0xaaea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.wrt_mask & 0xff; - else - temp2 = s3->accel.wrt_mask >> 16; + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.wrt_mask >> 16; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.wrt_mask & 0xff; + else + temp2 = s3->accel.wrt_mask >> 16; + } return temp2; case 0xa94b: case 0xaaeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.wrt_mask >> 8; - else - temp2 = s3->accel.wrt_mask >> 24; - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.wrt_mask >> 24; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.wrt_mask >> 8; + else + temp2 = s3->accel.wrt_mask >> 24; + s3->accel.multifunc[0xe] ^= 0x10; + } return temp2; case 0xad48: @@ -4925,9 +5233,20 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.rd_mask >> 16; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.rd_mask >> 16; + else + temp2 = s3->accel.rd_mask & 0xff; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 16; + else + temp2 = s3->accel.rd_mask & 0xff; + } + } else temp2 = s3->accel.rd_mask & 0xff; return temp2; @@ -4938,13 +5257,35 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.rd_mask >> 24; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.rd_mask >> 24; + else + temp2 = s3->accel.rd_mask >> 8; + + s3->accel.multifunc[0xe] ^= 0x10; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 24; + else + temp2 = s3->accel.rd_mask >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { temp2 = s3->accel.rd_mask >> 8; - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + if (s3->chip < S3_VISION964) + s3->accel.multifunc[0xe] ^= 0x10; + else { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } + return temp2; } break; @@ -4952,23 +5293,31 @@ s3_accel_in(uint16_t port, void *priv) case 0xaeea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.rd_mask & 0xff; - else - temp2 = s3->accel.rd_mask >> 16; + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.rd_mask >> 16; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.rd_mask & 0xff; + else + temp2 = s3->accel.rd_mask >> 16; + } return temp2; case 0xad4b: case 0xaeeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.rd_mask >> 8; - else - temp2 = s3->accel.rd_mask >> 24; - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.rd_mask >> 24; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.rd_mask >> 8; + else + temp2 = s3->accel.rd_mask >> 24; + s3->accel.multifunc[0xe] ^= 0x10; + } return temp2; case 0xb148: @@ -5045,33 +5394,58 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - switch (temp) { - case 0x0: - return s3->accel.multifunc[0x0] & 0xff; - case 0x1: - return s3->accel.multifunc[0x1] & 0xff; - case 0x2: - return s3->accel.multifunc[0x2] & 0xff; - case 0x3: - return s3->accel.multifunc[0x3] & 0xff; - case 0x4: - return s3->accel.multifunc[0x4] & 0xff; - case 0x5: - return s3->accel.multifunc[0xa] & 0xff; - case 0x6: - return s3->accel.multifunc[0xe] & 0xff; - case 0x7: - return s3->accel.cmd & 0xff; - case 0x8: - return s3->accel.subsys_cntl & 0xff; - case 0x9: - return s3->accel.setup_md & 0xff; - case 0xa: - return s3->accel.multifunc[0xd] & 0xff; + if (s3->chip >= S3_VISION964) { + temp = s3->accel.multifunc[0xf] & 0xf; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] & 0xff; + case 0x1: + return s3->accel.multifunc[0x1] & 0xff; + case 0x2: + return s3->accel.multifunc[0x2] & 0xff; + case 0x3: + return s3->accel.multifunc[0x3] & 0xff; + case 0x4: + return s3->accel.multifunc[0x4] & 0xff; + case 0x5: + return s3->accel.multifunc[0xa] & 0xff; + case 0x6: + return s3->accel.multifunc[0xe] & 0xff; + case 0x7: + return s3->accel.cmd & 0xff; + case 0x8: + return s3->accel.subsys_cntl & 0xff; + case 0x9: + return s3->accel.setup_md & 0xff; + case 0xa: + return s3->accel.multifunc[0xd] & 0xff; - default: - break; + default: + break; + } + } else { + temp = s3->accel.multifunc[0xf] & 7; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] & 0xff; + case 0x1: + return s3->accel.multifunc[0x1] & 0xff; + case 0x2: + return s3->accel.multifunc[0x2] & 0xff; + case 0x3: + return s3->accel.multifunc[0x3] & 0xff; + case 0x4: + return s3->accel.multifunc[0x4] & 0xff; + case 0x5: + return s3->accel.multifunc[0xa] & 0xff; + case 0x6: + return s3->accel.multifunc[0xe] & 0xff; + case 0x7: + return s3->accel.cmd & 0xff; + + default: + break; + } } return 0xff; } @@ -5081,34 +5455,60 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - s3->accel.multifunc[0xf]++; - switch (temp) { - case 0x0: - return s3->accel.multifunc[0x0] >> 8; - case 0x1: - return s3->accel.multifunc[0x1] >> 8; - case 0x2: - return s3->accel.multifunc[0x2] >> 8; - case 0x3: - return s3->accel.multifunc[0x3] >> 8; - case 0x4: - return s3->accel.multifunc[0x4] >> 8; - case 0x5: - return s3->accel.multifunc[0xa] >> 8; - case 0x6: - return s3->accel.multifunc[0xe] >> 8; - case 0x7: - return s3->accel.cmd >> 8; - case 0x8: - return (s3->accel.subsys_cntl >> 8) & ~0xe000; - case 0x9: - return (s3->accel.setup_md >> 8) & ~0xf000; - case 0xa: - return s3->accel.multifunc[0xd] >> 8; + if (s3->chip >= S3_VISION964) { + temp = s3->accel.multifunc[0xf] & 0xf; + s3->accel.multifunc[0xf] = (s3->accel.multifunc[0xf] + 1) & 0xf; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] >> 8; + case 0x1: + return s3->accel.multifunc[0x1] >> 8; + case 0x2: + return s3->accel.multifunc[0x2] >> 8; + case 0x3: + return s3->accel.multifunc[0x3] >> 8; + case 0x4: + return s3->accel.multifunc[0x4] >> 8; + case 0x5: + return s3->accel.multifunc[0xa] >> 8; + case 0x6: + return s3->accel.multifunc[0xe] >> 8; + case 0x7: + return s3->accel.cmd >> 8; + case 0x8: + return (s3->accel.subsys_cntl >> 8) & ~0xe000; + case 0x9: + return (s3->accel.setup_md >> 8) & ~0xf000; + case 0xa: + return s3->accel.multifunc[0xd] >> 8; - default: - break; + default: + break; + } + } else { + temp = s3->accel.multifunc[0xf] & 7; + s3->accel.multifunc[0xf] = (s3->accel.multifunc[0xf] + 1) & 7; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] >> 8; + case 0x1: + return s3->accel.multifunc[0x1] >> 8; + case 0x2: + return s3->accel.multifunc[0x2] >> 8; + case 0x3: + return s3->accel.multifunc[0x3] >> 8; + case 0x4: + return s3->accel.multifunc[0x4] >> 8; + case 0x5: + return s3->accel.multifunc[0xa] >> 8; + case 0x6: + return s3->accel.multifunc[0xe] >> 8; + case 0x7: + return s3->accel.cmd >> 8; + + default: + break; + } } return 0xff; } @@ -5118,21 +5518,27 @@ s3_accel_in(uint16_t port, void *priv) case 0xd2e8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); + return s3->accel.ropmix & 0xff; case 0xd149: case 0xd2e9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); + return s3->accel.ropmix >> 8; case 0xe548: case 0xe6e8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_bg_color >> 16; - else + + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 16; + else + temp2 = s3->accel.pat_bg_color & 0xff; + } else temp2 = s3->accel.pat_bg_color & 0xff; return temp2; @@ -5141,37 +5547,53 @@ s3_accel_in(uint16_t port, void *priv) case 0xe6e9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_bg_color >> 24; - else + + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 24; + else + temp2 = s3->accel.pat_bg_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } else temp2 = s3->accel.pat_bg_color >> 8; if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe54a: case 0xe6ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_bg_color & 0xff; - else - temp2 = s3->accel.pat_bg_color >> 16; + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.pat_bg_color >> 16; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.pat_bg_color & 0xff; + else + temp2 = s3->accel.pat_bg_color >> 16; + } return temp2; case 0xe54b: case 0xe6eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_bg_color >> 8; - else - temp2 = s3->accel.pat_bg_color >> 24; - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.pat_bg_color >> 24; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.pat_bg_color >> 8; + else + temp2 = s3->accel.pat_bg_color >> 24; + s3->accel.multifunc[0xe] ^= 0x10; + } return temp2; case 0xe948: @@ -5202,9 +5624,13 @@ s3_accel_in(uint16_t port, void *priv) case 0xeee8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_fg_color >> 16; - else + + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 16; + else + temp2 = s3->accel.pat_fg_color & 0xff; + } else temp2 = s3->accel.pat_fg_color & 0xff; return temp2; @@ -5213,37 +5639,53 @@ s3_accel_in(uint16_t port, void *priv) case 0xeee9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_fg_color >> 24; - else + + if (s3->bpp == 3) { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 24; + else + temp2 = s3->accel.pat_fg_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } else temp2 = s3->accel.pat_fg_color >> 8; if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xed4a: case 0xeeea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_fg_color & 0xff; - else - temp2 = s3->accel.pat_fg_color >> 16; + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.pat_fg_color >> 16; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.pat_fg_color & 0xff; + else + temp2 = s3->accel.pat_fg_color >> 16; + } return temp2; case 0xed4b: case 0xeeeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.pat_fg_color >> 8; - else - temp2 = s3->accel.pat_fg_color >> 24; - if (!(s3->accel.multifunc[0xe] & 0x200)) + if (s3->accel.multifunc[0xe] & 0x200) + temp2 = s3->accel.pat_fg_color >> 24; + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.pat_fg_color >> 8; + else + temp2 = s3->accel.pat_fg_color >> 24; + s3->accel.multifunc[0xe] ^= 0x10; + } return temp2; case 0xe148: @@ -5254,7 +5696,7 @@ s3_accel_in(uint16_t port, void *priv) if (s3->accel.cmd & 0x100) { 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)) s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else @@ -5263,7 +5705,7 @@ s3_accel_in(uint16_t port, void *priv) s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); break; case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) s3->accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); else @@ -5286,7 +5728,7 @@ s3_accel_in(uint16_t port, void *priv) if (s3->accel.cmd & 0x100) { 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)) s3->accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); else @@ -5295,7 +5737,7 @@ s3_accel_in(uint16_t port, void *priv) s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); break; case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.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) s3->accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); @@ -5409,10 +5851,21 @@ s3_accel_in_w(uint16_t port, void *priv) if (s3->accel.cmd & 0x1000) temp = (temp >> 8) | (temp << 8); s3->accel_start(8, 1, temp | (temp << 16), 0, s3); + } else { + if ((s3->bpp == 0) && s3->color_16bit) + 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; + + s3->accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); } else s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } else - s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } break; case 0x200: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -5501,15 +5954,40 @@ s3_accel_write(uint32_t addr, uint8_t val, void *priv) { s3_t *s3 = (s3_t *) priv; const svga_t *svga = &s3->svga; + uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff; if (!s3->enable_8514) return; if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); + if ((addr & addr_mask) < 0x8000) { + s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_BYTE); + } else { + switch (addr & addr_mask) { + case 0x83b0 ... 0x83df: + s3_out(addr & 0x3ff, val, s3); + break; + case 0x8504: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); + break; + case 0x8505: + s3->subsys_cntl = val; + s3_update_irqs(s3); + break; + case 0x850c: + s3->accel.advfunc_cntl = val; + s3_updatemapping(s3); + break; + case 0xff20: + s3->serialport = val; + i2c_gpio_set(s3->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); + break; + default: + s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_BYTE); + break; + } + } } else s3_accel_write_fifo(s3, addr & 0xffff, val); } @@ -5519,15 +5997,28 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) { s3_t *s3 = (s3_t *) priv; const svga_t *svga = &s3->svga; + uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff; if (!s3->enable_8514) return; if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); + if ((addr & (addr_mask - 1)) < 0x8000) { + s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_WORD); + } else { + switch (addr & (addr_mask - 1)) { + case 0x83d4: + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + break; + case 0xff20: + s3_accel_write_fifo(s3, addr, val); + break; + default: + s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_WORD); + break; + } + } } else s3_accel_write_fifo_w(s3, addr & 0xffff, val); } @@ -5536,16 +6027,162 @@ static void s3_accel_write_l(uint32_t addr, uint32_t val, void *priv) { s3_t *s3 = (s3_t *) priv; - const svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; + uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff; if (!s3->enable_8514) return; if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); + if ((addr & (addr_mask - 3)) < 0x8000) { + s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_DWORD); + } else { + switch (addr & (addr_mask - 3)) { + case 0x8180: + s3->streams.pri_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x8184: + s3->streams.chroma_ctrl = val; + break; + case 0x8190: + s3->streams.sec_ctrl = val; + s3->streams.dda_horiz_accumulator = val & 0xfff; + if (val & 0x1000) + s3->streams.dda_horiz_accumulator |= ~0xfff; + + s3->streams.sdif = (val >> 24) & 7; + break; + case 0x8194: + s3->streams.chroma_upper_bound = val; + break; + case 0x8198: + s3->streams.sec_filter = val; + s3->streams.k1_horiz_scale = val & 0x7ff; + if (val & 0x800) + s3->streams.k1_horiz_scale |= ~0x7ff; + + s3->streams.k2_horiz_scale = (val >> 16) & 0x7ff; + if ((val >> 16) & 0x800) + s3->streams.k2_horiz_scale |= ~0x7ff; + + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81a0: + s3->streams.blend_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81c0: + s3->streams.pri_fb0 = val & 0x3fffff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81c4: + s3->streams.pri_fb1 = val & 0x3fffff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81c8: + s3->streams.pri_stride = val & 0xfff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81cc: + s3->streams.buffer_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81d0: + s3->streams.sec_fb0 = val; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81d4: + s3->streams.sec_fb1 = val; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81d8: + s3->streams.sec_stride = val; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81dc: + s3->streams.overlay_ctrl = val; + break; + case 0x81e0: + s3->streams.k1_vert_scale = val & 0x7ff; + if (val & 0x800) + s3->streams.k1_vert_scale |= ~0x7ff; + break; + case 0x81e4: + s3->streams.k2_vert_scale = val & 0x7ff; + if (val & 0x800) + s3->streams.k2_vert_scale |= ~0x7ff; + break; + case 0x81e8: + s3->streams.dda_vert_accumulator = val & 0xfff; + if (val & 0x1000) + s3->streams.dda_vert_accumulator |= ~0xfff; + + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81ec: + s3->streams.fifo_ctrl = val; + break; + case 0x81f0: + s3->streams.pri_start = val; + s3->streams.pri_x = (val >> 16) & 0x7ff; + s3->streams.pri_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81f4: + s3->streams.pri_size = val; + s3->streams.pri_w = (val >> 16) & 0x7ff; + s3->streams.pri_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81f8: + s3->streams.sec_start = val; + s3->streams.sec_x = (val >> 16) & 0x7ff; + s3->streams.sec_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + case 0x81fc: + s3->streams.sec_size = val; + s3->streams.sec_w = (val >> 16) & 0x7ff; + s3->streams.sec_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = svga->monitor->mon_changeframecount;; + break; + + case 0x8504: + s3->subsys_stat &= ~(val & 0xff); + s3->subsys_cntl = (val >> 8); + s3_update_irqs(s3); + break; + + case 0x850c: + s3->accel.advfunc_cntl = val & 0xff; + s3_updatemapping(s3); + break; + + case 0xff20: + s3_accel_write_fifo(s3, addr, val); + break; + + default: + s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_DWORD); + break; + } + } } else s3_accel_write_fifo_l(s3, addr & 0xffff, val); } @@ -5944,15 +6581,11 @@ polygon_setup(s3_t *s3) } #define READ(addr, dat) \ - if ((s3->bpp == 0) && !s3->color_16bit) \ + if (((s3->bpp == 0) && !s3->color_16bit) || (s3->bpp == 2)) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if ((s3->bpp == 1) || (s3->color_16bit && (svga->bpp < 24))) \ + else if ((s3->bpp == 1) || s3->color_16bit) \ dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ - else if (s3->bpp == 2) \ - dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if (s3->color_16bit && (svga->bpp == 24)) { \ - dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ - } else \ + else \ dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; #define MIX_READ \ @@ -6009,11 +6642,11 @@ polygon_setup(s3_t *s3) } \ } -#define MIX \ - { \ - old_dest_dat = dest_dat; \ - MIX_READ \ - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); \ +#define MIX \ + { \ + old_dest_dat = dest_dat; \ + MIX_READ \ + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); \ } #define ROPMIX_READ(D, P, S) \ @@ -6798,20 +7431,14 @@ polygon_setup(s3_t *s3) } #define WRITE(addr, dat) \ - if ((s3->bpp == 0) && !s3->color_16bit) { \ - svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ + if (((s3->bpp == 0) && !s3->color_16bit) || (s3->bpp == 2)) { \ + svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if ((s3->bpp == 1) || (s3->color_16bit && (svga->bpp < 24))) { \ + } else if ((s3->bpp == 1) || s3->color_16bit) { \ vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ - } else if (s3->bpp == 2) { \ - svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ - svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if (s3->color_16bit && (svga->bpp == 24)) { \ - vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ - svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ } else { \ - vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ + vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ svga->changedvram[(dword_remap_l(svga, addr) & (s3->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \ } @@ -7197,758 +7824,16 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) } void -s3_911_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, void *priv) +s3_short_stroke_start(s3_t *s3, uint8_t ssv) { - s3_t *s3 = (s3_t *)priv; - svga_t *svga = &s3->svga; - uint32_t src_dat = 0; - uint32_t dest_dat; - uint32_t old_dest_dat; - int frgd_mix; - int bkgd_mix; - int clip_t = s3->accel.multifunc[1] & 0xfff; - int clip_l = s3->accel.multifunc[2] & 0xfff; - int clip_b = s3->accel.multifunc[3] & 0xfff; - int clip_r = s3->accel.multifunc[4] & 0xfff; - int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; - uint32_t mix_mask = (s3->accel.cmd & 0x200) ? 0x8000 : 0x80; - uint16_t *vram_w = (uint16_t *) svga->vram; - uint32_t *vram_l = (uint32_t *) svga->vram; - uint32_t rd_mask = s3->accel.rd_mask; - uint32_t wrt_mask = s3->accel.wrt_mask; - uint32_t frgd_color = s3->accel.frgd_color; - uint32_t bkgd_color = s3->accel.bkgd_color; - int cmd = s3->accel.cmd >> 13; + s3->accel.ssv_len = ssv & 0x0f; + s3->accel.ssv_dir = ssv & 0xe0; + s3->accel.ssv_draw = !!(ssv & 0x10); - if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) - s3->force_busy = 1; + if (s3_cpu_src(s3)) + return; /*Wait for data from CPU*/ - if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { - if (s3->color_16bit) { - if (count > 1) - count >>= 1; - } - } - - if (s3->color_16bit) - rd_mask &= 0xffff; - else - rd_mask &= 0xff; - - /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. - When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on - the NOP command)*/ - - switch (cmd) { - case 0: /*NOP (Short Stroke Vectors)*/ - if (s3->accel.ssv_state == 0) - break; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) { /*Radial*/ - while (count-- && s3->accel.ssv_len >= 0) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - if (s3->accel.ssv_draw) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - if (!s3->accel.ssv_len) - break; - - switch (s3->accel.ssv_dir & 0xe0) { - case 0x00: - s3->accel.cx++; - break; - case 0x20: - s3->accel.cx++; - s3->accel.cy--; - break; - case 0x40: - s3->accel.cy--; - break; - case 0x60: - s3->accel.cx--; - s3->accel.cy--; - break; - case 0x80: - s3->accel.cx--; - break; - case 0xa0: - s3->accel.cx--; - s3->accel.cy++; - break; - case 0xc0: - s3->accel.cy++; - break; - case 0xe0: - s3->accel.cx++; - s3->accel.cy++; - break; - - default: - break; - } - - s3->accel.ssv_len--; - s3->accel.cx &= 0xfff; - s3->accel.cy &= 0xfff; - } - - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - case 1: /*Draw line*/ - if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - s3->accel.sy = s3->accel.maj_axis_pcnt & 0x7ff; - - if (s3->color_16bit && (svga->bpp < 24)) { - if (s3->accel.wrt_mask != 0xffff) { - if (s3->accel.cur_x & 0x400) { - s3->accel.color_16bit_check = 0; - s3->accel.minus = 0x400; - } else { - s3->accel.color_16bit_check = 1; - s3->accel.minus = 0; - } - } else { - if (s3->accel.cur_x & 0x400) - s3->accel.color_16bit_check = 1; - else - s3->accel.color_16bit_check = 0; - - s3->accel.minus = 0; - } - } else { - s3->accel.color_16bit_check = 0; - s3->accel.minus = 0; - } - - if (s3_cpu_src(s3)) - return; /*Wait for data from CPU*/ - } - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) { /*Radial*/ - if (s3->color_16bit && (svga->bpp < 24)) { - if (s3->accel.color_16bit_check) - return; - if (s3->accel.wrt_mask != 0xffff) - wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); - } - - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - if (s3->color_16bit && (svga->bpp < 24)) - src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); - break; - case 1: - src_dat = frgd_color; - if (s3->color_16bit && (svga->bpp < 24)) - src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - - READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - - MIX - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - } - - mix_dat <<= 1; - mix_dat |= 1; - if ((s3->bpp == 0) && !s3->color_16bit) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - if (!s3->accel.sy) - break; - - switch (s3->accel.cmd & 0xe0) { - case 0x00: - s3->accel.cx++; - break; - case 0x20: - s3->accel.cx++; - s3->accel.cy--; - break; - case 0x40: - s3->accel.cy--; - break; - case 0x60: - s3->accel.cx--; - s3->accel.cy--; - break; - case 0x80: - s3->accel.cx--; - break; - case 0xa0: - s3->accel.cx--; - s3->accel.cy++; - break; - case 0xc0: - s3->accel.cy++; - break; - case 0xe0: - s3->accel.cx++; - s3->accel.cy++; - break; - - default: - break; - } - s3->accel.sy--; - s3->accel.cx &= 0xfff; - s3->accel.cy &= 0xfff; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } else { /*Bresenham*/ - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ - count = s3->accel.maj_axis_pcnt + 1; - s3->accel.temp_cnt = 16; - } - - if (s3->color_16bit && (svga->bpp < 24)) { - if (!s3->accel.b2e8_pix) { - if (!s3->accel.color_16bit_check) - wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); - else - return; - } - } - - s3_log("CMD=%04x, curx=%d, lwrtmask=%04x, actual wrtmask=%04x, frgdmix=%d, " - "bkgdmix=%d, input=%d, cnt=%d.\n", s3->accel.cmd, s3->accel.cur_x, - wrt_mask, s3->accel.wrt_mask, frgd_mix, bkgd_mix, cpu_input, count); - while (count-- && s3->accel.sy >= 0) { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { - mix_dat >>= 16; - s3->accel.temp_cnt = 16; - } - - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { - if (!s3->accel.color_16bit_check) - src_dat = s3->accel.bkgd_color_actual[0] | - (s3->accel.bkgd_color_actual[1] << 8); - } - break; - case 1: - src_dat = frgd_color; - if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix) { - if (!s3->accel.color_16bit_check) - src_dat = s3->accel.frgd_color_actual[0] | - (s3->accel.frgd_color_actual[1] << 8); - } - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - - READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - } - } - - if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { - if (s3->accel.temp_cnt > 0) { - s3->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; - } - } else { - mix_dat <<= 1; - mix_dat |= 1; - } - - if (s3->color_16bit) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (!s3->accel.sy) - break; - - if (s3->accel.cmd & 0x40) { - if (s3->accel.cmd & 0x80) - s3->accel.cy++; - else - s3->accel.cy--; - - if (s3->accel.err_term >= 0) { - s3->accel.err_term += s3->accel.destx_distp; - if (s3->accel.cmd & 0x20) - s3->accel.cx++; - else - s3->accel.cx--; - } else - s3->accel.err_term += s3->accel.desty_axstp; - } else { - if (s3->accel.cmd & 0x20) - s3->accel.cx++; - else - s3->accel.cx--; - - if (s3->accel.err_term >= 0) { - s3->accel.err_term += s3->accel.destx_distp; - if (s3->accel.cmd & 0x80) - s3->accel.cy++; - else - s3->accel.cy--; - } else - s3->accel.err_term += s3->accel.desty_axstp; - } - - s3->accel.sy--; - s3->accel.cx &= 0xfff; - s3->accel.cy &= 0xfff; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - case 2: /*Rectangle fill*/ - if (!cpu_input) { /*!cpu_input is trigger to start operation*/ - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - s3->accel.pix_trans_x_count = 0; - - s3->accel.dest = s3->accel.cy * s3->width; - - if (s3->color_16bit && (svga->bpp < 24)) { - if (s3->accel.cur_x & 0x400) { - s3->accel.color_16bit_check = 0; - s3->accel.minus = 0x400; - } else { - s3->accel.color_16bit_check = 1; - s3->accel.minus = 0; - } - - if (s3->accel.color_16bit_check) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x00) && !(s3->accel.cmd & 2)) - s3->accel.color_16bit_check_rectfill = !!s3_cpu_src(s3); - else - s3->accel.color_16bit_check_rectfill = 0; - } - - if (s3->accel.color_16bit_check_rectfill) { - if (s3->accel.color_16bit_check) { - s3->accel.pix_trans_ptr = (uint8_t *) calloc(1, (s3->accel.sx + 1) << 1); - s3->accel.pix_trans_ptr_cnt = (s3->accel.sx + 1) << 1; - } - } else - s3->accel.pix_trans_x_count = 0; - } else { - s3->accel.pix_trans_x_count = 0; - s3->accel.color_16bit_check = 0; - s3->accel.color_16bit_check_rectfill = 0; - s3->accel.minus = 0; - } - - if (s3_cpu_src(s3)) { - s3->data_available = 0; - return; /*Wait for data from CPU*/ - } else if (s3_cpu_dest(s3)) { - s3->data_available = 1; - return; - } - } - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ - count = s3->accel.maj_axis_pcnt + 1; - s3->accel.temp_cnt = 16; - } - - if (s3->color_16bit && (svga->bpp < 24)) { - if (!s3->accel.b2e8_pix) { - if (!s3->accel.color_16bit_check) { - wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); - } else if (s3->accel.color_16bit_check && (s3->accel.cmd == 0x40f3)) - return; - } - } - - while (count-- && s3->accel.sy >= 0) { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { - mix_dat >>= 16; - s3->accel.temp_cnt = 16; - } - - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (s3_cpu_dest(s3) && vram_mask) { - /* Mix data = current video memory value. */ - READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (s3_cpu_dest(s3)) { - READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, src_dat); - if (vram_mask) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix && (s3->accel.cmd != 0x41b3)) { - if (!s3->accel.color_16bit_check) - src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); - } - break; - case 1: - src_dat = frgd_color; - if (s3->color_16bit && (svga->bpp < 24) && !s3->accel.b2e8_pix && (s3->accel.cmd != 0x41b3)) { - if (!s3->accel.color_16bit_check) - src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); - } - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - } - - READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); - } - } - - if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { - if (s3->accel.temp_cnt > 0) { - s3->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; - } - } else { - mix_dat <<= 1; - mix_dat |= 1; - } - - if (s3->color_16bit) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (s3->accel.cmd & 0x20) - s3->accel.cx++; - else - s3->accel.cx--; - - s3->accel.cx &= 0xfff; - s3->accel.sx--; - if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - else - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - if (s3->accel.cmd & 0x80) - s3->accel.cy++; - else - s3->accel.cy--; - - s3->accel.cy &= 0xfff; - s3->accel.dest = s3->accel.cy * s3->width; - s3->accel.sy--; - - if (cpu_input) { - if (s3->accel.b2e8_pix) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - return; - } - if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - return; - } - } - } - break; - - case 6: /*BitBlt*/ - if (!cpu_input) { /*!cpu_input is trigger to start operation*/ - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; - - if (s3->color_16bit && (svga->bpp < 24)) { - if (s3->accel.destx_distp & 0x400) { - s3->accel.color_16bit_check = 0; - s3->accel.minus = 0x400; - } else { - s3->accel.color_16bit_check = 1; - s3->accel.minus = 0; - } - s3->accel.srcminus = 0x400; - } else { - s3->accel.color_16bit_check = 0; - s3->accel.minus = 0; - s3->accel.srcminus = 0; - } - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->color_16bit && (svga->bpp < 24)) { - if (!s3->accel.color_16bit_check) - wrt_mask = (s3->accel.wrt_mask_actual[0] | (s3->accel.wrt_mask_actual[1] << 8)); - else - return; - } - - if (!cpu_input && (frgd_mix == 3) && !vram_mask && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { - while (1) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { - READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, src_dat); - READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); - - dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); - - WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); - } - - s3->accel.cx++; - s3->accel.dx++; - s3->accel.sx--; - s3->accel.dx &= 0xfff; - if (s3->accel.sx < 0) { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - s3->accel.cy++; - s3->accel.dy++; - - s3->accel.dy &= 0xfff; - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (s3->accel.sy < 0) { /*It's evident that this is a clear undocumented difference compared to later chips, per what NT 3.5+ does to DX/DY.*/ - s3->accel.destx_distp = s3->accel.dx; - s3->accel.desty_axstp = s3->accel.dy; - return; - } - } - } - } else { - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && ((s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) { - if (vram_mask && (s3->accel.cmd & 0x10)) { - READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - if (s3->color_16bit && (svga->bpp < 24)) { - if (!s3->accel.color_16bit_check) - src_dat = s3->accel.bkgd_color_actual[0] | (s3->accel.bkgd_color_actual[1] << 8); - } - break; - case 1: - src_dat = frgd_color; - if (s3->color_16bit && (svga->bpp < 24)) { - if (!s3->accel.color_16bit_check) - src_dat = s3->accel.frgd_color_actual[0] | (s3->accel.frgd_color_actual[1] << 8); - } - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - READ(s3->accel.src + s3->accel.cx - s3->accel.srcminus, src_dat); - if (vram_mask && (s3->accel.cmd & 0x10)) - src_dat = ((src_dat & rd_mask) == rd_mask); - break; - - default: - break; - } - - READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); - - MIX - - if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { - WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - - if (s3->color_16bit) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - - if (s3->accel.cmd & 0x20) { - s3->accel.cx++; - s3->accel.dx++; - } else { - s3->accel.cx--; - s3->accel.dx--; - } - s3->accel.dx &= 0xfff; - s3->accel.sx--; - if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) { - s3->accel.cx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); - s3->accel.dx -= ((s3->accel.maj_axis_pcnt & 0xfff) + 1); - } else { - s3->accel.cx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); - s3->accel.dx += ((s3->accel.maj_axis_pcnt & 0xfff) + 1); - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) { - s3->accel.cy++; - s3->accel.dy++; - } else { - s3->accel.cy--; - s3->accel.dy--; - } - s3->accel.dy &= 0xfff; - s3->accel.src = s3->accel.cy * s3->width; - s3->accel.dest = s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input) - return; - - if (s3->accel.sy < 0) { /*It's evident that this is a clear undocumented difference compared to later chips, per what NT 3.5+ does to DX/DY.*/ - s3->accel.destx_distp = s3->accel.dx; - s3->accel.desty_axstp = s3->accel.dy; - return; - } - } - } - } - break; - - default: - break; - } -} - -void -s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) -{ - if (!cpu_input) { - s3->accel.ssv_len = ssv & 0x0f; - s3->accel.ssv_dir = ssv & 0xe0; - s3->accel.ssv_draw = ssv & 0x10; - - if (s3_cpu_src(s3)) { - return; /*Wait for data from CPU*/ - } - } - - s3->accel_start(count, cpu_input, mix_dat, cpu_dat, s3); + s3->accel_start(-1, 0, -1, 0, s3); } void @@ -7973,29 +7858,26 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi uint32_t *vram_l = (uint32_t *) svga->vram; uint32_t compare = s3->accel.color_cmp; uint8_t rop = s3->accel.ropmix & 0xff; - int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; uint32_t rd_mask = s3->accel.rd_mask; uint32_t wrt_mask = s3->accel.wrt_mask; uint32_t frgd_color = s3->accel.frgd_color; uint32_t bkgd_color = s3->accel.bkgd_color; int cmd = s3->accel.cmd >> 13; + int update = 1; uint32_t srcbase; uint32_t dstbase; - s3->accel.srcminus = 0; - s3->accel.minus = 0; - - if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) - cmd |= 8; + if (((s3->chip >= S3_TRIO64) || (s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) && (s3->accel.cmd & (1 << 11))) + cmd |= 0x08; // SRC-BASE/DST-BASE - if ((s3->accel.multifunc[0xd] >> 4) & 7) - srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); + if (((s3->accel.multifunc[0xd] >> 4) & 7) && (s3->chip >= S3_VISION964)) + srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 7); else srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); - if ((s3->accel.multifunc[0xd] >> 0) & 7) - dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); + if (((s3->accel.multifunc[0xd] >> 0) & 7) && (s3->chip >= S3_VISION964)) + dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 7); else dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); @@ -8010,10 +7892,36 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) s3->force_busy = 1; + if ((s3->bpp == 0) && s3->color_16bit && !s3->accel.b2e8_pix) { + if (cmd <= 2) { + if (s3->accel.cur_x & 0x400) { + if (s3->accel.cmd != 0x41b3) + wrt_mask = (wrt_mask << 8) & 0xff00; + else + wrt_mask &= 0xff; + + frgd_color = (frgd_color << 8) & 0xff00; + bkgd_color = (bkgd_color << 8) & 0xff00; + } else { + if (clip_r >= 0x400) { + wrt_mask &= 0xff; + frgd_color &= 0xff; + bkgd_color &= 0xff; + } + } + } else if (cmd == 6) { + if (s3->accel.destx_distp & 0x400) { + wrt_mask = (wrt_mask << 8) & 0xff00; + frgd_color = (frgd_color << 8) & 0xff00; + bkgd_color = (bkgd_color << 8) & 0xff00; + } + } + } + if (!cpu_input) s3->accel.dat_count = 0; - if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { + if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 0x02)))) { if ((s3->bpp == 3) && (count == 2)) { if (s3->accel.dat_count) { cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; @@ -8035,9 +7943,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi else if ((s3->bpp == 1) || s3->color_16bit) rd_mask &= 0xffff; - if (s3->bpp == 0) + if ((s3->bpp == 0) && !s3->color_16bit) compare &= 0xff; - else if (s3->bpp == 1) + else if ((s3->bpp == 1) || s3->color_16bit) compare &= 0xffff; switch (s3->accel.cmd & 0x600) { @@ -8058,19 +7966,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + /*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, multifuncE=%03x, 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, svgabpp=%d.\n", cmd, s3->accel.cmd, s3->bpp, s3->accel.multifunc[0x0e], 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, svga->bpp); + switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ if (s3->accel.ssv_state == 0) break; - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) /*Radial*/ - { + if (s3->accel.cmd & 0x08) { /*Radial*/ while (count-- && s3->accel.ssv_len >= 0) { if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -8091,7 +8000,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX @@ -8104,13 +8028,16 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; - if (!s3->accel.ssv_len) + if (!s3->accel.ssv_len) { + s3->accel.cur_x = s3->accel.cx & 0xfff; + s3->accel.cur_y = s3->accel.cy & 0xfff; break; + } switch (s3->accel.ssv_dir & 0xe0) { case 0x00: @@ -8150,25 +8077,23 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.cy &= 0xfff; } - - s3->accel.cur_x = s3->accel.cx & 0xfff; - s3->accel.cur_y = s3->accel.cy & 0xfff; } break; case 1: /*Draw line*/ if (!cpu_input) { + s3->accel.minus = 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.cur_x & 0x400)) + s3->accel.minus = 0x400; if (s3_cpu_src(s3)) return; /*Wait for data from CPU*/ } - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - if (s3->accel.cmd & 8) { /*Radial*/ + if (s3->accel.cmd & 0x08) { /*Radial*/ while (count-- && s3->accel.sy >= 0) { if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -8189,12 +8114,27 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); } } @@ -8278,12 +8218,27 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); } } @@ -8298,7 +8253,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat |= 1; } - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -8312,7 +8267,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi else s3->accel.cy--; - if (s3->accel.err_term >= 0) { + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { s3->accel.err_term += s3->accel.destx_distp; if (s3->accel.cmd & 0x20) s3->accel.cx++; @@ -8326,7 +8281,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi else s3->accel.cx--; - if (s3->accel.err_term >= 0) { + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { s3->accel.err_term += s3->accel.destx_distp; if (s3->accel.cmd & 0x80) s3->accel.cy++; @@ -8345,13 +8300,21 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } break; - case 2: /*Rectangle fill*/ + case 2: /*Rectangle fill*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { + s3->accel.minus = 0; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; + if ((s3->bpp == 0) && s3->color_16bit && (s3->accel.cur_x & 0x400)) + s3->accel.minus = 0x400; + + if (s3->accel.cur_x & 0x400) + s3_log("Rectangle Fill + 1024 FULLCMD=%04x: frgdcolor=%04x, s(%d,%d), c(%d,%d).\n", s3->accel.cmd, frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy); + else + s3_log("Rectangle Fill + 0 FULLCMD=%04x: frgdcolor=%04x, s(%d,%d), c(%d,%d).\n", s3->accel.cmd, frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy); s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -8364,21 +8327,19 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; } - while (count-- && s3->accel.sy >= 0) { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { + while (count-- && (s3->accel.sy >= 0)) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; s3->accel.temp_cnt = 16; } - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + if ((((s3->accel.cx >= clip_l) && (s3->accel.cx <= clip_r) && (s3->accel.cy >= clip_t) && (s3->accel.cy <= clip_b)) && !(s3->accel.multifunc[0xe] & 0x20)) || + (((s3->accel.cx < clip_l) && (s3->accel.cx > clip_r) && (s3->accel.cy < clip_t) && (s3->accel.cy > clip_b)) && (s3->accel.multifunc[0xe] & 0x20)) ) { if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (s3_cpu_dest(s3) && vram_mask) { @@ -8388,8 +8349,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat = mix_dat ? mix_mask : 0; } - if (s3_cpu_dest(s3)) { - READ(s3->accel.dest + s3->accel.cx, src_dat); + if (s3_cpu_dest(s3) || ((s3_cpu_src(s3)) && s3->color_16bit && (s3->bpp == 0) && (s3->accel.cmd == 0x41b3))) { + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, src_dat); if (vram_mask) src_dat = ((src_dat & rd_mask) == rd_mask); } else { @@ -8412,13 +8373,37 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3->accel.dest + s3->accel.cx, dest_dat); + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; - MIX + if (update) { + READ(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); + + if (s3_cpu_dest(s3)) { + if (vram_mask) { + MIX + } + } else { + MIX + } if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.cx, dest_dat); + if (s3->accel.cmd == 0x41b3) + s3_log("Full=%04x: Destination=%04x, OldDest=%04x, c=%d,%d.\n", s3->accel.cmd, dest_dat, old_dest_dat, s3->accel.cx, s3->accel.cy); + + WRITE(s3->accel.dest + s3->accel.cx - s3->accel.minus, dest_dat); } } } @@ -8434,7 +8419,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat |= 1; } - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -8447,12 +8432,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx &= 0xfff; s3->accel.sx--; if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - else - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x20) + s3->accel.cx -= (s3->accel.sx + 1); + else + s3->accel.cx += (s3->accel.sx + 1); + if (s3->accel.cmd & 0x80) s3->accel.cy++; else @@ -8494,8 +8480,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi end_y1 = s3->accel.desty_axstp; end_y2 = s3->accel.desty_axstp2; - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { int y = s3->accel.poly_cy; int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; @@ -8522,7 +8506,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ(s3->accel.dest + s3->accel.poly_x, dest_dat); MIX @@ -8557,41 +8556,43 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cur_x = s3->accel.poly_cx & 0xfff; s3->accel.cur_y = s3->accel.poly_cy & 0xfff; s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy2 & 0xfff; } break; - case 6: /*BitBlt*/ + case 6: /*BitBlt*/ if (!cpu_input) { /*!cpu_input is trigger to start operation*/ + s3->accel.minus = 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; + if ((s3->bpp == 0) && s3->color_16bit && (clip_r > 0x3ff) && (s3->accel.destx_distp & 0x400)) + s3->accel.minus = 0x400; + 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); } - if ((s3->accel.cmd & 0x100) && !cpu_input) { + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - } - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && (s3->accel.bkgd_mix & 0xf) == 7) { + 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)) { while (1) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { - READ(s3->accel.src + s3->accel.cx, src_dat); - READ(s3->accel.dest + s3->accel.dx, dest_dat); - + 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); + READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); + } } s3->accel.cx++; @@ -8606,9 +8607,8 @@ 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.dy &= 0xfff; - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; + s3->accel.src = srcbase + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.sy--; @@ -8620,8 +8620,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } } else { - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && ((s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) { + 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)) { READ(s3->accel.src + s3->accel.cx, mix_dat); mix_dat = ((mix_dat & rd_mask) == rd_mask); @@ -8638,7 +8638,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi src_dat = cpu_dat; break; case 3: - READ(s3->accel.src + s3->accel.cx, src_dat); + READ(s3->accel.src + s3->accel.cx - s3->accel.minus, src_dat); if (vram_mask && (s3->accel.cmd & 0x10)) src_dat = ((src_dat & rd_mask) == rd_mask); break; @@ -8647,13 +8647,28 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { - READ(s3->accel.dest + s3->accel.dx, dest_dat); + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + READ(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); MIX if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + WRITE(s3->accel.dest + s3->accel.dx - s3->accel.minus, dest_dat); } } } @@ -8661,7 +8676,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -8692,7 +8707,6 @@ 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.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -8711,7 +8725,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } break; - case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ + case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ if (!cpu_input) /*!cpu_input is trigger to start operation*/ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; @@ -8733,15 +8747,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); } - if ((s3->accel.cmd & 0x100) && !cpu_input) { + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - } - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + 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) { READ(s3->accel.src + s3->accel.cx, mix_dat); mix_dat = ((mix_dat & rd_mask) == rd_mask); @@ -8749,10 +8759,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: - src_dat = s3->accel.bkgd_color; + src_dat = bkgd_color; break; case 1: - src_dat = s3->accel.frgd_color; + src_dat = frgd_color; break; case 2: src_dat = cpu_dat; @@ -8767,7 +8777,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); MIX @@ -8780,7 +8805,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; else cpu_dat >>= 16; @@ -8812,15 +8837,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.dy--; } - s3->accel.dy &= 0xfff; s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); s3->accel.dest = dstbase + s3->accel.dy * s3->width; s3->accel.sy--; - if (cpu_input) { + if (cpu_input) return; - } + if (s3->accel.sy < 0) { s3->accel.destx_distp = s3->accel.dx; s3->accel.desty_axstp = s3->accel.dy; @@ -8858,7 +8882,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { src_dat = s3->accel.frgd_color; - if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) && (s3->accel.cmd & 0x10)) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX @@ -8892,7 +8931,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { src_dat = s3->accel.frgd_color; - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); MIX @@ -8942,9 +8996,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi end_y1 = s3->accel.desty_axstp; end_y2 = s3->accel.desty_axstp2; - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { int y = s3->accel.poly_cy; int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; @@ -8981,7 +9032,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ(s3->accel.dest + s3->accel.poly_x, dest_dat); MIX @@ -9053,9 +9119,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - while (count-- && s3->accel.sy >= 0) { if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -9114,7 +9177,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } } - if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX @@ -9205,18 +9283,19 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) return s3->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ else return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - break; + break; case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ - case 0x08: switch (s3->chip) { /*Revision ID*/ - case S3_TRIO64V: - return 0x40; - case S3_TRIO64V2: - return 0x16; /*Confirmed on an onboard 64V2/DX*/ - default: - return 0x00; + case 0x08: + switch (s3->chip) { /*Revision ID*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; } break; case 0x09: @@ -9238,24 +9317,13 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) case 0x0d: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; - case 0x10: - return 0x00; /*Linear frame buffer address*/ - case 0x11: - return 0x00; case 0x12: - if (svga->crtc[0x53] & 0x08) - return 0x00; - else - return (svga->crtc[0x5a] & 0x80); - break; + return ((s3->chip == S3_VISION868) || (s3->chip == S3_VISION968) || (s3->chip >= S3_TRIO64V)) ? 0x00 : + (svga->crtc[0x5a] & 0x80); case 0x13: - if (svga->crtc[0x53] & 0x08) { - return (s3->chip >= S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); - } else { - return svga->crtc[0x59]; - } - break; + return ((s3->chip == S3_VISION868) || (s3->chip == S3_VISION968) || (s3->chip >= S3_TRIO64V)) ? + (svga->crtc[0x59] & 0xfc) : svga->crtc[0x59]; case 0x30: return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ @@ -9305,17 +9373,22 @@ s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) + if (val & PCI_COMMAND_IO) { s3_io_set(s3); - else + } else s3_io_remove(s3); - s3->pci_regs[PCI_REG_COMMAND] = (val & 0x23); + + if (s3->chip >= S3_TRIO64V) + s3->pci_regs[PCI_REG_COMMAND] = (val & 0x27); + else + s3->pci_regs[PCI_REG_COMMAND] = (val & 0x23); + s3_updatemapping(s3); - break; + return; case 0x07: if (s3->chip == S3_TRIO64V2) { - s3->pci_regs[0x07] = val & 0x3e; + s3->pci_regs[0x07] &= ~(val & 0x30); return; } break; @@ -9328,18 +9401,14 @@ s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x12: - if (!(svga->crtc[0x53] & 0x08)) { - svga->crtc[0x5a] = (svga->crtc[0x5a] & 0x7f) | (val & 0x80); + if (s3->chip < S3_TRIO64V) { + svga->crtc[0x5a] = val & 0x80; s3_updatemapping(s3); } break; case 0x13: - if (svga->crtc[0x53] & 0x08) { - svga->crtc[0x59] = (s3->chip >= S3_TRIO64V) ? (val & 0xfc) : (val & 0xfe); - } else { - svga->crtc[0x59] = val; - } + svga->crtc[0x59] = (s3->chip >= S3_TRIO64V) ? (val & 0xfc) : val; s3_updatemapping(s3); break; @@ -9436,7 +9505,8 @@ static int vram_sizes[] = { static void s3_disable_handlers(s3_t *s3) { - s3_io_remove(s3); + if (s3->pci) + s3_io_remove(s3); mem_mapping_disable(&s3->linear_mapping); mem_mapping_disable(&s3->mmio_mapping); @@ -9454,6 +9524,9 @@ s3_disable_handlers(s3_t *s3) reset_state->svga.timer = s3->svga.timer; reset_state->svga.timer8514 = s3->svga.timer8514; + + memset(s3->svga.vram, 0x00, s3->svga.vram_max + 8); + memset(s3->svga.changedvram, 0x00, (s3->svga.vram_max >> 12) + 1); } static void @@ -9464,6 +9537,10 @@ s3_reset(void *priv) if (reset_state != NULL) { s3->accel.multifunc[0xe] &= ~(0x200 | 0x10); s3_disable_handlers(s3); + s3->force_busy = 0; + s3->blitter_busy = 0; + s3->fifo_read_idx = 0; + s3->fifo_write_idx = 0; if (s3->pci) reset_state->pci_slot = s3->pci_slot; @@ -9745,6 +9822,7 @@ s3_init(const device_t *info) vram_size = vram << 20; else vram_size = 512 << 10; + s3->vram_mask = vram_size - 1; s3->vram = vram; @@ -9758,6 +9836,7 @@ s3_init(const device_t *info) s3->pci = !!(info->flags & DEVICE_PCI); s3->vlb = !!(info->flags & DEVICE_VLB); + mem_mapping_add(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, @@ -9801,6 +9880,8 @@ s3_init(const device_t *info) NULL); } } + 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); svga->hwcursor.cur_ysize = 64; @@ -9899,10 +9980,7 @@ s3_init(const device_t *info) svga->force_old_addr = 1; - if (s3->chip <= S3_86C924) - s3->accel_start = s3_911_accel_start; - else - s3->accel_start = s3_accel_start; + s3->accel_start = s3_accel_start; switch (s3->card_type) { case S3_ORCHID_86C911: @@ -9913,11 +9991,16 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; - s3->width = 1024; svga->ramdac = device_add(&sc11483_ramdac_device); - svga->clock_gen = device_add(&av9194_device); - svga->getclock = av9194_getclock; + if (s3->card_type == S3_ORCHID_86C911) { + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + } else { + /* DCS2824-0 = Diamond ICD2061A-compatible. */ + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + } break; case S3_AMI_86C924: @@ -9927,7 +10010,6 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; - s3->width = 1024; svga->ramdac = device_add(&att490_ramdac_device); svga->clock_gen = device_add(&ics2494an_305_device); @@ -10027,6 +10109,7 @@ s3_init(const device_t *info) stepping = 0xc0; /*Vision864*/ else stepping = 0xc1; /*Vision864P*/ + s3->id = stepping; s3->id_ext = s3->id_ext_pci = stepping; s3->packed_mmio = 0; @@ -10152,10 +10235,6 @@ s3_init(const device_t *info) case S3_CARDEX_TRIO64VPLUS: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: - if (device_get_config_int("memory") == 1) - svga->vram_max = 1 << 20; /* Phoenix BIOS does not expect VRAM to be mirrored. */ - /* Fall over. */ - fallthrough; case S3_NUMBER9_9FX: svga->decode_mask = (4 << 20) - 1; s3->id = 0xe1; /*Trio64*/ @@ -10203,6 +10282,8 @@ s3_init(const device_t *info) s3->i2c = i2c_gpio_init("ddc_s3"); s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); + s3->accel.multifunc[0xd] = 0xd000; + s3->accel.multifunc[0xe] = 0xe000; s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); @@ -10462,109 +10543,136 @@ s3_force_redraw(void *priv) s3->svga.fullchange = s3->svga.monitor->mon_changeframecount; } +// clang-format off static const device_config_t s3_orchid_86c911_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1, - .selection = { - { .description = "512 KB", - .value = 0 }, - { .description = "1 MB", - .value = 1 }, - { .description = "" } } }, - { .type = CONFIG_END } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 0 }, + { .description = "1 MB", .value = 1 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t s3_9fx_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2, - .selection = { - { .description = "1 MB", - .value = 1 }, - { .description = "2 MB", - .value = 2 }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { - .description = "" } } }, - { .type = CONFIG_END } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + /* Trio64 also supports 4 MB, however the Number Nine BIOS does not */ + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t s3_phoenix_trio32_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2, - .selection = { - { .description = "512 KB", - .value = 0 }, - { .description = "1 MB", - .value = 1 }, - { .description = "2 MB", - .value = 2 }, - { .description = "" } } }, - { .type = CONFIG_END } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 0 }, + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t s3_standard_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { .description = "1 MB", - .value = 1 }, - { .description = "2 MB", - .value = 2 }, - { .description = "4 MB", - .value = 4 }, - { .description = "" } } }, - { .type = CONFIG_END } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t s3_968_config[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { .description = "1 MB", - .value = 1 }, - { .description = "2 MB", - .value = 2 }, - { .description = "4 MB", - .value = 4 }, - { .description = "8 MB", - .value = 8 }, - { .description = "" } } }, - { .type = CONFIG_END } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "8 MB", .value = 8 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t s3_standard_config2[] = { - { .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { .description = "2 MB", - .value = 2 }, - { .description = "4 MB", - .value = 4 }, - { .description = "" } } }, - { .type = CONFIG_END } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } }; +// clang-format on const device_t s3_orchid_86c911_isa_device = { .name = "S3 86c911 ISA (Orchid Fahrenheit 1280)", .internal_name = "orchid_s3_911", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = S3_ORCHID_86C911, .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_orchid_86c911_available }, + .available = s3_orchid_86c911_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_orchid_86c911_config @@ -10573,12 +10681,12 @@ const device_t s3_orchid_86c911_isa_device = { const device_t s3_diamond_stealth_vram_isa_device = { .name = "S3 86c911 ISA (Diamond Stealth VRAM)", .internal_name = "stealthvram_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = S3_DIAMOND_STEALTH_VRAM, .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth_vram_available }, + .available = s3_diamond_stealth_vram_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_orchid_86c911_config @@ -10587,12 +10695,12 @@ const device_t s3_diamond_stealth_vram_isa_device = { const device_t s3_ami_86c924_isa_device = { .name = "S3 86c924 ISA (AMI)", .internal_name = "ami_s3_924", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = S3_AMI_86C924, .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_ami_86c924_available }, + .available = s3_ami_86c924_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_orchid_86c911_config @@ -10601,12 +10709,12 @@ const device_t s3_ami_86c924_isa_device = { const device_t s3_spea_mirage_86c801_isa_device = { .name = "S3 86c801 ISA (SPEA Mirage ISA)", .internal_name = "px_s3_v7_801_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = S3_SPEA_MIRAGE_86C801, .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_spea_mirage_86c801_available }, + .available = s3_spea_mirage_86c801_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10620,7 +10728,7 @@ const device_t s3_86c805_onboard_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = NULL }, + .available = NULL, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10634,7 +10742,7 @@ const device_t s3_spea_mirage_86c805_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_spea_mirage_86c805_available }, + .available = s3_spea_mirage_86c805_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10648,7 +10756,7 @@ const device_t s3_mirocrystal_8s_805_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_mirocrystal_8s_805_available }, + .available = s3_mirocrystal_8s_805_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10662,7 +10770,7 @@ const device_t s3_mirocrystal_10sd_805_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_mirocrystal_10sd_805_available }, + .available = s3_mirocrystal_10sd_805_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10671,12 +10779,12 @@ const device_t s3_mirocrystal_10sd_805_vlb_device = { const device_t s3_phoenix_86c801_isa_device = { .name = "S3 86c801 ISA (Phoenix)", .internal_name = "px_86c801_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = S3_PHOENIX_86C801, .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_86c80x_available }, + .available = s3_phoenix_86c80x_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10690,7 +10798,7 @@ const device_t s3_phoenix_86c805_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_86c80x_available }, + .available = s3_phoenix_86c80x_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10699,12 +10807,12 @@ const device_t s3_phoenix_86c805_vlb_device = { const device_t s3_metheus_86c928_isa_device = { .name = "S3 86c928 ISA (Metheus Premier 928)", .internal_name = "metheus928_isa", - .flags = DEVICE_AT | DEVICE_ISA, + .flags = DEVICE_ISA16, .local = S3_METHEUS_86C928, .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_metheus_86c928_available }, + .available = s3_metheus_86c928_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10718,7 +10826,7 @@ const device_t s3_metheus_86c928_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_metheus_86c928_available }, + .available = s3_metheus_86c928_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10732,7 +10840,7 @@ const device_t s3_spea_mercury_lite_86c928_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_spea_mercury_lite_pci_available }, + .available = s3_spea_mercury_lite_pci_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_orchid_86c911_config @@ -10746,7 +10854,7 @@ const device_t s3_mirocrystal_20sd_864_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_mirocrystal_20sd_864_vlb_available }, + .available = s3_mirocrystal_20sd_864_vlb_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10760,7 +10868,7 @@ const device_t s3_bahamas64_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_bahamas64_available }, + .available = s3_bahamas64_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10774,7 +10882,7 @@ const device_t s3_bahamas64_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_bahamas64_available }, + .available = s3_bahamas64_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10788,7 +10896,7 @@ const device_t s3_mirocrystal_20sv_964_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_mirocrystal_20sv_964_vlb_available }, + .available = s3_mirocrystal_20sv_964_vlb_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10802,7 +10910,7 @@ const device_t s3_mirocrystal_20sv_964_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_mirocrystal_20sv_964_pci_available }, + .available = s3_mirocrystal_20sv_964_pci_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10816,7 +10924,7 @@ const device_t s3_diamond_stealth64_964_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth64_964_available }, + .available = s3_diamond_stealth64_964_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10830,7 +10938,7 @@ const device_t s3_diamond_stealth64_964_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth64_964_available }, + .available = s3_diamond_stealth64_964_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10844,7 +10952,7 @@ const device_t s3_diamond_stealth64_968_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth64_968_available }, + .available = s3_diamond_stealth64_968_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config2 @@ -10858,7 +10966,7 @@ const device_t s3_diamond_stealth64_968_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth64_968_available }, + .available = s3_diamond_stealth64_968_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config2 @@ -10872,7 +10980,7 @@ const device_t s3_9fx_771_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_9fx_771_available }, + .available = s3_9fx_771_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_968_config @@ -10886,7 +10994,7 @@ const device_t s3_phoenix_vision968_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_vision968_available }, + .available = s3_phoenix_vision968_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10900,7 +11008,7 @@ const device_t s3_mirovideo_40sv_ergo_968_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_mirovideo_40sv_ergo_968_pci_available }, + .available = s3_mirovideo_40sv_ergo_968_pci_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10914,7 +11022,7 @@ const device_t s3_spea_mercury_p64v_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_spea_mercury_p64v_pci_available }, + .available = s3_spea_mercury_p64v_pci_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -10928,7 +11036,7 @@ const device_t s3_9fx_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_9fx_available }, + .available = s3_9fx_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10942,7 +11050,7 @@ const device_t s3_9fx_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_9fx_available }, + .available = s3_9fx_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -10956,7 +11064,7 @@ const device_t s3_phoenix_trio32_onboard_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = NULL }, + .available = NULL, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -10970,7 +11078,7 @@ const device_t s3_phoenix_trio32_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_trio32_available }, + .available = s3_phoenix_trio32_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -10984,7 +11092,7 @@ const device_t s3_phoenix_trio32_onboard_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = NULL }, + .available = NULL, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -10998,7 +11106,7 @@ const device_t s3_phoenix_trio32_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_trio32_available }, + .available = s3_phoenix_trio32_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -11012,7 +11120,7 @@ const device_t s3_diamond_stealth_se_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth_se_available }, + .available = s3_diamond_stealth_se_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -11026,7 +11134,7 @@ const device_t s3_diamond_stealth_se_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth_se_available }, + .available = s3_diamond_stealth_se_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -11040,7 +11148,7 @@ const device_t s3_phoenix_trio64_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_trio64_available }, + .available = s3_phoenix_trio64_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11054,7 +11162,7 @@ const device_t s3_phoenix_trio64_onboard_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = NULL }, + .available = NULL, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11068,7 +11176,7 @@ const device_t s3_phoenix_trio64_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_trio64_available }, + .available = s3_phoenix_trio64_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11082,7 +11190,7 @@ const device_t s3_stb_powergraph_64_video_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_stb_powergraph_64_video_available }, + .available = s3_stb_powergraph_64_video_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_phoenix_trio32_config @@ -11096,7 +11204,7 @@ const device_t s3_phoenix_trio64vplus_onboard_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = NULL }, + .available = NULL, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11110,7 +11218,7 @@ const device_t s3_phoenix_trio64vplus_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_trio64vplus_available }, + .available = s3_phoenix_trio64vplus_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11124,7 +11232,7 @@ const device_t s3_cardex_trio64vplus_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_cardex_trio64vplus_available }, + .available = s3_cardex_trio64vplus_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11138,7 +11246,7 @@ const device_t s3_phoenix_vision864_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_vision864_available }, + .available = s3_phoenix_vision864_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11152,7 +11260,7 @@ const device_t s3_phoenix_vision864_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_vision864_available }, + .available = s3_phoenix_vision864_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11166,7 +11274,7 @@ const device_t s3_9fx_531_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_9fx_531_available }, + .available = s3_9fx_531_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -11180,7 +11288,7 @@ const device_t s3_phoenix_vision868_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_phoenix_vision868_available }, + .available = s3_phoenix_vision868_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11194,7 +11302,7 @@ const device_t s3_diamond_stealth64_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth64_764_available }, + .available = s3_diamond_stealth64_764_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -11208,7 +11316,7 @@ const device_t s3_diamond_stealth64_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_diamond_stealth64_764_available }, + .available = s3_diamond_stealth64_764_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -11222,7 +11330,7 @@ const device_t s3_spea_mirage_p64_vlb_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_spea_mirage_p64_vlb_available }, + .available = s3_spea_mirage_p64_vlb_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_9fx_config @@ -11236,7 +11344,7 @@ const device_t s3_elsa_winner2000_pro_x_964_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_elsa_winner2000_pro_x_964_available }, + .available = s3_elsa_winner2000_pro_x_964_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_968_config @@ -11250,7 +11358,7 @@ const device_t s3_elsa_winner2000_pro_x_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_elsa_winner2000_pro_x_available }, + .available = s3_elsa_winner2000_pro_x_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_968_config @@ -11264,7 +11372,7 @@ const device_t s3_trio64v2_dx_pci_device = { .init = s3_init, .close = s3_close, .reset = s3_reset, - { .available = s3_trio64v2_dx_available }, + .available = s3_trio64v2_dx_available, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config @@ -11278,7 +11386,7 @@ const device_t s3_trio64v2_dx_onboard_pci_device = { .init = s3_init, .close = s3_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = s3_speed_changed, .force_redraw = s3_force_redraw, .config = s3_standard_config diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index d2f99ba14..91b186240 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -40,46 +40,59 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#ifdef MIN + #undef MIN +#endif +#ifdef MAX + #undef MAX +#endif +#ifdef CLAMP + #undef CLAMP +#endif + +static uint64_t virge_time = 0; + static int dither[4][4] = { - {0, 4, 1, 5}, - { 6, 2, 7, 3}, - { 1, 5, 0, 4}, - { 7, 3, 6, 2}, + {0, 4, 1, 5}, + {6, 2, 7, 3}, + {1, 5, 0, 4}, + {7, 3, 6, 2} }; -#define RB_SIZE 256 -#define RB_MASK (RB_SIZE - 1) - -#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) -#define RB_FULL (RB_ENTRIES == RB_SIZE) -#define RB_EMPTY (!RB_ENTRIES) - -#define FIFO_SIZE (16 * 4096) - -#define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - #define ROM_VIRGE_325 "roms/video/s3virge/86c325.bin" #define ROM_DIAMOND_STEALTH3D_2000 "roms/video/s3virge/s3virge.bin" +#define ROM_MIROCRYSTAL_3D "roms/video/s3virge/miro Crystal 3D 1.02.bin" #define ROM_DIAMOND_STEALTH3D_3000 "roms/video/s3virge/diamondstealth3000.vbi" #define ROM_STB_VELOCITY_3D "roms/video/s3virge/stb_velocity3d_110.BIN" #define ROM_VIRGE_DX "roms/video/s3virge/86c375_1.bin" #define ROM_DIAMOND_STEALTH3D_2000PRO "roms/video/s3virge/virgedxdiamond.vbi" #define ROM_VIRGE_GX "roms/video/s3virge/86c375_4.bin" #define ROM_VIRGE_GX2 "roms/video/s3virge/flagpoint.VBI" -#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/86c357.bin" +#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/DS3D4K v1.03 Brightness bug fix.bin" #define ROM_TRIO3D2X "roms/video/s3virge/TRIO3D2X_8mbsdr.VBI" -#define FIFO_STATE_IDLE 0 -#define FIFO_STATE_RUN 1 +#define RB_SIZE 256 +#define RB_MASK (RB_SIZE - 1) + +#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) +#define RB_FULL (RB_ENTRIES == RB_SIZE) +#define RB_EMPTY (!RB_ENTRIES) + +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) + +#define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) +#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) + +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff enum { S3_VIRGE_325, S3_DIAMOND_STEALTH3D_2000, + S3_MIROCRYSTAL_3D, S3_DIAMOND_STEALTH3D_3000, S3_STB_VELOCITY_3D, S3_VIRGE_DX, @@ -99,58 +112,80 @@ enum { }; enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), FIFO_WRITE_DWORD = (0x03 << 24) }; -typedef struct -{ - uint32_t addr_type; - uint32_t val; +typedef struct { + uint32_t addr_type; + uint32_t val; } fifo_entry_t; typedef struct s3d_t { - uint32_t cmd_set; - int clip_l, clip_r, clip_t, clip_b; + uint32_t cmd_set; + int clip_l; + int clip_r; + int clip_t; + int clip_b; - uint32_t dest_base; - uint32_t dest_str; + uint32_t dest_base; + uint32_t dest_str; - uint32_t z_base; - uint32_t z_str; + uint32_t z_base; + uint32_t z_str; - uint32_t tex_base; - uint32_t tex_bdr_clr; - uint32_t tbv, tbu; - int32_t TdVdX, TdUdX; - int32_t TdVdY, TdUdY; - uint32_t tus, tvs; + uint32_t tex_base; + uint32_t tex_bdr_clr; + uint32_t tbv; + uint32_t tbu; + int32_t TdVdX; + int32_t TdUdX; + int32_t TdVdY; + int32_t TdUdY; + uint32_t tus; + uint32_t tvs; - int32_t TdZdX, TdZdY; - uint32_t tzs; + int32_t TdZdX; + int32_t TdZdY; + uint32_t tzs; - int32_t TdWdX, TdWdY; - uint32_t tws; + int32_t TdWdX; + int32_t TdWdY; + uint32_t tws; - int32_t TdDdX, TdDdY; - uint32_t tds; + int32_t TdDdX; + int32_t TdDdY; + uint32_t tds; - int16_t TdGdX, TdBdX, TdRdX, TdAdX; - int16_t TdGdY, TdBdY, TdRdY, TdAdY; - uint32_t tgs, tbs, trs, tas; + int16_t TdGdX; + int16_t TdBdX; + int16_t TdRdX; + int16_t TdAdX; + int16_t TdGdY; + int16_t TdBdY; + int16_t TdRdY; + int16_t TdAdY; + uint32_t tgs; + uint32_t tbs; + uint32_t trs; + uint32_t tas; - uint32_t TdXdY12; - uint32_t txend12; - uint32_t TdXdY01; - uint32_t txend01; - uint32_t TdXdY02; - uint32_t txs; - uint32_t tys; - int ty01, ty12, tlr; + uint32_t TdXdY12; + uint32_t txend12; + uint32_t TdXdY01; + uint32_t txend01; + uint32_t TdXdY02; + uint32_t txs; + uint32_t tys; + int ty01; + int ty12; + int tlr; - uint8_t fog_r, fog_g, fog_b; + uint8_t fog_r; + uint8_t fog_g; + uint8_t fog_b; } s3d_t; typedef struct virge_t { @@ -158,43 +193,51 @@ typedef struct virge_t { mem_mapping_t mmio_mapping; mem_mapping_t new_mmio_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; + svga_t svga; - uint8_t bank; - uint8_t ma_ext; - uint8_t reg6b, lfb_bios; + uint8_t bank; + uint8_t ma_ext; - uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; + uint8_t virge_id; + uint8_t virge_id_high; + uint8_t virge_id_low; + uint8_t virge_rev; - uint8_t int_line; + uint32_t linear_base; + uint32_t linear_size; - uint32_t linear_base, linear_size; + uint8_t pci_regs[256]; + uint8_t pci_slot; - uint8_t pci_regs[256]; + int chip; - uint8_t pci_slot; - uint8_t irq_state; + int bilinear_enabled; + int dithering_enabled; + int memory_size; - int pci; - int chip; - int is_agp; + int pixel_count; + int tri_count; - int bilinear_enabled; - int dithering_enabled; - uint32_t memory_size; - uint32_t vram_mask; + thread_t * render_thread; + event_t * wake_render_thread; + event_t * wake_main_thread; + event_t * not_full_event; - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; + uint32_t hwc_fg_col; + uint32_t hwc_bg_col; + int hwc_col_stack_pos; - struct - { + struct { uint32_t src_base; uint32_t dest_base; - int clip_l, clip_r, clip_t, clip_b; - int dest_str, src_str; + int clip_l; + int clip_r; + int clip_t; + int clip_b; + int dest_str; + int src_str; uint32_t mono_pat_0; uint32_t mono_pat_1; uint32_t pat_bg_clr; @@ -202,20 +245,28 @@ typedef struct virge_t { uint32_t src_bg_clr; uint32_t src_fg_clr; uint32_t cmd_set; - int r_width, r_height; - int rsrc_x, rsrc_y; - int rdest_x, rdest_y; + int r_width; + int r_height; + int rsrc_x; + int rsrc_y; + int rdest_x; + int rdest_y; - int lxend0, lxend1; + int lxend0; + int lxend1; int32_t ldx; - uint32_t lxstart, lystart; + uint32_t lxstart; + uint32_t lystart; int lycnt; int line_dir; - int src_x, src_y; - int dest_x, dest_y; - int w, h; - uint8_t rop; + int src_x; + int src_y; + int dest_x; + int dest_y; + int w; + int h; + uint8_t rop; int data_left_count; uint32_t data_left; @@ -234,14 +285,14 @@ typedef struct virge_t { uint32_t dest_l, dest_r; } s3d; - s3d_t s3d_tri; + s3d_t s3d_tri; - s3d_t s3d_buffer[RB_SIZE]; - atomic_int s3d_read_idx, s3d_write_idx; - atomic_int s3d_busy; + s3d_t s3d_buffer[RB_SIZE]; + atomic_int s3d_read_idx; + atomic_int s3d_write_idx; + atomic_int s3d_busy; - struct - { + struct { uint32_t pri_ctrl; uint32_t chroma_ctrl; uint32_t sec_ctrl; @@ -266,42 +317,72 @@ typedef struct virge_t { uint32_t sec_start; uint32_t sec_size; - int sdif; + int sdif; - int pri_x, pri_y, pri_w, pri_h; - int sec_x, sec_y, sec_w, sec_h; + int pri_x; + int pri_y; + int pri_w; + int pri_h; + int sec_x; + int sec_y; + int sec_w; + int sec_h; } streams; - uint8_t cmd_dma; - uint32_t cmd_dma_base; - uint32_t dma_ptr; - uint64_t blitter_time; + fifo_entry_t fifo[FIFO_SIZE]; + atomic_int fifo_read_idx, fifo_write_idx; + atomic_int fifo_thread_run, render_thread_run; + + thread_t * fifo_thread; + event_t *wake_fifo_thread; + event_t * fifo_not_full_event; + + atomic_int virge_busy; + + uint8_t subsys_stat; + uint8_t subsys_cntl; + + int local; + + uint8_t serialport; + + uint8_t irq_state; + uint8_t advfunc_cntl; + + void *i2c, *ddc; + + int onboard; int fifo_slots_num; - struct { - uint32_t addr_type; - uint32_t val; - } fifo[FIFO_SIZE]; - atomic_int fifo_write_idx, fifo_read_idx; + uint32_t vram_mask; - pc_timer_t fifo_timer; - pc_timer_t render_timer; + uint8_t reg6b; + uint8_t lfb_bios; + uint8_t int_line; + uint8_t cmd_dma; - atomic_int virge_busy; - int local; - int fifo_state; + uint32_t cmd_dma_base; + uint32_t cmd_dma_buf_size; + uint32_t cmd_dma_buf_size_mask; + uint32_t cmd_base_addr; + uint32_t cmd_dma_write_ptr_reg; + uint32_t cmd_dma_write_ptr_update; + uint32_t cmd_dma_read_ptr_reg; + uint32_t dma_val; + uint32_t dma_dbl_words; + uint32_t dma_mmio_addr; + uint32_t dma_data_type; - uint8_t subsys_stat, subsys_cntl, advfunc_cntl; - - uint8_t serialport; - - void *i2c, *ddc; - - int waiting; - - int onboard; + int pci; + int is_agp; } virge_t; +static __inline void +wake_fifo_thread(virge_t *virge) { + /* Wake up FIFO thread if moving from idle */ + thread_set_event(virge->wake_fifo_thread); +} + static virge_t *reset_state = NULL; static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; @@ -309,45 +390,47 @@ static video_timings_t timing_diamond_stealth3d_3000_pci = { .type = VIDEO_PCI, static video_timings_t timing_virge_dx_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; static video_timings_t timing_virge_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; -static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri); +static void queue_triangle(virge_t *virge); -static void s3_virge_recalctimings(svga_t *svga); -static void s3_virge_updatemapping(virge_t *virge); +static void s3_virge_recalctimings(svga_t *svga); +static void s3_virge_updatemapping(virge_t *virge); -static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat); +static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat); static uint8_t s3_virge_mmio_read(uint32_t addr, void *priv); -static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *rivp); +static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv); static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *priv); static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv); static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv); static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv); +static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type); + enum { - CMD_SET_AE = 1, - CMD_SET_HC = (1 << 1), + CMD_SET_AE = 1, + CMD_SET_HC = (1 << 1), - CMD_SET_FORMAT_MASK = (7 << 2), - CMD_SET_FORMAT_8 = (0 << 2), - CMD_SET_FORMAT_16 = (1 << 2), - CMD_SET_FORMAT_24 = (2 << 2), + CMD_SET_FORMAT_MASK = (7 << 2), + CMD_SET_FORMAT_8 = (0 << 2), + CMD_SET_FORMAT_16 = (1 << 2), + CMD_SET_FORMAT_24 = (2 << 2), - CMD_SET_MS = (1 << 6), - CMD_SET_IDS = (1 << 7), - CMD_SET_MP = (1 << 8), - CMD_SET_TP = (1 << 9), + CMD_SET_MS = (1 << 6), + CMD_SET_IDS = (1 << 7), + CMD_SET_MP = (1 << 8), + CMD_SET_TP = (1 << 9), - CMD_SET_ITA_MASK = (3 << 10), - CMD_SET_ITA_BYTE = (0 << 10), - CMD_SET_ITA_WORD = (1 << 10), - CMD_SET_ITA_DWORD = (2 << 10), + CMD_SET_ITA_MASK = (3 << 10), + CMD_SET_ITA_BYTE = (0 << 10), + CMD_SET_ITA_WORD = (1 << 10), + CMD_SET_ITA_DWORD = (2 << 10), - CMD_SET_ZUP = (1 << 23), + CMD_SET_ZUP = (1 << 23), - CMD_SET_ZB_MODE = (3 << 24), + CMD_SET_ZB_MODE = (3 << 24), - CMD_SET_XP = (1 << 25), - CMD_SET_YP = (1 << 26), + CMD_SET_XP = (1 << 25), + CMD_SET_YP = (1 << 26), CMD_SET_COMMAND_MASK = (15 << 27) }; @@ -358,17 +441,19 @@ enum { #define CMD_SET_TWE (1 << 26) enum { - CMD_SET_COMMAND_BITBLT = (0 << 27), - CMD_SET_COMMAND_RECTFILL = (2 << 27), - CMD_SET_COMMAND_LINE = (3 << 27), - CMD_SET_COMMAND_POLY = (5 << 27), - CMD_SET_COMMAND_NOP = (15 << 27) + CMD_SET_COMMAND_BITBLT = (0 << 27), + CMD_SET_COMMAND_RECTFILL = (2 << 27), + CMD_SET_COMMAND_LINE = (3 << 27), + CMD_SET_COMMAND_POLY = (5 << 27), + CMD_SET_COMMAND_NOP = (15 << 27) }; #define INT_VSY (1 << 0) #define INT_S3D_DONE (1 << 1) #define INT_FIFO_OVF (1 << 2) #define INT_FIFO_EMP (1 << 3) +#define INT_HOST_DONE (1 << 4) +#define INT_CMD_DONE (1 << 5) #define INT_3DF_EMP (1 << 6) #define INT_MASK 0xff @@ -377,77 +462,20 @@ enum { #define SERIAL_PORT_SCR (1 << 2) #define SERIAL_PORT_SDR (1 << 3) -#ifdef ENABLE_S3_VIRGE_LOG -int s3_virge_do_log = ENABLE_S3_VIRGE_LOG; - -static void -s3_virge_log(const char *fmt, ...) -{ - va_list ap; - - if (s3_virge_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define s3_virge_log(fmt, ...) -#endif - -static void -queue_triangle(virge_t *virge) -{ - if (RB_FULL) { - s3_virge_log("RB FULL, TBD.\n"); - return; - } - - virge->s3d_buffer[virge->s3d_write_idx] = virge->s3d_tri; - virge->s3d_write_idx++; - if (virge->s3d_write_idx >= RB_SIZE) - virge->s3d_write_idx = 0; - - if (!virge->s3d_busy) - timer_set_delay_u64(&virge->render_timer, 100 * TIMER_USEC); -} - static void s3_virge_update_irqs(virge_t *virge) { - if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK))) + if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) pci_set_irq(virge->pci_slot, PCI_INTA, &virge->irq_state); else pci_clear_irq(virge->pci_slot, PCI_INTA, &virge->irq_state); } -static void -s3_virge_render_timer(void *priv) -{ - virge_t *virge = (virge_t *) priv; - - virge->s3d_busy = 1; - while (virge->s3d_read_idx < virge->s3d_write_idx) { - s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx]); - virge->s3d_read_idx++; - if (virge->s3d_read_idx >= RB_SIZE) - virge->s3d_read_idx = 0; - - if (RB_ENTRIES == RB_MASK) - timer_disable(&virge->render_timer); - } - virge->s3d_busy = 0; - virge->s3d_read_idx = 0; - virge->s3d_write_idx = 0; - virge->subsys_stat |= INT_S3D_DONE; - s3_virge_update_irqs(virge); -} - static void s3_virge_out(uint16_t addr, uint8_t val, void *priv) { virge_t *virge = (virge_t *) priv; - svga_t *svga = &virge->svga; + svga_t * svga = &virge->svga; uint8_t old; uint32_t cursoraddr; @@ -457,12 +485,11 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c5: if (svga->seqaddr >= 0x10) { - svga->seqregs[svga->seqaddr & 0x1f] = val; + svga->seqregs[svga->seqaddr] = val; svga_recalctimings(svga); return; } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { + if (svga->seqaddr == 4) { /*Chain-4 - update banking*/ if (val & 8) svga->write_bank = svga->read_bank = virge->bank << 16; else @@ -486,19 +513,17 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) + if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && + (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && + (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) return; if ((svga->crtcreg >= 0x40) && ((svga->crtc[0x39] & 0xe0) != 0xa0)) return; if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) return; - if (svga->crtcreg >= 0x80) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (svga->crtcreg > 0x18) - s3_virge_log("OUTB VGA reg = %02x, val = %02x\n", svga->crtcreg, val); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; switch (svga->crtcreg) { case 0x31: @@ -556,7 +581,8 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.xoff = svga->crtc[0x4e] & 0x3f; svga->hwcursor.yoff = svga->crtc[0x4f] & 0x3f; cursoraddr = (virge->memory_size == 8) ? 0x1fff : 0x0fff; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16); + svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | + svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16); break; case 0x4a: @@ -580,7 +606,7 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) switch (virge->hwc_col_stack_pos) { case 0: virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; - break; + break; case 1: virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); break; @@ -644,7 +670,8 @@ 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->crtc[8] & 0x60) >> 5); + svga->ma_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); } else { @@ -662,10 +689,9 @@ s3_virge_out(uint16_t addr, uint8_t val, void *priv) } static uint8_t -s3_virge_in(uint16_t addr, void *priv) -{ +s3_virge_in(uint16_t addr, void *priv) { virge_t *virge = (virge_t *) priv; - svga_t *svga = &virge->svga; + svga_t * svga = &virge->svga; uint8_t ret; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -681,17 +707,17 @@ s3_virge_in(uint16_t addr, void *priv) case 0x3c5: if (svga->seqaddr >= 8) - ret = svga->seqregs[svga->seqaddr & 0x1f]; + ret = svga->seqregs[svga->seqaddr]; else if (svga->seqaddr <= 4) ret = svga_in(addr, svga); else ret = 0xff; break; - case 0x3D4: + case 0x3d4: ret = svga->crtcreg; break; - case 0x3D5: + case 0x3d5: switch (svga->crtcreg) { case 0x2d: ret = virge->virge_id_high; @@ -716,7 +742,7 @@ s3_virge_in(uint16_t addr, void *priv) break; case 0x45: virge->hwc_col_stack_pos = 0; - ret = svga->crtc[0x45]; + ret = svga->crtc[0x45]; break; case 0x51: ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); @@ -763,13 +789,16 @@ s3_virge_in(uint16_t addr, void *priv) ret = svga_in(addr, svga); break; } + return ret; } static void s3_virge_recalctimings(svga_t *svga) { - const virge_t *virge = (virge_t *) svga->priv; + int n, r, m; + double freq; + virge_t *virge = (virge_t *) svga->priv; svga->hdisp = svga->hdisp_old; @@ -785,36 +814,35 @@ s3_virge_recalctimings(svga_t *svga) } if (svga->crtc[0x5d] & 0x01) - svga->htotal += 0x100; + svga->htotal |= 0x100; if (svga->crtc[0x5d] & 0x02) { - svga->hdisp_time += 0x100; - svga->hdisp += 0x100 * svga->dots_per_clock; + svga->hdisp_time |= 0x100; + svga->hdisp |= (0x100 * svga->dots_per_clock); } if (svga->crtc[0x5e] & 0x01) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (svga->crtc[0x5e] & 0x02) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (svga->crtc[0x5e] & 0x04) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (svga->crtc[0x5e] & 0x10) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (svga->crtc[0x5e] & 0x40) - svga->split += 0x400; + svga->split |= 0x400; svga->interlace = svga->crtc[0x42] & 0x20; if (((svga->miscout >> 2) & 3) == 3) { - int n = svga->seqregs[0x12] & 0x1f; - int r = (svga->seqregs[0x12] >> 5); - - if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) - r &= 7; - else if (virge->chip >= S3_VIRGEGX2) - r &= 10; + n = svga->seqregs[0x12] & 0x1f; + if (virge->chip >= S3_VIRGEGX2) { + r = (svga->seqregs[0x12] >> 6) & 0x03; + r |= ((svga->seqregs[0x29] & 0x01) << 2); + } else if ((virge->chip == S3_VIRGEVX) || (virge->chip == S3_VIRGEDX)) + r = (svga->seqregs[0x12] >> 5) & 0x07; else - r &= 3; + r = (svga->seqregs[0x12] >> 5) & 0x03; - int m = svga->seqregs[0x13] & 0x7f; - double freq = (((double) m + 2) / (((double) n + 2) * (double) (1 << r))) * 14318184.0; + m = svga->seqregs[0x13] & 0x7f; + freq = (((double) m + 2) / (((double) n + 2) * (double) (1 << r))) * 14318184.0; svga->clock = (cpuclock * (float) (1ULL << 32)) / freq; } @@ -840,47 +868,111 @@ s3_virge_recalctimings(svga_t *svga) video_force_resize_set_monitor(1, svga->monitor_index); } - /* ViRGE/GX2 and later does not use primary stream registers. */ - if ((svga->crtc[0x67] & 0xc) != 0xc || virge->chip >= S3_VIRGEGX2) /*VGA mode*/ - { + if ((svga->crtc[0x67] & 0xc) != 0xc) { /*VGA mode*/ svga->ma_latch |= (virge->ma_ext << 16); if (svga->crtc[0x51] & 0x30) - svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; + svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) - svga->rowoffset += 0x100; + svga->rowoffset |= 0x100; if (!svga->rowoffset) svga->rowoffset = 256; svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + if ((virge->chip != S3_VIRGEVX) && (virge->chip < S3_VIRGEGX2)) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + case 16: + svga->render = svga_render_16bpp_highres; + if ((virge->chip != S3_VIRGEVX) && (virge->chip < S3_VIRGEGX2)) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + case 24: + svga->render = svga_render_24bpp_highres; + if ((virge->chip != S3_VIRGEVX) && (virge->chip < S3_VIRGEGX2)) + svga->rowoffset = (svga->rowoffset * 3) >> 2; /*Hack*/ + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + + default: + break; + } + + svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && + (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; + } else { /*Streams mode*/ + if (virge->chip < S3_VIRGEGX2) { + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + + svga->hdisp = virge->streams.pri_w + 1; + if (virge->streams.pri_h < svga->dispend) + svga->dispend = virge->streams.pri_h; + + 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); + if (svga->crtc[0x51] & 0x30) + svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) + svga->rowoffset |= 0x100; + if (!svga->rowoffset) + svga->rowoffset = 256; + + svga->overlay.x = virge->streams.sec_x; + svga->overlay.y = virge->streams.sec_y; + } + + svga->overlay.cur_ysize = virge->streams.sec_h; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->overlay.ena = (svga->overlay.x >= 0); + svga->overlay.h_acc = virge->streams.dda_horiz_accumulator; + svga->overlay.v_acc = virge->streams.dda_vert_accumulator; + + if (virge->chip < S3_VIRGEGX2) + svga->rowoffset = virge->streams.pri_stride >> 3; + + if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { + svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || + (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); + } else if (virge->chip >= S3_VIRGEGX2 && svga->overlay.ena) { + /* 0x20 = Secondary Stream enabled */ + /* 0x2000 = Primary Stream enabled */ + svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20); + } + + if (virge->chip >= S3_VIRGEGX2) { switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; break; case 15: svga->render = svga_render_15bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - // svga->htotal >>= 1; - // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) - // svga->hblank_end_val = svga->htotal - 1; - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } break; case 16: svga->render = svga_render_16bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { - // svga->htotal >>= 1; - // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) - // svga->hblank_end_val = svga->htotal - 1; - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } break; case 24: svga->render = svga_render_24bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) - svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ break; case 32: svga->render = svga_render_32bpp_highres; @@ -889,85 +981,24 @@ s3_virge_recalctimings(svga_t *svga) default: break; } - } - svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; - svga->overlay.ena = 0; - s3_virge_log("VGA mode\n"); - if (virge->chip >= S3_VIRGEGX2 && (svga->crtc[0x67] & 0xc) == 0xc) { - /* ViRGE/GX2 and later does not use primary stream registers. */ - svga->overlay.x = virge->streams.sec_x; - svga->overlay.y = virge->streams.sec_y; - svga->overlay.cur_ysize = virge->streams.sec_h; - - if (virge->streams.buffer_ctrl & 2) - svga->overlay.addr = virge->streams.sec_fb1; - else - svga->overlay.addr = virge->streams.sec_fb0; - - svga->overlay.ena = (svga->overlay.x >= 0) && !!(virge->streams.blend_ctrl & 0x20); - svga->overlay.v_acc = virge->streams.dda_vert_accumulator; - svga->rowoffset = virge->streams.pri_stride >> 3; - svga->vram_display_mask = virge->vram_mask; - } - } else /*Streams mode*/ - { - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; - else - svga->ma_latch = virge->streams.pri_fb0 >> 2; - - svga->hdisp = virge->streams.pri_w + 1; - if (virge->streams.pri_h < svga->dispend) - svga->dispend = virge->streams.pri_h; - - svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; - svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; - svga->overlay.cur_ysize = virge->streams.sec_h; - - if (virge->streams.buffer_ctrl & 2) - svga->overlay.addr = virge->streams.sec_fb1; - else - svga->overlay.addr = virge->streams.sec_fb0; - - svga->overlay.ena = (svga->overlay.x >= 0); - svga->overlay.v_acc = virge->streams.dda_vert_accumulator; - svga->rowoffset = virge->streams.pri_stride >> 3; - - if (virge->chip <= S3_VIRGEDX && svga->overlay.ena) { - svga->overlay.ena = (((virge->streams.blend_ctrl >> 24) & 7) == 0b000) || (((virge->streams.blend_ctrl >> 24) & 7) == 0b101); - } else if (virge->chip == S3_VIRGEGX2 && svga->overlay.ena) { - /* 0x20 = Secondary Stream enabled */ - /* 0x2000 = Primary Stream enabled */ - svga->overlay.ena = !!(virge->streams.blend_ctrl & 0x20); - } - - switch ((virge->streams.pri_ctrl >> 24) & 0x7) { - case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; - break; - case 3: /*KRGB-16 (1.5.5.5)*/ - // svga->htotal >>= 1; - // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) - // svga->hblank_end_val = svga->htotal - 1; - // svga->dots_per_clock >>= 1; - svga->render = svga_render_15bpp_highres; - break; - case 5: /*RGB-16 (5.6.5)*/ - // svga->htotal >>= 1; - // if ((svga->crtc[0x33] & 0x20) || ((svga->crtc[0x67] & 0xc) == 0xc)) - // svga->hblank_end_val = svga->htotal - 1; - // svga->dots_per_clock >>= 1; - svga->render = svga_render_16bpp_highres; - break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; - break; - case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; - break; - - default: - break; + } else { + switch ((virge->streams.pri_ctrl >> 24) & 0x7) { + case 0: /*RGB-8 (CLUT)*/ + svga->render = svga_render_8bpp_highres; + break; + case 3: /*KRGB-16 (1.5.5.5)*/ + svga->render = svga_render_15bpp_highres; + break; + case 5: /*RGB-16 (5.6.5)*/ + svga->render = svga_render_16bpp_highres; + break; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; + break; + case 7: /*XRGB-32 (X.8.8.8)*/ + svga->render = svga_render_32bpp_highres; + break; + } } svga->vram_display_mask = virge->vram_mask; } @@ -981,31 +1012,7 @@ s3_virge_recalctimings(svga_t *svga) } static void -s3_virge_update_buffer(virge_t *virge) -{ - svga_t *svga = &virge->svga; - - if ((svga->crtc[0x67] & 0xc) != 0xc) - return; - - if (virge->chip < S3_VIRGEGX2) { - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; - else - svga->ma_latch = virge->streams.pri_fb0 >> 2; - } - - if (virge->streams.buffer_ctrl & 2) - svga->overlay.addr = virge->streams.sec_fb1; - else - svga->overlay.addr = virge->streams.sec_fb0; - - svga->rowoffset = virge->streams.pri_stride >> 3; -} - -static void -s3_virge_updatemapping(virge_t *virge) -{ +s3_virge_updatemapping(virge_t *virge) { svga_t *svga = &virge->svga; if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { @@ -1016,10 +1023,8 @@ s3_virge_updatemapping(virge_t *virge) return; } - s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - /*Banked framebuffer*/ - switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ - case 0x0: /*128k at A0000*/ + switch (svga->gdcreg[6] & 0xc) { /*Banked framebuffer*/ + case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0xffff; break; @@ -1035,14 +1040,10 @@ s3_virge_updatemapping(virge_t *virge) mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; - - default: - break; } virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - s3_virge_log("Linear framebuffer %02X, linear base = %08x, display mask = %08x\n", svga->crtc[0x58] & 0x17, virge->linear_base, svga->vram_display_mask); if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/ switch (svga->crtc[0x58] & 7) { case 0: /*64k*/ @@ -1055,7 +1056,7 @@ s3_virge_updatemapping(virge_t *virge) virge->linear_size = 0x200000; break; case 3: /*4mb on other than ViRGE/VX, 8mb on ViRGE/VX*/ - if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) + if ((virge->chip == S3_VIRGEVX) || (virge->chip == S3_TRIO3D2X)) virge->linear_size = 0x800000; else virge->linear_size = 0x400000; @@ -1063,17 +1064,13 @@ s3_virge_updatemapping(virge_t *virge) case 7: virge->linear_size = 0x800000; break; - - default: - break; } virge->linear_base &= ~(virge->linear_size - 1); - s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); if (virge->linear_base == 0xa0000) { mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); mem_mapping_disable(&virge->linear_mapping); } else { - if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) + if ((virge->chip == S3_VIRGEVX) || (virge->chip == S3_TRIO3D2X)) virge->linear_base &= 0xfe000000; else virge->linear_base &= 0xfc000000; @@ -1086,11 +1083,7 @@ s3_virge_updatemapping(virge_t *virge) svga->fb_only = 0; } - s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x38); - - /* Memory mapped I/O. */ - /* Old MMIO. */ - if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { + if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { /*Old MMIO*/ if (svga->crtc[0x53] & 0x20) mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); else @@ -1098,16 +1091,14 @@ s3_virge_updatemapping(virge_t *virge) } else mem_mapping_disable(&virge->mmio_mapping); - /* New MMIO. */ - if (svga->crtc[0x53] & 0x08) + if (svga->crtc[0x53] & 0x08) /*New MMIO*/ mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); else mem_mapping_disable(&virge->new_mmio_mapping); } static void -s3_virge_vblank_start(svga_t *svga) -{ +s3_virge_vblank_start(svga_t *svga) { virge_t *virge = (virge_t *) svga->priv; virge->subsys_stat |= INT_VSY; @@ -1115,496 +1106,10 @@ s3_virge_vblank_start(svga_t *svga) } static void -s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge) -{ - if ((addr & 0xffff) < 0x8000) - s3_virge_bitblt(virge, 8, val); - else { - switch (addr & 0xffff) { - case 0x859c: - virge->cmd_dma = val; - break; - - default: - break; - } - } -} - -static void -s3_virge_mmio_fifo_write_w(uint32_t addr, uint16_t val, virge_t *virge) -{ - if ((addr & 0xfffe) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); - } else { - if ((addr & 0xfffe) == 0x859c) - virge->cmd_dma = val; - } -} - -static void -s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) -{ - if ((addr & 0xfffc) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); - } else { - switch (addr & 0xfffc) { - case 0x8590: - virge->cmd_dma_base = val; - break; - - case 0x8594: - virge->dma_ptr = val; - break; - - case 0x8598: - break; - - case 0x859c: - virge->cmd_dma = val; - break; - - case 0xa000: - case 0xa004: - case 0xa008: - case 0xa00c: - case 0xa010: - case 0xa014: - case 0xa018: - case 0xa01c: - case 0xa020: - case 0xa024: - case 0xa028: - case 0xa02c: - case 0xa030: - case 0xa034: - case 0xa038: - case 0xa03c: - case 0xa040: - case 0xa044: - case 0xa048: - case 0xa04c: - case 0xa050: - case 0xa054: - case 0xa058: - case 0xa05c: - case 0xa060: - case 0xa064: - case 0xa068: - case 0xa06c: - case 0xa070: - case 0xa074: - case 0xa078: - case 0xa07c: - case 0xa080: - case 0xa084: - case 0xa088: - case 0xa08c: - case 0xa090: - case 0xa094: - case 0xa098: - case 0xa09c: - case 0xa0a0: - case 0xa0a4: - case 0xa0a8: - case 0xa0ac: - case 0xa0b0: - case 0xa0b4: - case 0xa0b8: - case 0xa0bc: - case 0xa0c0: - case 0xa0c4: - case 0xa0c8: - case 0xa0cc: - case 0xa0d0: - case 0xa0d4: - case 0xa0d8: - case 0xa0dc: - case 0xa0e0: - case 0xa0e4: - case 0xa0e8: - case 0xa0ec: - case 0xa0f0: - case 0xa0f4: - case 0xa0f8: - case 0xa0fc: - case 0xa100: - case 0xa104: - case 0xa108: - case 0xa10c: - case 0xa110: - case 0xa114: - case 0xa118: - case 0xa11c: - case 0xa120: - case 0xa124: - case 0xa128: - case 0xa12c: - case 0xa130: - case 0xa134: - case 0xa138: - case 0xa13c: - case 0xa140: - case 0xa144: - case 0xa148: - case 0xa14c: - case 0xa150: - case 0xa154: - case 0xa158: - case 0xa15c: - case 0xa160: - case 0xa164: - case 0xa168: - case 0xa16c: - case 0xa170: - case 0xa174: - case 0xa178: - case 0xa17c: - case 0xa180: - case 0xa184: - case 0xa188: - case 0xa18c: - case 0xa190: - case 0xa194: - case 0xa198: - case 0xa19c: - case 0xa1a0: - case 0xa1a4: - case 0xa1a8: - case 0xa1ac: - case 0xa1b0: - case 0xa1b4: - case 0xa1b8: - case 0xa1bc: - case 0xa1c0: - case 0xa1c4: - case 0xa1c8: - case 0xa1cc: - case 0xa1d0: - case 0xa1d4: - case 0xa1d8: - case 0xa1dc: - case 0xa1e0: - case 0xa1e4: - case 0xa1e8: - case 0xa1ec: - case 0xa1f0: - case 0xa1f4: - case 0xa1f8: - case 0xa1fc: - { - int x = addr & 4; - int y = (addr >> 3) & 7; - int color; - int byte; - virge->s3d.pattern_8[y * 8 + x] = val & 0xff; - virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; - - x = (addr >> 1) & 6; - y = (addr >> 4) & 7; - virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; - virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; - - addr &= 0x00ff; - for (uint8_t xx = 0; xx < 4; xx++) { - x = ((addr + xx) / 3) % 8; - y = ((addr + xx) / 24) % 8; - color = ((addr + xx) % 3) << 3; - byte = (xx << 3); - virge->s3d.pattern_24[y * 8 + x] &= ~(0xff << color); - virge->s3d.pattern_24[y * 8 + x] |= ((val >> byte) & 0xff) << color; - } - - x = (addr >> 2) & 7; - y = (addr >> 5) & 7; - virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; - } - break; - - case 0xa4d4: /*2D BitBLT SRC Base*/ - case 0xa8d4: /*2D Line SRC Base*/ - case 0xacd4: /*2D Polygon SRC Base*/ - virge->s3d.src_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - s3_virge_log("PortWrite = %04x, SRC Base = %08x, memsize = %i\n", addr & 0xfffc, val, virge->memory_size); - break; - case 0xa4d8: /*2D BitBLT DEST Base*/ - case 0xa8d8: /*2D Line DEST Base*/ - case 0xacd8: /*2D Polygon DEST Base*/ - virge->s3d.dest_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - s3_virge_log("PortWrite = %04x, DST Base = %08x, memsize = %i\n", addr & 0xfffc, val, virge->memory_size); - break; - case 0xa4dc: /*2D BitBLT Left/Right Clipping*/ - case 0xa8dc: /*2D Line Left/Right Clipping*/ - case 0xacdc: /*2D Polygon Left/Right Clipping*/ - virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: /*2D BitBLT Top/Bottom Clipping*/ - case 0xa8e0: /*2D Line Top/Bottom Clipping*/ - case 0xace0: /*2D Polygon Top/Bottom Clipping*/ - virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: /*2D BitBLT DEST/SRC Stride*/ - case 0xa8e4: /*2D Line DEST/SRC Stride*/ - case 0xace4: /*2D Polygon DEST/SRC Stride*/ - virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: /*2D BitBLT Mono Pattern 0*/ - case 0xace8: /*2D Polygon Mono Pattern 0*/ - virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: /*2D BitBLT Mono Pattern 1*/ - case 0xacec: /*2D Polygon Mono Pattern 1*/ - virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: /*2D BitBLT Mono Pattern Background*/ - case 0xacf0: /*2D Polygon Mono Pattern Background*/ - virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: /*2D BitBLT Mono Pattern Foreground*/ - case 0xa8f4: /*2D Line Mono Pattern Foreground*/ - case 0xacf4: /*2D Polygon Mono Pattern Foreground*/ - virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8: /*2D BitBLT SRC Background*/ - virge->s3d.src_bg_clr = val; - break; - case 0xa4fc: /*2D BitBLT SRC Foreground*/ - virge->s3d.src_fg_clr = val; - break; - case 0xa500: /*2D BitBLT Command Set*/ - case 0xa900: /*2D Line Command Set*/ - case 0xad00: /*2D Polygon Command Set*/ - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) { - s3_virge_log("MMIO WriteL addr = %04x, val = %08x.\n", addr & 0xfffc, val); - s3_virge_bitblt(virge, -1, 0); - } - break; - case 0xa504: /*2D BitBLT Rectangle Width/Height*/ - virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508: /*2D BitBLT Rectangle SRC X/Y*/ - virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c: /*2D BitBLT Rectangle DEST X/Y*/ - virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) { - s3_virge_log("MMIO WriteL addr = %04x, val = %08x.\n", addr & 0xfffc, val); - s3_virge_bitblt(virge, -1, 0); - } - break; - case 0xa96c: /*2D Line Draw Endpoints*/ - virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970: /*2D Line X Delta*/ - virge->s3d.ldx = (int32_t) val; - break; - case 0xa974: /*2D Line X Start*/ - virge->s3d.lxstart = val; - break; - case 0xa978: /*2D Line Y Start*/ - virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c: /*2D Line Y Count*/ - virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) { - s3_virge_log("MMIO WriteL addr = %04x, val = %08x.\n", addr & 0xfffc, val); - s3_virge_bitblt(virge, -1, 0); - } - break; - - case 0xad68: /*2D Polygon Right X Delta*/ - virge->s3d.prdx = val; - break; - case 0xad6c: /*2D Polygon Right X Start*/ - virge->s3d.prxstart = val; - break; - case 0xad70: /*2D Polygon Left X Delta*/ - virge->s3d.pldx = val; - break; - case 0xad74: /*2D Polygon Left X Start*/ - virge->s3d.plxstart = val; - break; - case 0xad78: /*2D Polygon Y Start*/ - virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c: /*2D Polygon Y Count*/ - virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) { - s3_virge_log("MMIO WriteL addr = %04x, val = %08x.\n", addr & 0xfffc, val); - s3_virge_bitblt(virge, -1, 0); - } - break; - - case 0xb0d4: - case 0xb4d4: - virge->s3d_tri.z_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - break; - case 0xb0d8: - case 0xb4d8: - virge->s3d_tri.dest_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - break; - case 0xb0dc: - case 0xb4dc: - virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb0e0: - case 0xb4e0: - virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb0e4: - case 0xb4e4: - virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb0e8: - case 0xb4e8: - virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec: - virge->s3d_tri.tex_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - break; - case 0xb4f0: - virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb0f4: - case 0xb4f4: - virge->s3d_tri.fog_b = val & 0xff; - virge->s3d_tri.fog_g = (val >> 8) & 0xff; - virge->s3d_tri.fog_r = (val >> 16) & 0xff; - break; - case 0xb100: - case 0xb500: - virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); - break; - case 0xb504: - virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508: - virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c: - virge->s3d_tri.TdWdX = val; - break; - case 0xb510: - virge->s3d_tri.TdWdY = val; - break; - case 0xb514: - virge->s3d_tri.tws = val; - break; - case 0xb518: - virge->s3d_tri.TdDdX = val; - break; - case 0xb51c: - virge->s3d_tri.TdVdX = val; - break; - case 0xb520: - virge->s3d_tri.TdUdX = val; - break; - case 0xb524: - virge->s3d_tri.TdDdY = val; - break; - case 0xb528: - virge->s3d_tri.TdVdY = val; - break; - case 0xb52c: - virge->s3d_tri.TdUdY = val; - break; - case 0xb530: - virge->s3d_tri.tds = val; - break; - case 0xb534: - virge->s3d_tri.tvs = val; - break; - case 0xb538: - virge->s3d_tri.tus = val; - break; - case 0xb53c: - virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540: - virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544: - virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548: - virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c: - virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550: - virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; - - case 0xb554: - virge->s3d_tri.TdZdX = val; - break; - case 0xb558: - virge->s3d_tri.TdZdY = val; - break; - case 0xb55c: - virge->s3d_tri.tzs = val; - break; - case 0xb560: - virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564: - virge->s3d_tri.txend12 = val; - break; - case 0xb568: - virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c: - virge->s3d_tri.txend01 = val; - break; - case 0xb570: - virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574: - virge->s3d_tri.txs = val; - break; - case 0xb578: - virge->s3d_tri.tys = val; - break; - case 0xb57c: - virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) - queue_triangle(virge); - break; - - default: - break; - } +s3_virge_wait_fifo_idle(virge_t *virge) { + while (!FIFO_EMPTY) { + wake_fifo_thread(virge); + thread_wait_event(virge->fifo_not_full_event, 1); } } @@ -1612,26 +1117,24 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *priv) { virge_t *virge = (virge_t *) priv; - uint8_t ret = 0xff; - - s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff); + uint8_t ret; switch (addr & 0xffff) { case 0x8504: if (!virge->virge_busy) - virge->fifo_state = FIFO_STATE_RUN; + wake_fifo_thread(virge); ret = virge->subsys_stat; return ret; case 0x8505: ret = 0xc0; - if (virge->s3d_busy || virge->virge_busy || (virge->fifo_read_idx < virge->fifo_write_idx)) + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) ret |= 0x10; else ret |= 0x30; if (!virge->virge_busy) - virge->fifo_state = FIFO_STATE_RUN; + wake_fifo_thread(virge); return ret; case 0x850c: @@ -1643,55 +1146,8 @@ s3_virge_mmio_read(uint32_t addr, void *priv) ret = virge->fifo_slots_num >> 2; return ret; - case 0x83b0: - case 0x83b1: - case 0x83b2: - case 0x83b3: - case 0x83b4: - case 0x83b5: - case 0x83b6: - case 0x83b7: - case 0x83b8: - case 0x83b9: - case 0x83ba: - case 0x83bb: - case 0x83bc: - case 0x83bd: - case 0x83be: - case 0x83bf: - case 0x83c0: - case 0x83c1: - case 0x83c2: - case 0x83c3: - case 0x83c4: - case 0x83c5: - case 0x83c6: - case 0x83c7: - case 0x83c8: - case 0x83c9: - case 0x83ca: - case 0x83cb: - case 0x83cc: - case 0x83cd: - case 0x83ce: - case 0x83cf: - case 0x83d0: - case 0x83d1: - case 0x83d2: - case 0x83d3: - case 0x83d4: - case 0x83d5: - case 0x83d6: - case 0x83d7: - case 0x83d8: - case 0x83d9: - case 0x83da: - case 0x83db: - case 0x83dc: - case 0x83dd: - case 0x83de: - case 0x83df: - return s3_virge_in(addr & 0x3ff, virge); + case 0x83b0 ... 0x83df: + return s3_virge_in(addr & 0x3ff, priv); case 0x859c: return virge->cmd_dma; @@ -1704,31 +1160,27 @@ s3_virge_mmio_read(uint32_t addr, void *priv) if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) ret |= SERIAL_PORT_SDR; return ret; - - default: - break; } return 0xff; } + static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *priv) { virge_t *virge = (virge_t *) priv; - uint16_t ret = 0xffff; - - s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); + uint16_t ret; switch (addr & 0xfffe) { case 0x8504: ret = 0xc000; - if (virge->s3d_busy || virge->virge_busy || (virge->fifo_read_idx < virge->fifo_write_idx)) + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) ret |= 0x1000; else ret |= 0x3000; ret |= virge->subsys_stat; if (!virge->virge_busy) - virge->fifo_state = FIFO_STATE_RUN; + wake_fifo_thread(virge); return ret; case 0x850c: @@ -1740,17 +1192,15 @@ s3_virge_mmio_read_w(uint32_t addr, void *priv) return virge->cmd_dma; default: - return s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8); + return s3_virge_mmio_read(addr, priv) | (s3_virge_mmio_read(addr + 1, priv) << 8); } - return 0xffff; } static uint32_t -s3_virge_mmio_read_l(uint32_t addr, void *priv) -{ +s3_virge_mmio_read_l(uint32_t addr, void *priv) { virge_t *virge = (virge_t *) priv; - uint32_t ret = 0xffffffff; + uint32_t ret = 0xffffffff; switch (addr & 0xfffc) { case 0x8180: @@ -1822,14 +1272,14 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) case 0x8504: ret = 0x0000c000; - if (virge->s3d_busy || virge->virge_busy || (virge->fifo_read_idx < virge->fifo_write_idx)) + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) ret |= 0x00001000; else ret |= 0x00003000; ret |= virge->subsys_stat; if (!virge->virge_busy) - virge->fifo_state = FIFO_STATE_RUN; + wake_fifo_thread(virge); break; case 0x850c: @@ -1841,244 +1291,574 @@ s3_virge_mmio_read_l(uint32_t addr, void *priv) ret = virge->cmd_dma_base; break; case 0x8594: + ret = virge->cmd_dma_write_ptr_reg; break; case 0x8598: - ret = virge->dma_ptr; + ret = virge->cmd_dma_read_ptr_reg; + if (ret > virge->cmd_dma_write_ptr_reg) + ret = virge->cmd_dma_write_ptr_reg; break; case 0x859c: - ret = virge->cmd_dma; + ret = 0; /*To prevent DMA overflows.*/ break; case 0xa4d4: case 0xa8d4: case 0xacd4: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_base; break; case 0xa4d8: case 0xa8d8: case 0xacd8: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.dest_base; break; case 0xa4dc: case 0xa8dc: case 0xacdc: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; break; case 0xa4e0: case 0xa8e0: case 0xace0: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; break; case 0xa4e4: case 0xa8e4: case 0xace4: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; break; case 0xa4e8: case 0xace8: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.mono_pat_0; break; case 0xa4ec: case 0xacec: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.mono_pat_1; break; case 0xa4f0: case 0xacf0: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pat_bg_clr; break; case 0xa4f4: case 0xa8f4: case 0xacf4: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pat_fg_clr; break; case 0xa4f8: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_bg_clr; break; case 0xa4fc: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_fg_clr; break; case 0xa500: case 0xa900: case 0xad00: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.cmd_set; break; case 0xa504: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; break; case 0xa508: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; break; case 0xa50c: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; break; case 0xa96c: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.lxend0 << 16) | virge->s3d.lxend1; break; case 0xa970: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.ldx; break; case 0xa974: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.lxstart; break; case 0xa978: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.lystart; break; case 0xa97c: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.line_dir << 31) | virge->s3d.lycnt; break; case 0xad68: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.prdx; break; case 0xad6c: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.prxstart; break; case 0xad70: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pldx; break; case 0xad74: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.plxstart; break; case 0xad78: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pystart; break; case 0xad7c: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pycnt; break; default: - ret = s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8) | (s3_virge_mmio_read(addr + 2, virge) << 16) | (s3_virge_mmio_read(addr + 3, virge) << 24); + ret = s3_virge_mmio_read_w(addr, priv) | (s3_virge_mmio_read_w(addr + 2, priv) << 16); break; } - s3_virge_log("MMIO ReadL addr = %04x, val = %08x.\n", addr & 0xfffc, ret); + //pclog("MMIO ReadL=%04x, ret=%08x.\n", addr & 0xfffc, ret); return ret; } static void -s3_virge_fifo_timer(void *priv) +s3_virge_mmio_write_fifo_l(virge_t *virge, uint32_t addr, uint32_t val) { - virge_t *virge = (virge_t *)priv; + switch (addr) { + case 0xa000 ... 0xa1fc: + { + int x = addr & 4; + int y = (addr >> 3) & 7; + int color; + int byte; + uint32_t newaddr = addr; + virge->s3d.pattern_8[y * 8 + x] = val & 0xff; + virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; + virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; + virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; - timer_advance_u64(&virge->fifo_timer, 100 * TIMER_USEC); + x = (addr >> 1) & 6; + y = (addr >> 4) & 7; + virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; + virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; - while (virge->fifo_state == FIFO_STATE_RUN) { + newaddr &= 0x00ff; + for (uint8_t xx = 0; xx < 4; xx++) { + x = ((newaddr + xx) / 3) % 8; + y = ((newaddr + xx) / 24) % 8; + color = ((newaddr + xx) % 3) << 3; + byte = (xx << 3); + virge->s3d.pattern_24[y * 8 + x] &= ~(0xff << color); + virge->s3d.pattern_24[y * 8 + x] |= ((val >> byte) & 0xff) << color; + } + + x = (addr >> 2) & 7; + y = (addr >> 5) & 7; + virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; + } break; + + case 0xa4d4: + case 0xa8d4: + case 0xacd4: + virge->s3d.src_base = val & ((virge->memory_size == 8) ? + (val & 0x7ffff8) : (val & 0x3ffff8)); + break; + case 0xa4d8: + case 0xa8d8: + case 0xacd8: + virge->s3d.dest_base = val & ((virge->memory_size == 8) ? + (val & 0x7ffff8) : (val & 0x3ffff8)); + break; + case 0xa4dc: + case 0xa8dc: + case 0xacdc: + virge->s3d.clip_l = (val >> 16) & 0x7ff; + virge->s3d.clip_r = val & 0x7ff; + break; + case 0xa4e0: + case 0xa8e0: + case 0xace0: + virge->s3d.clip_t = (val >> 16) & 0x7ff; + virge->s3d.clip_b = val & 0x7ff; + break; + case 0xa4e4: + case 0xa8e4: + case 0xace4: + virge->s3d.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xa4e8: + case 0xace8: + virge->s3d.mono_pat_0 = val; + break; + case 0xa4ec: + case 0xacec: + virge->s3d.mono_pat_1 = val; + break; + case 0xa4f0: + case 0xacf0: + virge->s3d.pat_bg_clr = val; + break; + case 0xa4f4: + case 0xa8f4: + case 0xacf4: + virge->s3d.pat_fg_clr = val; + break; + case 0xa4f8: + virge->s3d.src_bg_clr = val; + break; + case 0xa4fc: + virge->s3d.src_fg_clr = val; + break; + case 0xa500: + case 0xa900: + case 0xad00: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa504: + virge->s3d.r_width = (val >> 16) & 0x7ff; + virge->s3d.r_height = val & 0x7ff; + break; + case 0xa508: + virge->s3d.rsrc_x = (val >> 16) & 0x7ff; + virge->s3d.rsrc_y = val & 0x7ff; + break; + case 0xa50c: + virge->s3d.rdest_x = (val >> 16) & 0x7ff; + virge->s3d.rdest_y = val & 0x7ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa96c: + virge->s3d.lxend0 = (val >> 16) & 0x7ff; + virge->s3d.lxend1 = val & 0x7ff; + break; + case 0xa970: + virge->s3d.ldx = (int32_t)val; + break; + case 0xa974: + virge->s3d.lxstart = val; + break; + case 0xa978: + virge->s3d.lystart = val & 0x7ff; + break; + case 0xa97c: + virge->s3d.lycnt = val & 0x7ff; + virge->s3d.line_dir = val >> 31; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + + case 0xad68: + virge->s3d.prdx = val; + break; + case 0xad6c: + virge->s3d.prxstart = val; + break; + case 0xad70: + virge->s3d.pldx = val; + break; + case 0xad74: + virge->s3d.plxstart = val; + break; + case 0xad78: + virge->s3d.pystart = val & 0x7ff; + break; + case 0xad7c: + virge->s3d.pycnt = val & 0x300007ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + + case 0xb0d4: + case 0xb4d4: + virge->s3d_tri.z_base = val & ((virge->memory_size == 8) ? + (val & 0x7ffff8) : (val & 0x3ffff8)); + break; + case 0xb0d8: + case 0xb4d8: + virge->s3d_tri.dest_base = val & ((virge->memory_size == 8) ? + (val & 0x7ffff8) : (val & 0x3ffff8)); + break; + case 0xb0dc: + case 0xb4dc: + virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_r = val & 0x7ff; + break; + case 0xb0e0: + case 0xb4e0: + virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_b = val & 0x7ff; + break; + case 0xb0e4: + case 0xb4e4: + virge->s3d_tri.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xb0e8: + case 0xb4e8: + virge->s3d_tri.z_str = val & 0xff8; + break; + case 0xb4ec: + virge->s3d_tri.tex_base = val & ((virge->memory_size == 8) ? + (val & 0x7ffff8) : (val & 0x3ffff8)); + break; + case 0xb4f0: + virge->s3d_tri.tex_bdr_clr = val & 0xffffff; + break; + case 0xb0f4: + case 0xb4f4: + virge->s3d_tri.fog_b = val & 0xff; + virge->s3d_tri.fog_g = (val >> 8) & 0xff; + virge->s3d_tri.fog_r = (val >> 16) & 0xff; + break; + case 0xb100: + case 0xb500: + virge->s3d_tri.cmd_set = val; + if (!(val & CMD_SET_AE)) + queue_triangle(virge); + break; + case 0xb504: + virge->s3d_tri.tbv = val & 0xfffff; + break; + case 0xb508: + virge->s3d_tri.tbu = val & 0xfffff; + break; + case 0xb50c: + virge->s3d_tri.TdWdX = val; + break; + case 0xb510: + virge->s3d_tri.TdWdY = val; + break; + case 0xb514: + virge->s3d_tri.tws = val; + break; + case 0xb518: + virge->s3d_tri.TdDdX = val; + break; + case 0xb51c: + virge->s3d_tri.TdVdX = val; + break; + case 0xb520: + virge->s3d_tri.TdUdX = val; + break; + case 0xb524: + virge->s3d_tri.TdDdY = val; + break; + case 0xb528: + virge->s3d_tri.TdVdY = val; + break; + case 0xb52c: + virge->s3d_tri.TdUdY = val; + break; + case 0xb530: + virge->s3d_tri.tds = val; + break; + case 0xb534: + virge->s3d_tri.tvs = val; + break; + case 0xb538: + virge->s3d_tri.tus = val; + break; + case 0xb53c: + virge->s3d_tri.TdGdX = val >> 16; + virge->s3d_tri.TdBdX = val & 0xffff; + break; + case 0xb540: + virge->s3d_tri.TdAdX = val >> 16; + virge->s3d_tri.TdRdX = val & 0xffff; + break; + case 0xb544: + virge->s3d_tri.TdGdY = val >> 16; + virge->s3d_tri.TdBdY = val & 0xffff; + break; + case 0xb548: + virge->s3d_tri.TdAdY = val >> 16; + virge->s3d_tri.TdRdY = val & 0xffff; + break; + case 0xb54c: + virge->s3d_tri.tgs = (val >> 16) & 0xffff; + virge->s3d_tri.tbs = val & 0xffff; + break; + case 0xb550: + virge->s3d_tri.tas = (val >> 16) & 0xffff; + virge->s3d_tri.trs = val & 0xffff; + break; + + case 0xb554: + virge->s3d_tri.TdZdX = val; + break; + case 0xb558: + virge->s3d_tri.TdZdY = val; + break; + case 0xb55c: + virge->s3d_tri.tzs = val; + break; + case 0xb560: + virge->s3d_tri.TdXdY12 = val; + break; + case 0xb564: + virge->s3d_tri.txend12 = val; + break; + case 0xb568: + virge->s3d_tri.TdXdY01 = val; + break; + case 0xb56c: + virge->s3d_tri.txend01 = val; + break; + case 0xb570: + virge->s3d_tri.TdXdY02 = val; + break; + case 0xb574: + virge->s3d_tri.txs = val; + break; + case 0xb578: + virge->s3d_tri.tys = val; + break; + case 0xb57c: + virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; + virge->s3d_tri.ty12 = val & 0x7ff; + virge->s3d_tri.tlr = val >> 31; + if (virge->s3d_tri.cmd_set & CMD_SET_AE) + queue_triangle(virge); + break; + } +} + +static void +fifo_thread(void *param) +{ + virge_t *virge = (virge_t *)param; + + while (virge->fifo_thread_run) { + thread_set_event(virge->fifo_not_full_event); + thread_wait_event(virge->wake_fifo_thread, -1); + thread_reset_event(virge->wake_fifo_thread); virge->virge_busy = 1; - while (virge->fifo_read_idx < virge->fifo_write_idx) { - switch (virge->fifo[virge->fifo_read_idx].addr_type & FIFO_TYPE) { + while (!FIFO_EMPTY) { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; + uint32_t val = fifo->val; + + switch (fifo->addr_type & FIFO_TYPE) { case FIFO_WRITE_BYTE: - s3_virge_mmio_fifo_write(virge->fifo[virge->fifo_read_idx].addr_type & FIFO_ADDR, virge->fifo[virge->fifo_read_idx].val, virge); + if (((fifo->addr_type & FIFO_ADDR) & 0xffff) < 0x8000) + s3_virge_bitblt(virge, 8, val); break; case FIFO_WRITE_WORD: - s3_virge_mmio_fifo_write_w(virge->fifo[virge->fifo_read_idx].addr_type & FIFO_ADDR, virge->fifo[virge->fifo_read_idx].val, virge); + if (((fifo->addr_type & FIFO_ADDR) & 0xfffe) < 0x8000) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } break; case FIFO_WRITE_DWORD: - s3_virge_mmio_fifo_write_l(virge->fifo[virge->fifo_read_idx].addr_type & FIFO_ADDR, virge->fifo[virge->fifo_read_idx].val, virge); - break; - default: + if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, + ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | + ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } else + s3_virge_mmio_write_fifo_l(virge, (fifo->addr_type & FIFO_ADDR) & 0xfffc, val); break; } - virge->fifo[virge->fifo_read_idx].addr_type = FIFO_INVALID; virge->fifo_read_idx++; - if (virge->fifo_read_idx >= FIFO_SIZE) - virge->fifo_read_idx = 0; + fifo->addr_type = FIFO_INVALID; - s3_virge_log("ReadIDX=%d.\n", virge->fifo_read_idx); - } - virge->virge_busy = 0; - virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; - s3_virge_update_irqs(virge); - virge->fifo_read_idx = 0; - virge->fifo_write_idx = 0; - virge->fifo_state = FIFO_STATE_IDLE; + if (FIFO_ENTRIES > 0xe000) + thread_set_event(virge->fifo_not_full_event); + + end_time = plat_timer_read(); + virge_time += end_time - start_time; + } + virge->virge_busy = 0; + virge->subsys_stat |= (INT_FIFO_EMP | INT_3DF_EMP); + if (virge->cmd_dma) + virge->subsys_stat |= (INT_HOST_DONE | INT_CMD_DONE); + + s3_virge_update_irqs(virge); } } static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) { - if (FIFO_FULL) { - s3_virge_log("FIFO FULL, TBD.\n"); - return; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; + int limit = 0; + + if (type == FIFO_WRITE_DWORD) { + switch (addr & 0xfffc) { + case 0xa500: + if (val & CMD_SET_AE) + limit = 1; + break; + default: + break; + } } - virge->fifo[virge->fifo_write_idx].val = val; - virge->fifo[virge->fifo_write_idx].addr_type = (addr & FIFO_ADDR) | type; - virge->fifo_write_idx++; - if (virge->fifo_write_idx >= FIFO_SIZE) - virge->fifo_write_idx = 0; + if (limit) { + if (FIFO_ENTRIES >= 16) { + thread_reset_event(virge->fifo_not_full_event); + if (FIFO_ENTRIES >= 16) + thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } else { + if (FIFO_FULL) { + thread_reset_event(virge->fifo_not_full_event); + if (FIFO_FULL) + thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - s3_virge_log("WriteIDX=%d.\n", virge->fifo_write_idx); - virge->fifo_state = FIFO_STATE_RUN; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + virge->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000) + wake_fifo_thread(virge); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(virge); } static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *priv) { virge_t *virge = (virge_t *) priv; - s3_virge_log("MMIO WriteB addr = %04x, val = %02x\n", addr & 0xffff, val); + if ((addr & 0xffff) < 0x8000) s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); else { switch (addr & 0xffff) { - case 0x83b0: - case 0x83b1: - case 0x83b2: - case 0x83b3: - case 0x83b4: - case 0x83b5: - case 0x83b6: - case 0x83b7: - case 0x83b8: - case 0x83b9: - case 0x83ba: - case 0x83bb: - case 0x83bc: - case 0x83bd: - case 0x83be: - case 0x83bf: - case 0x83c0: - case 0x83c1: - case 0x83c2: - case 0x83c3: - case 0x83c4: - case 0x83c5: - case 0x83c6: - case 0x83c7: - case 0x83c8: - case 0x83c9: - case 0x83ca: - case 0x83cb: - case 0x83cc: - case 0x83cd: - case 0x83ce: - case 0x83cf: - case 0x83d0: - case 0x83d1: - case 0x83d2: - case 0x83d3: - case 0x83d4: - case 0x83d5: - case 0x83d6: - case 0x83d7: - case 0x83d8: - case 0x83d9: - case 0x83da: - case 0x83db: - case 0x83dc: - case 0x83dd: - case 0x83de: - case 0x83df: - s3_virge_out(addr & 0x3ff, val, virge); + default: + case 0x83b0 ... 0x83df: + s3_virge_out(addr & 0x3ff, val, priv); break; case 0xff20: virge->serialport = val; i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); break; - - default: - break; } } } @@ -2087,15 +1867,21 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *priv) { virge_t *virge = (virge_t *) priv; - s3_virge_log("[%04X:%08X]: MMIO WriteW addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffe, val); + if ((addr & 0xfffe) < 0x8000) s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); else { - if ((addr & 0xfffe) == 0x83d4) { - s3_virge_mmio_write(addr, val, virge); - s3_virge_mmio_write(addr + 1, val >> 8, virge); - } else if ((addr & 0xfffe) == 0xff20) - s3_virge_mmio_write(addr, val, virge); + switch (addr & 0xfffe) { + default: + case 0x83d4: + s3_virge_mmio_write(addr, val, priv); + s3_virge_mmio_write(addr + 1, val >> 8, priv); + break; + + case 0xff20: + s3_virge_mmio_write(addr, val, priv); + break; + } } } @@ -2105,8 +1891,9 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; - s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val); - if (((addr & 0xfffc) < 0x8000) || ((addr & 0xe000) == 0xa000)) + if ((addr & 0xfffc) < 0x8000) + s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); + else if ((addr & 0xe000) == 0xa000) s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); else { switch (addr & 0xfffc) { @@ -2119,60 +1906,69 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) virge->streams.chroma_ctrl = val; break; case 0x8190: - virge->streams.sec_ctrl = val; + virge->streams.sec_ctrl = val; virge->streams.dda_horiz_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_horiz_accumulator |= 0xfffff800; + if (val & 0x1000) + virge->streams.dda_horiz_accumulator |= ~0xfff; + virge->streams.sdif = (val >> 24) & 7; break; case 0x8194: virge->streams.chroma_upper_bound = val; break; case 0x8198: - virge->streams.sec_filter = val; + virge->streams.sec_filter = val; virge->streams.k1_horiz_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_horiz_scale |= 0xfffff800; + if (val & 0x800) + virge->streams.k1_horiz_scale |= ~0x7ff; + virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff; - if ((val >> 16) & (1 << 10)) - virge->streams.k2_horiz_scale |= 0xfffff800; + if ((val >> 16) & 0x800) + virge->streams.k2_horiz_scale |= ~0x7ff; + + svga_recalctimings(svga); + svga->fullchange = changeframecount; break; case 0x81a0: virge->streams.blend_ctrl = val; svga_recalctimings(svga); + svga->fullchange = changeframecount; break; case 0x81c0: - virge->streams.pri_fb0 = val & 0x7fffff; - s3_virge_update_buffer(virge); + virge->streams.pri_fb0 = val & ((virge->memory_size == 8) ? + (val & 0x7fffff) : (val & 0x3fffff)); + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81c4: - virge->streams.pri_fb1 = val & 0x7fffff; - s3_virge_update_buffer(virge); + virge->streams.pri_fb1 = ((virge->memory_size == 8) ? + (val & 0x7fffff) : (val & 0x3fffff)); + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81c8: virge->streams.pri_stride = val & 0xfff; - s3_virge_update_buffer(virge); + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81cc: virge->streams.buffer_ctrl = val; - s3_virge_update_buffer(virge); + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81d0: virge->streams.sec_fb0 = val; - s3_virge_update_buffer(virge); + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81d4: virge->streams.sec_fb1 = val; - s3_virge_update_buffer(virge); + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81d8: virge->streams.sec_stride = val; + svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81dc: @@ -2180,47 +1976,50 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) break; case 0x81e0: virge->streams.k1_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_vert_scale |= 0xfffff800; + if (val & 0x800) + virge->streams.k1_vert_scale |= ~0x7ff; break; case 0x81e4: virge->streams.k2_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k2_vert_scale |= 0xfffff800; + if (val & 0x800) + virge->streams.k2_vert_scale |= ~0x7ff; break; case 0x81e8: virge->streams.dda_vert_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_vert_accumulator |= 0xfffff800; + if (val & 0x1000) + virge->streams.dda_vert_accumulator |= ~0xfff; + + svga_recalctimings(svga); + svga->fullchange = changeframecount; break; case 0x81ec: virge->streams.fifo_ctrl = val; break; case 0x81f0: virge->streams.pri_start = val; - virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; + virge->streams.pri_x = (val >> 16) & 0x7ff; + virge->streams.pri_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f4: virge->streams.pri_size = val; - virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; + virge->streams.pri_w = (val >> 16) & 0x7ff; + virge->streams.pri_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81f8: virge->streams.sec_start = val; - virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; + virge->streams.sec_x = (val >> 16) & 0x7ff; + virge->streams.sec_y = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81fc: virge->streams.sec_size = val; - virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; + virge->streams.sec_w = (val >> 16) & 0x7ff; + virge->streams.sec_h = val & 0x7ff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; @@ -2236,46 +2035,148 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) s3_virge_updatemapping(virge); break; - case 0xff20: - s3_virge_mmio_write(addr, val, virge); + case 0x8590: + virge->cmd_dma_base = val; + virge->cmd_dma_buf_size = (val & 2) ? 0x10000 : 0x1000; + virge->cmd_dma_buf_size_mask = virge->cmd_dma_buf_size - 1; + virge->cmd_base_addr = (val & 2) ? (val & 0xffff0000) : (val & 0xfffff000); break; - default: - s3_virge_log("Actual WriteL=%04x.\n", addr & 0xfffc); + case 0x8594: + virge->cmd_dma_write_ptr_update = val & (1 << 16); + if (virge->cmd_dma_write_ptr_update) { + virge->cmd_dma_write_ptr_reg = (virge->cmd_dma_buf_size == 0x10000) ? (val & 0xffff) : (val & 0xfff); + virge->dma_dbl_words = 0; + virge->dma_data_type = 0; + virge->dma_val = 0; + if (virge->cmd_dma) { + while (virge->cmd_dma_read_ptr_reg != virge->cmd_dma_write_ptr_reg) { + virge->cmd_dma_write_ptr_update = 0; + dma_bm_read(virge->cmd_base_addr + virge->cmd_dma_read_ptr_reg, (uint8_t *)&virge->dma_val, 4, 4); + if (!virge->dma_dbl_words) { + virge->dma_dbl_words = (virge->dma_val & 0xffff); + virge->dma_data_type = !!(virge->dma_val & (1 << 31)); + if (virge->dma_data_type) + virge->dma_mmio_addr = 0; + else + virge->dma_mmio_addr = ((virge->dma_val >> 16) << 2) & 0xfffc; + } else { + s3_virge_mmio_write_l(virge->dma_mmio_addr, virge->dma_val, virge); + virge->dma_dbl_words--; + virge->dma_mmio_addr = (virge->dma_mmio_addr + 4) & 0xfffc; + } + virge->cmd_dma_read_ptr_reg = (virge->cmd_dma_read_ptr_reg + 4) & (virge->cmd_dma_buf_size_mask - 3); + } + } + } + break; + + case 0x8598: + virge->cmd_dma_read_ptr_reg = (virge->cmd_dma_buf_size == 0x10000) ? (val & 0xffff) : (val & 0xfff); + break; + + case 0x859c: + virge->cmd_dma = val & 1; + virge->cmd_dma_write_ptr_reg = 0; + virge->cmd_dma_read_ptr_reg = 0; + break; + + case 0xff20: + s3_virge_mmio_write(addr, val, priv); break; } } } -#define READ(addr, val) \ - { \ - switch (bpp) { \ - case 0: /*8 bpp*/ \ - val = vram[addr & virge->vram_mask]; \ - break; \ - case 1: /*16 bpp*/ \ - val = *(uint16_t *) &vram[addr & virge->vram_mask]; \ - break; \ - case 2: /*24 bpp*/ \ - val = (*(uint32_t *) &vram[addr & virge->vram_mask]) & 0xffffff; \ - break; \ - } \ - } +#define READ(addr, val) \ + do { \ + switch (bpp) { \ + case 0: /*8 bpp*/ \ + val = vram[addr & virge->vram_mask]; \ + break; \ + case 1: /*16 bpp*/ \ + val = *(uint16_t *)&vram[addr & virge->vram_mask]; \ + break; \ + case 2: /*24 bpp*/ \ + val = (*(uint32_t *)&vram[addr & virge->vram_mask]) & 0xffffff; \ + break; \ + } \ + } while (0) -#define CLIP(x, y) \ - { \ - if ((virge->s3d.cmd_set & CMD_SET_HC) && (x < virge->s3d.clip_l || x > virge->s3d.clip_r || y < virge->s3d.clip_t || y > virge->s3d.clip_b)) \ - update = 0; \ - } +#define Z_READ(addr) *(uint16_t *)&vram[addr & virge->vram_mask] -#define CLIP_3D(x, y) \ - { \ - if ((s3d_tri->cmd_set & CMD_SET_HC) && (x < s3d_tri->clip_l || x > s3d_tri->clip_r || y < s3d_tri->clip_t || y > s3d_tri->clip_b)) \ - update = 0; \ - } +#define Z_WRITE(addr, val) \ + if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ + *(uint16_t *)&vram[addr & virge->vram_mask] = val + +#define CLIP(x, y) \ + do { \ + if ((virge->s3d.cmd_set & CMD_SET_HC) && \ + (x < virge->s3d.clip_l || x > virge->s3d.clip_r || \ + y < virge->s3d.clip_t || y > virge->s3d.clip_b)) \ + update = 0; \ + } while (0) + +#define CLIP_3D(x, y) \ + do { \ + if ((s3d_tri->cmd_set & CMD_SET_HC) && (x < s3d_tri->clip_l || \ + x > s3d_tri->clip_r || y < s3d_tri->clip_t || \ + y > s3d_tri->clip_b)) \ + update = 0; \ + } while (0) + +#define Z_CLIP(Zzb, Zs) \ + do { \ + if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ + switch ((s3d_tri->cmd_set >> 20) & 7) { \ + case 0: \ + update = 0; \ + break; \ + case 1: \ + if (Zs <= Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 2: \ + if (Zs != Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 3: \ + if (Zs < Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 4: \ + if (Zs >= Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 5: \ + if (Zs == Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 6: \ + if (Zs > Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 7: \ + update = 1; \ + Zzb = Zs; \ + break; \ + } \ + } while (0) #define MIX() \ - { \ + do { \ int c; \ for (c = 0; c < 24; c++) { \ int d = (dest & (1 << c)) ? 1 : 0; \ @@ -2286,78 +2187,74 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *priv) if (virge->s3d.rop & (1 << d)) \ out |= (1 << c); \ } \ - } + } while (0) -#define WRITE(addr, val) \ - { \ - switch (bpp) { \ - case 0: /*8 bpp*/ \ - vram[addr & virge->vram_mask] = val; \ - svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ - break; \ - case 1: /*16 bpp*/ \ - *(uint16_t *) &vram[addr & virge->vram_mask] = val; \ - svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ - break; \ - case 2: /*24 bpp*/ \ - *(uint32_t *) &vram[addr & virge->vram_mask] = (val & 0xffffff) | (vram[(addr + 3) & virge->vram_mask] << 24); \ - svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ - break; \ - } \ - } +#define WRITE(addr, val) \ + do { \ + switch (bpp) { \ + case 0: /*8 bpp*/ \ + vram[addr & virge->vram_mask] = val; \ + virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \ + changeframecount; \ + break; \ + case 1: /*16 bpp*/ \ + *(uint16_t *)&vram[addr & virge->vram_mask] = val; \ + virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \ + changeframecount; \ + break; \ + case 2: /*24 bpp*/ \ + *(uint32_t *)&vram[addr & virge->vram_mask] = (val & 0xffffff) | \ + (vram[(addr + 3) & virge->vram_mask] << 24); \ + virge->svga.changedvram[(addr & virge->vram_mask) >> 12] = \ + changeframecount; \ + break; \ + } \ + } while (0) static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { - svga_t *svga = &virge->svga; - uint8_t *vram = svga->vram; - uint32_t mono_pattern[64]; - int count_mask; - int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; - int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; - int bpp; - int x_mul; - int cpu_dat_shift; - const uint32_t *pattern_data; - uint32_t src_fg_clr; - uint32_t src_bg_clr; - uint32_t src_addr; - uint32_t dest_addr; - uint32_t source = 0; - uint32_t dest = 0; - uint32_t pattern; - uint32_t out = 0; - int update; + uint8_t *vram = virge->svga.vram; + uint32_t mono_pattern[64]; + int count_mask; + int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; + int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; + int bpp; + int x_mul; + int cpu_dat_shift; + uint32_t *pattern_data; + uint32_t src_fg_clr; + uint32_t src_bg_clr; switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { case CMD_SET_FORMAT_8: - bpp = 0; - x_mul = 1; + bpp = 0; + x_mul = 1; cpu_dat_shift = 8; - pattern_data = virge->s3d.pattern_8; - src_fg_clr = virge->s3d.src_fg_clr & 0xff; - src_bg_clr = virge->s3d.src_bg_clr & 0xff; + pattern_data = virge->s3d.pattern_8; + src_fg_clr = virge->s3d.src_fg_clr & 0xff; + src_bg_clr = virge->s3d.src_bg_clr & 0xff; break; case CMD_SET_FORMAT_16: - bpp = 1; - x_mul = 2; + bpp = 1; + x_mul = 2; cpu_dat_shift = 16; - pattern_data = virge->s3d.pattern_16; - src_fg_clr = virge->s3d.src_fg_clr & 0xffff; - src_bg_clr = virge->s3d.src_bg_clr & 0xffff; + pattern_data = virge->s3d.pattern_16; + src_fg_clr = virge->s3d.src_fg_clr & 0xffff; + src_bg_clr = virge->s3d.src_bg_clr & 0xffff; break; case CMD_SET_FORMAT_24: default: - bpp = 2; - x_mul = 3; + bpp = 2; + x_mul = 3; cpu_dat_shift = 24; - pattern_data = virge->s3d.pattern_24; - src_fg_clr = virge->s3d.src_fg_clr; - src_bg_clr = virge->s3d.src_bg_clr; + pattern_data = virge->s3d.pattern_24; + src_fg_clr = virge->s3d.src_fg_clr; + src_bg_clr = virge->s3d.src_bg_clr; break; - } - if (virge->s3d.cmd_set & CMD_SET_MP) - pattern_data = mono_pattern; + } + if (virge->s3d.cmd_set & CMD_SET_MP) + pattern_data = mono_pattern; switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { case CMD_SET_ITA_BYTE: @@ -2372,55 +2269,51 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) break; } if (virge->s3d.cmd_set & CMD_SET_MP) { - for (uint8_t y = 0; y < 4; y++) { - for (uint8_t x = 0; x < 8; x++) { - if (virge->s3d.mono_pat_0 & (1 << (x + y * 8))) - mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_fg_clr; - else - mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_bg_clr; - if (virge->s3d.mono_pat_1 & (1 << (x + y * 8))) - mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_fg_clr; - else - mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_bg_clr; - } + int x; + int y; + for (y = 0; y < 4; y++) { + for (x = 0; x < 8; x++) { + if (virge->s3d.mono_pat_0 & (1 << (x + y * 8))) + mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_fg_clr; + else + mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_bg_clr; + if (virge->s3d.mono_pat_1 & (1 << (x + y * 8))) + mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_fg_clr; + else + mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_bg_clr; + } } } - switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) { + case CMD_SET_COMMAND_NOP: + break; + case CMD_SET_COMMAND_BITBLT: if (count == -1) { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; virge->s3d.data_left_count = 0; - s3_virge_log("BitBlt start src_x=%i,src_y=%i,dest_x=%i,dest_y=%i,w=%i,h=%i,rop=%02X,src_base=%x,dest_base=%x\n", - virge->s3d.src_x, - virge->s3d.src_y, - virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, - virge->s3d.src_base, - virge->s3d.dest_base); - if (virge->s3d.cmd_set & CMD_SET_IDS) return; } - if (!virge->s3d.h) return; - while (count) { - src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); - dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - out = 0; - update = 1; + uint32_t src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + + (virge->s3d.src_y * virge->s3d.src_str); + uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0; + uint32_t dest = 0; + uint32_t pattern; + uint32_t out = 0; + int update = 1; switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { case 0: @@ -2438,18 +2331,18 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) count -= (cpu_dat_shift - virge->s3d.data_left_count); virge->s3d.data_left_count = 0; if (count < cpu_dat_shift) { - virge->s3d.data_left = cpu_dat; + virge->s3d.data_left = cpu_dat; virge->s3d.data_left_count = count; - count = 0; + count = 0; } } else { source = cpu_dat; cpu_dat >>= cpu_dat_shift; count -= cpu_dat_shift; if (count < cpu_dat_shift) { - virge->s3d.data_left = cpu_dat; + virge->s3d.data_left = cpu_dat; virge->s3d.data_left_count = count; - count = 0; + count = 0; } } if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) @@ -2462,9 +2355,6 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) cpu_dat <<= 1; count--; break; - - default: - break; } CLIP(virge->s3d.dest_x, virge->s3d.dest_y); @@ -2482,9 +2372,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.dest_x += x_inc; virge->s3d.dest_x &= 0x7ff; if (!virge->s3d.w) { - virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_x = virge->s3d.rsrc_x; virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; + virge->s3d.w = virge->s3d.r_width; virge->s3d.src_y += y_inc; virge->s3d.dest_y += y_inc; @@ -2501,9 +2391,6 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) cpu_dat <<= (count - (count & count_mask)); count &= count_mask; break; - - default: - break; } if (!virge->s3d.h) return; @@ -2515,27 +2402,23 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) case CMD_SET_COMMAND_RECTFILL: /*No source, pattern = pat_fg_clr*/ if (count == -1) { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; virge->s3d.dest_x = virge->s3d.rdest_x; virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - - s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, virge->s3d.dest_base); + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; } while (count && virge->s3d.h) { - source = virge->s3d.pat_fg_clr; - dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - pattern = virge->s3d.pat_fg_clr; - out = 0; - update = 1; + uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0; + uint32_t dest = 0; + uint32_t pattern = virge->s3d.pat_fg_clr; + uint32_t out = 0; + int update = 1; CLIP(virge->s3d.dest_x, virge->s3d.dest_y); @@ -2552,9 +2435,9 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) virge->s3d.dest_x += x_inc; virge->s3d.dest_x &= 0x7ff; if (!virge->s3d.w) { - virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_x = virge->s3d.rsrc_x; virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; + virge->s3d.w = virge->s3d.r_width; virge->s3d.src_y += y_inc; virge->s3d.dest_y += y_inc; @@ -2562,8 +2445,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) if (!virge->s3d.h) return; } else - virge->s3d.w--; - + virge->s3d.w--; count--; } break; @@ -2572,8 +2454,8 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) if (count == -1) { virge->s3d.dest_x = virge->s3d.lxstart; virge->s3d.dest_y = virge->s3d.lystart; - virge->s3d.h = virge->s3d.lycnt; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + virge->s3d.h = virge->s3d.lycnt; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; } while (virge->s3d.h) { int x; @@ -2582,7 +2464,8 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) x = virge->s3d.dest_x >> 20; - if (virge->s3d.h == virge->s3d.lycnt && ((virge->s3d.line_dir && x > virge->s3d.lxend0) || (!virge->s3d.line_dir && x < virge->s3d.lxend0))) + if (virge->s3d.h == virge->s3d.lycnt && ((virge->s3d.line_dir && x > virge->s3d.lxend0) || + (!virge->s3d.line_dir && x < virge->s3d.lxend0))) x = virge->s3d.lxend0; if (virge->s3d.h == 1) @@ -2594,17 +2477,22 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) goto skip_line; do { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0; - uint32_t dest = 0; + uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0; + uint32_t dest = 0; uint32_t pattern; - uint32_t out = 0; - int update = 1; + uint32_t out = 0; + int update = 1; - if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && ((virge->s3d.line_dir && x < virge->s3d.lxend0) || (!virge->s3d.line_dir && x > virge->s3d.lxend0))) + if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && + ((virge->s3d.line_dir && x < virge->s3d.lxend0) || + (!virge->s3d.line_dir && x > virge->s3d.lxend0))) update = 0; - if ((virge->s3d.h == 1 || !first_pixel) && ((virge->s3d.line_dir && x > virge->s3d.lxend1) || (!virge->s3d.line_dir && x < virge->s3d.lxend1))) + if ((virge->s3d.h == 1 || !first_pixel) && + ((virge->s3d.line_dir && x > virge->s3d.lxend1) || + (!virge->s3d.line_dir && x < virge->s3d.lxend1))) update = 0; CLIP(x, virge->s3d.dest_y); @@ -2638,68 +2526,71 @@ skip_line: virge->s3d.dest_r = virge->s3d.prxstart; if (virge->s3d.pycnt & (1 << 29)) virge->s3d.dest_l = virge->s3d.plxstart; - virge->s3d.h = virge->s3d.pycnt & 0x7ff; + virge->s3d.h = virge->s3d.pycnt & 0x7ff; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; while (virge->s3d.h) { - int x = virge->s3d.dest_l >> 20; - int xend = virge->s3d.dest_r >> 20; - int y = virge->s3d.pystart & 0x7ff; - int xdir = (x < xend) ? 1 : -1; - do { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); - uint32_t source = 0; - uint32_t dest = 0; - uint32_t pattern; - uint32_t out = 0; - int update = 1; + int x = virge->s3d.dest_l >> 20; + int xend = virge->s3d.dest_r >> 20; + int y = virge->s3d.pystart & 0x7ff; + int xdir = (x < xend) ? 1 : -1; + do { + uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); + uint32_t source = 0; + uint32_t dest = 0; + uint32_t pattern; + uint32_t out = 0; + int update = 1; - CLIP(x, y); + CLIP(x, y); - if (update) { - READ(dest_addr, dest); - pattern = pattern_data[(y & 7) * 8 + (x & 7)]; - MIX(); + if (update) { + READ(dest_addr, dest); + pattern = pattern_data[(y & 7) * 8 + (x & 7)]; - WRITE(dest_addr, out); - } + MIX(); - x = (x + xdir) & 0x7ff; - } while (x != (xend + xdir)); + WRITE(dest_addr, out); + } - virge->s3d.dest_l += virge->s3d.pldx; - virge->s3d.dest_r += virge->s3d.prdx; - virge->s3d.h--; - virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; + x = (x + xdir) & 0x7ff; + } while (x != (xend + xdir)); + + virge->s3d.dest_l += virge->s3d.pldx; + virge->s3d.dest_r += virge->s3d.prdx; + virge->s3d.h--; + virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; } break; - case CMD_SET_COMMAND_NOP: - break; - default: - break; + fatal("s3_virge_bitblt : blit command %i %08x\n", + (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set); } } -#define RGB15_TO_24(val, r, g, b) \ - b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ - g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ - r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); +#define RGB15_TO_24(val, r, g, b) \ + b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ + g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ + r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); -#define RGB24_TO_24(val, r, g, b) \ - b = val & 0xff; \ - g = (val & 0xff00) >> 8; \ - r = (val & 0xff0000) >> 16 +#define RGB24_TO_24(val, r, g, b) \ + b = val & 0xff; \ + g = (val & 0xff00) >> 8; \ + r = (val & 0xff0000) >> 16 -#define RGB15(r, g, b, dest) \ - if (virge->dithering_enabled) { \ - int add = dither[_y & 3][_x & 3]; \ - int _r = (r > 248) ? 248 : r + add; \ - int _g = (g > 248) ? 248 : g + add; \ - int _b = (b > 248) ? 248 : b + add; \ - dest = ((_b >> 3) & 0x1f) | (((_g >> 3) & 0x1f) << 5) | (((_r >> 3) & 0x1f) << 10); \ - } else \ - dest = ((b >> 3) & 0x1f) | (((g >> 3) & 0x1f) << 5) | (((r >> 3) & 0x1f) << 10) +#define RGB15(r, g, b, dest) \ + if (virge->dithering_enabled) { \ + int add = dither[_y & 3][_x & 3]; \ + int _r = (r > 248) ? 248 : r + add; \ + int _g = (g > 248) ? 248 : g + add; \ + int _b = (b > 248) ? 248 : b + add; \ + dest = ((_b >> 3) & 0x1f) | \ + (((_g >> 3) & 0x1f) << 5) | \ + (((_r >> 3) & 0x1f) << 10); \ + } else \ + dest = ((b >> 3) & 0x1f) | \ + (((g >> 3) & 0x1f) << 5) | \ + (((r >> 3) & 0x1f) << 10) #define RGB24(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) @@ -2708,32 +2599,50 @@ typedef struct rgba_t { } rgba_t; typedef struct s3d_state_t { - int32_t r, g, b, a, u, v, d, w; + int32_t r; + int32_t g; + int32_t b; + int32_t a; + int32_t u; + int32_t v; + int32_t d; + int32_t w; - int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; + int32_t base_r; + int32_t base_g; + int32_t base_b; + int32_t base_a; + int32_t base_u; + int32_t base_v; + int32_t base_d; + int32_t base_w; - uint32_t base_z; + uint32_t base_z; - uint32_t tbu, tbv; + uint32_t tbu; + uint32_t tbv; - uint32_t cmd_set; - int max_d; + uint32_t cmd_set; + int max_d; uint16_t *texture[10]; - uint32_t tex_bdr_clr; + uint32_t tex_bdr_clr; - int32_t x1, x2; - int y; + int32_t x1; + int32_t x2; - rgba_t dest_rgba; + int y; + + rgba_t dest_rgba; } s3d_state_t; typedef struct s3d_texture_state_t { - int level; - int texture_shift; + int level; + int texture_shift; - int32_t u, v; + int32_t u; + int32_t v; } s3d_texture_state_t; static void (*tex_read)(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out); @@ -2747,10 +2656,10 @@ static int _x; static int _y; static void -tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; +tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); @@ -2759,10 +2668,10 @@ tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out } static void -tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; +tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) val = state->tex_bdr_clr; @@ -2774,10 +2683,10 @@ tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba } static void -tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; +tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); @@ -2786,10 +2695,10 @@ tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out } static void -tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; +tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) val = state->tex_bdr_clr; @@ -2801,21 +2710,22 @@ tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba } static void -tex_ARGB8888(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *) state->texture[texture_state->level])[offset]; +tex_ARGB8888(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; out->r = (val >> 16) & 0xff; out->g = (val >> 8) & 0xff; out->b = val & 0xff; out->a = (val >> 24) & 0xff; } + static void -tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) -{ - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *) state->texture[texture_state->level])[offset]; +tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) val = state->tex_bdr_clr; @@ -2827,21 +2737,19 @@ tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba } static void -tex_sample_normal(s3d_state_t *state) -{ +tex_sample_normal(s3d_state_t *state) { s3d_texture_state_t texture_state; - texture_state.level = state->max_d; + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; tex_read(state, &texture_state, &state->dest_rgba); } static void -tex_sample_normal_filter(s3d_state_t *state) -{ +tex_sample_normal_filter(s3d_state_t *state) { s3d_texture_state_t texture_state; int tex_offset; rgba_t tex_samples[4]; @@ -2849,9 +2757,9 @@ tex_sample_normal_filter(s3d_state_t *state) int dv; int d[4]; - texture_state.level = state->max_d; + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + tex_offset = 1 << texture_state.texture_shift; texture_state.u = state->u + state->tbu; texture_state.v = state->v + state->tbv; @@ -2876,30 +2784,32 @@ tex_sample_normal_filter(s3d_state_t *state) d[2] = (256 - du) * dv; d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void -tex_sample_mipmap(s3d_state_t *state) -{ +tex_sample_mipmap(s3d_state_t *state) { s3d_texture_state_t texture_state; texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; tex_read(state, &texture_state, &state->dest_rgba); } static void -tex_sample_mipmap_filter(s3d_state_t *state) -{ +tex_sample_mipmap_filter(s3d_state_t *state) { s3d_texture_state_t texture_state; int tex_offset; rgba_t tex_samples[4]; @@ -2911,7 +2821,7 @@ tex_sample_mipmap_filter(s3d_state_t *state) if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + tex_offset = 1 << texture_state.texture_shift; texture_state.u = state->u + state->tbu; texture_state.v = state->v + state->tbv; @@ -2936,34 +2846,36 @@ tex_sample_mipmap_filter(s3d_state_t *state) d[2] = (256 - du) * dv; d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void -tex_sample_persp_normal(s3d_state_t *state) -{ +tex_sample_persp_normal(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - texture_state.level = state->max_d; + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; tex_read(state, &texture_state, &state->dest_rgba); } static void -tex_sample_persp_normal_filter(s3d_state_t *state) -{ +tex_sample_persp_normal_filter(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; int32_t u; int32_t v; int tex_offset; @@ -2973,14 +2885,14 @@ tex_sample_persp_normal_filter(s3d_state_t *state) int d[4]; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - texture_state.level = state->max_d; + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + tex_offset = 1 << texture_state.texture_shift; texture_state.u = u; texture_state.v = v; @@ -3005,34 +2917,36 @@ tex_sample_persp_normal_filter(s3d_state_t *state) d[2] = (256 - du) * dv; d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void -tex_sample_persp_normal_375(s3d_state_t *state) -{ +tex_sample_persp_normal_375(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - texture_state.level = state->max_d; + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; tex_read(state, &texture_state, &state->dest_rgba); } static void -tex_sample_persp_normal_filter_375(s3d_state_t *state) -{ +tex_sample_persp_normal_filter_375(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; int32_t u; int32_t v; int tex_offset; @@ -3042,14 +2956,14 @@ tex_sample_persp_normal_filter_375(s3d_state_t *state) int d[4]; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - texture_state.level = state->max_d; + texture_state.level = state->max_d; texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + tex_offset = 1 << texture_state.texture_shift; texture_state.u = u; texture_state.v = v; @@ -3074,36 +2988,38 @@ tex_sample_persp_normal_filter_375(s3d_state_t *state) d[2] = (256 - du) * dv; d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void -tex_sample_persp_mipmap(s3d_state_t *state) -{ +tex_sample_persp_mipmap(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; tex_read(state, &texture_state, &state->dest_rgba); } static void -tex_sample_persp_mipmap_filter(s3d_state_t *state) -{ +tex_sample_persp_mipmap_filter(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; int32_t u; int32_t v; int tex_offset; @@ -3113,16 +3029,16 @@ tex_sample_persp_mipmap_filter(s3d_state_t *state) int d[4]; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + tex_offset = 1 << texture_state.texture_shift; texture_state.u = u; texture_state.v = v; @@ -3147,36 +3063,38 @@ tex_sample_persp_mipmap_filter(s3d_state_t *state) d[2] = (256 - du) * dv; d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void -tex_sample_persp_mipmap_375(s3d_state_t *state) -{ +tex_sample_persp_mipmap_375(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; tex_read(state, &texture_state, &state->dest_rgba); } static void -tex_sample_persp_mipmap_filter_375(s3d_state_t *state) -{ +tex_sample_persp_mipmap_filter_375(s3d_state_t *state) { s3d_texture_state_t texture_state; - int32_t w = 0; + int32_t w = 0; int32_t u; int32_t v; int tex_offset; @@ -3186,16 +3104,16 @@ tex_sample_persp_mipmap_filter_375(s3d_state_t *state) int d[4]; if (state->w) - w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); if (texture_state.level < 0) texture_state.level = 0; texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + tex_offset = 1 << texture_state.texture_shift; texture_state.u = u; texture_state.v = v; @@ -3220,47 +3138,50 @@ tex_sample_persp_mipmap_filter_375(s3d_state_t *state) d[2] = (256 - du) * dv; d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } -#define CLAMP(x) \ - do { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ } while (0) -#define CLAMP_RGBA(r, g, b, a) \ - if ((r) & ~0xff) \ - r = ((r) < 0) ? 0 : 0xff; \ - if ((g) & ~0xff) \ - g = ((g) < 0) ? 0 : 0xff; \ - if ((b) & ~0xff) \ - b = ((b) < 0) ? 0 : 0xff; \ - if ((a) & ~0xff) \ - a = ((a) < 0) ? 0 : 0xff; +#define CLAMP_RGBA(r, g, b, a) \ + if ((r) & ~0xff) \ + r = ((r) < 0) ? 0 : 0xff; \ + if ((g) & ~0xff) \ + g = ((g) < 0) ? 0 : 0xff; \ + if ((b) & ~0xff) \ + b = ((b) < 0) ? 0 : 0xff; \ + if ((a) & ~0xff) \ + a = ((a) < 0) ? 0 : 0xff; -#define CLAMP_RGB(r, g, b) \ - do { \ - if ((r) < 0) \ - r = 0; \ - if ((r) > 0xff) \ - r = 0xff; \ - if ((g) < 0) \ - g = 0; \ - if ((g) > 0xff) \ - g = 0xff; \ - if ((b) < 0) \ - b = 0; \ - if ((b) > 0xff) \ - b = 0xff; \ +#define CLAMP_RGB(r, g, b) \ + do { \ + if ((r) < 0) \ + r = 0; \ + if ((r) > 0xff) \ + r = 0xff; \ + if ((g) < 0) \ + g = 0; \ + if ((g) > 0xff) \ + g = 0xff; \ + if ((b) < 0) \ + b = 0; \ + if ((b) > 0xff) \ + b = 0xff; \ } while (0) static void -dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) -{ +dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) { state->dest_rgba.r = state->r >> 7; CLAMP(state->dest_rgba.r); @@ -3275,8 +3196,7 @@ dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) } static void -dest_pixel_unlit_texture_triangle(s3d_state_t *state) -{ +dest_pixel_unlit_texture_triangle(s3d_state_t *state) { tex_sample(state); if (state->cmd_set & CMD_SET_ABC_SRC) @@ -3284,8 +3204,7 @@ dest_pixel_unlit_texture_triangle(s3d_state_t *state) } static void -dest_pixel_lit_texture_decal(s3d_state_t *state) -{ +dest_pixel_lit_texture_decal(s3d_state_t *state) { tex_sample(state); if (state->cmd_set & CMD_SET_ABC_SRC) @@ -3293,8 +3212,7 @@ dest_pixel_lit_texture_decal(s3d_state_t *state) } static void -dest_pixel_lit_texture_reflection(s3d_state_t *state) -{ +dest_pixel_lit_texture_reflection(s3d_state_t *state) { tex_sample(state); state->dest_rgba.r += (state->r >> 7); @@ -3307,8 +3225,7 @@ dest_pixel_lit_texture_reflection(s3d_state_t *state) } static void -dest_pixel_lit_texture_modulate(s3d_state_t *state) -{ +dest_pixel_lit_texture_modulate(s3d_state_t *state) { int r = state->r >> 7; int g = state->g >> 7; int b = state->b >> 7; @@ -3327,39 +3244,17 @@ dest_pixel_lit_texture_modulate(s3d_state_t *state) } static void -tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) -{ - svga_t *svga = &virge->svga; - uint8_t *vram = svga->vram; +tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) { + uint8_t *vram = virge->svga.vram; + int x_dir = s3d_tri->tlr ? 1 : -1; + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); + int y_count = yc; + int bpp = (s3d_tri->cmd_set >> 2) & 7; + uint32_t dest_offset; + uint32_t z_offset; - int x_dir = s3d_tri->tlr ? 1 : -1; - - int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); - - int y_count = yc; - - int bpp = (s3d_tri->cmd_set >> 2) & 7; - - uint32_t dest_offset = 0; - uint32_t z_offset = 0; - - uint32_t src_col; - int src_r = 0; - int src_g = 0; - int src_b = 0; - - int x; - int xe; - uint32_t z; - - uint32_t dest_addr; - uint32_t z_addr; - int dx; - int x_offset; - int xz_offset; - - int update; - uint16_t src_z = 0; + dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); + z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); if (s3d_tri->cmd_set & CMD_SET_HC) { if (state->y < s3d_tri->clip_t) @@ -3379,240 +3274,195 @@ tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int state->base_a += (s3d_tri->TdAdY * diff_y); state->base_d += (s3d_tri->TdDdY * diff_y); state->base_w += (s3d_tri->TdWdY * diff_y); - state->x1 += (dx1 * diff_y); - state->x2 += (dx2 * diff_y); - state->y -= diff_y; - dest_offset -= s3d_tri->dest_str * diff_y; - z_offset -= s3d_tri->z_str; - y_count -= diff_y; + state->x1 += (dx1 * diff_y); + state->x2 += (dx2 * diff_y); + state->y -= diff_y; + dest_offset -= s3d_tri->dest_str; + z_offset -= s3d_tri->z_str; + y_count -= diff_y; } if ((state->y - y_count) < s3d_tri->clip_t) y_count = (state->y - s3d_tri->clip_t) + 1; } - dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); - z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); + for (; y_count > 0; y_count--) { + int x = (state->x1 + ((1 << 20) - 1)) >> 20; + int xe = (state->x2 + ((1 << 20) - 1)) >> 20; + uint32_t z = (state->base_z > 0) ? (state->base_z << 1) : 0; - while (y_count > 0) { - x = (state->x1 + ((1 << 20) - 1)) >> 20; - xe = (state->x2 + ((1 << 20) - 1)) >> 20; - z = (state->base_z > 0) ? (state->base_z << 1) : 0; - if (x_dir < 0) { - x--; - xe--; + if (x_dir < 0) { + x--; + xe--; + } + + if (x != xe && ((x_dir > 0 && x < xe) || (x_dir < 0 && x > xe))) { + uint32_t dest_addr; + uint32_t z_addr; + int dx = (x_dir > 0) ? ((31 - ((state->x1 - 1) >> 15)) & 0x1f) : + (((state->x1 - 1) >> 15) & 0x1f); + int x_offset = x_dir * (bpp + 1); + int xz_offset = x_dir << 1; + + if (x_dir > 0) + dx += 1; + + state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); + state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); + state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); + state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); + state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); + state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); + state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); + state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); + z += ((s3d_tri->TdZdX * dx) >> 5); + + if (s3d_tri->cmd_set & CMD_SET_HC) { + if (x_dir > 0) { + if (x > s3d_tri->clip_r) + goto tri_skip_line; + if (xe < s3d_tri->clip_l) + goto tri_skip_line; + if (xe > s3d_tri->clip_r) + xe = s3d_tri->clip_r + 1; + if (x < s3d_tri->clip_l) { + int diff_x = s3d_tri->clip_l - x; + + z += (s3d_tri->TdZdX * diff_x); + state->u += (s3d_tri->TdUdX * diff_x); + state->v += (s3d_tri->TdVdX * diff_x); + state->r += (s3d_tri->TdRdX * diff_x); + state->g += (s3d_tri->TdGdX * diff_x); + state->b += (s3d_tri->TdBdX * diff_x); + state->a += (s3d_tri->TdAdX * diff_x); + state->d += (s3d_tri->TdDdX * diff_x); + state->w += (s3d_tri->TdWdX * diff_x); + + x = s3d_tri->clip_l; + } + } else { + if (x < s3d_tri->clip_l) + goto tri_skip_line; + if (xe > s3d_tri->clip_r) + goto tri_skip_line; + if (xe < s3d_tri->clip_l) + xe = s3d_tri->clip_l - 1; + if (x > s3d_tri->clip_r) { + int diff_x = x - s3d_tri->clip_r; + + z += (s3d_tri->TdZdX * diff_x); + state->u += (s3d_tri->TdUdX * diff_x); + state->v += (s3d_tri->TdVdX * diff_x); + state->r += (s3d_tri->TdRdX * diff_x); + state->g += (s3d_tri->TdGdX * diff_x); + state->b += (s3d_tri->TdBdX * diff_x); + state->a += (s3d_tri->TdAdX * diff_x); + state->d += (s3d_tri->TdDdX * diff_x); + state->w += (s3d_tri->TdWdX * diff_x); + + x = s3d_tri->clip_r; + } + } + } + + virge->svga.changedvram[(dest_offset & virge->vram_mask) >> 12] = changeframecount; + + dest_addr = dest_offset + (x * (bpp + 1)); + z_addr = z_offset + (x << 1); + + x &= 0xfff; + xe &= 0xfff; + + for (; x != xe; x = (x + x_dir) & 0xfff) { + int update = 1; + uint16_t src_z = 0; + + _x = x; + _y = state->y; + + if (use_z) { + src_z = Z_READ(z_addr); + Z_CLIP(src_z, z >> 16); + } + + if (update) { + uint32_t dest_col; + + dest_pixel(state); + + if (s3d_tri->cmd_set & CMD_SET_FE) { + int a = state->a >> 7; + state->dest_rgba.r = ((state->dest_rgba.r * a) + (s3d_tri->fog_r * (255 - a))) / 255; + state->dest_rgba.g = ((state->dest_rgba.g * a) + (s3d_tri->fog_g * (255 - a))) / 255; + state->dest_rgba.b = ((state->dest_rgba.b * a) + (s3d_tri->fog_b * (255 - a))) / 255; + } + + if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { + uint32_t src_col; + int src_r = 0; + uint32_t src_g = 0; + uint32_t src_b = 0; + + + switch (bpp) { + case 0: /*8 bpp*/ + /*Not implemented yet*/ + break; + case 1: /*16 bpp*/ + src_col = *(uint16_t *)&vram[dest_addr & virge->vram_mask]; + RGB15_TO_24(src_col, src_r, src_g, src_b); + break; + case 2: /*24 bpp*/ + src_col = (*(uint32_t *)&vram[dest_addr & virge->vram_mask]) & 0xffffff; + RGB24_TO_24(src_col, src_r, src_g, src_b); + break; + } + + state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + + (src_r * (255 - state->dest_rgba.a))) / 255; + state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + + (src_g * (255 - state->dest_rgba.a))) / 255; + state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + + (src_b * (255 - state->dest_rgba.a))) / 255; + } + + switch (bpp) { + case 0: /*8 bpp*/ + /*Not implemented yet*/ + break; + case 1: /*16 bpp*/ + RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); + *(uint16_t *)&vram[dest_addr] = dest_col; + break; + case 2: /*24 bpp*/ + dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); + *(uint8_t *)&vram[dest_addr] = dest_col & 0xff; + *(uint8_t *)&vram[dest_addr + 1] = (dest_col >> 8) & 0xff; + *(uint8_t *)&vram[dest_addr + 2] = (dest_col >> 16) & 0xff; + break; + } + + if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) + Z_WRITE(z_addr, src_z); + } + + z += s3d_tri->TdZdX; + state->u += s3d_tri->TdUdX; + state->v += s3d_tri->TdVdX; + state->r += s3d_tri->TdRdX; + state->g += s3d_tri->TdGdX; + state->b += s3d_tri->TdBdX; + state->a += s3d_tri->TdAdX; + state->d += s3d_tri->TdDdX; + state->w += s3d_tri->TdWdX; + dest_addr += x_offset; + z_addr += xz_offset; + virge->pixel_count++; + } } - if (((x != xe) && ((x_dir > 0) && (x < xe))) || ((x_dir < 0) && (x > xe))) { - dx = (x_dir > 0) ? ((31 - ((state->x1 - 1) >> 15)) & 0x1f) : (((state->x1 - 1) >> 15) & 0x1f); - x_offset = x_dir * (bpp + 1); - xz_offset = x_dir << 1; - if (x_dir > 0) - dx += 1; - state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); - state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); - state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); - state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); - state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); - state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); - state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); - state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); - z += ((s3d_tri->TdZdX * dx) >> 5); - - if (s3d_tri->cmd_set & CMD_SET_HC) { - if (x_dir > 0) { - if (x > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - xe = s3d_tri->clip_r + 1; - if (x < s3d_tri->clip_l) { - int diff_x = s3d_tri->clip_l - x; - - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); - - x = s3d_tri->clip_l; - } - } else { - if (x < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - xe = s3d_tri->clip_l - 1; - if (x > s3d_tri->clip_r) { - int diff_x = x - s3d_tri->clip_r; - - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); - - x = s3d_tri->clip_r; - } - } - } - - svga->changedvram[(dest_offset & virge->vram_mask) >> 12] = changeframecount; - - dest_addr = dest_offset + (x * (bpp + 1)); - z_addr = z_offset + (x << 1); - - x &= 0xfff; - xe &= 0xfff; - - while (x != xe) { - update = 1; - _x = x; - _y = state->y; - - if (use_z) { - src_z = *(uint16_t *) &vram[z_addr & virge->vram_mask]; - switch ((s3d_tri->cmd_set >> 20) & 7) { - case 0: - update = 0; - break; - case 1: - if ((z >> 16) > src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 2: - if ((z >> 16) == src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 3: - if ((z >> 16) >= src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 4: - if ((z >> 16) < src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 5: - if ((z >> 16) != src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 6: - if ((z >> 16) <= src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 7: - src_z = (z >> 16); - break; - - default: - break; - } - } - - if (update) { - uint32_t dest_col; - - dest_pixel(state); - - if (s3d_tri->cmd_set & CMD_SET_FE) { - int a = state->a >> 7; - state->dest_rgba.r = ((state->dest_rgba.r * a) + (s3d_tri->fog_r * (255 - a))) / 255; - state->dest_rgba.g = ((state->dest_rgba.g * a) + (s3d_tri->fog_g * (255 - a))) / 255; - state->dest_rgba.b = ((state->dest_rgba.b * a) + (s3d_tri->fog_b * (255 - a))) / 255; - } - - if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { - switch (bpp) { - case 0: /*8 bpp*/ - /*TODO: Not implemented yet*/ - break; - case 1: /*16 bpp*/ - src_col = *(uint16_t *) &vram[dest_addr & virge->vram_mask]; - RGB15_TO_24(src_col, src_r, src_g, src_b); - break; - case 2: /*24 bpp*/ - src_col = (*(uint32_t *) &vram[dest_addr & virge->vram_mask]) & 0xffffff; - RGB24_TO_24(src_col, src_r, src_g, src_b); - break; - - default: - break; - } - - state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + (src_g * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + (src_b * (255 - state->dest_rgba.a))) / 255; - } - - switch (bpp) { - case 0: /*8 bpp*/ - /*TODO: Not implemented yet*/ - break; - case 1: /*16 bpp*/ - RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); - *(uint16_t *) &vram[dest_addr & virge->vram_mask] = dest_col; - svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; - break; - case 2: /*24 bpp*/ - dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); - *(uint8_t *) &vram[dest_addr & virge->vram_mask] = dest_col & 0xff; - *(uint8_t *) &vram[(dest_addr + 1) & virge->vram_mask] = (dest_col >> 8) & 0xff; - *(uint8_t *) &vram[(dest_addr + 2) & virge->vram_mask] = (dest_col >> 16) & 0xff; - svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; - break; - - default: - break; - } - } - - if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) { - *(uint16_t *) &vram[z_addr & virge->vram_mask] = src_z; - svga->changedvram[(z_addr & virge->vram_mask) >> 12] = changeframecount; - } - - z += s3d_tri->TdZdX; - state->u += s3d_tri->TdUdX; - state->v += s3d_tri->TdVdX; - state->r += s3d_tri->TdRdX; - state->g += s3d_tri->TdGdX; - state->b += s3d_tri->TdBdX; - state->a += s3d_tri->TdAdX; - state->d += s3d_tri->TdDdX; - state->w += s3d_tri->TdWdX; - dest_addr += x_offset; - z_addr += xz_offset; - - x = (x + x_dir) & 0xfff; - } - } - - y_count--; - tri_skip_line: - state->x1 += dx1; - state->x2 += dx2; + state->x1 += dx1; + state->x2 += dx2; state->base_u += s3d_tri->TdUdY; state->base_v += s3d_tri->TdVdY; state->base_z += s3d_tri->TdZdY; @@ -3623,31 +3473,22 @@ tri_skip_line: state->base_d += s3d_tri->TdDdY; state->base_w += s3d_tri->TdWdY; state->y--; - dest_offset -= s3d_tri->dest_str; - z_offset -= s3d_tri->z_str; + dest_offset -= s3d_tri->dest_str; + z_offset -= s3d_tri->z_str; } } -static int tex_size[8] = { - 4 * 2, - 2 * 2, - 2 * 2, - 1 * 2, - 2 / 1, - 2 / 1, - 1 * 2, - 1 * 2 -}; +static int tex_size[8] = {4 * 2, 2 * 2, 2 * 2, 1 * 2, 2 / 1, 2 / 1, 1 * 2, 1 * 2}; static void -s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) -{ +s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) { s3d_state_t state; - uint32_t tex_base; + uint32_t tex_base; + int c; - uint64_t start_time = plat_timer_read(); - uint64_t end_time; + uint64_t start_time = plat_timer_read(); + uint64_t end_time; state.tbu = s3d_tri->tbu << 11; state.tbv = s3d_tri->tbv << 11; @@ -3661,18 +3502,18 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.base_u = s3d_tri->tus; state.base_v = s3d_tri->tvs; state.base_z = s3d_tri->tzs; - state.base_r = (int32_t) s3d_tri->trs; - state.base_g = (int32_t) s3d_tri->tgs; - state.base_b = (int32_t) s3d_tri->tbs; - state.base_a = (int32_t) s3d_tri->tas; + state.base_r = (int32_t)s3d_tri->trs; + state.base_g = (int32_t)s3d_tri->tgs; + state.base_b = (int32_t)s3d_tri->tbs; + state.base_a = (int32_t)s3d_tri->tas; state.base_d = s3d_tri->tds; state.base_w = s3d_tri->tws; tex_base = s3d_tri->tex_base; - for (int c = 9; c >= 0; c--) { - state.texture[c] = (uint16_t *) &virge->svga.vram[tex_base]; - if (c <= state.max_d) - tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; + for (c = 9; c >= 0; c--) { + state.texture[c] = (uint16_t *)&virge->svga.vram[tex_base]; + if (c <= state.max_d) + tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; } switch ((s3d_tri->cmd_set >> 27) & 0xf) { @@ -3692,7 +3533,6 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) dest_pixel = dest_pixel_lit_texture_decal; break; default: - s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); return; } break; @@ -3701,7 +3541,6 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) dest_pixel = dest_pixel_unlit_texture_triangle; break; default: - s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); return; } @@ -3724,34 +3563,35 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) break; case (0 | 8): case (1 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) + if ((virge->chip == S3_VIRGEDX) || (virge->chip >= S3_VIRGEGX2)) tex_sample = tex_sample_persp_mipmap_375; else tex_sample = tex_sample_persp_mipmap; break; case (2 | 8): case (3 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; + if ((virge->chip == S3_VIRGEDX) || (virge->chip >= S3_VIRGEGX2)) + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : + tex_sample_persp_mipmap_375; else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : + tex_sample_persp_mipmap; break; case (4 | 8): case (5 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) + if ((virge->chip == S3_VIRGEDX) || (virge->chip >= S3_VIRGEGX2)) tex_sample = tex_sample_persp_normal_375; else tex_sample = tex_sample_persp_normal; break; case (6 | 8): case (7 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; + if ((virge->chip == S3_VIRGEDX) || (virge->chip >= S3_VIRGEGX2)) + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : + tex_sample_persp_normal_375; else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; - break; - - default: + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : + tex_sample_persp_normal; break; } @@ -3766,7 +3606,6 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; break; default: - s3_virge_log("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; break; } @@ -3778,21 +3617,60 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.x2 = s3d_tri->txend12; tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); + virge->tri_count++; + end_time = plat_timer_read(); - virge->blitter_time += end_time - start_time; + virge_time += end_time - start_time; +} + +static void +render_thread(void *param) +{ + virge_t *virge = (virge_t *)param; + + while (virge->render_thread_run) { + thread_wait_event(virge->wake_render_thread, -1); + thread_reset_event(virge->wake_render_thread); + virge->s3d_busy = 1; + while (!RB_EMPTY) { + s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); + virge->s3d_read_idx++; + + if (RB_ENTRIES == RB_MASK) + thread_set_event(virge->not_full_event); + } + virge->s3d_busy = 0; + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); + } +} + +static void +queue_triangle(virge_t *virge) +{ + if (RB_FULL) { + thread_reset_event(virge->not_full_event); + if (RB_FULL) + thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ + } + virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; + virge->s3d_write_idx++; + if (!virge->s3d_busy) + thread_set_event(virge->wake_render_thread); /*Wake up render thread if moving from idle*/ } static void s3_virge_hwcursor_draw(svga_t *svga, int displine) { - const virge_t *virge = (virge_t *) svga->priv; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg; - uint32_t bg; - uint32_t vram_mask = virge->vram_mask; + virge_t *virge = (virge_t *) svga->priv; + int x; + uint16_t dat[2] = { 0, 0 }; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg; + uint32_t bg; + uint32_t vram_mask = virge->vram_mask; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -3829,13 +3707,16 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) break; } - for (uint8_t x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[svga->hwcursor_latch.addr & vram_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & vram_mask]; - dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & vram_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & vram_mask]; + for (x = 0; x < 64; x += 16) { + dat[0] = (svga->vram[svga->hwcursor_latch.addr & vram_mask] << 8) | + svga->vram[(svga->hwcursor_latch.addr + 1) & vram_mask]; + dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & vram_mask] << 8) | + svga->vram[(svga->hwcursor_latch.addr + 3) & vram_mask]; + if (svga->crtc[0x55] & 0x10) { /*X11*/ for (xx = 0; xx < 16; xx++) { - if (offset >= 0) { + if (offset >= svga->hwcursor_latch.x) { if (virge->chip == S3_VIRGEGX2) dat[0] ^= 0x8000; @@ -3844,13 +3725,14 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) } offset++; + dat[0] <<= 1; dat[1] <<= 1; } } else { /*Windows*/ for (xx = 0; xx < 16; xx++) { - if (offset >= 0) { + if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; else if (dat[1] & 0x8000) @@ -3858,24 +3740,28 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) } offset++; + dat[0] <<= 1; dat[1] <<= 1; } } + svga->hwcursor_latch.addr += 4; } + if (svga->interlace && !svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; } #define DECODE_YCbCr() \ do { \ - int c; \ - \ - for (c = 0; c < 2; c++) { \ + for (uint8_t c = 0; c < 2; c++) { \ uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ + int8_t Cr; \ + int8_t Cb; \ + int dR; \ + int dG; \ + int dB; \ \ y1 = src[0]; \ Cr = src[1] - 0x80; \ @@ -3902,20 +3788,22 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) CLAMP(b[x_write + 1]); \ \ x_write = (x_write + 2) & 7; \ - } \ + } \ } while (0) /*Both YUV formats are untested*/ #define DECODE_YUV211() \ do { \ uint8_t y1, y2, y3, y4; \ - int8_t U, V; \ - int dR, dG, dB; \ + int8_t U, V; \ + int dR; \ + int dG; \ + int dB; \ \ - U = src[0] - 0x80; \ + U = src[0] - 0x80; \ y1 = (298 * (src[1] - 16)) >> 8; \ y2 = (298 * (src[2] - 16)) >> 8; \ - V = src[3] - 0x80; \ + V = src[3] - 0x80; \ y3 = (298 * (src[4] - 16)) >> 8; \ y4 = (298 * (src[5] - 16)) >> 8; \ src += 6; \ @@ -3957,16 +3845,18 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) #define DECODE_YUV422() \ do { \ - int c; \ + for (uint8_t c = 0; c < 2; c++) { \ + uint8_t y1; \ + uint8_t y2; \ + int8_t U; \ + int8_t V; \ + int dR; \ + int dG; \ + int dB; \ \ - for (c = 0; c < 2; c++) { \ - uint8_t y1, y2; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ + U = src[0] - 0x80; \ y1 = (298 * (src[1] - 16)) >> 8; \ - V = src[2] - 0x80; \ + V = src[2] - 0x80; \ y2 = (298 * (src[3] - 16)) >> 8; \ src += 4; \ \ @@ -3992,64 +3882,68 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) } \ } while (0) -#define DECODE_RGB555() \ - do { \ - int c; \ - \ - for (c = 0; c < 4; c++) { \ - uint16_t dat; \ - \ - dat = *(uint16_t *) src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ - b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_RGB555() \ + do { \ + for (uint8_t c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *)src; \ + src += 2; \ + \ + r[x_write + c] = \ + ((dat & 0x001f) << 3) | \ + ((dat & 0x001f) >> 2); \ + g[x_write + c] = \ + ((dat & 0x03e0) >> 2) | \ + ((dat & 0x03e0) >> 7); \ + b[x_write + c] = \ + ((dat & 0x7c00) >> 7) | \ + ((dat & 0x7c00) >> 12); \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_RGB565() \ - do { \ - int c; \ - \ - for (c = 0; c < 4; c++) { \ - uint16_t dat; \ - \ - dat = *(uint16_t *) src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ - b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_RGB565() \ + do { \ + for (uint8_t c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *)src; \ + src += 2; \ + \ + r[x_write + c] = \ + ((dat & 0x001f) << 3) | \ + ((dat & 0x001f) >> 2); \ + g[x_write + c] = \ + ((dat & 0x07e0) >> 3) | \ + ((dat & 0x07e0) >> 9); \ + b[x_write + c] = \ + ((dat & 0xf800) >> 8) | \ + ((dat & 0xf800) >> 13); \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_RGB888() \ - do { \ - int c; \ - \ - for (c = 0; c < 4; c++) { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 3; \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_RGB888() \ + do { \ + for (uint8_t c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 3; \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_XRGB8888() \ - do { \ - int c; \ - \ - for (c = 0; c < 4; c++) { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 4; \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_XRGB8888() \ + do { \ + for (uint8_t c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 4; \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) #define OVERLAY_SAMPLE() \ @@ -4083,37 +3977,46 @@ s3_virge_hwcursor_draw(svga_t *svga, int displine) static void s3_virge_overlay_draw(svga_t *svga, int displine) { - const virge_t *virge = (virge_t *) svga->priv; - int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; - int h_acc = virge->streams.dda_horiz_accumulator; - int r[8]; - int g[8]; - int b[8]; - int x_size; - int x_read = 4; - int x_write = 4; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; + virge_t *virge = (virge_t *) svga->priv; + int offset; + int r[8]; + int g[8]; + int b[8]; + int x_size; + int x_read = 4; + int x_write = 4; + int x; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - p = &(buffer32->line[displine][offset + svga->x_add]); - - if ((offset + virge->streams.sec_w) > virge->streams.pri_w) - x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; + if (virge->chip < S3_VIRGEGX2) + offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; else + offset = virge->streams.sec_x + 1; + + p = &((uint32_t *)buffer32->line[displine])[offset + svga->x_add]; + + if (virge->chip < S3_VIRGEGX2) { + if ((offset + virge->streams.sec_w) > virge->streams.pri_w) + x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; + else + x_size = virge->streams.sec_w + 1; + } else x_size = virge->streams.sec_w + 1; OVERLAY_SAMPLE(); - for (int x = 0; x < x_size; x++) { + for (x = 0; x < x_size; x++) { *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - h_acc += virge->streams.k1_horiz_scale; - if (h_acc >= 0) { + svga->overlay_latch.h_acc += virge->streams.k1_horiz_scale; + if (svga->overlay_latch.h_acc >= 0) { if ((x_read ^ (x_read + 1)) & ~3) OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; - h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); + svga->overlay_latch.h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); } } @@ -4318,7 +4221,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) s3_virge_updatemapping(virge); return; case 0x07: - virge->pci_regs[0x07] = val & 0x3e; + virge->pci_regs[0x07] &= ~(val & 0x30); return; case 0x0d: virge->pci_regs[0x0d] = val & 0xf8; @@ -4397,9 +4300,6 @@ s3_virge_disable_handlers(virge_t *dev) reset_state->svga.timer = dev->svga.timer; reset_state->svga.timer8514 = dev->svga.timer8514; - - reset_state->fifo_timer = dev->fifo_timer; - reset_state->render_timer = dev->render_timer; } static void @@ -4412,7 +4312,6 @@ s3_virge_reset(void *priv) dev->virge_busy = 0; dev->fifo_write_idx = 0; dev->fifo_read_idx = 0; - dev->fifo_state = FIFO_STATE_IDLE; dev->s3d_busy = 0; dev->s3d_write_idx = 0; dev->s3d_read_idx = 0; @@ -4425,8 +4324,8 @@ s3_virge_reset(void *priv) static void * s3_virge_init(const device_t *info) { - const char *bios_fn; - virge_t *virge = calloc(1, sizeof(virge_t)); + const char *bios_fn = NULL; + virge_t *virge = (virge_t *) calloc(1, sizeof(virge_t)); reset_state = calloc(1, sizeof(virge_t)); virge->bilinear_enabled = device_get_config_int("bilinear"); @@ -4438,13 +4337,16 @@ s3_virge_init(const device_t *info) virge->onboard = !!(info->local & 0x100); - switch (info->local) { + if (!virge->onboard) switch (info->local) { case S3_VIRGE_325: bios_fn = ROM_VIRGE_325; break; case S3_DIAMOND_STEALTH3D_2000: bios_fn = ROM_DIAMOND_STEALTH3D_2000; break; + case S3_MIROCRYSTAL_3D: + bios_fn = ROM_MIROCRYSTAL_3D; + break; case S3_DIAMOND_STEALTH3D_3000: bios_fn = ROM_DIAMOND_STEALTH3D_3000; break; @@ -4452,7 +4354,7 @@ s3_virge_init(const device_t *info) bios_fn = ROM_STB_VELOCITY_3D; break; case S3_VIRGE_DX: - bios_fn = virge->onboard ? NULL : ROM_VIRGE_DX; + bios_fn = ROM_VIRGE_DX; break; case S3_DIAMOND_STEALTH3D_2000PRO: bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; @@ -4523,7 +4425,7 @@ s3_virge_init(const device_t *info) io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[PCI_REG_COMMAND] = 3; + virge->pci_regs[PCI_REG_COMMAND] = 7; virge->pci_regs[0x05] = 0; virge->pci_regs[0x06] = 0; virge->pci_regs[0x07] = 2; @@ -4539,6 +4441,7 @@ s3_virge_init(const device_t *info) switch (info->local) { case S3_VIRGE_325: case S3_DIAMOND_STEALTH3D_2000: + case S3_MIROCRYSTAL_3D: virge->fifo_slots_num = 8; virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x56; @@ -4657,8 +4560,16 @@ s3_virge_init(const device_t *info) virge->svga.force_old_addr = 1; - timer_add(&virge->fifo_timer, s3_virge_fifo_timer, virge, 1); - timer_add(&virge->render_timer, s3_virge_render_timer, virge, 0); + virge->render_thread_run = 1; + virge->wake_render_thread = thread_create_event(); + virge->wake_main_thread = thread_create_event(); + virge->not_full_event = thread_create_event(); + virge->render_thread = thread_create(render_thread, virge); + + virge->fifo_thread_run = 1; + virge->wake_fifo_thread = thread_create_event(); + virge->fifo_not_full_event = thread_create_event(); + virge->fifo_thread = thread_create(fifo_thread, virge); virge->local = info->local; @@ -4672,6 +4583,19 @@ s3_virge_close(void *priv) { virge_t *virge = (virge_t *) priv; + virge->render_thread_run = 0; + thread_set_event(virge->wake_render_thread); + thread_wait(virge->render_thread); + thread_destroy_event(virge->not_full_event); + thread_destroy_event(virge->wake_main_thread); + thread_destroy_event(virge->wake_render_thread); + + virge->fifo_thread_run = 0; + thread_set_event(virge->wake_fifo_thread); + thread_wait(virge->fifo_thread); + thread_destroy_event(virge->fifo_not_full_event); + thread_destroy_event(virge->wake_fifo_thread); + svga_close(&virge->svga); ddc_close(virge->ddc); @@ -4695,6 +4619,12 @@ s3_virge_325_available(void) return rom_present(ROM_VIRGE_325); } +static int +s3_mirocrystal_3d_available(void) +{ + return rom_present(ROM_MIROCRYSTAL_3D); +} + static int s3_virge_988_diamond_available(void) { @@ -4762,141 +4692,150 @@ s3_virge_force_redraw(void *priv) static const device_config_t s3_virge_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "dithering", - .description = "Dithering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "dithering", + .description = "Dithering", + .type = CONFIG_BINARY, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_config_t s3_virge_stb_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "8 MB", .value = 8 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "dithering", - .description = "Dithering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "dithering", + .description = "Dithering", + .type = CONFIG_BINARY, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_config_t s3_virge_357_config[] = { // clang-format off { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "dithering", - .description = "Dithering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "dithering", + .description = "Dithering", + .type = CONFIG_BINARY, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; static const device_config_t s3_trio3d2x_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "4 MB", .value = 4 }, + { .description = "8 MB", .value = 8 }, + { .description = "" } + }, + .bios = { { 0 } } }, { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "dithering", - .description = "Dithering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "dithering", + .description = "Dithering", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -4908,7 +4847,21 @@ const device_t s3_virge_325_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_325_available }, + .available = s3_virge_325_available, + .speed_changed = s3_virge_speed_changed, + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config +}; + +const device_t s3_virge_325_onboard_pci_device = { + .name = "S3 ViRGE (325) On-Board PCI", + .internal_name = "virge325_onboard_pci", + .flags = DEVICE_PCI, + .local = S3_VIRGE_325 | 0x100, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, + .available = NULL, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_config @@ -4922,7 +4875,21 @@ const device_t s3_diamond_stealth_2000_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_325_diamond_available }, + .available = s3_virge_325_diamond_available, + .speed_changed = s3_virge_speed_changed, + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config +}; + +const device_t s3_mirocrystal_3d_pci_device = { + .name = "S3 ViRGE (miroCRYSTAL 3D) PCI", + .internal_name = "mirocrystal_3d_pci", + .flags = DEVICE_PCI, + .local = S3_MIROCRYSTAL_3D, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, + .available = s3_mirocrystal_3d_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_config @@ -4936,7 +4903,7 @@ const device_t s3_diamond_stealth_3000_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_988_diamond_available }, + .available = s3_virge_988_diamond_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_stb_config @@ -4950,7 +4917,7 @@ const device_t s3_stb_velocity_3d_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_988_stb_available }, + .available = s3_virge_988_stb_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_stb_config @@ -4964,7 +4931,7 @@ const device_t s3_virge_375_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_375_available }, + .available = s3_virge_375_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_config @@ -4978,7 +4945,7 @@ const device_t s3_virge_375_onboard_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = NULL }, + .available = NULL, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_config @@ -4992,7 +4959,7 @@ const device_t s3_diamond_stealth_2000pro_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_375_diamond_available }, + .available = s3_virge_375_diamond_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_config @@ -5006,7 +4973,7 @@ const device_t s3_virge_385_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_385_available }, + .available = s3_virge_385_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_config @@ -5020,7 +4987,7 @@ const device_t s3_virge_357_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_357_available }, + .available = s3_virge_357_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_357_config @@ -5034,7 +5001,7 @@ const device_t s3_virge_357_agp_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_357_available }, + .available = s3_virge_357_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_357_config @@ -5048,7 +5015,7 @@ const device_t s3_diamond_stealth_4000_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_357_diamond_available }, + .available = s3_virge_357_diamond_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_357_config @@ -5062,7 +5029,7 @@ const device_t s3_diamond_stealth_4000_agp_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_virge_357_diamond_available }, + .available = s3_virge_357_diamond_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_virge_357_config @@ -5076,7 +5043,7 @@ const device_t s3_trio3d2x_pci_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_trio3d2x_available }, + .available = s3_trio3d2x_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_trio3d2x_config @@ -5090,7 +5057,7 @@ const device_t s3_trio3d2x_agp_device = { .init = s3_virge_init, .close = s3_virge_close, .reset = s3_virge_reset, - { .available = s3_trio3d2x_available }, + .available = s3_trio3d2x_available, .speed_changed = s3_virge_speed_changed, .force_redraw = s3_virge_force_redraw, .config = s3_trio3d2x_config diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index 24ca4aeec..0ebcb49b6 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -156,7 +156,7 @@ const device_t sc11483_ramdac_device = { .init = sc1148x_ramdac_init, .close = sc1148x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -170,7 +170,7 @@ const device_t sc11487_ramdac_device = { .init = sc1148x_ramdac_init, .close = sc1148x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -184,7 +184,7 @@ const device_t sc11484_nors2_ramdac_device = { .init = sc1148x_ramdac_init, .close = sc1148x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -198,7 +198,7 @@ const device_t sc11486_ramdac_device = { .init = sc1148x_ramdac_init, .close = sc1148x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 7315c65ad..1c7d4014d 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -249,7 +249,7 @@ const device_t sc1502x_ramdac_device = { .init = sc1502x_ramdac_init, .close = sc1502x_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 83796506e..4e6deacdc 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -313,7 +313,7 @@ const device_t gendac_ramdac_device = { .init = sdac_ramdac_init, .close = sdac_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -327,7 +327,7 @@ const device_t tseng_ics5301_ramdac_device = { .init = sdac_ramdac_init, .close = sdac_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -341,7 +341,7 @@ const device_t tseng_ics5341_ramdac_device = { .init = sdac_ramdac_init, .close = sdac_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL @@ -355,7 +355,7 @@ const device_t sdac_ramdac_device = { .init = sdac_ramdac_init, .close = sdac_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 56f8b99aa..d771260ed 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -860,100 +860,59 @@ sigma_speed_changed(void *priv) device_config_t sigma_config[] = { // clang-format off { - .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, - .default_int = 0, - .selection = { - { - .description = "Color", - .value = 0 - }, - { - .description = "Green Monochrome", - .value = 1 - }, - { - .description = "Amber Monochrome", - .value = 2 - }, - { - .description = "Gray Monochrome", - .value = 3 - }, - { - .description = "Color (no brown)", - .value = 4 - }, - { - .description = "" - } - } - }, - { - .name = "enable_nmi", - .description = "Enable NMI for CGA emulation", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_int = 0xc0000, - .selection = { - { - .description = "C000H", - .value = 0xc0000 - }, - { - .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 = "E000H", - .value = 0xe0000 - }, - { - .description = "E400H", - .value = 0xe4000 - }, - { - .description = "E800H", - .value = 0xe8000 - }, - { - .description = "EC00H", - .value = 0xec000 - }, - { - .description = "" - } + .name = "rgb_type", + .description = "RGB type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Color", .value = 0 }, + { .description = "Green Monochrome", .value = 1 }, + { .description = "Amber Monochrome", .value = 2 }, + { .description = "Gray Monochrome", .value = 3 }, + { .description = "Color (no brown)", .value = 4 }, + { .description = "" } }, + .bios = { { 0 } } }, { - .type = CONFIG_END - } + .name = "enable_nmi", + .description = "Enable NMI for CGA emulation", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc0000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "C000H", .value = 0xc0000 }, + { .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 = "E000H", .value = 0xe0000 }, + { .description = "E400H", .value = 0xe4000 }, + { .description = "E800H", .value = 0xe8000 }, + { .description = "EC00H", .value = 0xec000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -965,7 +924,7 @@ const device_t sigma_device = { .init = sigma_init, .close = sigma_close, .reset = NULL, - { .available = sigma_available }, + .available = sigma_available, .speed_changed = sigma_speed_changed, .force_redraw = NULL, .config = sigma_config diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index 187139b3b..85d492ce7 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -263,7 +263,7 @@ const device_t stg_ramdac_device = { .init = stg_ramdac_init, .close = stg_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 6d952ddb7..ef6381598 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -58,7 +58,6 @@ uint8_t svga_rotate[8][256]; /*Primary SVGA device. As multiple video cards are not yet supported this is the only SVGA device.*/ static svga_t *svga_pri; -int vga_on; #ifdef ENABLE_SVGA_LOG int svga_do_log = ENABLE_SVGA_LOG; @@ -84,13 +83,77 @@ svga_get_pri(void) return svga_pri; } +void +svga_set_poll(svga_t *svga) +{ + svga_log("SVGA Timer activated, enabled?=%x.\n", timer_is_enabled(&svga->timer)); + timer_set_callback(&svga->timer, svga_poll); + if (!timer_is_enabled(&svga->timer)) + timer_enable(&svga->timer); +} + void svga_set_override(svga_t *svga, int val) { + ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret_poll = 0; + if (svga->override && !val) svga->fullchange = svga->monitor->mon_changeframecount; + svga->override = val; + svga_log("Override=%x.\n", val); + if (ibm8514_active && (svga->dev8514 != NULL)) + ret_poll |= 1; + + if (xga_active && (svga->xga != NULL)) + ret_poll |= 2; + + if (svga->override) + svga_set_poll(svga); + else { + switch (ret_poll) { + case 0: + default: + svga_set_poll(svga); + break; + + case 1: + if (ibm8514_active && (svga->dev8514 != NULL)) { + if (dev->on) + ibm8514_set_poll(svga); + else + svga_set_poll(svga); + } else + svga_set_poll(svga); + break; + + case 2: + if (xga_active && (svga->xga != NULL)) { + if (xga->on) + xga_set_poll(svga); + else + svga_set_poll(svga); + } else + svga_set_poll(svga); + break; + + case 3: + if (ibm8514_active && (svga->dev8514 != NULL) && xga_active && (svga->xga != NULL)) { + if (dev->on) + ibm8514_set_poll(svga); + else if (xga->on) + xga_set_poll(svga); + else + svga_set_poll(svga); + } else + svga_set_poll(svga); + break; + } + } + #ifdef OVERRIDE_OVERSCAN if (!val) { /* Override turned off, restore overscan X and Y per the CRTC. */ @@ -119,11 +182,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) uint8_t index; uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f }; - if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) - return; - - if (addr >= 0x3c6 && addr <= 0x3c9) - svga_log("VGA OUT addr=%03x, val=%02x.\n", addr, val); + if ((addr >= 0x2ea) && (addr <= 0x2ed)) { + if (!dev) + return; + } switch (addr) { case 0x2ea: @@ -149,13 +211,13 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 2: index = dev->dac_addr & 0xff; dev->dac_b = val; - svga->vgapal[index].r = dev->dac_r; - svga->vgapal[index].g = dev->dac_g; - svga->vgapal[index].b = dev->dac_b; + dev->_8514pal[index].r = dev->dac_r; + dev->_8514pal[index].g = dev->dac_g; + dev->_8514pal[index].b = dev->dac_b; if (svga->ramdac_type == RAMDAC_8BIT) - dev->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + dev->pallook[index] = makecol32(dev->_8514pal[index].r, dev->_8514pal[index].g, dev->_8514pal[index].b); else - dev->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); + dev->pallook[index] = makecol32(video_6to8[dev->_8514pal[index].r & 0x3f], video_6to8[dev->_8514pal[index].g & 0x3f], video_6to8[dev->_8514pal[index].b & 0x3f]); dev->dac_pos = 0; dev->dac_addr = (dev->dac_addr + 1) & 0xff; break; @@ -172,6 +234,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) if ((val & 0x20) != svga->attr_palette_enable) { svga->fullchange = 3; svga->attr_palette_enable = val & 0x20; + svga_log("Write Port %03x palette enable=%02x.\n", addr, svga->attr_palette_enable); svga_recalctimings(svga); } } else { @@ -196,12 +259,16 @@ svga_out(uint16_t addr, uint8_t val, void *priv) /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ if (svga->attraddr == 0x10) { - if (o != val) + if (o != val) { + svga_log("ATTR10.\n"); svga_recalctimings(svga); + } } else if (svga->attraddr == 0x11) { svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) + if (o != val) { + svga_log("ATTR11.\n"); svga_recalctimings(svga); + } } else if (svga->attraddr == 0x12) { if ((val & 0xf) != svga->plane_mask) svga->fullchange = svga->monitor->mon_changeframecount; @@ -221,14 +288,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 0x3c3: if (xga_active && xga) xga->on = (val & 0x01) ? 0 : 1; - if (ibm8514_active && dev) { - dev->on[0] = (val & 0x01) ? 0 : 1; - if (dev->local & 0xff) - dev->on[1] = dev->on[0]; - } + if (ibm8514_active && dev) + dev->on = (val & 0x01) ? 0 : 1; - svga_log("3C3: VGA ON = %d.\n", val & 0x01); - vga_on = val & 0x01; + svga_log("Write Port 3C3=%x.\n", val & 0x01); svga_recalctimings(svga); break; case 0x3c4: @@ -239,13 +302,16 @@ svga_out(uint16_t addr, uint8_t val, void *priv) return; o = svga->seqregs[svga->seqaddr & 0xf]; svga->seqregs[svga->seqaddr & 0xf] = val; - if (o != val && (svga->seqaddr & 0xf) == 1) + if (o != val && (svga->seqaddr & 0xf) == 1) { + svga_log("SEQADDR1 write1.\n"); svga_recalctimings(svga); + } switch (svga->seqaddr & 0xf) { case 1: if (svga->scrblank && !(val & 0x20)) svga->fullchange = 3; svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); + svga_log("SEQADDR1 write2.\n"); svga_recalctimings(svga); break; case 2: @@ -276,7 +342,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 0x3c8: svga->dac_pos = 0; svga->dac_status = addr & 0x03; - svga->dac_addr = (val + (addr & 0x01)) & 255; + svga->dac_addr = (val + (addr & 0x01)) & 0xff; break; case 0x3c9: if (svga->adv_flags & FLAG_RAMDAC_SHIFT) @@ -292,7 +358,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga->dac_pos++; break; case 2: - index = svga->dac_addr & 255; + index = svga->dac_addr & 0xff; svga->dac_b = val; svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; @@ -302,7 +368,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) else svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); svga->dac_pos = 0; - svga->dac_addr = (svga->dac_addr + 1) & 255; + svga->dac_addr = (svga->dac_addr + 1) & 0xff; break; default: @@ -360,8 +426,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) } svga->gdcreg[svga->gdcaddr & 15] = val; svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); - if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) + if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) { + svga_log("GDCADDR%02x recalc.\n", svga->gdcaddr & 0x0f); svga_recalctimings(svga); + } break; case 0x3da: svga->fcr = val; @@ -377,11 +445,14 @@ svga_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; uint8_t index; uint8_t ret = 0xff; - if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) - return ret; + if ((addr >= 0x2ea) && (addr <= 0x2ed)) { + if (!dev) + return ret; + } switch (addr) { case 0x2ea: @@ -399,24 +470,24 @@ svga_in(uint16_t addr, void *priv) case 0: dev->dac_pos++; if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[index].r; + ret = dev->_8514pal[index].r; else - ret = svga->vgapal[index].r & 0x3f; + ret = dev->_8514pal[index].r & 0x3f; break; case 1: dev->dac_pos++; if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[index].g; + ret = dev->_8514pal[index].g; else - ret = svga->vgapal[index].g & 0x3f; + ret = dev->_8514pal[index].g & 0x3f; break; case 2: dev->dac_pos = 0; dev->dac_addr = (dev->dac_addr + 1) & 0xff; if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[index].b; + ret = dev->_8514pal[index].b; else - ret = svga->vgapal[index].b & 0x3f; + ret = dev->_8514pal[index].b & 0x3f; break; default: @@ -451,7 +522,16 @@ svga_in(uint16_t addr, void *priv) } break; case 0x3c3: - ret = vga_on; + ret = 0x01; + if (xga_active && xga) { + if (xga->on) + ret = 0x00; + } + if (ibm8514_active && dev) { + if (dev->on) + ret = 0x00; + } + svga_log("VGA read: (0x%04x) ret=%02x.\n", addr, ret); break; case 0x3c4: ret = svga->seqaddr; @@ -469,7 +549,7 @@ svga_in(uint16_t addr, void *priv) ret = svga->dac_addr; break; case 0x3c9: - index = (svga->dac_addr - 1) & 255; + index = (svga->dac_addr - 1) & 0xff; switch (svga->dac_pos) { case 0: svga->dac_pos++; @@ -487,7 +567,7 @@ svga_in(uint16_t addr, void *priv) break; case 2: svga->dac_pos = 0; - svga->dac_addr = (svga->dac_addr + 1) & 255; + svga->dac_addr = (svga->dac_addr + 1) & 0xff; if (svga->ramdac_type == RAMDAC_8BIT) ret = svga->vgapal[index].b; else @@ -549,6 +629,8 @@ svga_in(uint16_t addr, void *priv) if ((addr >= 0x3c6) && (addr <= 0x3c9)) svga_log("VGA IN addr=%03x, temp=%02x.\n", addr, ret); + else if ((addr >= 0x2ea) && (addr <= 0x2ed)) + svga_log("8514/A IN addr=%03x, temp=%02x.\n", addr, ret); return ret; } @@ -565,19 +647,20 @@ svga_set_ramdac_type(svga_t *svga, int type) for (int c = 0; c < 256; c++) { if (ibm8514_active && dev) { if (svga->ramdac_type == RAMDAC_8BIT) - dev->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + dev->pallook[c] = makecol32(dev->_8514pal[c].r, dev->_8514pal[c].g, dev->_8514pal[c].b); else - dev->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); + dev->pallook[c] = makecol32((dev->_8514pal[c].r & 0x3f) * 4, + (dev->_8514pal[c].g & 0x3f) * 4, + (dev->_8514pal[c].b & 0x3f) * 4); } if (xga_active && xga) { if (svga->ramdac_type == RAMDAC_8BIT) - xga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - xga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); + xga->pallook[c] = makecol32(xga->xgapal[c].r, xga->xgapal[c].g, xga->xgapal[c].b); + else { + xga->pallook[c] = makecol32((xga->xgapal[c].r & 0x3f) * 4, + (xga->xgapal[c].g & 0x3f) * 4, + (xga->xgapal[c].b & 0x3f) * 4); + } } if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); @@ -593,6 +676,8 @@ void svga_recalctimings(svga_t *svga) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; + xga_t *xga = (xga_t *) svga->xga; + uint8_t set_timer = 0; double crtcconst; double _dispontime; double _dispofftime; @@ -601,6 +686,10 @@ svga_recalctimings(svga_t *svga) double _dispontime8514 = 0.0; double _dispofftime8514 = 0.0; double disptime8514 = 0.0; + double crtcconst_xga = 0.0; + double _dispontime_xga = 0.0; + double _dispofftime_xga = 0.0; + double disptime_xga = 0.0; #ifdef ENABLE_SVGA_LOG int vsyncend; int vblankend; @@ -609,6 +698,8 @@ svga_recalctimings(svga_t *svga) 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; svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -683,10 +774,16 @@ svga_recalctimings(svga_t *svga) } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { /*40 column*/ + if (svga->seqregs[1] & 8) { /*40 column*/ svga->render = svga_render_text_40; - } else { + } else svga->render = svga_render_text_80; + + if (xga_active && (svga->xga != NULL)) { + if (xga->on) { + 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 { @@ -701,7 +798,7 @@ 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; - pclog("2 bpp low res\n"); + svga_log("2 bpp low res\n"); } else svga->render = svga_render_2bpp_highres; } else { @@ -842,7 +939,7 @@ svga_recalctimings(svga_t *svga) #ifdef TBD if (ibm8514_active && (svga->dev8514 != NULL)) { - if (dev->on[0] || dev->on[1]) { + if (dev->on) { uint32_t dot8514 = dev->h_blankstart; uint32_t adj_dot8514 = dev->h_blankstart; uint32_t eff_mask8514 = 0x0000003f; @@ -873,14 +970,20 @@ svga_recalctimings(svga_t *svga) svga->y_add = (svga->monitor->mon_overscan_y >> 1); svga->x_add = (svga->monitor->mon_overscan_x >> 1); - if (svga->vblankstart < svga->dispend) + if (svga->vblankstart < svga->dispend) { + svga_log("DISPEND > VBLANKSTART.\n"); svga->dispend = svga->vblankstart; + } crtcconst = svga->clock * svga->char_width; if (ibm8514_active && (svga->dev8514 != NULL)) { - if (dev->on[0] || dev->on[1]) + if (dev->on) crtcconst8514 = svga->clock8514; } + if (xga_active && (svga->xga != NULL)) { + if (xga->on) + crtcconst_xga = svga->clock_xga; + } #ifdef ENABLE_SVGA_LOG vsyncend = (svga->vsyncstart & 0xfffffff0) | (svga->crtc[0x11] & 0x0f); @@ -923,12 +1026,19 @@ svga_recalctimings(svga_t *svga) _dispontime = svga->hdisp_time; if (ibm8514_active && (svga->dev8514 != NULL)) { - if (dev->on[0] || dev->on[1]) { + if (dev->on) { disptime8514 = dev->h_total ? dev->h_total : TIMER_USEC; _dispontime8514 = dev->hdisped; } } + if (xga_active && (svga->xga != NULL)) { + if (xga->on) { + disptime_xga = xga->h_total ? xga->h_total : TIMER_USEC; + _dispontime_xga = xga->h_disp; + } + } + if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; @@ -945,25 +1055,84 @@ svga_recalctimings(svga_t *svga) if (svga->dispofftime < TIMER_USEC) svga->dispofftime = TIMER_USEC; - if (ibm8514_active && (svga->dev8514 != NULL)) { - if (dev->on[0] || dev->on[1]) { - _dispofftime8514 = disptime8514 - _dispontime8514; - _dispontime8514 *= crtcconst8514; - _dispofftime8514 *= crtcconst8514; + if (ibm8514_active && (svga->dev8514 != NULL)) + set_timer |= 1; - dev->dispontime = (uint64_t) (_dispontime8514); - dev->dispofftime = (uint64_t) (_dispofftime8514); - if (dev->dispontime < TIMER_USEC) - dev->dispontime = TIMER_USEC; - if (dev->dispofftime < TIMER_USEC) - dev->dispofftime = TIMER_USEC; + if (xga_active && (svga->xga != NULL)) + set_timer |= 2; - svga_log("IBM 8514/A poll.\n"); - timer_set_callback(&svga->timer, ibm8514_poll); - } else { - svga_log("SVGA Poll.\n"); - timer_set_callback(&svga->timer, svga_poll); - } + switch (set_timer) { + default: + case 0: /*VGA only*/ + svga_set_poll(svga); + break; + + case 1: /*Plus 8514/A*/ + if (dev->on) { + _dispofftime8514 = disptime8514 - _dispontime8514; + _dispontime8514 *= crtcconst8514; + _dispofftime8514 *= crtcconst8514; + + dev->dispontime = (uint64_t) (_dispontime8514); + dev->dispofftime = (uint64_t) (_dispofftime8514); + if (dev->dispontime < TIMER_USEC) + dev->dispontime = TIMER_USEC; + if (dev->dispofftime < TIMER_USEC) + dev->dispofftime = TIMER_USEC; + + ibm8514_set_poll(svga); + } else + svga_set_poll(svga); + break; + + case 2: /*Plus XGA*/ + if (xga->on) { + _dispofftime_xga = disptime_xga - _dispontime_xga; + _dispontime_xga *= crtcconst_xga; + _dispofftime_xga *= crtcconst_xga; + + xga->dispontime = (uint64_t) (_dispontime_xga); + xga->dispofftime = (uint64_t) (_dispofftime_xga); + if (xga->dispontime < TIMER_USEC) + xga->dispontime = TIMER_USEC; + if (xga->dispofftime < TIMER_USEC) + xga->dispofftime = TIMER_USEC; + + xga_set_poll(svga); + } else + svga_set_poll(svga); + break; + + case 3: /*Plus 8514/A and XGA*/ + if (dev->on) { + _dispofftime8514 = disptime8514 - _dispontime8514; + _dispontime8514 *= crtcconst8514; + _dispofftime8514 *= crtcconst8514; + + dev->dispontime = (uint64_t) (_dispontime8514); + dev->dispofftime = (uint64_t) (_dispofftime8514); + if (dev->dispontime < TIMER_USEC) + dev->dispontime = TIMER_USEC; + if (dev->dispofftime < TIMER_USEC) + dev->dispofftime = TIMER_USEC; + + ibm8514_set_poll(svga); + } else if (xga->on) { + _dispofftime_xga = disptime_xga - _dispontime_xga; + _dispontime_xga *= crtcconst_xga; + _dispofftime_xga *= crtcconst_xga; + + xga->dispontime = (uint64_t) (_dispontime_xga); + xga->dispofftime = (uint64_t) (_dispofftime_xga); + if (xga->dispontime < TIMER_USEC) + xga->dispontime = TIMER_USEC; + if (xga->dispofftime < TIMER_USEC) + xga->dispofftime = TIMER_USEC; + + xga_set_poll(svga); + } else + svga_set_poll(svga); + break; } if (!svga->force_old_addr) @@ -988,6 +1157,9 @@ svga_recalctimings(svga_t *svga) svga->dpms_ui = 0; ui_sb_set_text_w(NULL); } + + 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); } static void @@ -1027,6 +1199,7 @@ svga_do_render(svga_t *svga) if (svga->hwcursor_on) { if (!svga->override && svga->hwcursor_draw) svga->hwcursor_draw(svga, (svga->displine + svga->y_add + ((svga->hwcursor_latch.y >= 0) ? 0 : svga->hwcursor_latch.y)) & 2047); + svga->hwcursor_on--; if (svga->hwcursor_on && svga->interlace) svga->hwcursor_on--; @@ -1037,7 +1210,6 @@ void svga_poll(void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; uint32_t x; uint32_t blink_delay; int wx; @@ -1045,15 +1217,7 @@ svga_poll(void *priv) int ret; int old_ma; - if (!svga->override) { - if (xga_active && xga && xga->on) { - if ((xga->disp_cntl_2 & 7) >= 2) { - xga_poll(xga, svga); - return; - } - } - } - + svga_log("SVGA Poll.\n"); if (!svga->linepos) { if (svga->displine == ((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) && svga->hwcursor_latch.ena) { svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff; @@ -1098,9 +1262,8 @@ svga_poll(void *priv) video_wait_for_buffer_monitor(svga->monitor_index); } - if (svga->hwcursor_on || svga->dac_hwcursor_on || svga->overlay_on) { + 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; - } if (svga->vertical_linedbl) { old_ma = svga->ma; @@ -1186,6 +1349,7 @@ svga_poll(void *priv) svga->ma = svga->maback = (svga->rowoffset << 1) + svga->hblank_sub; else svga->ma = svga->maback = svga->hblank_sub; + svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); @@ -1218,6 +1382,7 @@ svga_poll(void *priv) if (svga->changedvram[x]) svga->changedvram[x]--; } + if (svga->fullchange) svga->fullchange--; } @@ -1236,9 +1401,11 @@ svga_poll(void *priv) if (!svga->override) { if (svga->vertical_linedbl) { wy = (svga->lastline - svga->firstline) << 1; + svga->vdisp = wy + 1; svga_doblit(wx, wy, svga); } else { wy = svga->lastline - svga->firstline; + svga->vdisp = wy + 1; svga_doblit(wx, wy, svga); } } @@ -1314,7 +1481,7 @@ svga_poll(void *priv) } uint32_t -svga_conv_16to32(struct svga_t *svga, uint16_t color, uint8_t bpp) +svga_conv_16to32(UNUSED(struct svga_t *svga), uint16_t color, uint8_t bpp) { return (bpp == 15) ? video_15to32[color] : video_16to32[color]; } @@ -1377,19 +1544,40 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->cable_connected = 1; svga->ksc5601_english_font_type = 0; - vga_on = 1; - - if ((info->flags & DEVICE_PCI) || (info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) { + /* TODO: Move DEVICE_MCA to 16-bit once the device flags have been appropriately corrected. */ + if ((info->flags & DEVICE_MCA) || (info->flags & DEVICE_MCA32) || + (info->flags & DEVICE_EISA) || (info->flags & DEVICE_AT32) || + (info->flags & DEVICE_OLB) || (info->flags & DEVICE_VLB) || + (info->flags & DEVICE_PCI) || (info->flags & DEVICE_AGP)) { + svga->read = svga_read; + svga->readw = svga_readw; + svga->readl = svga_readl; + svga->write = svga_write; + svga->writew = svga_writew; + svga->writel = svga_writel; mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); - } else if ((info->flags & DEVICE_ISA) && (info->flags & DEVICE_AT)) { + /* The chances of ever seeing a C-BUS (S)VGA card are approximately zero, but you never know. */ + } else if ((info->flags & DEVICE_CBUS) || (info->flags & DEVICE_ISA16)) { + svga->read = svga_read; + svga->readw = svga_readw; + svga->readl = NULL; + svga->write = svga_write; + svga->writew = svga_writew; + svga->writel = NULL; mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, NULL, svga_write, svga_writew, NULL, NULL, MEM_MAPPING_EXTERNAL, svga); } else { + svga->read = svga_read; + svga->readw = NULL; + svga->readl = NULL; + svga->write = svga_write; + svga->writew = NULL; + svga->writel = NULL; mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, NULL, NULL, svga_write, NULL, NULL, @@ -1419,7 +1607,7 @@ svga_close(svga_t *svga) svga_pri = NULL; } -static uint32_t +uint32_t svga_decode_addr(svga_t *svga, uint32_t addr, int write) { int memory_map_mode = (svga->gdcreg[6] >> 2) & 3; @@ -1460,7 +1648,6 @@ static __inline void svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; int writemask2 = svga->writemask; int reset_wm = 0; latch_t vall; @@ -1474,44 +1661,12 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; if (!linear) { - if (xga_active && xga) { - if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { - 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; - - xga->on = 0; - vga_on = 1; - xga->disp_cntl_2 = 0; - svga_log("XGA test1 addr = %05x.\n", addr); - return; - } else if (val == 0x5a) { - xga->test = val; - xga->on = 0; - vga_on = 1; - xga->disp_cntl_2 = 0; - svga_log("XGA test2 addr = %05x.\n", addr); - return; - } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += xga->write_bank; - xga->vram[addr & xga->vram_mask] = val; - svga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x.\n", val, addr, svga->banked_mask); - if (!xga->a5_test) - xga->linear_endian_reverse = 1; - return; - } - } else { - xga->on = 0; - vga_on = 1; - } - } + xga_write_test(addr, val, svga); addr = svga_decode_addr(svga, addr, 1); - - if (addr == 0xffffffff) + if (addr == 0xffffffff) { + svga_log("WriteCommon Over.\n"); return; + } } if (!(svga->gdcreg[6] & 1)) @@ -1543,8 +1698,10 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) if (svga->translate_address) addr = svga->translate_address(addr, priv); - if (addr >= svga->vram_max) + if (addr >= svga->vram_max) { + svga_log("WriteBankedOver=%08x, val=%02x.\n", addr & svga->vram_mask, val); return; + } addr &= svga->vram_mask; @@ -1682,12 +1839,11 @@ static __inline uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; uint32_t latch_addr = 0; int readplane = svga->readplane; uint8_t count; uint8_t temp; - uint8_t ret; + uint8_t ret = 0x00; if (svga->adv_flags & FLAG_ADDR_BY8) readplane = svga->gdcreg[4] & 7; @@ -1695,41 +1851,8 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; if (!linear) { - if (xga_active && xga) { - if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { - if (xga->test == 0xa5) { /*Memory size test of XGA*/ - if (addr == 0xa0001) { - ret = xga->test; - xga->on = 1; - vga_on = 0; - } else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ - svga_log("A5 test bank = %x.\n", addr); - addr += xga->read_bank; - ret = xga->vram[addr & xga->vram_mask]; - } else { - ret = xga->test; - xga->on = 1; - vga_on = 0; - } - svga_log("A5 read: XGA ON = %d, addr = %05x, ret = %02x, test1 = %x.\n", xga->on, addr, ret, xga->a5_test); - return ret; - } else if (xga->test == 0x5a) { - ret = xga->test; - xga->on = 1; - vga_on = 0; - svga_log("5A read: XGA ON = %d.\n", xga->on); - return ret; - } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += xga->read_bank; - return xga->vram[addr & xga->vram_mask]; - } - } else { - xga->on = 0; - vga_on = 1; - } - } + (void) xga_read_test(addr, svga); addr = svga_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) return 0xff; } @@ -1951,6 +2074,8 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_write_w; if (!linear) { + xga_write_test(addr, val & 0xff, svga); + xga_write_test(addr + 1, val >> 8, svga); addr = svga_decode_addr(svga, addr, 1); if (addr == 0xffffffff) @@ -2007,6 +2132,10 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_write_l; if (!linear) { + xga_write_test(addr, val & 0xff, svga); + xga_write_test(addr + 1, (val >> 8) & 0xff, svga); + xga_write_test(addr + 2, (val >> 16) & 0xff, svga); + xga_write_test(addr + 3, (val >> 24) & 0xff, svga); addr = svga_decode_addr(svga, addr, 1); if (addr == 0xffffffff) @@ -2039,6 +2168,7 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *priv) } if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; @@ -2083,8 +2213,9 @@ svga_readw_common(uint32_t addr, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_read_w; if (!linear) { + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); addr = svga_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) return 0xffff; } @@ -2130,8 +2261,11 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_read_l; if (!linear) { + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + (void) xga_read_test(addr + 2, svga); + (void) xga_read_test(addr + 3, svga); addr = svga_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) return 0xffffffff; } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 74d9a4d0c..c05d308fa 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -178,14 +178,14 @@ svga_render_text_40(svga_t *svga) charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; + bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; + fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; if (svga->blink & 16) fg = bg; } @@ -256,13 +256,13 @@ svga_render_text_80(svga_t *svga) charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; + bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; + fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; if (svga->blink & 16) fg = bg; } @@ -323,13 +323,13 @@ svga_render_text_80_ksc5601(svga_t *svga) attr = svga->vram[addr + 1]; if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; + bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; + fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; if (svga->blink & 16) fg = bg; } @@ -378,13 +378,13 @@ svga_render_text_80_ksc5601(svga_t *svga) attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; + bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; + fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; + bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; if (svga->blink & 16) fg = bg; } @@ -468,14 +468,14 @@ svga_render_2bpp_s3_lowres(svga_t *svga) else svga->ma += 4; svga->ma &= svga->vram_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[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]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]; p += 16; } } @@ -501,14 +501,14 @@ svga_render_2bpp_s3_lowres(svga_t *svga) svga->ma &= svga->vram_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[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]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]; p += 16; } @@ -566,14 +566,14 @@ svga_render_2bpp_s3_highres(svga_t *svga) else svga->ma += 4; svga->ma &= svga->vram_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[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]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]; p += 8; } } @@ -599,14 +599,14 @@ svga_render_2bpp_s3_highres(svga_t *svga) svga->ma &= svga->vram_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[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]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]; p += 8; } @@ -652,17 +652,17 @@ svga_render_2bpp_headland_highres(svga_t *svga) svga->ma &= svga->vram_mask; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_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]]; + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_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]]; + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_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[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; p += 8; } @@ -868,8 +868,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } else if (combine8bits) { if (svga->packed_4bpp) { - uint32_t p0 = svga->map8[c0]; - uint32_t p1 = svga->map8[c1]; + uint32_t p0 = svga->map8[c0 & svga->dac_mask]; + uint32_t p1 = svga->map8[c1 & svga->dac_mask]; const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -877,14 +877,14 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx + dotwidth] = p1; } else { uint32_t ccombined = (c0 << 4) | c1; - uint32_t p0 = svga->map8[ccombined]; + uint32_t p0 = svga->map8[ccombined & svga->dac_mask]; const int outoffs = (i >> 1) << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; } } else { - uint32_t p0 = svga->pallook[svga->egapal[c0]]; - uint32_t p1 = svga->pallook[svga->egapal[c1]]; + uint32_t p0 = svga->pallook[svga->egapal[c0] & svga->dac_mask]; + uint32_t p1 = svga->pallook[svga->egapal[c1] & svga->dac_mask]; const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -934,16 +934,16 @@ svga_render_8bpp_clone_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + 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]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + 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; p += 8; @@ -963,16 +963,16 @@ 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]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + p[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]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + 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; p += 8; @@ -981,10 +981,10 @@ svga_render_8bpp_clone_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + p[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; p += 4; @@ -1043,10 +1043,10 @@ 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]); - 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]; + 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; p += 8; @@ -1055,10 +1055,10 @@ svga_render_8bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & 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]; + 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; p += 8; @@ -1091,16 +1091,16 @@ svga_render_8bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + 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]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + 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; p += 8; @@ -1120,16 +1120,16 @@ 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]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + p[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]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + 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; p += 8; @@ -1138,10 +1138,10 @@ svga_render_8bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + p[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; p += 4; @@ -1173,19 +1173,19 @@ svga_render_8bpp_tseng_lowres(svga_t *svga) dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[0] = p[1] = svga->map8[dat & 0xff]; + p[0] = p[1] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[2] = p[3] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[4] = p[5] = svga->map8[dat & 0xff]; + p[4] = p[5] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[6] = p[7] = svga->map8[dat & 0xff]; + p[6] = p[7] = svga->map8[dat & svga->dac_mask & 0xff]; svga->ma += 4; p += 8; @@ -1214,36 +1214,36 @@ svga_render_8bpp_tseng_highres(svga_t *svga) dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[0] = svga->map8[dat & 0xff]; + p[0] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[1] = svga->map8[dat & 0xff]; + p[1] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[2] = svga->map8[dat & 0xff]; + p[2] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[3] = svga->map8[dat & 0xff]; + p[3] = svga->map8[dat & svga->dac_mask & 0xff]; dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[4] = svga->map8[dat & 0xff]; + p[4] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[5] = svga->map8[dat & 0xff]; + p[5] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[6] = svga->map8[dat & 0xff]; + p[6] = svga->map8[dat & svga->dac_mask & 0xff]; dat >>= 8; if (svga->attrregs[0x10] & 0x80) dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[7] = svga->map8[dat & 0xff]; + p[7] = svga->map8[dat & svga->dac_mask & 0xff]; svga->ma += 8; p += 8; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index cda3f95e0..ff3073c73 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -50,204 +50,206 @@ static int was_reset = 0; static const VIDEO_CARD video_cards[] = { // clang-format off - { &device_none }, - { &device_internal }, - { &atiega800p_device }, - { &mach8_vga_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_isa_device }, - { &ati28800k_device }, - { &ati18800_vga88_device }, - { &ati28800_device }, - { &compaq_ati28800_device }, -#if defined(DEV_BRANCH) && defined(USE_XL24) - { &ati28800_wonderxl24_device }, -#endif - { &ati18800_device }, - { &ati18800_wonder_device }, - { &cga_device }, - { &sega_device }, - { &gd5401_isa_device }, - { &gd5402_isa_device }, - { &gd5420_isa_device }, - { &gd5422_isa_device }, - { &gd5426_isa_device }, - { &gd5426_diamond_speedstar_pro_a1_isa_device }, - { &gd5428_boca_isa_device }, - { &gd5428_isa_device }, - { &gd5429_isa_device }, - { &gd5434_isa_device }, - { &gd5434_diamond_speedstar_64_a3_isa_device }, - { &compaq_cga_device }, - { &compaq_cga_2_device }, - { &cpqega_device }, - { &ega_device }, - { &g2_gc205_device }, - { &hercules_device, VIDEO_FLAG_TYPE_MDA }, - { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, - { &incolor_device }, - { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, - { &im1024_device }, - { &iskra_ega_device }, - { &et4000_kasan_isa_device }, - { &mda_device, VIDEO_FLAG_TYPE_MDA }, - { &genius_device }, - { &nga_device }, - { &ogc_device }, - { &oti037c_device }, - { &oti067_device }, - { &oti077_device }, - { ¶dise_pvga1a_device }, - { ¶dise_wd90c11_device }, - { ¶dise_wd90c30_device }, - { &colorplus_device }, - { &pgc_device }, - { &cga_pravetz_device }, - { &radius_svga_multiview_isa_device }, - { &realtek_rtg3105_device }, - { &realtek_rtg3106_device }, - { &s3_diamond_stealth_vram_isa_device }, - { &s3_orchid_86c911_isa_device }, - { &s3_ami_86c924_isa_device }, - { &s3_metheus_86c928_isa_device }, - { &s3_phoenix_86c801_isa_device }, - { &s3_spea_mirage_86c801_isa_device }, - { &sigma_device }, - { &tvga8900b_device }, - { &tvga8900d_device }, - { &tvga8900dr_device }, - { &tvga9000b_device }, - { &nec_sv9000_device }, - { &et4000k_isa_device }, - { &et2000_device }, - { &et3000_isa_device }, - { &et4000_tc6058af_isa_device }, - { &et4000_isa_device }, - { &et4000w32_device }, - { &et4000w32i_isa_device }, - { &vga_device }, - { &v7_vga_1024i_device }, - { &wy700_device }, - { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, - { &gd5426_mca_device }, - { &gd5428_mca_device }, - { &et4000_mca_device }, - { &radius_svga_multiview_mca_device }, - { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_pci_device }, - { &mach64vt2_device }, - { &bochs_svga_device }, - { &chips_69000_device }, - { &gd5430_pci_device, }, - { &gd5434_pci_device }, - { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5440_pci_device }, - { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5480_pci_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, - { &s3_spea_mercury_lite_86c928_pci_device }, - { &s3_diamond_stealth64_964_pci_device }, - { &s3_elsa_winner2000_pro_x_964_pci_device }, - { &s3_mirocrystal_20sv_964_pci_device }, - { &s3_bahamas64_pci_device }, - { &s3_phoenix_vision864_pci_device }, - { &s3_diamond_stealth_se_pci_device }, - { &s3_phoenix_trio32_pci_device }, - { &s3_diamond_stealth64_pci_device }, - { &s3_9fx_pci_device }, - { &s3_phoenix_trio64_pci_device }, - { &s3_diamond_stealth64_968_pci_device }, - { &s3_elsa_winner2000_pro_x_pci_device }, - { &s3_mirovideo_40sv_ergo_968_pci_device }, - { &s3_9fx_771_pci_device }, - { &s3_phoenix_vision968_pci_device }, - { &s3_spea_mercury_p64v_pci_device }, - { &s3_9fx_531_pci_device }, - { &s3_phoenix_vision868_pci_device }, - { &s3_cardex_trio64vplus_pci_device }, - { &s3_phoenix_trio64vplus_pci_device }, - { &s3_trio64v2_dx_pci_device }, - { &s3_virge_325_pci_device }, - { &s3_diamond_stealth_2000_pci_device }, - { &s3_diamond_stealth_3000_pci_device }, - { &s3_stb_velocity_3d_pci_device }, - { &s3_virge_375_pci_device }, - { &s3_diamond_stealth_2000pro_pci_device }, - { &s3_virge_385_pci_device }, - { &s3_virge_357_pci_device }, - { &s3_diamond_stealth_4000_pci_device }, - { &s3_trio3d2x_pci_device }, - { &millennium_device }, - { &millennium_ii_device }, - { &mystique_device }, - { &mystique_220_device }, - { &tgui9440_pci_device }, - { &tgui9660_pci_device }, - { &tgui9680_pci_device }, - { &voodoo_banshee_device }, - { &creative_voodoo_banshee_device }, - { &voodoo_3_1000_device }, - { &voodoo_3_2000_device }, - { &voodoo_3_3000_device }, - { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_vlb_device }, - { &et4000w32i_vlb_device }, - { &et4000w32p_videomagic_revb_vlb_device }, - { &et4000w32p_revc_vlb_device }, - { &et4000w32p_cardex_vlb_device }, - { &et4000w32p_vlb_device }, - { &et4000w32p_noncardex_vlb_device }, - { &gd5424_vlb_device }, - { &gd5426_vlb_device }, - { &gd5428_vlb_device }, - { &gd5428_diamond_speedstar_pro_b1_vlb_device }, - { &gd5429_vlb_device }, - { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, - { &gd5430_vlb_device }, - { &gd5434_vlb_device }, - { &s3_metheus_86c928_vlb_device }, - { &s3_mirocrystal_8s_805_vlb_device }, - { &s3_mirocrystal_10sd_805_vlb_device }, - { &s3_phoenix_86c805_vlb_device }, - { &s3_spea_mirage_86c805_vlb_device }, - { &s3_diamond_stealth64_964_vlb_device }, - { &s3_mirocrystal_20sv_964_vlb_device }, - { &s3_mirocrystal_20sd_864_vlb_device }, - { &s3_bahamas64_vlb_device }, - { &s3_phoenix_vision864_vlb_device }, - { &s3_diamond_stealth_se_vlb_device }, - { &s3_phoenix_trio32_vlb_device }, - { &s3_diamond_stealth64_vlb_device }, - { &s3_9fx_vlb_device }, - { &s3_phoenix_trio64_vlb_device }, - { &s3_spea_mirage_p64_vlb_device }, - { &s3_diamond_stealth64_968_vlb_device }, - { &s3_stb_powergraph_64_video_vlb_device }, - { &ht216_32_standalone_device }, - { &tgui9400cxi_device }, - { &tgui9440_vlb_device }, - { &s3_virge_357_agp_device }, - { &s3_diamond_stealth_4000_agp_device }, - { &s3_trio3d2x_agp_device }, + { .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 }, + { .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 = &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 = &gd5401_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5402_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 }, + { .device = &gd5426_diamond_speedstar_pro_a1_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5428_boca_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5428_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .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 = &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 = &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 }, + { .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 }, + { .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 }, + { .device = &bochs_svga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &chips_69000_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5430_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5434_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5436_pci_device, .flags = VIDEO_FLAG_TYPE_SPECIAL }, + { .device = &gd5440_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &gd5446_pci_device, .flags = VIDEO_FLAG_TYPE_SPECIAL }, + { .device = &gd5446_stb_pci_device, .flags = VIDEO_FLAG_TYPE_SPECIAL }, + { .device = &gd5480_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_videomagic_revb_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_revc_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner2000_pro_x_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirocrystal_20sv_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_bahamas64_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_vision864_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth_se_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_trio32_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth64_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_9fx_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_trio64_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth64_968_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner2000_pro_x_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirovideo_40sv_ergo_968_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_9fx_771_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_vision968_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_spea_mercury_p64v_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_9fx_531_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_vision868_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_cardex_trio64vplus_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_phoenix_trio64vplus_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_trio64v2_dx_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_virge_325_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth_2000_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_mirocrystal_3d_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth_3000_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_stb_velocity_3d_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_virge_375_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth_2000pro_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_virge_385_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_virge_357_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_diamond_stealth_4000_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_trio3d2x_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &millennium_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &millennium_ii_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &mystique_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &mystique_220_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tgui9440_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tgui9660_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &tgui9680_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_banshee_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &creative_voodoo_banshee_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .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 }, + { .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 }, #ifdef USE_G100 - { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, -#endif - { &velocity_100_agp_device }, - { &velocity_200_agp_device }, - { &voodoo_3_1000_agp_device }, - { &voodoo_3_2000_agp_device }, - { &voodoo_3_3000_agp_device }, - { &voodoo_3_3500_agp_ntsc_device }, - { &voodoo_3_3500_agp_pal_device }, - { &compaq_voodoo_3_3500_agp_device }, - { &voodoo_3_3500_se_agp_device }, - { &voodoo_3_3500_si_agp_device }, - { NULL } + { .device = &productiva_g100_device, .flags = VIDEO_FLAG_TYPE_SPECIAL }, +#endif /*USE_G100 */ + { .device = &velocity_100_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &velocity_200_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_1000_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_2000_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_3000_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_3500_agp_ntsc_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_3500_agp_pal_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &compaq_voodoo_3_3500_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_3500_se_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &voodoo_3_3500_si_agp_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = NULL, .flags = VIDEO_FLAG_TYPE_NONE } // clang-format on }; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 490c724ce..d1391f1d1 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -112,8 +112,7 @@ typedef struct tgui_t { uint8_t int_line; uint8_t pci_regs[256]; - struct - { + struct { int16_t src_x, src_y; int16_t src_x_clip, src_y_clip; int16_t dst_x, dst_y; @@ -145,12 +144,11 @@ typedef struct tgui_t { uint32_t pattern_32[8 * 8]; } accel; - uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ - uint8_t copy_latch[16]; + uint8_t copy_latch[16]; /*TGUI9400CXi only*/ uint8_t tgui_3d8, tgui_3d9; int oldmode; - uint8_t oldctrl1, newctrl1; + uint8_t oldctrl1; uint8_t oldctrl2, newctrl2; uint8_t oldgr0e, newgr0e; @@ -160,6 +158,7 @@ typedef struct tgui_t { int ramdac_state; uint8_t ramdac_ctrl; + uint8_t alt_clock; int clock_m, clock_n, clock_k; @@ -210,11 +209,8 @@ static void tgui_ext_writel(uint32_t addr, uint32_t val, void *priv); /*Remap address for chain-4/doubleword style layout*/ static __inline uint32_t -dword_remap(svga_t *svga, uint32_t in_addr) +dword_remap(UNUSED(svga_t *svga), uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); } @@ -297,7 +293,7 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) { tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; - uint8_t old; + uint8_t old, o; if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -331,6 +327,15 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) svga->read_bank = svga->write_bank; return; + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + svga->seqregs[svga->seqaddr] = val; + return; + default: break; } @@ -344,20 +349,9 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) if (tgui->ramdac_state == 4) { tgui->ramdac_state = 0; tgui->ramdac_ctrl = val; - switch ((tgui->ramdac_ctrl >> 4) & 0x0f) { - case 1: - svga->bpp = 15; - break; - case 3: - svga->bpp = 16; - break; - case 0x0d: - svga->bpp = (tgui->type >= TGUI_9660) ? 32 : 24; - break; - default: - svga->bpp = 8; - break; - } +#if 0 + pclog("TGUI ramdac ctrl=%02x.\n", (tgui->ramdac_ctrl >> 4) & 0x0f); +#endif svga_recalctimings(svga); return; } @@ -374,30 +368,35 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) break; case 0x3CF: - if (svga->gdcaddr == 0x23) { - svga->dpms = !!(val & 0x03); - svga_recalctimings(svga); - } - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) { - old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; - tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; - if (svga->gdcaddr == 16) - tgui_recalcmapping(tgui); - return; - } + o = svga->gdcreg[svga->gdcaddr]; switch (svga->gdcaddr) { - case 0x6: + case 2: + svga->colourcompare = val; + break; + case 4: + svga->readplane = val & 3; + break; + case 5: + svga->writemode = val & 3; + svga->readmode = val & 8; + svga->chain2_read = val & 0x10; + break; + case 6: if (svga->gdcreg[6] != val) { svga->gdcreg[6] = val; tgui_recalcmapping(tgui); } - return; + break; + case 7: + svga->colournocare = val; + break; case 0x0e: svga->gdcreg[0xe] = val ^ 2; if ((svga->gdcreg[0xf] & 1) == 1) svga->read_bank = (svga->gdcreg[0xe]) * 65536; break; + case 0x0f: if (val & 1) svga->read_bank = (svga->gdcreg[0xe]) * 65536; @@ -414,6 +413,12 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) svga->write_bank = (svga->seqregs[0xe]) * 65536; break; + case 0x23: + svga->dpms = !!(val & 0x03); + svga_recalctimings(svga); + break; + + case 0x2f: case 0x5a: case 0x5b: case 0x5c: @@ -426,11 +431,36 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) default: break; } - break; + svga->gdcreg[svga->gdcaddr] = val; + + if (tgui->type == TGUI_9400CXI) { + if ((svga->gdcaddr >= 0x10) && (svga->gdcaddr <= 0x1f)) { + tgui_recalcmapping(tgui); + return; + } + } + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); + if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || ((svga->gdcaddr == 6) && ((val ^ o) & 1))) + svga_recalctimings(svga); + return; case 0x3D4: svga->crtcreg = val; return; case 0x3D5: + if (!(svga->seqregs[0x0e] & 0x80) && !tgui->oldmode) { + switch (svga->crtcreg) { + case 0x21: + case 0x29: + case 0x2a: + case 0x38: + case 0x39: + case 0x3b: + case 0x3c: + return; + default: + break; + } + } if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -482,8 +512,12 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; if ((tgui->accel.ger22 & 0xff) == 8) { - if (svga->bpp != 24) + if (svga->bpp != 24) { svga->hwcursor.x <<= 1; + svga_recalctimings(svga); + if ((svga->vdisp == 1022) && svga->interlace) + svga->hwcursor.x >>= 1; + } } svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; @@ -531,6 +565,10 @@ tgui_out(uint16_t addr, uint8_t val, void *priv) svga->read_bank = (val & 0x3f) * 65536; return; + case 0x3DB: + tgui->alt_clock = val & 0xe3; + return; + case 0x43c8: tgui->clock_n = val & 0x7f; tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7); @@ -591,6 +629,8 @@ tgui_in(uint16_t addr, void *priv) return tgui->oldctrl1 | 0x88; return svga->seqregs[0x0e]; } + if ((svga->seqaddr >= 0x5a) && (svga->seqaddr <= 0x5f)) + return svga->seqregs[svga->seqaddr]; break; case 0x3C6: @@ -610,10 +650,10 @@ tgui_in(uint16_t addr, void *priv) break; case 0x3CF: - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) - return tgui->ext_gdc_regs[svga->gdcaddr & 15]; if (svga->gdcaddr >= 0x5a && svga->gdcaddr <= 0x5f) return svga->gdcreg[svga->gdcaddr]; + if (svga->gdcaddr == 0x2f) + return svga->gdcreg[svga->gdcaddr]; break; case 0x3D4: return svga->crtcreg; @@ -636,6 +676,8 @@ tgui_in(uint16_t addr, void *priv) return tgui->tgui_3d8; case 0x3d9: return tgui->tgui_3d9; + case 0x3db: + return tgui->alt_clock; default: break; @@ -650,28 +692,51 @@ tgui_recalctimings(svga_t *svga) uint8_t ger22lower = (tgui->accel.ger22 & 0xff); uint8_t ger22upper = (tgui->accel.ger22 >> 8); - if (!svga->rowoffset) - svga->rowoffset = 0x100; - - if (svga->crtc[0x29] & 0x10) - svga->rowoffset |= 0x100; + if (tgui->type >= TGUI_9440) { + if ((svga->crtc[0x38] & 0x19) == 0x09) + svga->bpp = 32; + else { + switch ((tgui->ramdac_ctrl >> 4) & 0x0f) { + case 0x01: + svga->bpp = 15; + break; + case 0x03: + svga->bpp = 16; + break; + case 0x0d: + svga->bpp = 24; + break; + default: + svga->bpp = 8; + break; + } + } + } if ((tgui->type >= TGUI_9440) && (svga->bpp >= 24)) - svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp = (svga->crtc[1] + 1) << 3; + + if (((svga->crtc[0x29] & 0x30) && (svga->bpp >= 15)) || !svga->rowoffset) + svga->rowoffset |= 0x100; + +#if 0 + pclog("BPP=%d, DataWidth=%02x, CRTC29 bit 4-5=%02x, pixbusmode=%02x, rowoffset=%02x, doublerowoffset=%x.\n", svga->bpp, svga->crtc[0x2a] & 0x40, svga->crtc[0x29] & 0x30, svga->crtc[0x38], svga->rowoffset, svga->gdcreg[0x2f] & 4); +#endif if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) + if (svga->crtc[0x27] & 0x01) svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) + if (svga->crtc[0x27] & 0x02) svga->ma_latch |= 0x40000; - if ((svga->crtc[0x27] & 0x04) == 0x04) + if (svga->crtc[0x27] & 0x04) svga->ma_latch |= 0x80000; if (svga->crtc[0x27] & 0x08) svga->split |= 0x400; if (svga->crtc[0x27] & 0x10) svga->dispend |= 0x400; + if (svga->crtc[0x27] & 0x20) svga->vsyncstart |= 0x400; if (svga->crtc[0x27] & 0x40) @@ -684,15 +749,18 @@ tgui_recalctimings(svga_t *svga) svga->lowres = 0; } + svga->interlace = !!(svga->crtc[0x1e] & 4); + if (svga->interlace && (tgui->type < TGUI_9440)) + svga->rowoffset >>= 1; + + if (svga->vdisp == 1020) + svga->vdisp += 2; + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) svga->ma_latch <<= 1; svga->lowres = !(svga->crtc[0x2a] & 0x40); - svga->interlace = !!(svga->crtc[0x1e] & 4); - if (svga->interlace && (tgui->type < TGUI_9440)) - svga->rowoffset >>= 1; - if (tgui->type >= TGUI_9440) { if (svga->miscout & 8) svga->clock = (cpuclock * (double) (1ULL << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); @@ -749,6 +817,7 @@ tgui_recalctimings(svga_t *svga) default: break; } + if (svga->gdcreg[0xf] & 0x08) { svga->htotal <<= 1; svga->hdisp <<= 1; @@ -760,7 +829,24 @@ tgui_recalctimings(svga_t *svga) switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; + if (svga->vdisp == 1022) { + if (svga->interlace) + svga->dispend++; + else + svga->dispend += 2; + } if (tgui->type >= TGUI_9660) { + switch (svga->vdisp) { + case 1024: + case 1200: + svga->htotal <<= 1; + svga->hdisp <<= 1; + svga->hdisp_time <<= 1; + break; + default: + break; + } +#if OLD_CODE if (svga->dispend == ((1024 >> 1) - 2)) svga->dispend += 2; if (svga->dispend == (1024 >> 1)) @@ -773,6 +859,7 @@ tgui_recalctimings(svga_t *svga) else if (!svga->interlace && (svga->dispend == 768)) svga->hdisp <<= 1; } +#endif if (ger22upper & 0x80) { svga->htotal <<= 1; @@ -782,7 +869,7 @@ tgui_recalctimings(svga_t *svga) switch (svga->hdisp) { case 640: if (!ger22lower) - svga->rowoffset = 80; + svga->rowoffset = 0x50; break; default: @@ -806,11 +893,10 @@ tgui_recalctimings(svga_t *svga) svga->hdisp = (svga->hdisp << 1) / 3; break; case 32: + if (svga->rowoffset == 0x100) + svga->rowoffset <<= 1; + svga->render = svga_render_32bpp_highres; - if (tgui->type >= TGUI_9660) { - if (!ger22upper) - svga->rowoffset <<= 1; - } break; default: @@ -825,14 +911,14 @@ tgui_recalcmapping(tgui_t *tgui) svga_t *svga = &tgui->svga; if (tgui->type == TGUI_9400CXI) { - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + if (svga->gdcreg[0x10] & EXT_CTRL_LATCH_COPY) { mem_mapping_set_handler(&tgui->linear_mapping, tgui_ext_linear_read, NULL, NULL, tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); mem_mapping_set_handler(&svga->mapping, tgui_ext_read, NULL, NULL, tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) { + } else if (svga->gdcreg[0x10] & EXT_CTRL_MONO_EXPANSION) { mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); @@ -928,7 +1014,7 @@ tgui_recalcmapping(tgui_t *tgui) } if (tgui->type >= TGUI_9440) { - if ((tgui->mmio_base != 0x00000000) && (svga->crtc[0x39] & 1)) + if ((tgui->mmio_base != 0x00000000) && (svga->crtc[0x39] & 0x01)) mem_mapping_set_addr(&tgui->mmio_mapping, tgui->mmio_base, 0x10000); else mem_mapping_disable(&tgui->mmio_mapping); @@ -939,7 +1025,7 @@ static void tgui_hwcursor_draw(svga_t *svga, int displine) { uint32_t dat[2]; - int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; int pitch = (svga->hwcursor_latch.cur_xsize == 64) ? 16 : 8; if (svga->interlace && svga->hwcursor_oddeven) @@ -1121,26 +1207,24 @@ tgui_ext_linear_read(uint32_t addr, void *priv) svga_t *svga = (svga_t *) priv; tgui_t *tgui = (tgui_t *) svga->priv; - cycles -= video_timing_read_b; + cycles -= svga->monitor->mon_video_timing_read_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; - addr = dword_remap(svga, addr); + addr &= ~0x0f; + addr = dword_remap(svga, addr); - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { - for (int c = 0; c < 16; c++) { - tgui->copy_latch[c] = svga->vram[addr]; - addr += (c & 3) ? 1 : 13; - addr &= svga->vram_mask; - } - return svga->vram[addr]; + for (int i = 0; i < 16; i++) { + tgui->copy_latch[i] = svga->vram[addr]; + addr += ((i & 3) == 3) ? 0x0d : 0x01; } - return svga_read_linear(addr, svga); + addr &= svga->vram_mask; + + return svga->vram[addr]; } static uint8_t @@ -1158,65 +1242,77 @@ tgui_ext_linear_write(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; const tgui_t *tgui = (tgui_t *) svga->priv; - int c; - int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT); - uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; - uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; - uint8_t mask = tgui->ext_gdc_regs[7]; + int bpp = (svga->gdcreg[0x10] & EXT_CTRL_16BIT); + uint8_t fg[2] = { svga->gdcreg[0x14], svga->gdcreg[0x15] }; + uint8_t bg[2] = { svga->gdcreg[0x11], svga->gdcreg[0x12] }; - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_write_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) return; - addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; - addr = dword_remap(svga, addr); + addr &= svga->vram_mask; + addr &= (svga->gdcreg[0x10] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; + addr = dword_remap(svga, addr); + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { - for (c = 0; c < 16; c++) { - svga->vram[addr] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; + if (svga->gdcreg[0x10] & EXT_CTRL_LATCH_COPY) { + for (int i = 0; i < 8; i++) { + if (val & (0x80 >> i)) + svga->vram[addr] = tgui->copy_latch[i]; + + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } - } else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) { - if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) { + } else { + if (svga->gdcreg[0x10] & EXT_CTRL_MONO_TRANSPARENT) { if (bpp) { - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; + for (int i = 0; i < 8; i++) { + if (val & (0x80 >> i)) + svga->vram[addr] = fg[i & 1]; + + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } else { - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - svga->vram[addr] = tgui->ext_gdc_regs[4]; - addr += (c == 4) ? 13 : 1; + for (int i = 0; i < 8; i++) { + if (val & (0x80 >> i)) + svga->vram[addr] = fg[0]; + + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } } else { if (bpp) { - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; + for (int i = 0; i < 8; i++) { + if (val & (0x80 >> i)) { + if (svga->gdcreg[0x17] & (0x80 >> i)) + svga->vram[addr] = fg[i & 1]; + } else { + if (svga->gdcreg[0x17] & (0x80 >> i)) + svga->vram[addr] = bg[i & 1]; + } + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } else { - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1]; - addr += (c == 4) ? 13 : 1; + for (int i = 0; i < 8; i++) { + if (val & (0x80 >> i)) { + if (svga->gdcreg[0x17] & (0x80 >> i)) + svga->vram[addr] = fg[0]; + } else { + if (svga->gdcreg[0x17] & (0x80 >> i)) + svga->vram[addr] = bg[0]; + } + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } } - } else - svga_write_linear(addr, val, svga); + } } static void @@ -1224,94 +1320,85 @@ tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *priv) { svga_t *svga = (svga_t *) priv; const tgui_t *tgui = (tgui_t *) svga->priv; - int c; - int bpp = (tgui->ext_gdc_regs[0] & EXT_CTRL_16BIT); - uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; - uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; - uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; + int bpp = (svga->gdcreg[0x10] & EXT_CTRL_16BIT); + uint8_t fg[2] = { svga->gdcreg[0x14], svga->gdcreg[0x15] }; + uint8_t bg[2] = { svga->gdcreg[0x11], svga->gdcreg[0x12] }; + uint16_t mask = svga->gdcreg[0x18] | (svga->gdcreg[0x17] << 8); - cycles -= video_timing_write_w; + cycles -= svga->monitor->mon_video_timing_write_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) return; + addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; + addr &= ~0x0f; + addr = dword_remap(svga, addr); - addr = dword_remap(svga, addr); svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - val = (val >> 8) | (val << 8); - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { - for (c = 0; c < 16; c++) { - svga->vram[addr] = tgui->copy_latch[c]; - addr += (c & 3) ? 1 : 13; + if (svga->gdcreg[0x10] & EXT_CTRL_LATCH_COPY) { + for (int i = 0; i < 16; i++) { + if (val & (0x8000 >> i)) + svga->vram[addr] = tgui->copy_latch[i]; + + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } - } else if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT)) { - if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_TRANSPARENT) { + } else { + if (svga->gdcreg[0x10] & EXT_CTRL_MONO_TRANSPARENT) { if (bpp) { - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; + for (int i = 0; i < 16; i++) { + if (val & (0x8000 >> i)) + svga->vram[addr] = fg[i & 1]; + + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } else { - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - svga->vram[addr] = tgui->ext_gdc_regs[4]; + for (int i = 0; i < 16; i++) { + if (val & (0x8000 >> i)) + svga->vram[addr] = fg[0]; - addr += (c & 3) ? 1 : 13; + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } } else { if (bpp) { - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; + for (int i = 0; i < 16; i++) { + if (val & (0x8000 >> i)) { + if (mask & (0x8000 >> i)) + svga->vram[addr] = fg[i & 1]; + } else { + if (mask & (0x8000 >> i)) + svga->vram[addr] = bg[i & 1]; + } + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } else { - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - svga->vram[addr] = (val & (1 << c)) ? tgui->ext_gdc_regs[4] : tgui->ext_gdc_regs[1]; - - addr += (c & 3) ? 1 : 13; + for (int i = 0; i < 16; i++) { + if (val & (0x8000 >> i)) { + if (mask & (0x8000 >> i)) + svga->vram[addr] = fg[0]; + } else { + if (mask & (0x8000 >> i)) + svga->vram[addr] = bg[0]; + } + addr += ((i & 3) == 3) ? 0x0d : 0x01; addr &= svga->vram_mask; } } } - } else - svga_writew_linear(addr, val, svga); + } } static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) priv; - const tgui_t *tgui = (tgui_t *) svga->priv; - - cycles -= video_timing_write_l; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) ? ~0x0f : ~0x07; - - addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; - - if (tgui->ext_gdc_regs[0] & (EXT_CTRL_MONO_EXPANSION | EXT_CTRL_MONO_TRANSPARENT | EXT_CTRL_LATCH_COPY)) { - tgui_ext_linear_writew(addr, val & 0xffff, priv); - tgui_ext_linear_writew(addr + 2, val >> 16, priv); - } else { - svga_writel_linear(addr, val, svga); - } + tgui_ext_linear_writew(addr, val, priv); } static void @@ -1384,15 +1471,15 @@ enum { } \ } while (0) -#define WRITE(addr, dat) \ - if (tgui->accel.bpp == 0) { \ - svga->vram[(addr) &tgui->vram_mask] = dat; \ +#define WRITE(addr, dat) \ + if (tgui->accel.bpp == 0) { \ + svga->vram[(addr) &tgui->vram_mask] = dat; \ svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; \ - } else if (tgui->accel.bpp == 1) { \ - vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \ + } else if (tgui->accel.bpp == 1) { \ + vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \ svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ - } else { \ - vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \ + } else { \ + vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \ svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = svga->monitor->mon_changeframecount; \ } @@ -1484,6 +1571,8 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) case 32: tgui->accel.pitch <<= 1; break; + default: + break; } #if 0 pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); @@ -2029,7 +2118,9 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *priv) case 0x2123: tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); - //pclog("Pitch IO23: val = %02x, rowoffset = %x.\n", tgui->accel.ger22, svga->crtc[0x13]); +#if 0 + pclog("Pitch IO23: val = %02x, rowoffset = %x.\n", tgui->accel.ger22, svga->crtc[0x13]); +#endif switch (svga->bpp) { case 8: case 24: @@ -3213,7 +3304,6 @@ tgui_init(const device_t *info) if (tgui->type >= TGUI_9440) { svga->packed_chain4 = 1; - tgui->i2c = i2c_gpio_init("ddc_tgui"); tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c)); } @@ -3279,56 +3369,41 @@ tgui_force_redraw(void *priv) // clang-format off static const device_config_t tgui9440_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; static const device_config_t tgui96xx_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 4, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1 MB", .value = 1 }, + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } }, - .default_int = 4 + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } }; // clang-format on @@ -3340,7 +3415,7 @@ const device_t tgui9400cxi_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9400cxi_available }, + .available = tgui9400cxi_available, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3354,7 +3429,7 @@ const device_t tgui9440_vlb_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9440_vlb_available }, + .available = tgui9440_vlb_available, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3368,7 +3443,7 @@ const device_t tgui9440_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui9440_pci_available }, + .available = tgui9440_pci_available, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3382,7 +3457,7 @@ const device_t tgui9440_onboard_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui9440_config @@ -3396,7 +3471,7 @@ const device_t tgui9660_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui96xx_available }, + .available = tgui96xx_available, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui96xx_config @@ -3410,7 +3485,7 @@ const device_t tgui9660_onboard_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui96xx_config @@ -3424,7 +3499,7 @@ const device_t tgui9680_pci_device = { .init = tgui_init, .close = tgui_close, .reset = NULL, - { .available = tgui96xx_available }, + .available = tgui96xx_available, .speed_changed = tgui_speed_changed, .force_redraw = tgui_force_redraw, .config = tgui96xx_config diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index f23cb7396..fcc046cb4 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -266,7 +266,7 @@ const device_t ibm_ps1_2121_device = { .init = vid_init, .close = vid_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = vid_speed_changed, .force_redraw = vid_force_redraw, .config = NULL diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index 4108b9a4e..c8ad1c421 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -129,7 +129,7 @@ const device_t tkd8001_ramdac_device = { .init = tkd8001_ramdac_init, .close = tkd8001_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index cd5714d04..9dd7e424d 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -521,101 +521,92 @@ tvga_force_redraw(void *priv) static const device_config_t tvga_config[] = { // clang-format off { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1024, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, + .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 }, /*Chip supports 2mb, but drivers are buggy*/ - { - .description = "" - } - } + { .description = "" } + }, + .bios = { { 0 } } }, - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format off }; const device_t tvga8900b_device = { - .name = "Trident TVGA 8900B", + .name = "Trident TVGA 8900B", .internal_name = "tvga8900b", - .flags = DEVICE_ISA, - .local = TVGA8900B_ID, - .init = tvga_init, - .close = tvga_close, - .reset = NULL, - { .available = tvga8900b_available }, + .flags = DEVICE_ISA, + .local = TVGA8900B_ID, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + .available = tvga8900b_available, .speed_changed = tvga_speed_changed, - .force_redraw = tvga_force_redraw, - .config = tvga_config + .force_redraw = tvga_force_redraw, + .config = tvga_config }; const device_t tvga8900d_device = { - .name = "Trident TVGA 8900D", + .name = "Trident TVGA 8900D", .internal_name = "tvga8900d", - .flags = DEVICE_ISA, - .local = TVGA8900CLD_ID, - .init = tvga_init, - .close = tvga_close, - .reset = NULL, - { .available = tvga8900d_available }, + .flags = DEVICE_ISA, + .local = TVGA8900CLD_ID, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + .available = tvga8900d_available, .speed_changed = tvga_speed_changed, - .force_redraw = tvga_force_redraw, - .config = tvga_config + .force_redraw = tvga_force_redraw, + .config = tvga_config }; const device_t tvga8900dr_device = { - .name = "Trident TVGA 8900D-R", + .name = "Trident TVGA 8900D-R", .internal_name = "tvga8900dr", - .flags = DEVICE_ISA, - .local = TVGA8900CLD_ID | 0x0100, - .init = tvga_init, - .close = tvga_close, - .reset = NULL, - { .available = tvga8900dr_available }, + .flags = DEVICE_ISA, + .local = TVGA8900CLD_ID | 0x0100, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + .available = tvga8900dr_available, .speed_changed = tvga_speed_changed, - .force_redraw = tvga_force_redraw, - .config = tvga_config + .force_redraw = tvga_force_redraw, + .config = tvga_config }; const device_t tvga9000b_device = { - .name = "Trident TVGA 9000B", + .name = "Trident TVGA 9000B", .internal_name = "tvga9000b", - .flags = DEVICE_ISA, - .local = TVGA9000B_ID, - .init = tvga_init, - .close = tvga_close, - .reset = NULL, - { .available = tvga9000b_available }, + .flags = DEVICE_ISA, + .local = TVGA9000B_ID, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + .available = tvga9000b_available, .speed_changed = tvga_speed_changed, - .force_redraw = tvga_force_redraw, - .config = NULL + .force_redraw = tvga_force_redraw, + .config = NULL }; const device_t nec_sv9000_device = { - .name = "NEC SV9000 (Trident TVGA 9000B)", + .name = "NEC SV9000 (Trident TVGA 9000B)", .internal_name = "nec_sv9000", - .flags = DEVICE_ISA, - .local = TVGA9000B_ID | 0x100, - .init = tvga_init, - .close = tvga_close, - .reset = NULL, - { .available = tvga9000b_nec_sv9000_available }, + .flags = DEVICE_ISA, + .local = TVGA9000B_ID | 0x100, + .init = tvga_init, + .close = tvga_close, + .reset = NULL, + .available = tvga9000b_nec_sv9000_available, .speed_changed = tvga_speed_changed, - .force_redraw = tvga_force_redraw, - .config = NULL + .force_redraw = tvga_force_redraw, + .config = NULL }; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index b50d0406b..bd5a83fd0 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -516,7 +516,7 @@ tvp3026_recalctimings(void *priv, svga_t *svga) svga->interlace = !!(ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ - svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); + svga->lut_map = !!((svga->bpp >= 15 && (svga->bpp != 24)) && (ramdac->true_color & 0xf0) != 0x00); if (!(ramdac->clock_sel & 0x70)) { if (ramdac->mcr != 0x98) { @@ -733,7 +733,7 @@ const device_t tvp3026_ramdac_device = { .init = tvp3026_ramdac_init, .close = tvp3026_ramdac_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = NULL, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 8d4439f95..97889e007 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -31,6 +31,7 @@ #include <86box/vid_svga.h> #include <86box/vid_vga.h> +static video_timings_t timing_vga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static video_timings_t timing_ps1_svga_isa = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; static video_timings_t timing_ps1_svga_mca = { .type = VIDEO_MCA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; @@ -225,7 +226,7 @@ const device_t vga_device = { .init = vga_init, .close = vga_close, .reset = NULL, - { .available = vga_available }, + .available = vga_available, .speed_changed = vga_speed_changed, .force_redraw = vga_force_redraw, .config = NULL @@ -239,7 +240,7 @@ const device_t ps1vga_device = { .init = ps1vga_init, .close = vga_close, .reset = NULL, - { .available = vga_available }, + .available = NULL, .speed_changed = vga_speed_changed, .force_redraw = vga_force_redraw, .config = NULL @@ -253,7 +254,7 @@ const device_t ps1vga_mca_device = { .init = ps1vga_init, .close = vga_close, .reset = NULL, - { .available = vga_available }, + .available = NULL, .speed_changed = vga_speed_changed, .force_redraw = vga_force_redraw, .config = NULL diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 93bdd1a4c..e45f112ed 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -222,12 +222,12 @@ voodoo_readl(uint32_t addr, void *priv) { int fifo_entries = FIFO_ENTRIES; int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo + voodoo->cmd_written_fifo_2; int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); if (SLI_ENABLED && voodoo->type != VOODOO_2) { voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; - int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; + int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo + voodoo->cmd_written_fifo_2; if (voodoo_other->swap_count > swap_count) swap_count = voodoo_other->swap_count; @@ -1308,124 +1308,124 @@ voodoo_close(void *priv) static const device_config_t voodoo_config[] = { // clang-format off { - .name = "type", - .description = "Voodoo type", - .type = CONFIG_SELECTION, + .name = "type", + .description = "Voodoo type", + .type = CONFIG_SELECTION, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, .selection = { - { - .description = "3Dfx Voodoo Graphics", - .value = VOODOO_1 - }, - { - .description = "Obsidian SB50 + Amethyst (2 TMUs)", - .value = VOODOO_SB50 - }, - { - .description = "3Dfx Voodoo 2", - .value = VOODOO_2 - }, - { - .description = "" - } + { .description = "3Dfx Voodoo Graphics", .value = VOODOO_1 }, + { .description = "Obsidian SB50 + Amethyst (2 TMUs)", .value = VOODOO_SB50 }, + { .description = "3Dfx Voodoo 2", .value = VOODOO_2 }, + { .description = "" } }, - .default_int = 0 + .bios = { { 0 } } }, { - .name = "framebuffer_memory", - .description = "Framebuffer memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } + .name = "framebuffer_memory", + .description = "Framebuffer memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, { - .name = "texture_memory", - .description = "Texture memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } + .name = "texture_memory", + .description = "Texture memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "2 MB", .value = 2 }, + { .description = "4 MB", .value = 4 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1", .value = 1 }, + { .description = "2", .value = 2 }, + { .description = "4", .value = 4 }, + { .description = "" } }, - .default_int = 2 + .bios = { { 0 } } }, { - .name = "sli", - .description = "SLI", - .type = CONFIG_BINARY, - .default_int = 0 + .name = "sli", + .description = "SLI", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, #ifndef NO_CODEGEN { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 + .name = "recompiler", + .description = "Dynamic Recompiler", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } }, #endif - { - .type = CONFIG_END - } + { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -1437,7 +1437,7 @@ const device_t voodoo_device = { .init = voodoo_init, .close = voodoo_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = voodoo_speed_changed, .force_redraw = voodoo_force_blit, .config = voodoo_config diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 5b6dbb434..fadd782a5 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -204,6 +204,17 @@ enum { cmdFifoDepth0 = 0x44, cmdHoleCnt0 = 0x48, + cmdBaseAddr1 = 0x50, + cmdBaseSize1 = 0x50 + 0x4, + cmdBump1 = 0x50 + 0x8, + cmdRdPtrL1 = 0x50 + 0xc, + cmdRdPtrH1 = 0x50 + 0x10, + cmdAMin1 = 0x50 + 0x14, + cmdAMax1 = 0x50 + 0x1c, + cmdStatus1 = 0x50 + 0x20, + cmdFifoDepth1 = 0x50 + 0x24, + cmdHoleCnt1 = 0x50 + 0x28, + Agp_agpReqSize = 0x00, Agp_agpHostAddressLow = 0x04, Agp_agpHostAddressHigh = 0x08, @@ -430,7 +441,9 @@ banshee_updatemapping(banshee_t *banshee) svga_t *svga = &banshee->svga; if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - // banshee_log("Update mapping - PCI disabled\n"); +#if 0 + banshee_log("Update mapping - PCI disabled\n"); +#endif mem_mapping_disable(&svga->mapping); mem_mapping_disable(&banshee->linear_mapping); mem_mapping_disable(&banshee->reg_mapping_low); @@ -469,7 +482,7 @@ banshee_updatemapping(banshee_t *banshee) } uint32_t -banshee_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +banshee_conv_16to32(svga_t* svga, uint16_t color, UNUSED(uint8_t bpp)) { banshee_t *banshee = (banshee_t *) svga->priv; uint32_t ret = 0x00000000; @@ -513,7 +526,7 @@ banshee_render_16bpp_tiled(svga_t *svga) if (addr >= svga->vram_max) return; - for (int x = 0; x <= svga->hdisp; x += 64) { + for (int x = 0; x < svga->hdisp; x += 64) { if (svga->hwcursor_on || svga->overlay_on) svga->changedvram[addr >> 12] = 2; if (svga->changedvram[addr >> 12] || svga->fullchange) { @@ -1071,7 +1084,9 @@ banshee_ext_in(uint16_t addr, void *priv) break; } - // banshee_log("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); +#if 0 + banshee_log("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); +#endif return ret; } @@ -1084,7 +1099,7 @@ banshee_status(banshee_t *banshee) int fifo_entries = FIFO_ENTRIES; int swap_count = voodoo->swap_count; int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; uint32_t ret = 0; if (fifo_entries < 0x20) @@ -1106,6 +1121,9 @@ banshee_status(banshee_t *banshee) if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) ret |= (1 << 11); + if (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2) + ret |= (1 << 12); + if (!voodoo->voodoo_busy) voodoo_wake_fifo_thread(voodoo); @@ -1259,7 +1277,9 @@ banshee_ext_inl(uint16_t addr, void *priv) break; default: - // fatal("bad banshee_ext_inl: addr=%04x\n", addr); +#if 0 + fatal("bad banshee_ext_inl: addr=%04x\n", addr); +#endif break; } @@ -1320,17 +1340,23 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr) case cmdBaseAddr0: ret = voodoo->cmdfifo_base >> 12; - // banshee_log("Read cmdfifo_base %08x\n", ret); +#if 0 + banshee_log("Read cmdfifo_base %08x\n", ret); +#endif break; case cmdRdPtrL0: ret = voodoo->cmdfifo_rp; - // banshee_log("Read cmdfifo_rp %08x\n", ret); +#if 0 + banshee_log("Read cmdfifo_rp %08x\n", ret); +#endif break; case cmdFifoDepth0: ret = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; - // banshee_log("Read cmdfifo_depth %08x\n", ret); +#if 0 + banshee_log("Read cmdfifo_depth %08x\n", ret); +#endif break; case cmdStatus0: @@ -1341,6 +1367,35 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr) ret = voodoo->cmdfifo_size; break; + case cmdBaseAddr1: + ret = voodoo->cmdfifo_base_2 >> 12; +#if 0 + banshee_log("Read cmdfifo_base %08x\n", ret); +#endif + break; + + case cmdRdPtrL1: + ret = voodoo->cmdfifo_rp_2; +#if 0 + banshee_log("Read cmdfifo_rp %08x\n", ret); +#endif + break; + + case cmdFifoDepth1: + ret = voodoo->cmdfifo_depth_wr_2 - voodoo->cmdfifo_depth_rd_2; +#if 0 + banshee_log("Read cmdfifo_depth %08x\n", ret); +#endif + break; + + case cmdStatus1: + ret = voodoo->cmd_status_2; + break; + + case cmdBaseSize1: + ret = voodoo->cmdfifo_size_2; + break; + case 0x108: break; @@ -1625,6 +1680,45 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) voodoo->cmdfifo_depth_wr = val & 0xffff; break; + case cmdBaseAddr1: + voodoo->cmdfifo_base_2 = (val & 0xfff) << 12; + voodoo->cmdfifo_end_2 = voodoo->cmdfifo_base_2 + (((voodoo->cmdfifo_size_2 & 0xff) + 1) << 12); +#if 0 + banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val); +#endif + break; + + case cmdBaseSize1: + voodoo->cmdfifo_size_2 = val; + voodoo->cmdfifo_end_2 = voodoo->cmdfifo_base_2 + (((voodoo->cmdfifo_size_2 & 0xff) + 1) << 12); + voodoo->cmdfifo_enabled_2 = val & 0x100; + if (!voodoo->cmdfifo_enabled_2) + voodoo->cmdfifo_in_sub_2 = 0; /*Not sure exactly when this should be reset*/ +#if 0 + banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); +#endif + break; + +#if 0 + voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; + banshee_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + break; +#endif + + case cmdRdPtrL1: + voodoo->cmdfifo_rp_2 = val; + break; + case cmdAMin1: + voodoo->cmdfifo_amin_2 = val; + break; + case cmdAMax1: + voodoo->cmdfifo_amax_2 = val; + break; + case cmdFifoDepth1: + voodoo->cmdfifo_depth_rd_2 = 0; + voodoo->cmdfifo_depth_wr_2 = val & 0xffff; + break; + default: banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x reg=0x%03x\n", addr, val, addr & 0x1fc); break; @@ -2064,6 +2158,60 @@ banshee_write_linear_l(uint32_t addr, uint32_t val, void *priv) voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; #if 0 banshee_log("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); +#endif + } + } + + if (voodoo->cmdfifo_enabled_2 && addr >= voodoo->cmdfifo_base_2 && addr < voodoo->cmdfifo_end_2) { +#if 0 + banshee_log("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); +#endif + if (addr == voodoo->cmdfifo_base_2 && !voodoo->cmdfifo_holecount_2) { +#if 0 + if (voodoo->cmdfifo_holecount) + fatal("CMDFIFO reset pointers while outstanding holes\n"); +#endif + /*Reset pointers*/ + voodoo->cmdfifo_amin_2 = voodoo->cmdfifo_base_2; + voodoo->cmdfifo_amax_2 = voodoo->cmdfifo_base_2; + voodoo->cmdfifo_depth_wr_2++; + voodoo_wake_fifo_thread(voodoo); + } else if (voodoo->cmdfifo_holecount_2) { +#if 0 + if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax) + fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); + banshee_log("holecount %i\n", voodoo->cmdfifo_holecount); +#endif + voodoo->cmdfifo_holecount_2--; + if (!voodoo->cmdfifo_holecount_2) { + /*Filled in holes, resume normal operation*/ + voodoo->cmdfifo_depth_wr_2 += ((voodoo->cmdfifo_amax_2 - voodoo->cmdfifo_amin_2) >> 2); + voodoo->cmdfifo_amin_2 = voodoo->cmdfifo_amax_2; + voodoo_wake_fifo_thread(voodoo); +#if 0 + banshee_log("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); +#endif + } + } else if (addr == voodoo->cmdfifo_amax_2 + 4) { + /*In-order write*/ + voodoo->cmdfifo_amin_2 = addr; + voodoo->cmdfifo_amax_2 = addr; + voodoo->cmdfifo_depth_wr_2++; + voodoo_wake_fifo_thread(voodoo); + } else { + /*Out-of-order write*/ + if (addr < voodoo->cmdfifo_amin_2) { + /*Reset back to start. Note that write is still out of order!*/ + voodoo->cmdfifo_amin_2 = voodoo->cmdfifo_base_2 - 4; + } +#if 0 + else if (addr < voodoo->cmdfifo_amax) + fatal("Out-of-order write really out of order\n"); +#endif + voodoo->cmdfifo_amax_2 = addr; + voodoo->cmdfifo_holecount_2 = ((voodoo->cmdfifo_amax_2 - voodoo->cmdfifo_amin_2) >> 2) - 1; +#if 0 + banshee_log("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); #endif } } @@ -2703,7 +2851,9 @@ banshee_pci_read(int func, int addr, void *priv) if (func) return 0xff; - // banshee_log("Banshee PCI read %08X ", addr); +#if 0 + banshee_log("Banshee PCI read %08X ", addr); +#endif switch (addr) { case 0x00: ret = 0x1a; @@ -3028,192 +3178,6 @@ banshee_pci_write(int func, int addr, uint8_t val, void *priv) } } -// clang-format off -static const device_config_t banshee_sgram_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "" - } - }, - .default_int = 16 - }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, -#ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, -#endif - { - .type = CONFIG_END - } -}; - -static const device_config_t banshee_sgram_16mbonly_config[] = { - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, -#ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, -#endif - { - .type = CONFIG_END - } -}; - -static const device_config_t banshee_sdram_config[] = { - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, -#ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, -#endif - { - .type = CONFIG_END - } -}; -// clang-format on - static void * banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int voodoo_type, int agp) { @@ -3313,6 +3277,7 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->voodoo->tex_mem_w[1] = (uint16_t *) banshee->svga.vram; banshee->voodoo->texture_mask = banshee->svga.vram_mask; banshee->voodoo->cmd_status = (1 << 28); + banshee->voodoo->cmd_status_2 = (1 << 28); voodoo_generate_filter_v1(banshee->voodoo); banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; @@ -3604,6 +3569,221 @@ banshee_force_redraw(void *priv) banshee->svga.fullchange = changeframecount; } +// clang-format off +static const device_config_t banshee_sgram_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 16, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "8 MB", .value = 8 }, + { .description = "16 MB", .value = 16 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1", .value = 1 }, + { .description = "2", .value = 2 }, + { .description = "4", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Dynamic Recompiler", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, +#endif + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t banshee_sgram_16mbonly_config[] = { + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1", .value = 1 }, + { .description = "2", .value = 2 }, + { .description = "4", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Dynamic Recompiler", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, +#endif + { .name = "", .description = "", .type = CONFIG_END } +}; + +static const device_config_t banshee_sdram_config[] = { + { + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "dithersub", + .description = "Dither subtraction", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 2, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "1", .value = 1 }, + { .description = "2", .value = 2 }, + { .description = "4", .value = 4 }, + { .description = "" } + }, + .bios = { { 0 } } + }, +#ifndef NO_CODEGEN + { + .name = "recompiler", + .description = "Dynamic Recompiler", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, +#endif + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + const device_t voodoo_banshee_device = { .name = "3Dfx Voodoo Banshee", .internal_name = "voodoo_banshee_pci", @@ -3612,7 +3792,7 @@ const device_t voodoo_banshee_device = { .init = banshee_init, .close = banshee_close, .reset = NULL, - { .available = banshee_available }, + .available = banshee_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sgram_config @@ -3626,7 +3806,7 @@ const device_t creative_voodoo_banshee_device = { .init = creative_banshee_init, .close = banshee_close, .reset = NULL, - { .available = creative_banshee_available }, + .available = creative_banshee_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3640,7 +3820,7 @@ const device_t voodoo_3_1000_device = { .init = v3_1000_init, .close = banshee_close, .reset = NULL, - { .available = v3_1000_available }, + .available = v3_1000_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sgram_config @@ -3654,7 +3834,7 @@ const device_t voodoo_3_1000_agp_device = { .init = v3_1000_agp_init, .close = banshee_close, .reset = NULL, - { .available = v3_1000_agp_available }, + .available = v3_1000_agp_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sgram_16mbonly_config @@ -3668,7 +3848,7 @@ const device_t voodoo_3_2000_device = { .init = v3_2000_init, .close = banshee_close, .reset = NULL, - { .available = v3_2000_available }, + .available = v3_2000_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3682,7 +3862,7 @@ const device_t voodoo_3_2000_agp_device = { .init = v3_2000_agp_init, .close = banshee_close, .reset = NULL, - { .available = v3_2000_agp_available }, + .available = v3_2000_agp_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3696,7 +3876,7 @@ const device_t voodoo_3_2000_agp_onboard_8m_device = { .init = v3_2000_agp_onboard_init, .close = banshee_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sgram_config @@ -3710,7 +3890,7 @@ const device_t voodoo_3_3000_device = { .init = v3_3000_init, .close = banshee_close, .reset = NULL, - { .available = v3_3000_available }, + .available = v3_3000_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3724,7 +3904,7 @@ const device_t voodoo_3_3000_agp_device = { .init = v3_3000_agp_init, .close = banshee_close, .reset = NULL, - { .available = v3_3000_agp_available }, + .available = v3_3000_agp_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3738,7 +3918,7 @@ const device_t voodoo_3_3500_agp_ntsc_device = { .init = v3_3500_agp_ntsc_init, .close = banshee_close, .reset = NULL, - { .available = v3_3500_agp_ntsc_available }, + .available = v3_3500_agp_ntsc_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3752,7 +3932,7 @@ const device_t voodoo_3_3500_agp_pal_device = { .init = v3_3500_agp_pal_init, .close = banshee_close, .reset = NULL, - { .available = v3_3500_agp_pal_available }, + .available = v3_3500_agp_pal_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3766,7 +3946,7 @@ const device_t compaq_voodoo_3_3500_agp_device = { .init = compaq_v3_3500_agp_init, .close = banshee_close, .reset = NULL, - { .available = compaq_v3_3500_agp_available }, + .available = compaq_v3_3500_agp_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3780,7 +3960,7 @@ const device_t voodoo_3_3500_se_agp_device = { .init = v3_3500_se_agp_init, .close = banshee_close, .reset = NULL, - { .available = v3_3500_se_agp_available }, + .available = v3_3500_se_agp_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3794,7 +3974,7 @@ const device_t voodoo_3_3500_si_agp_device = { .init = v3_3500_si_agp_init, .close = banshee_close, .reset = NULL, - { .available = v3_3500_si_agp_available }, + .available = v3_3500_si_agp_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3808,7 +3988,7 @@ const device_t velocity_100_agp_device = { .init = velocity_100_agp_init, .close = banshee_close, .reset = NULL, - { .available = velocity_100_available }, + .available = velocity_100_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sdram_config @@ -3822,7 +4002,7 @@ const device_t velocity_200_agp_device = { .init = velocity_200_agp_init, .close = banshee_close, .reset = NULL, - { .available = velocity_200_available }, + .available = velocity_200_available, .speed_changed = banshee_speed_changed, .force_redraw = banshee_force_redraw, .config = banshee_sgram_16mbonly_config diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 94394e115..ddf68360f 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -252,6 +252,9 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) { rgba8_t write_data = colour_data; uint16_t new_depth = depth_data; + int colbfog_r = 0; + int colbfog_g = 0; + int colbfog_b = 0; if (params->fbzMode & FBZ_DEPTH_ENABLE) { uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); @@ -262,6 +265,10 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) goto skip_pixel; + colbfog_r = write_data.r; + colbfog_g = write_data.g; + colbfog_b = write_data.b; + if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; int64_t w_depth = (int64_t) (int32_t) new_depth; @@ -364,6 +371,35 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) addr >>= 1; break; + case LFB_FORMAT_XRGB8888: + colour_data[0].b = val & 0xff; + colour_data[0].g = (val >> 8) & 0xff; + colour_data[0].r = (val >> 16) & 0xff; + alpha_data[0] = 0xff; + write_mask = LFB_WRITE_COLOUR; + addr >>= 1; + break; + + case LFB_FORMAT_DEPTH_RGB565: + colour_data[0] = rgb565[val & 0xffff]; + depth_data[0] = val >> 16; + write_mask = LFB_WRITE_BOTH; + count = 1; + break; + case LFB_FORMAT_DEPTH_RGB555: + colour_data[0] = argb1555[val & 0xffff]; + depth_data[0] = val >> 16; + write_mask = LFB_WRITE_BOTH; + count = 1; + break; + case LFB_FORMAT_DEPTH_ARGB1555: + colour_data[0] = argb1555[val & 0xffff]; + alpha_data[0] = colour_data[0].a; + depth_data[0] = val >> 16; + write_mask = LFB_WRITE_BOTH; + count = 1; + break; + case LFB_FORMAT_DEPTH: depth_data[0] = val; depth_data[1] = val >> 16; @@ -409,6 +445,9 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) for (int c = 0; c < count; c++) { rgba8_t write_data = colour_data[c]; uint16_t new_depth = depth_data[c]; + int colbfog_r = 0; + int colbfog_g = 0; + int colbfog_b = 0; if (params->fbzMode & FBZ_DEPTH_ENABLE) { uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); @@ -419,6 +458,10 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) goto skip_pixel; + colbfog_r = write_data.r; + colbfog_g = write_data.g; + colbfog_b = write_data.b; + if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; int64_t w_depth = new_depth; @@ -460,9 +503,15 @@ skip_pixel: } else { for (int c = 0; c < count; c++) { if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); + *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = + do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); if (write_mask & LFB_WRITE_DEPTH) *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; + if (write_mask & LFB_WRITE_BOTH) { + *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = + do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); + *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; + } write_addr += 2; write_addr_aux += 2; diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index f8495edec..54a0140f6 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -188,6 +188,40 @@ cmdfifo_get_f(voodoo_t *voodoo) return tempif.f; } +static uint32_t +cmdfifo_get_2(voodoo_t *voodoo) +{ + uint32_t val; + + if (!voodoo->cmdfifo_in_sub_2) { + while (voodoo->fifo_thread_run && (voodoo->cmdfifo_depth_rd_2 == voodoo->cmdfifo_depth_wr_2)) { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + } + } + + val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp_2 & voodoo->fb_mask]; + + if (!voodoo->cmdfifo_in_sub_2) + voodoo->cmdfifo_depth_rd_2++; + voodoo->cmdfifo_rp_2 += 4; + + // voodoo_fifo_log(" CMDFIFO get %08x\n", val); + return val; +} + +static inline float +cmdfifo_get_f_2(voodoo_t *voodoo) +{ + union { + uint32_t i; + float f; + } tempif; + + tempif.i = cmdfifo_get_2(voodoo); + return tempif.f; +} + enum { CMDFIFO3_PC_MASK_RGB = (1 << 10), CMDFIFO3_PC_MASK_ALPHA = (1 << 11), @@ -283,6 +317,7 @@ voodoo_fifo_thread(void *param) } voodoo->cmd_status |= (1 << 24); + voodoo->cmd_status_2 |= (1 << 24); while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) { uint64_t start_time = plat_timer_read(); @@ -545,6 +580,269 @@ voodoo_fifo_thread(void *param) end_time = plat_timer_read(); voodoo->time += end_time - start_time; } + + while (voodoo->cmdfifo_enabled_2 && (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2 || voodoo->cmdfifo_in_sub_2)) { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + uint32_t header = cmdfifo_get_2(voodoo); + uint32_t addr; + uint32_t mask; + int smode; + int num; + int num_verticies; + int v_num; + +#if 0 + voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); +#endif + + voodoo->cmd_status_2 &= ~7; + voodoo->cmd_status_2 |= (header & 7); + voodoo->cmd_status_2 |= (1 << 11); + switch (header & 7) { + case 0: +#if 0 + voodoo_fifo_log("CMDFIFO0\n"); +#endif + voodoo->cmd_status_2 = (voodoo->cmd_status_2 & 0xffff8fff) | (((header >> 3) & 7) << 12); + switch ((header >> 3) & 7) { + case 0: /*NOP*/ + break; + + case 1: /*JSR*/ +#if 0 + voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc); +#endif + voodoo->cmdfifo_ret_addr_2 = voodoo->cmdfifo_rp_2; + voodoo->cmdfifo_rp_2 = (header >> 4) & 0xfffffc; + voodoo->cmdfifo_in_sub_2 = 1; + break; + + case 2: /*RET*/ + voodoo->cmdfifo_rp_2 = voodoo->cmdfifo_ret_addr_2; + voodoo->cmdfifo_in_sub_2 = 0; + break; + + case 3: /*JMP local frame buffer*/ + voodoo->cmdfifo_rp_2 = (header >> 4) & 0xfffffc; +#if 0 + voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); +#endif + break; + + default: + fatal("Bad CMDFIFO0 %08x\n", header); + } + voodoo->cmd_status_2 = (voodoo->cmd_status_2 & ~(1 << 27)) | (voodoo->cmdfifo_in_sub_2 << 27); + break; + + case 1: + num = header >> 16; + addr = (header & 0x7ff8) >> 1; +#if 0 + voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr); +#endif + while (num--) { + uint32_t val = cmdfifo_get_2(voodoo); + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { +#if 0 + if (voodoo->type != VOODOO_BANSHEE) + fatal("CMDFIFO1: Not Banshee\n"); +#endif + +#if 0 + voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); +#endif + voodoo_2d_reg_writel(voodoo, addr, val); + } else { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo_2++; + + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo_2++; + voodoo_reg_writel(addr, val, voodoo); + } + + if (header & (1 << 15)) + addr += 4; + } + break; + + case 2: + if (voodoo->type < VOODOO_2) + fatal("CMDFIFO2: Not Voodoo 2\n"); + mask = (header >> 3); + addr = 8; + while (mask) { + if (mask & 1) { + uint32_t val = cmdfifo_get_2(voodoo); + + voodoo_2d_reg_writel(voodoo, addr, val); + } + + addr += 4; + mask >>= 1; + } + break; + + case 3: + num = (header >> 29) & 7; + mask = header; //(header >> 10) & 0xff; + smode = (header >> 22) & 0xf; + voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); + num_verticies = (header >> 6) & 0xf; + v_num = 0; + if (((header >> 3) & 7) == 2) + v_num = 1; +#if 0 + voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); + voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); +#endif + + while (num_verticies--) { + voodoo->verts[3].sVx = cmdfifo_get_f_2(voodoo); + voodoo->verts[3].sVy = cmdfifo_get_f_2(voodoo); + if (mask & CMDFIFO3_PC_MASK_RGB) { + if (header & CMDFIFO3_PC) { + uint32_t val = cmdfifo_get_2(voodoo); + voodoo->verts[3].sBlue = (float) (val & 0xff); + voodoo->verts[3].sGreen = (float) ((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float) ((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float) ((val >> 24) & 0xff); + } else { + voodoo->verts[3].sRed = cmdfifo_get_f_2(voodoo); + voodoo->verts[3].sGreen = cmdfifo_get_f_2(voodoo); + voodoo->verts[3].sBlue = cmdfifo_get_f_2(voodoo); + } + } + if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) + voodoo->verts[3].sAlpha = cmdfifo_get_f_2(voodoo); + if (mask & CMDFIFO3_PC_MASK_Z) + voodoo->verts[3].sVz = cmdfifo_get_f_2(voodoo); + if (mask & CMDFIFO3_PC_MASK_Wb) + voodoo->verts[3].sWb = cmdfifo_get_f_2(voodoo); + if (mask & CMDFIFO3_PC_MASK_W0) + voodoo->verts[3].sW0 = cmdfifo_get_f_2(voodoo); + if (mask & CMDFIFO3_PC_MASK_S0_T0) { + voodoo->verts[3].sS0 = cmdfifo_get_f_2(voodoo); + voodoo->verts[3].sT0 = cmdfifo_get_f_2(voodoo); + } + if (mask & CMDFIFO3_PC_MASK_W1) + voodoo->verts[3].sW1 = cmdfifo_get_f_2(voodoo); + if (mask & CMDFIFO3_PC_MASK_S1_T1) { + voodoo->verts[3].sS1 = cmdfifo_get_f_2(voodoo); + voodoo->verts[3].sT1 = cmdfifo_get_f_2(voodoo); + } + if (v_num) + voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); + else + voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); + v_num++; + if (v_num == 3 && ((header >> 3) & 7) == 0) + v_num = 0; + } + while (num--) + cmdfifo_get_2(voodoo); + break; + + case 4: + num = (header >> 29) & 7; + mask = (header >> 15) & 0x3fff; + addr = (header & 0x7ff8) >> 1; +#if 0 + voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr); +#endif + while (mask) { + if (mask & 1) { + uint32_t val = cmdfifo_get_2(voodoo); + + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { + if (voodoo->type < VOODOO_BANSHEE) + fatal("CMDFIFO1: Not Banshee\n"); +#if 0 + voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); +#endif + + voodoo_2d_reg_writel(voodoo, addr, val); + } else { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo_2++; + + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo_2++; + voodoo_reg_writel(addr, val, voodoo); + } + } + + addr += 4; + mask >>= 1; + } + while (num--) + cmdfifo_get_2(voodoo); + break; + + case 5: +#if 0 + if (header & 0x3fc00000) + fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); +#endif + num = (header >> 3) & 0x7ffff; + addr = cmdfifo_get_2(voodoo) & 0xffffff; + if (!num) + num = 1; +#if 0 + voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num); +#endif + switch (header >> 30) { + case 0: /*Linear framebuffer (Banshee)*/ + case 1: /*Planar YUV*/ + if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { +#if 0 + voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#endif + flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); + } + if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { +#if 0 + voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); +#endif + flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1); + } + while (num--) { + uint32_t val = cmdfifo_get_2(voodoo); + if (addr <= voodoo->fb_mask) + *(uint32_t *) &voodoo->fb_mem[addr] = val; + addr += 4; + } + break; + case 2: /*Framebuffer*/ + while (num--) { + uint32_t val = cmdfifo_get_2(voodoo); + voodoo_fb_writel(addr, val, voodoo); + addr += 4; + } + break; + case 3: /*Texture*/ + while (num--) { + uint32_t val = cmdfifo_get_2(voodoo); + voodoo_tex_writel(addr, val, voodoo); + addr += 4; + } + break; + + default: + fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); + } + break; + + default: + fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + } + + end_time = plat_timer_read(); + voodoo->time += end_time - start_time; + } + voodoo->voodoo_busy = 0; } } diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 0f31fbc9f..cc52fc61a 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -43,8 +43,7 @@ typedef struct voodoo_state_t { int xstart, xend, xdir; uint32_t base_r, base_g, base_b, base_a, base_z; - struct - { + struct { int64_t base_s, base_t, base_w; int lod; } tmu[2]; @@ -967,6 +966,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * int src_g = 0; int src_b = 0; int src_a = 0; + int colbfog_r = 0; + int colbfog_g = 0; + int colbfog_b = 0; int msel_r; int msel_g; int msel_b; @@ -1263,6 +1265,10 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * if (cca_invert_output) src_a ^= 0xff; + colbfog_r = src_r; + colbfog_g = src_g; + colbfog_b = src_b; + if (params->fogMode & FOG_ENABLE) APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); @@ -1417,11 +1423,14 @@ voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) if ((params->vertexAy & 0xf) > 8) dy += 16; - /* voodoo_render_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, - (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, - (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ +#if 0 +voodoo_render_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", + odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, + (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, + (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, + (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, + (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode); +#endif state.base_r = params->startR; state.base_g = params->startG; diff --git a/src/video/vid_voodoo_setup.c b/src/video/vid_voodoo_setup.c index e1d13ba35..11f4ff861 100644 --- a/src/video/vid_voodoo_setup.c +++ b/src/video/vid_voodoo_setup.c @@ -191,8 +191,8 @@ voodoo_triangle_setup(voodoo_t *voodoo) voodoo->params.dWdX = (int64_t) (((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); voodoo->params.dWdY = (int64_t) (((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; - voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; - voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; + voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; + voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; } if (voodoo->sSetupMode & SETUPMODE_W0) { voodoo->params.tmu[0].startW = (int64_t) (verts[va].sW0 * 4294967296.0f); diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 3939db3cd..f6894ec0f 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -61,10 +61,10 @@ voodoo_texture_log(const char *fmt, ...) void voodoo_recalc_tex12(voodoo_t *voodoo, int tmu) { - int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; - int width = 256; - int height = 256; - int shift = 8; + int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; + int width = 256; + int height = 256; + int shift = 8; uint32_t base = voodoo->params.texBaseAddr[tmu]; uint32_t offset = 0; int tex_lod = 0; diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index 600fa21a8..a52bad4ee 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -1004,7 +1004,7 @@ const device_t wy700_device = { .init = wy700_init, .close = wy700_close, .reset = NULL, - { .available = NULL }, + .available = NULL, .speed_changed = wy700_speed_changed, .force_redraw = NULL, .config = NULL diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index f1cad184e..2cc20044a 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -19,7 +19,7 @@ #include #include #include -#include <86box/bswap.h> +//#include <86box/bswap.h> #include <86box/86box.h> #include <86box/io.h> #include <86box/machine.h> @@ -41,7 +41,7 @@ #define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin" #define INMOS_XGA_BIOS_PATH "roms/video/xga/InMOS XGA - Fairchild NM27C256Q-150.BIN" -static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; static void xga_ext_outb(uint16_t addr, uint8_t val, void *priv); @@ -54,6 +54,13 @@ static void xga_render_4bpp(svga_t *svga); static void xga_render_8bpp(svga_t *svga); static void xga_render_16bpp(svga_t *svga); +static void xga_write(uint32_t addr, uint8_t val, void *priv); +static void xga_writew(uint32_t addr, uint16_t val, void *priv); +static void xga_writel(uint32_t addr, uint32_t val, void *priv); +static uint8_t xga_read(uint32_t addr, void *priv); +static uint16_t xga_readw(uint32_t addr, void *priv); +static uint32_t xga_readl(uint32_t addr, void *priv); + int xga_active = 0; #ifdef ENABLE_XGA_LOG @@ -157,37 +164,76 @@ xga_updatemapping(svga_t *svga) 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); break; case 2: xga_log("XGA: 132-Column mode address decode disabled.\n"); 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); break; default: - xga_log("XGA: Extended Graphics mode.\n"); + xga_log("XGA: Extended Graphics mode, ap=%d.\n", xga->aperture_cntl); switch (xga->aperture_cntl) { case 0: - xga_log("XGA: No 64KB aperture.\n"); - if (xga->base_addr_1mb) + 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); + if (xga->base_addr_1mb) { mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - else if (xga->linear_base) + mem_mapping_enable(&xga->linear_mapping); + } else if (xga->linear_base) { mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - else + mem_mapping_enable(&xga->linear_mapping); + } else mem_mapping_disable(&xga->linear_mapping); - mem_mapping_disable(&xga->video_mapping); + 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; + } break; case 1: xga_log("XGA: 64KB aperture at A0000.\n"); - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); + 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: xga_log("XGA: 64KB aperture at B0000.\n"); - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); + 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; break; default: @@ -197,12 +243,32 @@ xga_updatemapping(svga_t *svga) } } +static void +xga_render_blank(svga_t *svga) +{ + xga_t *xga = (xga_t *) svga->xga; + + if ((xga->displine + svga->y_add) < 0) + return; + + if (xga->firstline_draw == 2000) + xga->firstline_draw = xga->displine; + + xga->lastline_draw = xga->displine; + + uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (uint32_t)(xga->h_disp) * sizeof(uint32_t); + + if (xga->h_disp > 0) + memset(line_ptr, 0, line_width); +} + void xga_recalctimings(svga_t *svga) { xga_t *xga = (xga_t *) svga->xga; - if (xga->on) { + xga->h_total = xga->htotal + 1; xga->v_total = xga->vtotal + 1; xga->dispend = xga->vdispend + 1; xga->v_syncstart = xga->vsyncstart + 1; @@ -211,7 +277,7 @@ xga_recalctimings(svga_t *svga) xga->h_disp = (xga->hdisp + 1) << 3; - xga->rowoffset = xga->hdisp + 1; + xga->rowoffset = xga->pix_map_width; xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -226,31 +292,43 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; - if ((xga->disp_cntl_2 & 7) == 2) - xga->rowoffset >>= 1; - else if ((xga->disp_cntl_2 & 7) == 4) - xga->rowoffset <<= 1; - xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80); + 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) { case 0: xga_log("HDISP VGA0 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp); if (xga->clk_sel_2 & 0x80) - svga->clock = (cpuclock * (double) (1ULL << 32)) / 41539000.0; + svga->clock_xga = (cpuclock * (double) (1ULL << 32)) / 41539000.0; else - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock_xga = (cpuclock * (double) (1ULL << 32)) / 25175000.0; break; case 1: xga_log("HDISP VGA1 = %d, XGA = %d.\n", svga->hdisp, xga->h_disp); - svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0; + svga->clock_xga = (cpuclock * (double) (1ULL << 32)) / 28322000.0; break; case 3: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + svga->clock_xga = (cpuclock * (double) (1ULL << 32)) / 44900000.0; break; default: break; } + + switch (xga->disp_cntl_2 & 7) { + case 2: + svga->render_xga = xga_render_4bpp; + break; + case 3: + svga->render_xga = xga_render_8bpp; + break; + case 4: + svga->render_xga = xga_render_16bpp; + break; + + default: + svga->render_xga = xga_render_blank; + break; + } } } @@ -371,12 +449,15 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x40: xga->disp_start_addr = (xga->disp_start_addr & 0x7ff00) | val; + xga_log("DISPSTARTADDR0=%x.\n", xga->disp_start_addr); break; case 0x41: xga->disp_start_addr = (xga->disp_start_addr & 0x700ff) | (val << 8); + xga_log("DISPSTARTADDR8=%x.\n", xga->disp_start_addr); break; case 0x42: xga->disp_start_addr = (xga->disp_start_addr & 0x0ffff) | ((val & 0x07) << 16); + xga_log("DISPSTARTADDR16=%x.\n", xga->disp_start_addr); svga_recalctimings(svga); break; @@ -385,19 +466,19 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x44: xga->pix_map_width = (xga->pix_map_width & 0xff) | ((val & 0x07) << 8); + svga_recalctimings(svga); break; case 0x50: - xga_log("Reg50 write = %02x.\n", val); + xga_log("Reg50 write=%02x.\n", val); xga->disp_cntl_1 = val; svga_recalctimings(svga); break; case 0x51: - xga_log("Reg51 write = %02x.\n", val); + xga_log("Reg51 write=%02x.\n", val & 0x07); xga->disp_cntl_2 = val; - xga->on = ((val & 7) >= 2); - vga_on = !xga->on; + xga->on = ((val & 0x07) >= 0x02); svga_recalctimings(svga); break; @@ -417,8 +498,8 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x60: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0x3f00) | val; - svga->dac_pos = 0; - svga->dac_addr = val & 0xff; + xga->dac_pos = 0; + xga->dac_addr = val & 0xff; break; case 0x61: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); @@ -428,40 +509,32 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); break; - case 0x62: - xga->sprite_pal_addr_idx_prefetch = (xga->sprite_pal_addr_idx_prefetch & 0x3f00) | val; - svga->dac_pos = 0; - svga->dac_addr = val & 0xff; - break; - case 0x63: - xga->sprite_pal_addr_idx_prefetch = (xga->sprite_pal_addr_idx_prefetch & 0xff) | ((val & 0x3f) << 8); - xga->sprite_pos_prefetch = xga->sprite_pal_addr_idx_prefetch & 0x1ff; - break; - case 0x64: - svga->dac_mask = val; + xga->dac_mask = val; + xga_log("DAC mask=%02x.\n", val); break; case 0x65: svga->fullchange = svga->monitor->mon_changeframecount; - switch (svga->dac_pos) { + switch (xga->dac_pos) { case 0: - svga->dac_r = val; - svga->dac_pos++; + xga->dac_r = val; + xga->dac_pos++; break; case 1: - svga->dac_g = val; - svga->dac_pos++; + xga->dac_g = val; + xga->dac_pos++; break; case 2: xga->pal_b = val; - index = svga->dac_addr & 0xff; - svga->vgapal[index].r = svga->dac_r; - svga->vgapal[index].g = svga->dac_g; - svga->vgapal[index].b = xga->pal_b; - xga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); - svga->dac_pos = 0; - svga->dac_addr = (svga->dac_addr + 1) & 0xff; + 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; default: @@ -470,19 +543,10 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x66: + xga_log("Palette Sequence=%02x.\n", val); xga->pal_seq = val; break; - case 0x67: - svga->dac_r = val; - break; - case 0x68: - xga->pal_b = val; - break; - case 0x69: - svga->dac_g = val; - break; - case 0x6a: xga->sprite_data[xga->sprite_pos] = val; xga->sprite_pos = (xga->sprite_pos + 1) & 0x3ff; @@ -508,16 +572,14 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); switch (addr & 0x0f) { case 0: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); xga->op_mode = val; break; case 1: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); xga->aperture_cntl = val & 3; xga_updatemapping(svga); break; - case 4: - if ((xga->disp_cntl_2 & 7) == 4) - xga->aperture_cntl = 0; - break; case 8: xga->ap_idx = val; xga_log("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, @@ -556,6 +618,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) break; default: + xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); break; } } @@ -590,6 +653,9 @@ xga_ext_inb(uint16_t addr, void *priv) case 0x0e: case 0x0f: switch (xga->regs_idx) { + case 0: + ret = (xga->bus & DEVICE_MCA) ? 0x02 : 0x01; + break; case 4: if (xga->bus & DEVICE_MCA) ret = 0x01; /*32-bit MCA*/ @@ -722,32 +788,25 @@ xga_ext_inb(uint16_t addr, void *priv) ret = xga->sprite_pal_addr_idx >> 8; break; - case 0x62: - ret = xga->sprite_pal_addr_idx_prefetch & 0xff; - break; - case 0x63: - ret = xga->sprite_pal_addr_idx_prefetch >> 8; - break; - case 0x64: - ret = svga->dac_mask; + ret = xga->dac_mask; break; case 0x65: - index = svga->dac_addr & 0xff; - switch (svga->dac_pos) { + index = xga->dac_addr & 0xff; + switch (xga->dac_pos) { case 0: - svga->dac_pos++; - ret = svga->vgapal[index].r; + xga->dac_pos++; + ret = xga->xgapal[index].r; break; case 1: - svga->dac_pos++; - ret = svga->vgapal[index].g; + xga->dac_pos++; + ret = xga->xgapal[index].g; break; case 2: - svga->dac_pos = 0; - svga->dac_addr = (svga->dac_addr + 1) & 0xff; - ret = svga->vgapal[index].b; + xga->dac_pos = 0; + xga->dac_addr = (xga->dac_addr + 1) & 0xff; + ret = xga->xgapal[index].b; break; default: @@ -759,21 +818,10 @@ xga_ext_inb(uint16_t addr, void *priv) ret = xga->pal_seq; break; - case 0x67: - ret = svga->dac_r; - break; - case 0x68: - ret = xga->pal_b; - break; - case 0x69: - ret = svga->dac_g; - break; - case 0x6a: - xga_log("Sprite POS Read = %d, addr idx = %04x\n", xga->sprite_pos, - xga->sprite_pal_addr_idx_prefetch); - ret = xga->sprite_data[xga->sprite_pos_prefetch]; - xga->sprite_pos_prefetch = (xga->sprite_pos_prefetch + 1) & 0x3ff; + xga_log("Sprite POS Read=%d.\n", xga->sprite_pos); + ret = xga->sprite_data[xga->sprite_pos]; + xga->sprite_pos = (xga->sprite_pos + 1) & 0x3ff; break; case 0x70: @@ -799,6 +847,7 @@ xga_ext_inb(uint16_t addr, void *priv) break; default: + xga_log("[%04X:%08X]: EXT INB = %02x, ret = %02x.\n\n", CS, cpu_state.pc, addr, ret); break; } @@ -807,27 +856,18 @@ xga_ext_inb(uint16_t addr, void *priv) return ret; } -#define READ(addr, dat) \ +#define READ(addr, dat) \ dat = xga->vram[(addr) & (xga->vram_mask)]; -#define WRITE(addr, dat) \ - xga->vram[((addr)) & (xga->vram_mask)] = dat; \ +#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) \ +#define READW(addr, dat) \ dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)]; -#define READW_INV(addr, dat) \ - dat = xga->vram[(addr + 1) & (xga->vram_mask)]; \ - dat |= (xga->vram[(addr) & (xga->vram_mask)] << 8); - -#define WRITEW(addr, dat) \ - *(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ - xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - -#define WRITEW_INV(addr, dat) \ - xga->vram[((addr + 1)) & (xga->vram_mask)] = dat & 0xff; \ - xga->vram[((addr)) & (xga->vram_mask)] = dat >> 8; \ +#define WRITEW(addr, dat) \ + *(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; #define ROP(mix, d, s) \ @@ -888,7 +928,7 @@ xga_ext_inb(uint16_t addr, void *priv) d = MIN(s, d); \ break; \ case 0x12: \ - d = MIN(~0, s + d); \ + d = MIN(~0, s + d); \ break; \ case 0x13: \ d = MAX(0, d - s); \ @@ -903,7 +943,7 @@ xga_ext_inb(uint16_t addr, void *priv) } static uint32_t -xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) +xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width) { const xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; @@ -912,13 +952,8 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b uint8_t px; int skip = 0; - if (xga->base_addr_1mb) { - if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) - skip = 1; - } else { - if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) - skip = 1; - } + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; addr += (y * (width >> 3)); addr += (x >> 3); @@ -927,27 +962,46 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b } else byte = mem_readb_phys(addr); - if (xga->linear_endian_reverse) - bits = 7 - (x & 7); - else { - if (xga->accel.px_map_format[xga->accel.dst_map] & 8) { - if ((xga->accel.px_map_format[xga->accel.src_map] & 8) && (xga->accel.px_map_format[map] & 8)) - bits = (x & 7); - else - bits = 7 - (x & 7); - } else { - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - bits = (x & 7); - else - bits = 7 - (x & 7); - } + bits = 7 - (x & 7); + + 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; } + px = (byte >> bits) & 1; return px; } static uint32_t -xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, UNUSED(int usesrc)) +xga_accel_read_area_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width) +{ + const xga_t *xga = (xga_t *) svga->xga; + uint32_t addr = base; + int bits; + uint8_t byte; + uint8_t px; + int skip = 0; + + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; + + addr += (y * (width >> 3)); + addr += (x >> 3); + if (!skip) { + READ(addr, byte); + } else + byte = mem_readb_phys(addr); + + bits = 7 - (x & 7); + + px = (byte >> bits) & 1; + return px; +} + +static uint32_t +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) { xga_t *xga = (xga_t *) svga->xga; uint32_t addr = base; @@ -956,15 +1010,10 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int uint8_t px; int skip = 0; - if (xga->base_addr_1mb) { - if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) - skip = 1; - } else { - if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) - skip = 1; - } + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; - switch (xga->accel.px_map_format[map] & 7) { + switch (xga->accel.px_map_format[map] & 0x07) { case 0: /*1-bit*/ addr += (y * (width >> 3)); addr += (x >> 3); @@ -973,14 +1022,12 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else byte = mem_readb_phys(addr); - if (xga->linear_endian_reverse) + 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); - else { - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - bits = (x & 7); - else - bits = 7 - (x & 7); - } + px = (byte >> bits) & 1; return px; case 2: /*4-bit*/ @@ -991,6 +1038,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else byte = mem_readb_phys(addr); + 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); @@ -1004,17 +1052,15 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int case 4: /*16-bit*/ addr += (y * (width << 1)); addr += (x << 1); - if (xga->linear_endian_reverse) { + + if (!skip) { + READW(addr, byte); + } else { byte = mem_readw_phys(addr); - if ((xga->access_mode & 7) == 4) + if ((xga->access_mode & 0x07) == 0x04) byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); - else if (xga->access_mode & 8) + else if (xga->access_mode & 0x08) byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); - } else { - if (!skip) { - READW(addr, byte); - } else - byte = mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); } return byte; @@ -1033,15 +1079,10 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui uint8_t mask; int skip = 0; - if (xga->base_addr_1mb) { - if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) - skip = 1; - } else { - if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) - skip = 1; - } + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) + skip = 1; - switch (xga->accel.px_map_format[map] & 7) { + switch (xga->accel.px_map_format[map] & 0x07) { case 0: /*1-bit*/ addr += (y * (width >> 3)); addr += (x >> 3); @@ -1050,15 +1091,16 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else byte = mem_readb_phys(addr); - if (xga->linear_endian_reverse) { + if (xga->access_mode & 0x08) mask = 1 << (7 - (x & 7)); - } else { - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { + 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 { + } else mask = 1 << (7 - (x & 7)); - } } + byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); if (pixel & 1) { if (!skip) { @@ -1078,18 +1120,14 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui addr += (x >> 1); if (!skip) { READ(addr, byte); - } else { + } else byte = mem_readb_phys(addr); - } - if (xga->linear_endian_reverse) + if (xga->accel.px_map_format[map] & 0x08) + mask = 0x0f << ((x & 1) << 2); + else mask = 0x0f << ((1 - (x & 1)) << 2); - else { - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - mask = 0x0f << ((x & 1) << 2); - else - mask = 0x0f << ((1 - (x & 1)) << 2); - } + byte = (byte & ~mask) | (pixel & mask); if (!skip) { WRITE(addr, byte); @@ -1107,15 +1145,14 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui case 4: /*16-bit*/ addr += (y * width << 1); addr += (x << 1); - if (xga->linear_endian_reverse) { - if ((xga->access_mode & 7) == 4) - pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); - else if (xga->access_mode & 8) - pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); + + if (!skip) { + WRITEW(addr, pixel); } else { - if (!skip) { - WRITEW(addr, pixel); - } + 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); break; @@ -1143,11 +1180,11 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) int dirx = 0; int diry = 0; - dx = xga->accel.dst_map_x & 0x1fff; + dx = xga->accel.dst_map_x; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; - dy = xga->accel.dst_map_y & 0x1fff; + dy = xga->accel.dst_map_y; if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; @@ -1193,8 +1230,8 @@ 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, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((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; @@ -1213,8 +1250,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((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; @@ -1261,65 +1298,85 @@ xga_line_draw_write(svga_t *svga) 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; int16_t dx; int16_t dy; int16_t cx; int16_t cy; - int err = xga->accel.bres_err_term; - int draw_pixel = 0; cx = xga->accel.src_map_x & 0xfff; cy = xga->accel.src_map_y & 0xfff; - dx = xga->accel.dst_map_x & 0x1fff; + dx = xga->accel.dst_map_x; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; - dy = xga->accel.dst_map_y & 0x1fff; + dy = xga->accel.dst_map_y; if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; if ((xga->accel.command & 0x30) == 0x30) - xga_log("Line Draw Write: BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, XDIR=%i, YDIR=%i, steep=%s, ERR=%04x.\n", xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, xdir, ydir, (xga->accel.octant & 0x01) ? "0" : "1", err); - + 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); if (xga->accel.pat_src == 8) { if ((xga->accel.command & 0x30) == 0x30) { while (y >= 0) { draw_pixel = 0; - if (xga->accel.octant & 0x01) { - if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/ + if (xga->accel.octant & 0x01) { /*Y Major*/ + if (xga->accel.octant & 0x02) { /*Bottom to Top*/ if (x) draw_pixel = 1; - } else { /*Top-to-Bottom*/ + } else { /*Top to Bottom*/ if (y) draw_pixel = 1; } - } else if (!(xga->accel.octant & 0x04) && (err < (xga->accel.bres_k2 + xga->accel.bres_k1))) /*X+*/ - draw_pixel = 1; - else if ((xga->accel.octant & 0x04) && (err >= 0)) /*X-*/ - draw_pixel = 1; - - if (xga->accel.command & 0xc0) { - if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - if (draw_pixel) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); - - if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { - ROP(1, dest_dat, src_dat); - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); + } else { /*X Major*/ + if (xga->accel.octant & 0x04) { /*Right to Left*/ + if (xga->accel.bres_err_term >= 0) { + if (xga->accel.octant & 0x02) { /*Bottom to Top*/ + if (x) + draw_pixel = 1; + } else { /*Top to Bottom*/ + if (y) + draw_pixel = 1; } } + } else { /*Left to Right*/ + if (xga->accel.bres_err_term < (xga->accel.bres_k1 + xga->accel.bres_k2)) { + if (xga->accel.octant & 0x02) { /*Bottom to Top*/ + if (x) + draw_pixel = 1; + } else { /*Top to Bottom*/ + if (y) + draw_pixel = 1; + } + } + } + } + + 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); + + 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); + } } } else { if (draw_pixel) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + 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); 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); } } @@ -1334,28 +1391,28 @@ xga_line_draw_write(svga_t *svga) else dy++; - if (err >= 0) { - err += xga->accel.bres_k2; + if (xga->accel.bres_err_term >= 0) { + xga->accel.bres_err_term += xga->accel.bres_k2; if (xga->accel.octant & 0x04) dx--; else dx++; } else - err += xga->accel.bres_k1; + xga->accel.bres_err_term += xga->accel.bres_k1; } else { if (xga->accel.octant & 0x04) dx--; else dx++; - if (err >= 0) { - err += xga->accel.bres_k2; + if (xga->accel.bres_err_term >= 0) { + xga->accel.bres_err_term += xga->accel.bres_k2; if (xga->accel.octant & 0x02) dy--; else dy++; } else - err += xga->accel.bres_k1; + xga->accel.bres_err_term += xga->accel.bres_k1; } x++; y--; @@ -1364,8 +1421,8 @@ 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, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((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; @@ -1380,8 +1437,8 @@ xga_line_draw_write(svga_t *svga) } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, 0); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((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; @@ -1408,28 +1465,28 @@ xga_line_draw_write(svga_t *svga) else dy++; - if (err >= 0) { - err += xga->accel.bres_k2; + if (xga->accel.bres_err_term >= 0) { + xga->accel.bres_err_term += xga->accel.bres_k2; if (xga->accel.octant & 0x04) dx--; else dx++; } else - err += xga->accel.bres_k1; + xga->accel.bres_err_term += xga->accel.bres_k1; } else { if (xga->accel.octant & 0x04) dx--; else dx++; - if (err >= 0) { - err += xga->accel.bres_k2; + if (xga->accel.bres_err_term >= 0) { + xga->accel.bres_err_term += xga->accel.bres_k2; if (xga->accel.octant & 0x02) dy--; else dy++; } else - err += xga->accel.bres_k1; + xga->accel.bres_err_term += xga->accel.bres_k1; } y--; x++; @@ -1447,7 +1504,7 @@ 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 = xga->accel.px_map_base[xga->accel.pat_src]; + 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]; @@ -1471,26 +1528,28 @@ xga_bitblt(svga_t *svga) xga->accel.sy = xga->accel.src_map_y & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; xga->accel.py = xga->accel.pat_map_y & 0xfff; - dx = xga->accel.dst_map_x & 0x1fff; - dy = xga->accel.dst_map_y & 0x1fff; + dx = xga->accel.dst_map_x; + dy = xga->accel.dst_map_y; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; - xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth); + + xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d, frgdcol=%04x, bkgdcol=%04x.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth, frgdcol, bkgdcol); xga->accel.pattern = 0; xga->accel.filling = 0; - xga_log("XGA bitblt linear endian reverse=%d, access_mode=%x, octanty=%d, src command = %08x, " + 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.\n", - xga->linear_endian_reverse, xga->access_mode & 0x0f, ydir, xga->accel.command, + "usesrcvramfr=%d, usevrambk=%d, 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.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)); + 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); if (xga->accel.pat_src == 8) { if (srcheight == 7) @@ -1498,7 +1557,7 @@ xga_bitblt(svga_t *svga) else { if ((dstwidth == (xga->h_disp - 1)) && (srcwidth == 1)) { if ((xga->accel.dst_map == 1) && (xga->accel.src_map == 2)) { - if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px_map_format[xga->accel.src_map] >= 0x0b)) + 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; } } @@ -1519,8 +1578,8 @@ xga_bitblt(svga_t *svga) 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, 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + 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); 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); @@ -1530,8 +1589,8 @@ xga_bitblt(svga_t *svga) } } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + 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); 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); @@ -1551,7 +1610,7 @@ xga_bitblt(svga_t *svga) if (xga->accel.x < 0) { xga->accel.x = xga->accel.blt_width & 0xfff; - dx = xga->accel.dst_map_x & 0x1fff; + dx = xga->accel.dst_map_x; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; xga->accel.sx = xga->accel.src_map_x & 0xfff; @@ -1573,6 +1632,8 @@ xga_bitblt(svga_t *svga) } } } else if (xga->accel.pat_src >= 1) { + patbase = xga->accel.px_map_base[xga->accel.pat_src]; + if (patheight == 7) { if (xga->accel.src_map != 1) xga->accel.pattern = 1; @@ -1582,12 +1643,12 @@ xga_bitblt(svga_t *svga) if (dstwidth == (xga->h_disp - 1)) { if (srcwidth == (xga->h_disp - 1)) { if ((xga->accel.src_map == 1) && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) { - if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) + if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0a) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) xga->accel.pattern = 1; } } else { if (!xga->accel.src_map && (xga->accel.dst_map == 1) && (xga->accel.pat_src == 2)) { - if ((xga->accel.px_map_format[xga->accel.dst_map] >= 0x0b) && (xga->accel.px <= 7) && (xga->accel.py <= 3)) { + 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)) xga->accel.pattern = 0; else @@ -1616,17 +1677,19 @@ xga_bitblt(svga_t *svga) 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); - if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) { - while (xga->accel.y >= 0) { - mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); - if (mix) - xga->accel.filling = !xga->accel.filling; + if (((xga->accel.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); + if (mix) + xga->accel.filling ^= 1; - if (xga->accel.command & 0xc0) { - if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - if (xga->accel.filling) { - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024, 0); + xga_log("Area Fill Command: dx=%d, dy=%d, mix=%x, filling=%x.\n", dx, dy, mix, xga->accel.filling); + + 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); 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); @@ -1635,12 +1698,10 @@ xga_bitblt(svga_t *svga) xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } - } - } else { - if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; - if (xga->accel.filling) { - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + } 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); 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); @@ -1650,46 +1711,51 @@ xga_bitblt(svga_t *svga) } } } - } - xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); - xga->accel.px++; + xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); + xga->accel.px++; - dx++; - xga->accel.x--; - if (xga->accel.x < 0) { - xga->accel.y--; - xga->accel.x = xga->accel.blt_width & 0xfff; + dx++; + xga->accel.x--; + if (xga->accel.x < 0) { + xga->accel.y--; + xga->accel.x = xga->accel.blt_width & 0xfff; - dx = xga->accel.dst_map_x & 0x1fff; - if (xga->accel.dst_map_x >= 0x1800) - dx |= ~0x17ff; + dx = xga->accel.dst_map_x; + if (xga->accel.dst_map_x >= 0x1800) + dx |= ~0x17ff; - xga->accel.sx = xga->accel.src_map_x & 0xfff; - xga->accel.px = xga->accel.pat_map_x & 0xfff; + xga->accel.sx = xga->accel.src_map_x & 0xfff; + xga->accel.px = xga->accel.pat_map_x & 0xfff; - xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); - xga->accel.py++; + xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); + xga->accel.py++; - dy++; - xga->accel.filling = 0; + dy++; + xga->accel.filling = 0; - if (xga->accel.y < 0) - return; + if (xga->accel.y < 0) { + xga->accel.dst_map_x = dx; + xga->accel.dst_map_y = dy; + return; + } + } } } } 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, xga->accel.pat_src, patbase, patwidth + 1); + mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1); if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + 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; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; + 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; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); @@ -1700,11 +1766,11 @@ xga_bitblt(svga_t *svga) } else { if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : frgdcol; + 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; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, 1) : bkgdcol; + 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; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) { old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); @@ -1726,7 +1792,7 @@ xga_bitblt(svga_t *svga) xga->accel.y--; xga->accel.x = xga->accel.blt_width & 0xfff; - dx = xga->accel.dst_map_x & 0x1fff; + dx = xga->accel.dst_map_x; if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; @@ -1755,9 +1821,24 @@ xga_bitblt(svga_t *svga) static void xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) { - addr &= 0x1fff; + uint32_t min_addr; + uint32_t max_addr; + int mmio_addr_enable = 0; - if (addr >= 0x1800) { + if (xga_standalone_enabled) { + addr &= 0x1fff; + min_addr = (0x1c00 + (xga->instance << 7)); + max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + } else { + addr &= 0x7fff; + min_addr = (0x7c00 + (xga->instance << 7)); + max_addr = (0x7c00 + (xga->instance << 7)) + 0x7f; + } + + if ((addr >= min_addr) && (addr <= max_addr)) + mmio_addr_enable = 1; + + if (mmio_addr_enable) { switch (addr & 0x7f) { case 0x11: xga->accel.control = val; @@ -1818,6 +1899,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) case 0x1c: xga->accel.px_map_format[xga->accel.px_map_idx] = val; + if (val & 0x08) + xga_log("Big Endian Pixel Format=%d, AccessMode=%x.\n", xga->accel.px_map_idx, xga->access_mode & 0x08); + else + xga_log("Little Endian Pixel Format=%d, AccessMode=%x.\n", xga->accel.px_map_idx, xga->access_mode & 0x08); break; case 0x20: @@ -2173,8 +2258,8 @@ exec_command: xga->accel.pat_src = ((xga->accel.command >> 12) & 0x0f); xga->accel.dst_map = ((xga->accel.command >> 16) & 0x0f); xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); + 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]); -#ifdef ENABLE_XGA_LOG if (xga->accel.pat_src) xga_log("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, " "dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, " @@ -2199,7 +2284,6 @@ exec_command: xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); -#endif switch ((xga->accel.command >> 24) & 0x0f) { case 2: /*Short Stroke Vectors Read */ @@ -2267,7 +2351,7 @@ xga_memio_writeb(uint32_t addr, uint8_t val, void *priv) xga_mem_write(addr, val, xga, svga, 1); - xga_log("Write MEMIOB = %04x, val = %02x\n", addr & 0x7f, val); + xga_log("[%04X:%08X]: Write MEMIOB = %04x, val = %02x\n", CS, cpu_state.pc, addr, val); } static void @@ -2278,7 +2362,7 @@ xga_memio_writew(uint32_t addr, uint16_t val, void *priv) xga_mem_write(addr, val, xga, svga, 2); - xga_log("Write MEMIOW = %04x, val = %04x\n", addr & 0x7f, val); + xga_log("[%04X:%08X]: Write MEMIOW = %04x, val = %04x\n", CS, cpu_state.pc, addr, val); } static void @@ -2289,21 +2373,40 @@ xga_memio_writel(uint32_t addr, uint32_t val, void *priv) xga_mem_write(addr, val, xga, svga, 4); - xga_log("Write MEMIOL = %04x, val = %08x\n", addr & 0x7f, val); + xga_log("[%04X:%08X]: Write MEMIOL = %04x, val = %08x\n", CS, cpu_state.pc, addr, val); } static uint8_t xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) { + uint32_t min_addr; + uint32_t max_addr; uint8_t temp = 0; + int mmio_addr_enable = 0; - addr &= 0x1fff; - if (addr < 0x1800) { - if (xga_standalone_enabled) + if (xga_standalone_enabled) { + addr &= 0x1fff; + min_addr = (0x1c00 + (xga->instance << 7)); + max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + if (addr < 0x1c00) temp = xga->bios_rom.rom[addr]; - else - temp = xga->vga_bios_rom.rom[addr]; + else if ((addr >= 0x1c00) && (addr <= 0x1c7f) && xga->instance) + temp = 0xff; + else if ((addr >= min_addr) && (addr <= max_addr)) + mmio_addr_enable = 1; } else { + addr &= 0x7fff; + min_addr = (0x7c00 + (xga->instance << 7)); + max_addr = (0x7c00 + (xga->instance << 7)) + 0x7f; + if (addr < 0x7c00) + temp = xga->bios_rom.rom[addr]; + else if ((addr >= 0x7c00) && (addr <= 0x7c7f) && xga->instance) + temp = 0xff; + else if ((addr >= min_addr) && (addr <= max_addr)) + mmio_addr_enable = 1; + } + + if (mmio_addr_enable) { switch (addr & 0x7f) { case 0x11: temp = xga->accel.control; @@ -2371,8 +2474,8 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) default: break; } + xga_log("MMIO Addr=%02x, ret=%02x.\n", addr & 0x7f, temp); } - return temp; } @@ -2491,7 +2594,7 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; - uint32_t *line_ptr = svga->monitor->target_buffer->line[xga->displine + svga->y_add]; + uint32_t *line_ptr = buffer32->line[xga->displine + svga->y_add]; for (int i = 0; i < svga->x_add; i++) *line_ptr++ = svga->overscan_color; } @@ -2507,7 +2610,7 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; - uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp]; + uint32_t *line_ptr = &buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp]; right = (overscan_x >> 1); for (int i = 0; i < right; i++) *line_ptr++ = svga->overscan_color; @@ -2524,35 +2627,28 @@ xga_render_4bpp(svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + 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 += 16) { + 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 >> 4) & 0x0f]; - p[2] = xga->pallook[(dat >> 8) & 0x0f]; - p[3] = xga->pallook[(dat >> 12) & 0x0f]; - p[4] = xga->pallook[(dat >> 16) & 0x0f]; - p[5] = xga->pallook[(dat >> 20) & 0x0f]; - p[6] = xga->pallook[(dat >> 24) & 0x0f]; - p[7] = xga->pallook[(dat >> 28) & 0x0f]; + 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 + 4) & xga->vram_mask]); - p[8] = xga->pallook[dat & 0x0f]; - p[9] = xga->pallook[(dat >> 4) & 0x0f]; - p[10] = xga->pallook[(dat >> 8) & 0x0f]; - p[11] = xga->pallook[(dat >> 12) & 0x0f]; - p[12] = xga->pallook[(dat >> 16) & 0x0f]; - p[13] = xga->pallook[(dat >> 20) & 0x0f]; - p[14] = xga->pallook[(dat >> 24) & 0x0f]; - p[15] = xga->pallook[(dat >> 28) & 0x0f]; + 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]; + p[7] = xga->pallook[(dat >> 24) & 0x0f]; xga->ma += 8; - p += 16; + p += 8; } xga->ma &= xga->vram_mask; } @@ -2569,7 +2665,7 @@ xga_render_8bpp(svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2607,7 +2703,7 @@ xga_render_16bpp(svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2635,17 +2731,61 @@ xga_render_16bpp(svga_t *svga) } } +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; + + if (xga_active && xga) { + if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl) { + 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; + + 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); + } + } else if (xga->aperture_cntl || (!xga->aperture_cntl && (svga->mapping.base == 0xa0000))) { + xga->on = 0; + xga_log("OFF XGA write.\n"); + } + } +} + +static void +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[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + xga->vram[addr & xga->vram_mask] = val; +} + static void xga_write(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - if (!xga->on) { - svga_write(addr, val, svga); - return; - } - addr &= xga->banked_mask; addr += xga->write_bank; @@ -2654,69 +2794,96 @@ xga_write(uint32_t addr, uint8_t val, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; - if (xga->access_mode & 8) { - if ((xga->access_mode & 7) == 4) - addr ^= 1; - } - - xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; - xga->vram[addr & xga->vram_mask] = val; + xga_write_banked(addr, val, svga); } static void xga_writew(uint32_t addr, uint16_t val, void *priv) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - if (!xga->on) { - svga_writew(addr, val, svga); - return; - } + addr &= xga->banked_mask; + addr += xga->write_bank; - xga_write(addr, val & 0xff, svga); - xga_write(addr + 1, val >> 8, svga); + 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); } static void xga_writel(uint32_t addr, uint32_t val, void *priv) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - if (!xga->on) { - svga_writel(addr, val, svga); - return; - } + addr &= xga->banked_mask; + addr += xga->write_bank; - xga_write(addr, val & 0xff, svga); - xga_write(addr + 1, (val >> 8) & 0xff, svga); - xga_write(addr + 2, (val >> 16) & 0xff, svga); - xga_write(addr + 3, (val >> 24) & 0xff, svga); + 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); +} + +uint8_t +xga_read_test(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0x00; + + if (xga_active && xga) { + if (((xga->op_mode & 7) >= 1) && xga->aperture_cntl) { + if (xga->test == 0xa5) { /*Memory size test of XGA*/ + if (addr == 0xa0001) { + 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); + addr += xga->read_bank; + ret = xga->vram[addr & xga->vram_mask]; + } else { + ret = xga->test; + 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) { + 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 if (xga->aperture_cntl || (!xga->aperture_cntl && (svga->mapping.base == 0xa0000))) { + xga->on = 0; + xga_log("OFF XGA read.\n"); + } + } + return ret; } static uint8_t -xga_read(uint32_t addr, void *priv) +xga_read_banked(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; uint8_t ret = 0xff; - if (!xga->on) { - ret = svga_read(addr, svga); - return ret; - } - - addr &= xga->banked_mask; - addr += xga->read_bank; - - if (addr >= xga->vram_size) - return ret; - - cycles -= svga->monitor->mon_video_timing_read_b; - - if (xga->access_mode & 8) { - if ((xga->access_mode & 7) == 4) + if (xga->access_mode & 0x08) { + if ((xga->access_mode & 0x07) == 0x04) addr ^= 1; } @@ -2725,21 +2892,46 @@ xga_read(uint32_t addr, void *priv) return ret; } +static uint8_t +xga_read(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0xff; + + addr &= xga->banked_mask; + addr += xga->read_bank; + + if (addr >= xga->vram_size) { + xga_log("Over Read ADDR=%x.\n", addr); + return ret; + } + + cycles -= svga->monitor->mon_video_timing_read_b; + + ret = xga_read_banked(addr, svga); + return ret; +} + static uint16_t xga_readw(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint16_t ret = 0xffff; - if (!xga->on) { - ret = svga_readw(addr, svga); + addr &= xga->banked_mask; + addr += xga->read_bank; + + if (addr >= xga->vram_size) { + xga_log("Over Read ADDR=%x.\n", addr); return ret; } - ret = xga_read(addr, svga); - ret |= (xga_read(addr + 1, svga) << 8); + cycles -= svga->monitor->mon_video_timing_read_w; + ret = xga_read_banked(addr, svga); + ret |= (xga_read_banked(addr + 1, svga) << 8); return ret; } @@ -2747,19 +2939,23 @@ static uint32_t xga_readl(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; + xga_t *xga = (xga_t *) svga->xga; uint32_t ret = 0xffffffff; - if (!xga->on) { - ret = svga_readl(addr, svga); + addr &= xga->banked_mask; + addr += xga->read_bank; + + if (addr >= xga->vram_size) { + xga_log("Over Read ADDR=%x.\n", addr); return ret; } - ret = xga_read(addr, svga); - ret |= (xga_read(addr + 1, svga) << 8); - ret |= (xga_read(addr + 2, svga) << 16); - ret |= (xga_read(addr + 3, svga) << 24); + 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); return ret; } @@ -2769,28 +2965,21 @@ 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); if (!xga->on) { svga_write_linear(addr, val, svga); return; } - addr &= svga->decode_mask; + addr &= (xga->vram_size - 1); - if (addr >= xga->vram_size) + if (addr >= xga->vram_size) { + xga_log("Write Linear Over!.\n"); return; + } cycles -= svga->monitor->mon_video_timing_write_b; - if (xga->linear_endian_reverse) { - if ((xga->access_mode & 7) == 4) { - if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) - addr ^= 1; - } else if (xga->access_mode & 8) { - if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) - addr ^= 1; - } - } - xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; xga->vram[addr & xga->vram_mask] = val; } @@ -2837,24 +3026,18 @@ xga_read_linear(uint32_t addr, void *priv) if (!xga->on) return svga_read_linear(addr, svga); - addr &= svga->decode_mask; + addr &= (xga->vram_size - 1); - if (addr >= xga->vram_size) + if (addr >= xga->vram_size) { + xga_log("Read Linear Over ADDR=%x!.\n", addr); return ret; + } cycles -= svga->monitor->mon_video_timing_read_b; - if (xga->linear_endian_reverse) { - if ((xga->access_mode & 7) == 4) { - if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) - addr ^= 1; - } else if (xga->access_mode & 8) { - if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) - addr ^= 1; - } - } + ret = xga->vram[addr & xga->vram_mask]; - return xga->vram[addr & xga->vram_mask]; + return ret; } static uint16_t @@ -2891,187 +3074,182 @@ xga_readl_linear(uint32_t addr, void *priv) return ret; } -static void -xga_do_render(svga_t *svga) +void +xga_set_poll(svga_t *svga) { - xga_t *xga = (xga_t *) svga->xga; - - xga_log("DISPCNTL = %d, vga = %d.\n", xga->disp_cntl_2 & 7, vga_on); - switch (xga->disp_cntl_2 & 7) { - case 2: - xga_render_4bpp(svga); - break; - case 3: - xga_render_8bpp(svga); - break; - case 4: - xga_render_16bpp(svga); - break; - default: - break; - } - - svga->x_add = (overscan_x >> 1); - xga_render_overscan_left(xga, svga); - xga_render_overscan_right(xga, svga); - svga->x_add = (overscan_x >> 1); - - if (xga->hwcursor_on) { - xga_hwcursor_draw(svga, xga->displine + svga->y_add); - xga->hwcursor_on--; - if (xga->hwcursor_on && xga->interlace) - xga->hwcursor_on--; - } + timer_set_callback(&svga->timer, xga_poll); } void -xga_poll(void *priv, svga_t *svga) +xga_poll(void *priv) { - xga_t *xga = (xga_t *) priv; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint32_t x; int wx; int wy; - if (!xga->linepos) { - if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); - xga->hwcursor_oddeven = 0; - } - - if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); - xga->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, svga->dispofftime); - xga->linepos = 1; - - if (xga->dispon) { - xga->h_disp_on = 1; - - xga->ma &= xga->vram_mask; - - if (xga->firstline == 2000) { - xga->firstline = xga->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + xga_log("XGA Poll=%d.\n", xga->on); + if (xga->on) { + if (!xga->linepos) { + if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); + xga->hwcursor_oddeven = 0; } - if (xga->hwcursor_on) - xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; + if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); + xga->hwcursor_oddeven = 1; + } - xga_do_render(svga); + timer_advance_u64(&svga->timer, xga->dispofftime); + svga->cgastat |= 1; + xga->linepos = 1; - if (xga->lastline < xga->displine) - xga->lastline = xga->displine; - } + if (xga->dispon) { + xga->h_disp_on = 1; + + xga->ma &= xga->vram_mask; + + if (xga->firstline == 2000) { + xga->firstline = xga->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (xga->hwcursor_on) + xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; + + svga->render_xga(svga); + + svga->x_add = (overscan_x >> 1); + xga_render_overscan_left(xga, svga); + xga_render_overscan_right(xga, svga); + svga->x_add = (overscan_x >> 1); + + if (xga->hwcursor_on) { + xga_hwcursor_draw(svga, xga->displine + svga->y_add); + xga->hwcursor_on--; + if (xga->hwcursor_on && xga->interlace) + xga->hwcursor_on--; + } + + if (xga->lastline < xga->displine) + xga->lastline = xga->displine; + } - xga->displine++; - if (xga->interlace) xga->displine++; - if (xga->displine > 1500) - xga->displine = 0; - } else { - timer_advance_u64(&svga->timer, svga->dispontime); - xga->h_disp_on = 0; + if (xga->interlace) + xga->displine++; + if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + if (xga->displine > 1500) + xga->displine = 0; + } else { + timer_advance_u64(&svga->timer, xga->dispontime); + if (xga->dispon) + svga->cgastat &= ~1; - xga->linepos = 0; - if (xga->dispon) { - if (xga->sc == xga->rowcount) { - xga->sc = 0; + xga->h_disp_on = 0; - xga->maback += (xga->rowoffset << 3); - if (xga->interlace) + xga->linepos = 0; + if (xga->dispon) { + if (xga->sc == xga->rowcount) { + xga->sc = 0; + + xga_log("MA=%08x, MALATCH=%x.\n", xga->ma, xga->ma_latch); xga->maback += (xga->rowoffset << 3); + if (xga->interlace) + xga->maback += (xga->rowoffset << 3); - xga->maback &= xga->vram_mask; - xga->ma = xga->maback; - } else { - xga->sc++; - xga->sc &= 0x1f; - xga->ma = xga->maback; + xga->maback &= xga->vram_mask; + xga->ma = xga->maback; + } else { + xga->sc++; + xga->sc &= 0x1f; + xga->ma = xga->maback; + } + } + + xga->vc++; + xga->vc &= 0x7ff; + + if (xga->vc == xga->split) { + if (xga->interlace && xga->oddeven) + xga->ma = xga->maback = (xga->rowoffset << 1); + else + xga->ma = xga->maback = 0; + + xga->ma = (xga->ma << 2); + xga->maback = (xga->maback << 2); + + xga->sc = 0; + } + if (xga->vc == xga->dispend) { + xga->dispon = 0; + + for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { + if (xga->changedvram[x]) + xga->changedvram[x]--; + } + if (svga->fullchange) + svga->fullchange--; + } + if (xga->vc == xga->v_syncstart) { + xga->dispon = 0; + svga->cgastat |= 8; + x = xga->h_disp; + + if (xga->interlace && !xga->oddeven) + xga->lastline++; + if (xga->interlace && xga->oddeven) + xga->firstline--; + + wx = x; + + wy = xga->lastline - xga->firstline; + svga_doblit(wx, wy, svga); + + xga->firstline = 2000; + xga->lastline = 0; + + xga->firstline_draw = 2000; + xga->lastline_draw = 0; + + xga->oddeven ^= 1; + + svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; + + if (xga->interlace && xga->oddeven) + xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1); + else + xga->ma = xga->maback = xga->ma_latch; + + xga->ma = (xga->ma << 2); + xga->maback = (xga->maback << 2); + } + if (xga->vc == xga->v_total) { + xga->vc = 0; + xga->sc = 0; + xga->dispon = 1; + xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; + + svga->x_add = (overscan_x >> 1); + + xga->hwcursor_on = 0; + xga->hwcursor_latch = xga->hwcursor; } } - - xga->vc++; - xga->vc &= 0x7ff; - - if (xga->vc == xga->split) { - if (xga->interlace && xga->oddeven) - xga->ma = xga->maback = (xga->rowoffset << 1); - else - xga->ma = xga->maback = 0; - - xga->ma = (xga->ma << 2); - xga->maback = (xga->maback << 2); - - xga->sc = 0; - } - if (xga->vc == xga->dispend) { - xga->dispon = 0; - - for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { - if (xga->changedvram[x]) - xga->changedvram[x]--; - } - if (svga->fullchange) - svga->fullchange--; - } - if (xga->vc == xga->v_syncstart) { - xga->dispon = 0; - x = xga->h_disp; - - if (xga->interlace && !xga->oddeven) - xga->lastline++; - if (xga->interlace && xga->oddeven) - xga->firstline--; - - wx = x; - - wy = xga->lastline - xga->firstline; - svga_doblit(wx, wy, svga); - - xga->firstline = 2000; - xga->lastline = 0; - - xga->firstline_draw = 2000; - xga->lastline_draw = 0; - - xga->oddeven ^= 1; - - svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; - - if (xga->interlace && xga->oddeven) - xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1); - else - xga->ma = xga->maback = xga->ma_latch; - - xga->ma = (xga->ma << 2); - xga->maback = (xga->maback << 2); - } - if (xga->vc == xga->v_total) { - xga->vc = 0; - xga->sc = 0; - xga->dispon = 1; - xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; - - svga->x_add = (overscan_x >> 1); - - xga->hwcursor_on = 0; - xga->hwcursor_latch = xga->hwcursor; - } - } + } else + svga_recalctimings(svga); } static uint8_t xga_mca_read(int port, void *priv) { - const 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; uint8_t ret = xga->pos_regs[port & 7]; - if (((port & 7) == 3) && !(ret & 1)) /*Always enable the mapping.*/ - ret |= 1; - xga_log("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]); @@ -3089,16 +3267,13 @@ xga_mca_write(int port, uint8_t val, void *priv) return; io_removehandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - mem_mapping_disable(&xga->bios_rom.mapping); mem_mapping_disable(&xga->memio_mapping); xga->on = 0; - vga_on = 1; - xga->linear_endian_reverse = 0; xga->a5_test = 0; /* Save the MCA register value. */ xga->pos_regs[port & 7] = val; - if (!(xga->pos_regs[4] & 1) && (mem_size >= 16384)) /*MCA 4MB addressing on systems with more than 16MB of memory*/ + 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) { @@ -3109,10 +3284,10 @@ xga_mca_write(int port, uint8_t val, void *priv) io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - if (xga->pos_regs[3] & 1) - mem_mapping_set_addr(&xga->bios_rom.mapping, xga->rom_addr, 0x2000); - else - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); + if (xga->rom_addr) { + mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); + xga_log("ROM address=%05x.\n", xga->rom_addr); + } } xga_log("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, " @@ -3126,6 +3301,7 @@ xga_mca_feedb(void *priv) const svga_t *svga = (svga_t *) priv; const xga_t *xga = (xga_t *) svga->xga; + xga_log("FeedB.\n"); return xga->pos_regs[2] & 1; } @@ -3133,15 +3309,10 @@ static void xga_mca_reset(void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; - mem_mapping_disable(&xga->bios_rom.mapping); - mem_mapping_disable(&xga->memio_mapping); - xga->on = 0; - vga_on = 1; + xga_log("MCA Reset.\n"); + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); xga_mca_write(0x102, 0, svga); - xga->linear_endian_reverse = 0; - xga->a5_test = 0; } static void @@ -3150,12 +3321,14 @@ xga_reset(void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - mem_mapping_disable(&xga->bios_rom.mapping); - mem_mapping_disable(&xga->memio_mapping); + xga_log("Normal Reset.\n"); + if (xga_standalone_enabled) + mem_mapping_disable(&xga->memio_mapping); + xga->on = 0; - vga_on = 1; - xga->linear_endian_reverse = 0; xga->a5_test = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + svga_set_poll(svga); } static uint8_t @@ -3163,32 +3336,31 @@ xga_pos_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - uint8_t ret = 0xff; + uint8_t ret = 0x00; if (!xga_standalone_enabled) { switch (addr) { case 0x0100: case 0x0101: - if (xga->instance_isa == xga->instance_num) + if (xga->instance == xga->instance_num) ret = xga->pos_regs[addr & 7]; else ret = 0xff; + + xga_log("%03xRead=%02x.\n", addr, ret); break; case 0x0102: + ret = xga->pos_regs[2] | 0x30; + break; case 0x0105: - ret = xga->pos_regs[addr & 7]; - break; - case 0x0106: - ret = xga->pos_idx >> 8; - break; - case 0x0107: - ret = xga->pos_idx & 0xff; + ret = xga->pos_regs[5]; + xga_log("POS IDX Read 010%x ret = %02x.\n", addr & 7, ret); break; case 0x0103: - if (!(xga->pos_idx & 3)) + if ((xga->pos_idx & 3) == 0) { ret = xga->pos_regs[3]; - else - ret = 0; + ret |= (xga->dma_channel << 3); + } xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; @@ -3203,31 +3375,25 @@ xga_pos_in(uint16_t addr, void *priv) case 2: ret = xga->pos_regs[1]; break; - case 3: - ret = 0; - break; default: break; } - xga_log("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; - if (xga->instance_isa == xga->instance_num) - ret = xga->instance_isa; - else - ret = 0; + case 0x0106: + ret = xga->pos_idx >> 8; + break; + case 0x0107: + ret = xga->pos_idx & 0xff; + break; + case 0x0108 ... 0x010f: + xga->instance_num = addr & 0x07; + if (xga->instance == xga->instance_num) + ret = xga->instance; ret |= xga->isa_pos_enable; + xga_log("%03xRead=%02x.\n", addr, ret); break; default: @@ -3235,12 +3401,15 @@ xga_pos_in(uint16_t addr, void *priv) } } else { switch (addr) { + case 0x0096: + ret = xga->vga_post; + break; case 0x0100: case 0x0101: ret = xga->pos_regs[addr & 7]; break; case 0x0103: - ret = xga->pos_regs[3] | 7; + ret = xga->pos_regs[3] | 0x06; ret |= (xga->dma_channel << 3); break; case 0x0102: @@ -3250,27 +3419,12 @@ xga_pos_in(uint16_t addr, void *priv) case 0x0107: ret = (xga_mca_read(addr, svga)); break; - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; - if (xga->instance_isa == xga->instance_num) - ret = xga->instance_isa; - else - ret = 0; - - ret |= xga->isa_pos_enable; - break; default: break; } } + xga_log("[%04X:%08X]: XGA POS IN addr=%04x, ret=%02x.\n", CS, cpu_state.pc, addr, ret); return ret; } @@ -3280,8 +3434,47 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; + xga_log("[%04X:%08X]: XGA POS OUT addr=%04x, val=%02x.\n", CS, cpu_state.pc, addr, val); if (!xga_standalone_enabled) { switch (addr) { + case 0x0096: + xga->instance_num = val & 0x07; + xga->isa_pos_enable = val & 0x08; + xga_log("096Write=%02x.\n", val); + break; + case 0x0102: + xga_log("[%04X:%08X]: 102Write=%02x.\n", CS, cpu_state.pc, val); + xga->pos_regs[2] = val | 0x02; /*Instance 0 is not recommended on AT bus/ISA bus systems, so force it to use instance 1.*/ + io_removehandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + mem_mapping_disable(&xga->memio_mapping); + if (xga->pos_regs[2] & 0x01) { + xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xc0) >> 6) * 0x8000); + xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; + xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); + xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; + io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + xga_log("XGA ISA ROM address=%05x, instance=%d.\n", xga->rom_addr, xga->instance); + mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x8000); + } + break; + case 0x0103: + if ((xga->pos_idx & 3) == 0) + xga->pos_regs[3] = val; + + xga_log("[%04X:%08X]: 103Write=%02x.\n", CS, cpu_state.pc, val); + break; + case 0x0104: + xga_log("104Write=%02x.\n", val); + 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); + xga->pos_regs[5] = val; + break; case 0x0106: xga->pos_idx = (xga->pos_idx & 0x00ff) | (val << 8); break; @@ -3289,15 +3482,9 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) xga->pos_idx = (xga->pos_idx & 0xff00) | val; xga_log("POS IDX Write = %04x.\n", xga->pos_idx); break; - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; + case 0x0108 ... 0x010f: + xga_log("%03xWrite=%02x.\n", addr, val); + xga->instance_num = addr & 0x07; xga->isa_pos_enable = val & 0x08; break; @@ -3305,17 +3492,10 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) break; } } else { + xga_log("XGA Standalone ISA Write Port=%04x, Val=%02x.\n", addr, val); switch (addr) { - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; - xga->isa_pos_enable = val & 0x08; + case 0x0096: + xga->vga_post = val; break; default: @@ -3332,8 +3512,6 @@ xga_init(const device_t *info) svga_t *svga = svga_get_pri(); xga_t *xga = (xga_t *) calloc(1, sizeof(xga_t)); - FILE *fp; - uint8_t *rom = NULL; svga->xga = xga; @@ -3350,54 +3528,51 @@ xga_init(const device_t *info) xga->on = 0; xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; - xga->bios_rom.sz = 0x2000; - xga->linear_endian_reverse = 0; xga->a5_test = 0; - fp = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); - (void) fseek(fp, 0L, SEEK_END); - (void) fseek(fp, 0L, SEEK_SET); - - rom = malloc(xga->bios_rom.sz); - memset(rom, 0xff, xga->bios_rom.sz); - (void) !fread(rom, xga->bios_rom.sz, 1, fp); - (void) fclose(fp); - - xga->bios_rom.rom = rom; - xga->bios_rom.mask = xga->bios_rom.sz - 1; - if (fp != NULL) { - free(rom); - } - - xga->base_addr_1mb = 0; if (info->flags & DEVICE_MCA) { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_mca); + xga->base_addr_1mb = 0; xga->linear_base = 0; xga->instance = 0; xga->rom_addr = 0; rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&xga->bios_rom.mapping); + 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 { - if (!xga_standalone_enabled) - rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa); - - xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr; - xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; - xga->pos_regs[4] = 1 | 2; - xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + xga->pos_regs[4] = 0x02; + if (!xga_standalone_enabled) { + rom_init(&xga->bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); /*VGA BIOS only*/ + 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); + } } - mem_mapping_add(&xga->video_mapping, 0, 0, xga_read, xga_readw, xga_readl, - xga_write, xga_writew, xga_writel, - NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear, xga_write_linear, xga_writew_linear, xga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); - mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, - xga_memio_writeb, xga_memio_writew, xga_memio_writel, - !xga_standalone_enabled ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); mem_mapping_disable(&xga->linear_mapping); mem_mapping_disable(&xga->memio_mapping); @@ -3408,13 +3583,12 @@ xga_init(const device_t *info) if (xga->bus & DEVICE_MCA) { mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga); } else { - io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga); - if (!xga_standalone_enabled) - io_sethandler(0x0106, 0x0002, NULL, NULL, NULL, xga_pos_out, NULL, NULL, svga); - - io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - io_sethandler(0x0108, 0x0008, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); + 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; } @@ -3486,24 +3660,19 @@ xga_force_redraw(void *priv) static const device_config_t xga_mca_configuration[] = { // clang-format off { - .name = "type", - .description = "XGA type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "XGA-1", - .value = 0 - }, - { - .description = "XGA-2", - .value = 1 - }, - { .description = "" } - } + .name = "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 = "", .description = "", .type = CONFIG_END } // clang-format on @@ -3512,34 +3681,29 @@ static const device_config_t xga_mca_configuration[] = { static const device_config_t xga_isa_configuration[] = { // clang-format off { - .name = "type", - .description = "XGA type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { - .description = "XGA-1", - .value = 0 - }, - { - .description = "XGA-2", - .value = 1 - }, - { .description = "" } - } + .name = "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 = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -3548,18 +3712,19 @@ static const device_config_t xga_isa_configuration[] = { { .description = "5 (2150h-215Fh)", .value = 5 }, { .description = "6 (2160h-216Fh)", .value = 6 }, { .description = "7 (2170h-217Fh)", .value = 7 }, - { .description = "" } + { .description = "" } }, + .bios = { { 0 } } }, { - .name = "ext_mem_addr", - .description = "MMIO address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x00f0, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 }, @@ -3572,23 +3737,62 @@ static const device_config_t xga_isa_configuration[] = { { .description = "DA00h", .value = 0x00d0 }, { .description = "DC00h", .value = 0x00e0 }, { .description = "DE00h", .value = 0x00f0 }, - { .description = "" } + { .description = "" } }, + .bios = { { 0 } } }, { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 7, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .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 = "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 + { + .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 = "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 @@ -3602,7 +3806,7 @@ const device_t xga_device = { .init = xga_init, .close = xga_close, .reset = xga_reset, - { .available = xga_available }, + .available = xga_available, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, .config = xga_mca_configuration @@ -3611,12 +3815,12 @@ const device_t xga_device = { const device_t xga_isa_device = { .name = "XGA (ISA)", .internal_name = "xga_isa", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = xga_init, .close = xga_close, .reset = xga_reset, - { .available = xga_available }, + .available = xga_available, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, .config = xga_isa_configuration @@ -3625,15 +3829,15 @@ const device_t xga_isa_device = { const device_t inmos_isa_device = { .name = "INMOS XGA (ISA)", .internal_name = "inmos_xga_isa", - .flags = DEVICE_ISA | DEVICE_AT, + .flags = DEVICE_ISA16, .local = 0, .init = svga_xga_init, .close = xga_close, .reset = xga_reset, - { .available = inmos_xga_available }, + .available = inmos_xga_available, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = xga_isa_configuration + .config = xga_inmos_isa_configuration }; void diff --git a/src/vnc.c b/src/vnc.c index 7b4b1f7b0..cd9911b02 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -125,7 +125,6 @@ vnc_clientgone(UNUSED(rfbClientPtr cl)) #if 0 plat_mouse_capture(0); #endif - mouse_set_poll_ex(NULL); plat_pause(1); } @@ -152,7 +151,6 @@ vnc_newclient(rfbClientPtr cl) #if 0 plat_mouse_capture(1); #endif - mouse_set_poll_ex(vnc_mouse_poll); plat_pause(0); } diff --git a/vcpkg.json b/vcpkg.json index 0d71210c2..87859869b 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "4.2.1", + "version-string": "4.3", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later",