From 6a6bff7f492741841e154e9e185ef924447ce33a Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 17:53:46 +0700 Subject: [PATCH 01/46] Enable regular builds --- .github/workflows/cmake_windows_msys2.yml | 4 ++-- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 91442eafd..a2d21b572 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -41,8 +41,8 @@ jobs: fail-fast: true matrix: build: -# - name: Regular -# preset: regular + - name: Regular + preset: regular - name: Debug preset: dev_debug slug: -Debug diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 652a1986a..4d4189310 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -45,8 +45,8 @@ jobs: matrix: language: [ 'cpp' ] build: -# - name: Regular -# preset: regular + - name: Regular + preset: regular # - name: Debug # preset: debug # slug: -Debug From 88569af6592cc135642e20530463447532823dbe Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 18:02:20 +0700 Subject: [PATCH 02/46] Reverted --- .github/workflows/cmake_windows_msys2.yml | 4 ++-- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index a2d21b572..91442eafd 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -41,8 +41,8 @@ jobs: fail-fast: true matrix: build: - - name: Regular - preset: regular +# - name: Regular +# preset: regular - name: Debug preset: dev_debug slug: -Debug diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 4d4189310..652a1986a 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -45,8 +45,8 @@ jobs: matrix: language: [ 'cpp' ] build: - - name: Regular - preset: regular +# - name: Regular +# preset: regular # - name: Debug # preset: debug # slug: -Debug From cdcc8dd8f6efea197daa7c32557347ee0acb2dac Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 18:01:11 +0700 Subject: [PATCH 03/46] Actions --- .github/workflows/msys2_windows.yml | 144 ++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .github/workflows/msys2_windows.yml diff --git a/.github/workflows/msys2_windows.yml b/.github/workflows/msys2_windows.yml new file mode 100644 index 000000000..91442eafd --- /dev/null +++ b/.github/workflows/msys2_windows.yml @@ -0,0 +1,144 @@ +name: CMake (Windows, msys2) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake_windows_msys2.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake_windows_msys2.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + msys2: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + + runs-on: windows-2022 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + defaults: + run: + shell: msys2 {0} + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: dev_debug + slug: -Debug + - name: Dev + preset: development + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Qt GUI + qt: on + static: on + slug: -Qt + packages: >- + qt5-static:p + vulkan-headers:p + environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: MINGW32 +# prefix: mingw-w64-i686 +# toolchain: ./cmake/flags-gcc-i686.cmake + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 +# toolchain: ./cmake/llvm-win32-i686.cmake +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake +# - msystem: UCRT64 +# prefix: mingw-w64-ucrt-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake + + steps: + - name: Prepare MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + release: false + update: true + msystem: ${{ matrix.environment.msystem }} + pacboy: >- + ninja:p + cmake:p + gcc:p + pkgconf:p + freetype:p + SDL2:p + zlib:p + libpng:p + openal:p + rtmidi:p + libslirp:p + fluidsynth:p + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ${{ matrix.environment.toolchain }} + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D STATIC_BUILD=${{ matrix.ui.static }} + + - name: Build + run: | + .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' + path: build/artifacts/** From bd14852717daee5215167f634982768f5bf16af8 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 18:12:07 +0700 Subject: [PATCH 04/46] Create cmake-single-platform.yml --- .github/workflows/cmake-single-platform.yml | 144 ++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .github/workflows/cmake-single-platform.yml diff --git a/.github/workflows/cmake-single-platform.yml b/.github/workflows/cmake-single-platform.yml new file mode 100644 index 000000000..facb4ee88 --- /dev/null +++ b/.github/workflows/cmake-single-platform.yml @@ -0,0 +1,144 @@ +name: CMake (Windows, msys2) + +on: + + push: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/cmake-single-platform.yml + - vcpkg.json + - "!**/Makefile*" + + pull_request: + paths: + - src/** + - cmake/** + - "**/CMakeLists.txt" + - "CMakePresets.json" + - .github/workflows/** + - .github/workflows/cmake-single-platform.yml + - vcpkg.json + - "!**/Makefile*" + +jobs: + + msys2: + name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" + + runs-on: windows-2022 + + env: + BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed + + defaults: + run: + shell: msys2 {0} + + strategy: + fail-fast: true + matrix: + build: +# - name: Regular +# preset: regular + - name: Debug + preset: dev_debug + slug: -Debug + - name: Dev + preset: development + slug: -Dev + dynarec: + - name: ODR + new: off + slug: -ODR + - name: NDR + new: on + slug: -NDR + ui: + - name: Qt GUI + qt: on + static: on + slug: -Qt + packages: >- + qt5-static:p + vulkan-headers:p + environment: +# - msystem: MSYS +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: MINGW32 +# prefix: mingw-w64-i686 +# toolchain: ./cmake/flags-gcc-i686.cmake + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 +# toolchain: ./cmake/llvm-win32-i686.cmake +# - msystem: CLANG64 +# prefix: mingw-w64-clang-x86_64 +# toolchain: ./cmake/llvm-win32-x86_64.cmake +# - msystem: UCRT64 +# prefix: mingw-w64-ucrt-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake + + steps: + - name: Prepare MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + release: false + update: true + msystem: ${{ matrix.environment.msystem }} + pacboy: >- + ninja:p + cmake:p + gcc:p + pkgconf:p + freetype:p + SDL2:p + zlib:p + libpng:p + openal:p + rtmidi:p + libslirp:p + fluidsynth:p + ${{ matrix.ui.packages }} + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + + - name: Install sonar-scanner and build-wrapper + uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d + + - name: Configure CMake + run: >- + cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} + --toolchain ${{ matrix.environment.toolchain }} + -D NEW_DYNAREC=${{ matrix.dynarec.new }} + -D CMAKE_INSTALL_PREFIX=./build/artifacts + -D QT=${{ matrix.ui.qt }} + -D STATIC_BUILD=${{ matrix.ui.static }} + + - name: Build + run: | + .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build + + - name: Run sonar-scanner + if: 0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: | + .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" + + - name: Generate package + run: cmake --install build + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' + path: build/artifacts/** From 6d458acab082ad6b637b49f7bf4f16a696062199 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 18:16:59 +0700 Subject: [PATCH 05/46] Delete msys2_windows.yml --- .github/workflows/msys2_windows.yml | 144 ---------------------------- 1 file changed, 144 deletions(-) delete mode 100644 .github/workflows/msys2_windows.yml diff --git a/.github/workflows/msys2_windows.yml b/.github/workflows/msys2_windows.yml deleted file mode 100644 index 91442eafd..000000000 --- a/.github/workflows/msys2_windows.yml +++ /dev/null @@ -1,144 +0,0 @@ -name: CMake (Windows, msys2) - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/cmake_windows_msys2.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/cmake_windows_msys2.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - msys2: - name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: dev_debug - slug: -Debug - - name: Dev - preset: development - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Qt GUI - qt: on - static: on - slug: -Qt - packages: >- - qt5-static:p - vulkan-headers:p - environment: -# - msystem: MSYS -# toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: MINGW32 -# prefix: mingw-w64-i686 -# toolchain: ./cmake/flags-gcc-i686.cmake - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# toolchain: ./cmake/llvm-win32-x86_64.cmake -# - msystem: UCRT64 -# prefix: mingw-w64-ucrt-x86_64 -# toolchain: ./cmake/flags-gcc-x86_64.cmake - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - pacboy: >- - ninja:p - cmake:p - gcc:p - pkgconf:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libslirp:p - fluidsynth:p - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ${{ matrix.environment.toolchain }} - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D STATIC_BUILD=${{ matrix.ui.static }} - - - name: Build - run: | - .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' - path: build/artifacts/** From 5dbf3f7edd664f6a0e8ab3e32daa585f8917f678 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 18:24:08 +0700 Subject: [PATCH 06/46] Delete cmake-single-platform.yml --- .github/workflows/cmake-single-platform.yml | 144 -------------------- 1 file changed, 144 deletions(-) delete mode 100644 .github/workflows/cmake-single-platform.yml diff --git a/.github/workflows/cmake-single-platform.yml b/.github/workflows/cmake-single-platform.yml deleted file mode 100644 index facb4ee88..000000000 --- a/.github/workflows/cmake-single-platform.yml +++ /dev/null @@ -1,144 +0,0 @@ -name: CMake (Windows, msys2) - -on: - - push: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/cmake-single-platform.yml - - vcpkg.json - - "!**/Makefile*" - - pull_request: - paths: - - src/** - - cmake/** - - "**/CMakeLists.txt" - - "CMakePresets.json" - - .github/workflows/** - - .github/workflows/cmake-single-platform.yml - - vcpkg.json - - "!**/Makefile*" - -jobs: - - msys2: - name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}" - - runs-on: windows-2022 - - env: - BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed - - defaults: - run: - shell: msys2 {0} - - strategy: - fail-fast: true - matrix: - build: -# - name: Regular -# preset: regular - - name: Debug - preset: dev_debug - slug: -Debug - - name: Dev - preset: development - slug: -Dev - dynarec: - - name: ODR - new: off - slug: -ODR - - name: NDR - new: on - slug: -NDR - ui: - - name: Qt GUI - qt: on - static: on - slug: -Qt - packages: >- - qt5-static:p - vulkan-headers:p - environment: -# - msystem: MSYS -# toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: MINGW32 -# prefix: mingw-w64-i686 -# toolchain: ./cmake/flags-gcc-i686.cmake - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake -# - msystem: CLANG32 -# prefix: mingw-w64-clang-i686 -# toolchain: ./cmake/llvm-win32-i686.cmake -# - msystem: CLANG64 -# prefix: mingw-w64-clang-x86_64 -# toolchain: ./cmake/llvm-win32-x86_64.cmake -# - msystem: UCRT64 -# prefix: mingw-w64-ucrt-x86_64 -# toolchain: ./cmake/flags-gcc-x86_64.cmake - - steps: - - name: Prepare MSYS2 environment - uses: msys2/setup-msys2@v2 - with: - release: false - update: true - msystem: ${{ matrix.environment.msystem }} - pacboy: >- - ninja:p - cmake:p - gcc:p - pkgconf:p - freetype:p - SDL2:p - zlib:p - libpng:p - openal:p - rtmidi:p - libslirp:p - fluidsynth:p - ${{ matrix.ui.packages }} - - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - - name: Install sonar-scanner and build-wrapper - uses: SonarSource/sonarcloud-github-c-cpp@5c3c39143e381909307f6903f13774b275ed956d - - - name: Configure CMake - run: >- - cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }} - --toolchain ${{ matrix.environment.toolchain }} - -D NEW_DYNAREC=${{ matrix.dynarec.new }} - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D QT=${{ matrix.ui.qt }} - -D STATIC_BUILD=${{ matrix.ui.static }} - - - name: Build - run: | - .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build - - - name: Run sonar-scanner - if: 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: | - .sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" - - - name: Generate package - run: cmake --install build - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' - path: build/artifacts/** From ca2dc20149bcf0e1c5a94e9e6f238d3ab6f0196b Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 18:32:54 +0700 Subject: [PATCH 07/46] Update cmake_windows_msys2.yml --- .github/workflows/cmake_windows_msys2.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 91442eafd..c9399fa1b 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -3,6 +3,9 @@ name: CMake (Windows, msys2) on: push: + branches: + - main + paths: - src/** - cmake/** From cb722f2a7224a4e2cf429109bfe9b42f99d0f62e Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sun, 4 Aug 2024 19:13:18 +0700 Subject: [PATCH 08/46] Update actions --- .github/workflows/cmake_linux.yml | 3 +++ .github/workflows/cmake_macos.yml | 3 +++ .github/workflows/codeql_linux.yml | 3 +++ .github/workflows/codeql_macos.yml | 3 +++ .github/workflows/codeql_windows_msys2.yml | 3 +++ 5 files changed, 15 insertions(+) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index ed0f055a2..9c78cf7ea 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -3,6 +3,9 @@ name: CMake (Linux) on: push: + branches: + - main + paths: - src/** - cmake/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index dc45312f5..f87f813f9 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -3,6 +3,9 @@ name: CMake (macos) on: push: + branches: + - main + paths: - src/** - cmake/** diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index fee26a0a6..9fc1c0fbf 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -3,6 +3,9 @@ name: CodeQL Analysis (Linux) on: push: + branches: + - main + paths: - src/** - cmake/** diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index 266a1f051..51a3d212f 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -3,6 +3,9 @@ name: CodeQL Analysis (macos) on: push: + branches: + - main + paths: - src/** - cmake/** diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 652a1986a..4d1fd3194 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -3,6 +3,9 @@ name: CodeQL Analysis (Windows, msys2) on: push: + branches: + - main + paths: - src/** - cmake/** From e7086848e606c4526b6fcabbf90ac3390bead486 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 30 Jun 2025 00:53:42 +0700 Subject: [PATCH 09/46] Let CodeQL action not run --- .github/workflows/codeql_linux.yml | 2 +- .github/workflows/codeql_macos.yml | 2 +- .github/workflows/codeql_windows_msys2.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql_linux.yml b/.github/workflows/codeql_linux.yml index aecbc6dbb..2b542b186 100644 --- a/.github/workflows/codeql_linux.yml +++ b/.github/workflows/codeql_linux.yml @@ -3,7 +3,7 @@ name: CodeQL Analysis (Linux) on: push: - branches: [ "main" ] + branches: [ "master" ] paths: - src/** - cmake/** diff --git a/.github/workflows/codeql_macos.yml b/.github/workflows/codeql_macos.yml index f25559588..eeab0ecc8 100644 --- a/.github/workflows/codeql_macos.yml +++ b/.github/workflows/codeql_macos.yml @@ -3,7 +3,7 @@ name: CodeQL Analysis (macos) on: push: - branches: [ "main" ] + branches: [ "master" ] paths: - src/** - cmake/** diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index b8a0d662f..f513831e8 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -3,7 +3,7 @@ name: CodeQL Analysis (Windows, msys2) on: push: - branches: [ "main" ] + branches: [ "master" ] paths: - src/** - cmake/** @@ -14,7 +14,7 @@ on: - "!**/Makefile*" pull_request: - branches: [ "main" ] + branches: [ "master" ] paths: - src/** - cmake/** From 3f72771d715f18c79d583ab9065f1f6961a218f4 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Sat, 30 Aug 2025 08:55:19 +0700 Subject: [PATCH 10/46] Pervent merge conflict --- .github/workflows/cmake_linux.yml | 2 -- .github/workflows/cmake_macos.yml | 2 -- .github/workflows/cmake_windows_msys2.yml | 2 -- 3 files changed, 6 deletions(-) diff --git a/.github/workflows/cmake_linux.yml b/.github/workflows/cmake_linux.yml index 3fcd3a409..5dc0387d8 100644 --- a/.github/workflows/cmake_linux.yml +++ b/.github/workflows/cmake_linux.yml @@ -3,7 +3,6 @@ name: CMake (Linux) on: push: - branches: [ "main" ] paths: - src/** - cmake/** @@ -15,7 +14,6 @@ on: - "!**/Makefile*" pull_request: - branches: [ "main" ] paths: - src/** - cmake/** diff --git a/.github/workflows/cmake_macos.yml b/.github/workflows/cmake_macos.yml index dac1fc92f..c917932fe 100644 --- a/.github/workflows/cmake_macos.yml +++ b/.github/workflows/cmake_macos.yml @@ -3,7 +3,6 @@ name: CMake (macos) on: push: - branches: [ "main" ] paths: - src/** - cmake/** @@ -15,7 +14,6 @@ on: - "!**/Makefile*" pull_request: - branches: [ "main" ] paths: - src/** - cmake/** diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index abfbaff34..eb83d4674 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -3,7 +3,6 @@ name: CMake (Windows, msys2) on: push: - branches: [ "main" ] paths: - src/** - cmake/** @@ -15,7 +14,6 @@ on: - "!**/Makefile*" pull_request: - branches: [ "msin" ] paths: - src/** - cmake/** From 6f71e92385ca75f54c0e9c8d53dafe0a52dcbcbe Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Aug 2025 23:33:42 +0200 Subject: [PATCH 11/46] Implemented the "Parallel port FIFO" mode of ECP, made config.c sanitize the jumpered DMA on load and save, and made the PC87306 no longer able set the ECP dma if one is jumpered. --- src/config.c | 9 ++++++++- src/device/lpt.c | 8 +++++--- src/sio/sio_pc87306.c | 3 ++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/config.c b/src/config.c index 43757d6a4..9fce92ded 100644 --- a/src/config.c +++ b/src/config.c @@ -884,6 +884,10 @@ load_ports(void) if (!has_jumpers || (jumpered_internal_ecp_dma == def_jumper)) ini_section_delete_var(cat, "jumpered_internal_ecp_dma"); + else if (has_jumpers && !(machine_has_jumpered_ecp_dma(machine, jumpered_internal_ecp_dma))) { + jumpered_internal_ecp_dma = def_jumper; + ini_section_delete_var(cat, "jumpered_internal_ecp_dma"); + } for (int c = 0; c < (SERIAL_MAX - 1); c++) { sprintf(temp, "serial%d_enabled", c + 1); @@ -2908,7 +2912,10 @@ save_ports(void) if (!has_jumpers || (jumpered_internal_ecp_dma == def_jumper)) ini_section_delete_var(cat, "jumpered_internal_ecp_dma"); - else + else if (has_jumpers && !(machine_has_jumpered_ecp_dma(machine, jumpered_internal_ecp_dma))) { + jumpered_internal_ecp_dma = def_jumper; + ini_section_set_int(cat, "jumpered_internal_ecp_dma", jumpered_internal_ecp_dma); + } else ini_section_set_int(cat, "jumpered_internal_ecp_dma", jumpered_internal_ecp_dma); for (int c = 0; c < (SERIAL_MAX - 1); c++) { diff --git a/src/device/lpt.c b/src/device/lpt.c index 29689d2de..268e4200e 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -319,7 +319,7 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) switch (port & mask) { case 0x0000: if (dev->ecp) { - if ((dev->ecr & 0xe0) == 0x60) + if (((dev->ecr & 0xe0) == 0x40) || ((dev->ecr & 0xe0) == 0x60)) /* AFIFO */ lpt_write_fifo(dev, val, 0x00); else if (!(dev->ecr & 0xc0) && (!(dev->ecr & 0x20) || !(lpt_get_ctrl_raw(dev) & 0x20)) && @@ -424,7 +424,7 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); } else { dev->state = LPT_STATE_WRITE_FIFO; - if (lpt_get_ctrl_raw(dev) & 0x20) + if (((dev->ecr & 0xe0) == 0x40) || (lpt_get_ctrl_raw(dev) & 0x20)) dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; else dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; @@ -463,7 +463,7 @@ lpt_fifo_d_ready_evt(void *priv) lpt_t *dev = (lpt_t *) priv; if (!(dev->ecr & 0x08)) { - if (lpt_get_ctrl_raw(dev) & 0x20) + if (((dev->ecr & 0xe0) == 0x40) || (lpt_get_ctrl_raw(dev) & 0x20)) dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; else dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; @@ -480,6 +480,8 @@ lpt_write_to_fifo(void *priv, const uint8_t val) if (dev->ecp) { if (((dev->ecr & 0xe0) == 0x20) && (lpt_get_ctrl_raw(dev) & 0x20)) dev->dat = val; + else if (((dev->ecr & 0xe0) == 0x40) && !fifo_get_full(dev->fifo)) + fifo_write_evt_tagged(0x01, val, dev->fifo); else if (((dev->ecr & 0xe0) == 0x60) && (lpt_get_ctrl_raw(dev) & 0x20) && !fifo_get_full(dev->fifo)) fifo_write_evt_tagged(0x01, val, dev->fifo); diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index e95292fbb..f3c635dc8 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -174,7 +174,8 @@ lpt_handler(pc87306_t *dev) lpt_port_irq(dev->lpt, lpt_irq); - if ((dev->regs[0x18] & 0x06) != 0x00) + if (((jumpered_internal_ecp_dma < 0) || (jumpered_internal_ecp_dma == 4)) && + ((dev->regs[0x18] & 0x06) != 0x00)) lpt_port_dma(dev->lpt, (dev->regs[0x18] & 0x08) ? 3 : 1); } From 5c3118f6ea6e3505a2c1302abf1f5e7dbadcb05f Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sun, 31 Aug 2025 17:00:02 -0500 Subject: [PATCH 12/46] Add BIOS selector and 1998 BIOS with working PS/2 mouse to the Rise R534F --- src/include/86box/machine.h | 3 +++ src/machine/m_at_socket7.c | 50 +++++++++++++++++++++++++++++++++---- src/machine/machine_table.c | 2 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ef8803812..7ab675a6c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1046,6 +1046,9 @@ extern int machine_at_via809ds_init(const machine_t *); /* SiS 5571 */ extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t r534f_device; +#endif extern int machine_at_r534f_init(const machine_t *); /* SiS 5581 */ diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index cbc5ec05f..6239d4272 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1590,17 +1590,57 @@ machine_at_ms5146_init(const machine_t *model) return ret; } +static const device_config_t r534f_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "r534f_1998", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "06/12/1998", .internal_name = "r534f_1998", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/r534f/r534f008-1998.bin", "" } }, + { .name = "03/13/2000 (Unicore)", .internal_name = "r534f", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/r534f/r534f008.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t r534f_device = { + .name = "Rise R534F", + .internal_name = "r534f_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = r534f_config +}; + int machine_at_r534f_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/r534f/r534f008.bin", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 30b859544..7891bb3db 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -15595,7 +15595,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &r534f_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, From 0261e043651b408a432875731c900694a8ccdf04 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 1 Sep 2025 00:24:32 +0200 Subject: [PATCH 13/46] S3 changes of the night (September 1st, 2025) 1. If a card uses the icd2061a clock, so be it in a better way. 2. Vertical display fixes for heights greater than 1024 pixels, e.g.: 1600x1200 on the ELSA 96x cards. 3. Misc fixes (ROPBLT). 4. 0x3ca and 0x3cb in read mode are actually different from writes. --- src/video/vid_s3.c | 197 ++++++++++++++++++++++++++++----------------- 1 file changed, 125 insertions(+), 72 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index a0f074e70..943441f1c 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2953,13 +2953,11 @@ s3_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c2: - if (s3->chip == S3_VISION964) { - if (s3->card_type != S3_ELSAWIN2KPROX_964) { + if (svga->getclock == icd2061_getclock) { if (((val >> 2) & 3) != 3) icd2061_write(svga->clock_gen, (val >> 2) & 3); } - } - break; + break; case 0x3c5: if (s3->chip == S3_TRIO64V2) { @@ -3167,8 +3165,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.x /= 3; else if ((s3->chip <= S3_86C805) && s3->color_16bit) svga->hwcursor.x >>= 1; - else if ((s3->chip == S3_TRIO32) && ((svga->bpp == 15) || (svga->bpp == 16))) - svga->hwcursor.x >>= 1; break; case 0x4a: @@ -3231,11 +3227,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if (((svga->miscout >> 2) & 3) == 3) s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); - if (s3->chip == S3_VISION964) { - if (s3->card_type != S3_ELSAWIN2KPROX_964) { - if (((svga->miscout >> 2) & 3) == 3) - icd2061_write(svga->clock_gen, svga->crtc[0x42] & 0x0f); - } + if (svga->getclock == icd2061_getclock) { + if (((svga->miscout >> 2) & 3) == 3) + icd2061_write(svga->clock_gen, val & 0x0f); } break; @@ -3350,8 +3344,6 @@ s3_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - case 0x3ca: /*0x3c6 alias*/ - case 0x3cb: /*0x3c7 alias*/ rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) return svga_in(addr, svga); @@ -3414,6 +3406,11 @@ s3_in(uint16_t addr, void *priv) temp |= svga->crtc[0x42] & 0x0f; else temp |= ((svga->miscout >> 2) & 3); + if (s3->elsa_eeprom) { + temp &= 0xaf; + if ((svga->crtc[0x5c] & 0x10) && nmc93cxx_eeprom_read(s3->eeprom)) + temp |= 0x10; + } return temp; case 0x69: return s3->ma_ext; @@ -3637,6 +3634,7 @@ s3_recalctimings(svga_t *svga) svga->split++; if (s3->accel.advfunc_cntl & 0x01) svga->split = 0x7fff; + s3_log("SPLIT=%d, crtc5e bit 6=%02x, advfunccntl bit 0=%x.\n", svga->split, svga->crtc[0x5e] & 0x40, s3->accel.advfunc_cntl & 0x01); if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) @@ -3649,6 +3647,7 @@ s3_recalctimings(svga_t *svga) if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip < S3_TRIO32)) clk_sel = svga->crtc[0x42] & 0x0f; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { @@ -3855,12 +3854,26 @@ s3_recalctimings(svga_t *svga) svga->hdisp -= 32; break; case S3_ELSAWIN2KPROX: + s3_log("S3 width 8bpp=%d, hdisp=%d.\n", s3->width, svga->hdisp); switch (s3->width) { case 1280: case 1600: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -3983,6 +3996,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4030,6 +4056,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4165,6 +4204,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4199,6 +4251,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4338,6 +4403,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4371,6 +4449,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4451,7 +4542,7 @@ s3_trio64v_recalctimings(svga_t *svga) svga->vblankstart |= 0x400; if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; - svga->split = svga->crtc[0x18]; + svga->split = svga->crtc[0x18]; if (svga->crtc[7] & 0x10) svga->split |= 0x100; if (svga->crtc[9] & 0x40) @@ -4459,6 +4550,7 @@ s3_trio64v_recalctimings(svga_t *svga) if (svga->crtc[0x5e] & 0x40) svga->split |= 0x400; svga->split++; + svga->interlace = svga->crtc[0x42] & 0x20; svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); @@ -6132,6 +6224,7 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) } else { switch (addr & (addr_mask - 1)) { case 0x83c8: + case 0x83ca: case 0x83d4: s3_accel_write(addr, val, s3); s3_accel_write(addr + 1, val >> 8, s3); @@ -6326,54 +6419,7 @@ s3_accel_read(uint32_t addr, void *priv) if ((addr >= 0x08000) && (addr <= 0x0803f)) return s3_pci_read(0, addr & 0xff, s3); 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: + case 0x83b0 ... 0x83df: return s3_in(addr & 0x3ff, s3); case 0x8504: return s3->subsys_stat; @@ -9598,6 +9644,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else update = 1; + if (s3->bpp == 2) { + src_dat &= 0xff; + pat_dat &= 0xff; + } else if (s3->bpp == 1) { + src_dat &= 0xffff; + pat_dat &= 0xffff; + } + if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); @@ -9656,6 +9710,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -10489,10 +10545,8 @@ s3_init(const device_t *info) svga->ramdac = device_add(&att491_ramdac_device); svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; - if (info->local == S3_WINNER1000_805) { + if (info->local == S3_WINNER1000_805) s3->elsa_eeprom = 1; - sprintf(s3->nvr_path, "s3_elsa_1k_805_%i.nvr", device_get_instance()); - } break; case S3_86C805_ONBOARD: @@ -10749,14 +10803,20 @@ s3_init(const device_t *info) switch (s3->card_type) { case S3_WINNER1000_805: s3->eeprom_data[0x02] = 0x091a; + s3->eeprom_data[0x07] = 0x83d6; + s3->eeprom_data[0x08] = 0x83d6; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_805_%d.nvr", s3->eeprom_inst); break; case S3_ELSAWIN2KPROX: s3->eeprom_data[0x02] = 0x094a; + s3->eeprom_data[0x07] = 0xf424; + s3->eeprom_data[0x08] = 0xf424; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_pro_x8_968_%d.nvr", s3->eeprom_inst); break; case S3_ELSAWIN2KPROX_964: s3->eeprom_data[0x02] = 0x094a; + s3->eeprom_data[0x07] = 0xf424; + s3->eeprom_data[0x08] = 0xf424; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_pro_x8_964_%d.nvr", s3->eeprom_inst); break; default: @@ -10764,16 +10824,9 @@ s3_init(const device_t *info) } s3->eeprom_data[0x05] = 0x0040; - s3->eeprom_data[0x07] = 0xf424; - s3->eeprom_data[0x08] = 0xf424; - // s3->eeprom_data[0x09] = 0x0500; - // s3->eeprom_data[0x0b] = 0x0640; - // s3->eeprom_data[0x0c] = 0x04b0; s3->eeprom_data[0x0b] = 0x0c80; s3->eeprom_data[0x0c] = 0x0a00; s3->eeprom_data[0x0d] = 0x0001; - for (uint8_t i = 0; i < 0x32; i++) - s3->eeprom_data[0x0e + i] = 0xffff; checksum = s3_calc_crc16(64, s3->eeprom_data); From 7c13047fe6dedef1b5747ddfe0e03de862041746 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Sep 2025 01:03:06 +0200 Subject: [PATCH 14/46] Printers: Use the new timer API for the timeout timers, fixes printers on faster emulated CPU's. --- src/printer/prt_escp.c | 16 ++++++++-------- src/printer/prt_ps.c | 16 ++++++++-------- src/printer/prt_text.c | 16 ++++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 6af374fba..8fb6a1059 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -401,7 +401,7 @@ timeout_timer(void *priv) if (dev->page->dirty) new_page(dev, 1, 1); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -483,7 +483,7 @@ reset_printer_hard(escp_t *dev) { dev->ack = 0; timer_disable(&dev->pulse_timer); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); reset_printer(dev); } @@ -1898,8 +1898,8 @@ strobe(uint8_t old, uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -1909,7 +1909,7 @@ strobe(uint8_t old, uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } } @@ -1939,8 +1939,8 @@ write_ctrl(uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -1950,7 +1950,7 @@ write_ctrl(uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } dev->ctrl = val; diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index c07ad475a..9c54dccab 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -136,7 +136,7 @@ reset_ps(ps_t *dev) dev->buffer_pos = 0; timer_disable(&dev->pulse_timer); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -253,7 +253,7 @@ timeout_timer(void *priv) write_buffer(dev, true); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -333,8 +333,8 @@ ps_strobe(uint8_t old, uint8_t val, void *priv) if (!(val & 0x01) && (old & 0x01)) { process_data(dev); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -344,7 +344,7 @@ ps_strobe(uint8_t old, uint8_t val, void *priv) dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } } @@ -371,8 +371,8 @@ ps_write_ctrl(uint8_t val, void *priv) if (!(val & 0x01) && (dev->ctrl & 0x01)) { process_data(dev); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -382,7 +382,7 @@ ps_write_ctrl(uint8_t val, void *priv) dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } dev->ctrl = val; diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index eb951de08..41d3737d1 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -214,7 +214,7 @@ timeout_timer(void *priv) if (dev->page->dirty) new_page(dev); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -244,7 +244,7 @@ reset_printer(prnt_t *dev) plat_tempfile(dev->filename, NULL, ".txt"); timer_disable(&dev->pulse_timer); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static int @@ -381,8 +381,8 @@ strobe(uint8_t old, uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -393,7 +393,7 @@ strobe(uint8_t old, uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } } @@ -427,8 +427,8 @@ write_ctrl(uint8_t val, void *priv) /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -436,7 +436,7 @@ write_ctrl(uint8_t val, void *priv) } timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } dev->ctrl = val; From 04e83efcd307b79c7927c99e8b51e373621ee25a Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 1 Sep 2025 14:07:26 +0700 Subject: [PATCH 15/46] BIOS versions corrections/fixes --- src/machine/m_at_socket3.c | 6 +++--- src/machine/m_at_socket3_pci.c | 6 +++--- src/machine/m_at_socket4.c | 8 ++++---- src/machine/m_at_socket5.c | 8 ++++---- src/machine/m_at_socket7.c | 14 +++++++------- src/machine/m_at_socket7_3v.c | 20 ++++++++++---------- src/machine/m_at_socket8.c | 6 +++--- 7 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/machine/m_at_socket3.c b/src/machine/m_at_socket3.c index 32cb77973..2d6ea9730 100644 --- a/src/machine/m_at_socket3.c +++ b/src/machine/m_at_socket3.c @@ -178,11 +178,11 @@ static const device_config_t j403tg_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AMI 060692", .internal_name = "403tg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50G", .internal_name = "403tg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/403TG.BIN", "" } }, - { .name = "AMI 060692", .internal_name = "403tg_d", .bios_type = BIOS_NORMAL, + { .name = "AMI WinBIOS (121593)", .internal_name = "403tg_d", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/J403TGRevD.BIN", "" } }, - { .name = "AMI 060692", .internal_name = "403tg_d_mr", .bios_type = BIOS_NORMAL, + { .name = "MR BIOS V2.02", .internal_name = "403tg_d_mr", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/MRBiosOPT895.bin", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket3_pci.c b/src/machine/m_at_socket3_pci.c index 451d791ca..41fab4958 100644 --- a/src/machine/m_at_socket3_pci.c +++ b/src/machine/m_at_socket3_pci.c @@ -291,16 +291,16 @@ static const device_config_t pc330_6573_config[] = { // clang-format off { .name = "bios", - .description = "BIOS Version", + .description = "BIOS Language", .type = CONFIG_BIOS, .default_string = "pc330_6573", .default_int = 0, .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "IBM Aptiva 510/710/Vision", .internal_name = "aptiva510", .bios_type = BIOS_NORMAL, + { .name = "Japanese (Aptiva 510/710/Vision)", .internal_name = "aptiva510", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/aptiva510_$IMAGES.USF", "" } }, - { .name = "IBM PC 330 (type 6573)", .internal_name = "pc330_6573", .bios_type = BIOS_NORMAL, + { .name = "English (PC 330, type 6573)", .internal_name = "pc330_6573", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/$IMAGES.USF", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index d1f9c637f..5e1bf533f 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -288,11 +288,11 @@ static const device_config_t batman_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AMBRA DP60 PCI", .internal_name = "ambradp60", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/batman/1004AF1P.BIO", "roms/machines/batman/1004AF1P.BI1", "" } }, - { .name = "Dell Dimension XPS P60", .internal_name = "dellxp60", .bios_type = BIOS_NORMAL, + { .name = "AMIBIOS 111192 - Revision A08 (Dell Dimension XPS P60)", .internal_name = "dellxp60", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/batman/XP60-A08.ROM", "" } }, - { .name = "Intel Premiere/PCI (Batman)", .internal_name = "batman", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.04.AF1P (AMBRA DP60 PCI)", .internal_name = "ambradp60", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/batman/1004AF1P.BIO", "roms/machines/batman/1004AF1P.BI1", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.08.AF1", .internal_name = "batman", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/batman/1008AF1_.BIO", "roms/machines/batman/1008AF1_.BI1", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index a55e2bc2d..cb3803e0d 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -100,12 +100,12 @@ static const device_config_t plato_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AMBRA DP90 PCI", .internal_name = "ambradp90", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.02.AX1P (AMBRA DP90 PCI)", .internal_name = "ambradp90", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1002AX1P.BIO", "roms/machines/plato/1002AX1P.BI1", "" } }, - { .name = "Dell Dimension XPS Pxxx", .internal_name = "dellplato", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1016AX1J.BIO", "roms/machines/plato/1016AX1J.BI1", "" } }, - { .name = "Intel Premiere/PCI II (Plato)", .internal_name = "plato", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.16.AX1", .internal_name = "plato", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1016ax1_.bio", "roms/machines/plato/1016ax1_.bi1", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.16.AX1J (Dell Dimension XPS P___)", .internal_name = "dellplato", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1016AX1J.BIO", "roms/machines/plato/1016AX1J.BI1", "" } }, { .files_no = 0 } }, }, diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 6239d4272..30c9e649c 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -151,14 +151,14 @@ static const device_config_t cu430hx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Intel CU430HX (Cumberland)", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, - .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", - "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3", - "roms/machines/cu430hx/1006DK0_.RCV", "" } }, - { .name = "Toshiba Equium 5200D", .internal_name = "equium5200", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.03.DK08 (Toshiba Equium 5200D)", .internal_name = "equium5200", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1003DK08.BIO", "roms/machines/cu430hx/1003DK08.BI1", "roms/machines/cu430hx/1003DK08.BI2", "roms/machines/cu430hx/1003DK08.BI3", "roms/machines/cu430hx/1003DK08.RCV", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.06.DK0", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, + .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", + "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3", + "roms/machines/cu430hx/1006DK0_.RCV", "" } }, { .files_no = 0 } }, }, @@ -262,11 +262,11 @@ static const device_config_t tc430hx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Intel TC430HX (Tucson)", .internal_name = "tc430hx", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.07.DH0", .internal_name = "tc430hx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/tc430hx/1007DH0_.BIO", "roms/machines/tc430hx/1007DH0_.BI1", "roms/machines/tc430hx/1007DH0_.BI2", "roms/machines/tc430hx/1007DH0_.BI3", "roms/machines/tc430hx/1007DH0_.RCV", "" } }, - { .name = "Toshiba Infinia 7201", .internal_name = "infinia7200", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.08.DH08 (Toshiba Infinia 7201)", .internal_name = "infinia7200", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/tc430hx/1008DH08.BIO", "roms/machines/tc430hx/1008DH08.BI1", "roms/machines/tc430hx/1008DH08.BI2", "roms/machines/tc430hx/1008DH08.BI3", "roms/machines/tc430hx/1008DH08.RCV", "" } }, diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 64d8a0fd5..54cc6e35b 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -53,7 +53,7 @@ static const device_config_t p54tp4xe_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Award BIOS v4.51PG", .internal_name = "p54tp4xe", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG", .internal_name = "p54tp4xe", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/p54tp4xe/t15i0302.awd", "" } }, { .name = "MR BIOS V3.30", .internal_name = "p54tp4xe_mr", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/p54tp4xe/TRITON.BIO", "" } }, @@ -183,11 +183,11 @@ static const device_config_t thor_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Gateway 2000 (AMIBIOS)", .internal_name = "gw2katx", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.03.CN0T (Gateway 2000)", .internal_name = "gw2katx", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/thor/1003CN0T.BIO", "roms/machines/thor/1003CN0T.BI1", "" } }, - { .name = "Intel (AMIBIOS)", .internal_name = "thor", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.06.CN0", .internal_name = "thor", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/thor/1006cn0_.bio", "roms/machines/thor/1006cn0_.bi1", "" } }, - { .name = "Intel (MR BIOS)", .internal_name = "mrthor", .bios_type = BIOS_NORMAL, + { .name = "MR BIOS V3.28", .internal_name = "mrthor", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/thor/mr_atx.bio", "" } }, { .files_no = 0 } }, @@ -798,11 +798,11 @@ static const device_config_t c5sbm2_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AwardBIOS v4.50GP - Revision 07/17/1995", .internal_name = "5sbm2_v450gp", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50GP - Revision 07/17/1995", .internal_name = "5sbm2_v450gp", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0717.BIN", "" } }, - { .name = "AwardBIOS v4.50PG - Revision 03/26/1996", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50PG - Revision 03/26/1996", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0326.BIN", "" } }, - { .name = "AwardBIOS v4.51PG - Revision 2.2 (by Unicore Software)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 2.2 (by Unicore Software)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/2A5ICC3A.BIN", "" } }, { .files_no = 0 } }, @@ -901,11 +901,11 @@ static const device_config_t ap5s_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AwardBIOS v4.50PG - Revision R1.20", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50PG - Revision R1.20", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s120.bin", "" } }, - { .name = "AwardBIOS v4.51PG - Revision R1.50", .internal_name = "ap5s_r150", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision R1.50", .internal_name = "ap5s_r150", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/AP5S150.BIN", "" } }, - { .name = "AwardBIOS v4.51PG - Revision R1.60", .internal_name = "ap5s", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision R1.60", .internal_name = "ap5s", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s160.bin", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e7975f601..3d5f4787e 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -331,15 +331,15 @@ static const device_config_t vs440fx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Dell Dimension XPS Pro___n", .internal_name = "dellvenus", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.06.CS1J (Dell Dimension XPS Pro___n)", .internal_name = "dellvenus", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/vs440fx/1006CS1J.BIO", "roms/machines/vs440fx/1006CS1J.BI1", "roms/machines/vs440fx/1006CS1J.BI2", "roms/machines/vs440fx/1006CS1J.BI3", "roms/machines/vs440fx/1006CS1J.RCV", "" } }, - { .name = "Gateway 2000 Venus", .internal_name = "gw2kvenus", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.11.CS1T (Gateway 2000)", .internal_name = "gw2kvenus", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/vs440fx/1011CS1T.BIO", "roms/machines/vs440fx/1011CS1T.BI1", "roms/machines/vs440fx/1011CS1T.BI2", "roms/machines/vs440fx/1011CS1T.BI3", "roms/machines/vs440fx/1011CS1T.RCV", "" } }, - { .name = "Intel VS440FX (Venus)", .internal_name = "vs440fx", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.18.CS1", .internal_name = "vs440fx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/vs440fx/1018CS1_.BIO", "roms/machines/vs440fx/1018CS1_.BI1", "roms/machines/vs440fx/1018CS1_.BI2", "roms/machines/vs440fx/1018CS1_.BI3", "roms/machines/vs440fx/1018CS1_.RCV", "" } }, From 52f3ed1b42d1eaf10a2c66784edac7fab0e73f60 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Sep 2025 13:21:59 +0600 Subject: [PATCH 16/46] Add support for parsing edid-decode text dumps --- src/CMakeLists.txt | 1 + src/edid_parse.cpp | 120 ++++++++++++++++++++++++++++++++++ src/qt/qt_settingsdisplay.cpp | 2 +- src/utils/ini.c | 2 +- src/video/vid_ddc.c | 29 +++++++- 5 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 src/edid_parse.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 724e1fda6..89a97f683 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,7 @@ add_executable(86Box nvr_at.c nvr_ps2.c machine_status.c + edid_parse.cpp ) if(CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/src/edid_parse.cpp b/src/edid_parse.cpp new file mode 100644 index 000000000..241844fa3 --- /dev/null +++ b/src/edid_parse.cpp @@ -0,0 +1,120 @@ +#include +#include +#include +#include + +#include + +extern "C" +{ +#include <86box/86box.h> +#include <86box/plat.h> + +extern int ini_detect_bom(const char *fn); +extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); +} + +// https://stackoverflow.com/a/64886763 +static std::vector split(const std::string str, const std::string regex_str) +{ + std::regex regexz(regex_str); + std::vector list(std::sregex_token_iterator(str.begin(), str.end(), regexz, -1), + std::sregex_token_iterator()); + return list; +} + +extern "C" +{ + bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size_out) + { + std::regex regexLib("^([a-f0-9]{32}|[a-f0-9 ]{47})$", std::regex_constants::egrep); + FILE* file; + pclog("Parse %s\n", path); + try { + bool bom = ini_detect_bom(path); + { + // First check for "edid-decode (hex)" string. + file = plat_fopen(path, "rb"); + if (file) { + std::string str; + size_t size; + if (!fseek(file, 0, SEEK_END)) { + size = ftell(file); + if (size != -1) { + str.resize(size); + } + fseek(file, 0, SEEK_SET); + auto read = fread((void*)str.data(), 1, size, file); + str.resize(read); + fclose(file); + file = NULL; + + if (str.size() == 0) { + return false; + } + + if (str.find("edid-decode") == std::string::npos) { + return false; + } + } + } else { + return false; + } + } + file = plat_fopen(path, "rb"); + if (file) { + char* buf = NULL; + size_t size = 0; + std::string edid_decode_text; + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + if (bom) { + fseek(file, 3, SEEK_SET); + size -= 3; + } + edid_decode_text.resize(size); + auto err = fread((void*)edid_decode_text.data(), size, 1, file); + fclose(file); + file = NULL; + if (err == 0) { + return false; + } + std::istringstream isstream(edid_decode_text); + std::string line; + std::string edid; + while (std::getline(isstream, line)) { + if (line[line.size() - 1] == '\r') { + line.resize(line.size() - 1); + } + std::smatch matched; + if (std::regex_match(line, matched, regexLib)) { + edid.append(matched.str() + " "); + } + } + if (edid.size() >= 3) { + edid.resize(edid.size() - 1); + auto vals = split(edid, "\\s+"); + if (vals.size()) { + *size_out = vals.size(); + if (vals.size() > 256) + return false; + for (int i = 0; i < vals.size(); i++) { + out[i] = (uint8_t)std::strtoul(&vals[i][0], nullptr, 16); + } + return true; + } + } + } + + return false; + } catch (std::bad_alloc&) { + if (file) { + fclose(file); + file = NULL; + } + return false; + } + return false; + } +} \ No newline at end of file diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index b03930806..bbe64dc00 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -46,7 +46,7 @@ SettingsDisplay::SettingsDisplay(QWidget *parent) for (uint8_t i = 0; i < GFXCARD_MAX; i ++) videoCard[i] = gfxcard[i]; - ui->lineEdit->setFilter(tr("EDID") % util::DlgFilter({ "bin", "dat", "edid" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + ui->lineEdit->setFilter(tr("EDID") % util::DlgFilter({ "bin", "dat", "edid", "txt" }) % tr("All files") % util::DlgFilter({ "*" }, true)); onCurrentMachineChanged(machine); } diff --git a/src/utils/ini.c b/src/utils/ini.c index b267f38b5..47e792594 100644 --- a/src/utils/ini.c +++ b/src/utils/ini.c @@ -316,7 +316,7 @@ ini_close(ini_t ini) free(list); } -static int +int ini_detect_bom(const char *fn) { FILE *fp; diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index d6c9095ef..6d86a25c9 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -14,6 +14,7 @@ * * Copyright 2020 RichardG. */ +#include #include #include #include @@ -231,13 +232,36 @@ ddc_create_default_edid(ssize_t* size_out) return edid; } +extern bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size); + void * ddc_init(void *i2c) { ssize_t edid_size = 0; uint8_t* edid_bytes = NULL; if (monitor_edid == 1 && monitor_edid_path[0]) { - FILE* file = plat_fopen(monitor_edid_path, "rb"); + FILE* file; + { + edid_bytes = calloc(1, 256); + if (parse_edid_decode_file(monitor_edid_path, edid_bytes, &edid_size) == false) { + if (edid_size > 256) { + wchar_t errmsg[2048] = { 0 }; + wchar_t path[2048] = { 0 }; + +#ifdef _WIN32 + mbstoc16s(path, monitor_edid_path, sizeof_w(path)); +#else + mbstowcs(path, monitor_edid_path, sizeof_w(path)); +#endif + swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); + ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); + } + free(edid_bytes); + } else { + goto calculate_cksum; + } + } + file = plat_fopen(monitor_edid_path, "rb"); if (!file) goto default_init; @@ -282,6 +306,8 @@ ddc_init(void *i2c) goto default_init; } + fclose(file); +calculate_cksum: if (edid_size < 128) { edid_bytes = realloc(edid_bytes, 128); edid_size = 128; @@ -306,7 +332,6 @@ ddc_init(void *i2c) } } - fclose(file); return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } default_init: From c5f9d65ee31a80e2aea25ecf8e7e3cdb22536b9e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Sep 2025 13:25:48 +0600 Subject: [PATCH 17/46] Fix compile errors --- src/edid_parse.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/edid_parse.cpp b/src/edid_parse.cpp index 241844fa3..8bc8a0684 100644 --- a/src/edid_parse.cpp +++ b/src/edid_parse.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include From 2ddbc3461da6c16da5f7bb7b6a6194837e260f1a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Sep 2025 13:27:42 +0600 Subject: [PATCH 18/46] Warning fixes --- src/edid_parse.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/edid_parse.cpp b/src/edid_parse.cpp index 8bc8a0684..e62767ba5 100644 --- a/src/edid_parse.cpp +++ b/src/edid_parse.cpp @@ -38,7 +38,7 @@ extern "C" file = plat_fopen(path, "rb"); if (file) { std::string str; - size_t size; + ssize_t size; if (!fseek(file, 0, SEEK_END)) { size = ftell(file); if (size != -1) { @@ -64,7 +64,6 @@ extern "C" } file = plat_fopen(path, "rb"); if (file) { - char* buf = NULL; size_t size = 0; std::string edid_decode_text; fseek(file, 0, SEEK_END); @@ -100,7 +99,7 @@ extern "C" *size_out = vals.size(); if (vals.size() > 256) return false; - for (int i = 0; i < vals.size(); i++) { + for (size_t i = 0; i < vals.size(); i++) { out[i] = (uint8_t)std::strtoul(&vals[i][0], nullptr, 16); } return true; From a359ec77badfbdf7a9881701be65c39249ac9f18 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Sep 2025 14:07:12 +0600 Subject: [PATCH 19/46] Add more missing strings --- src/unix/unix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/unix/unix.c b/src/unix/unix.c index b4d6daa17..de35f4e93 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -290,6 +290,8 @@ plat_get_string(int i) return L"Hardware not available"; case STRING_MONITOR_SLEEP: return L"Monitor in sleep mode"; + case STRING_EDID_TOO_LARGE: + return "EDID file \"%ls\" is too large."; } return L""; } From e51e3d9b72d4f9d7f1753f3e5b368bfa5630f031 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 1 Sep 2025 17:06:06 +0600 Subject: [PATCH 20/46] Make EDID text dump detection more robust to avoid false positives --- src/edid_parse.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/edid_parse.cpp b/src/edid_parse.cpp index e62767ba5..3d74245ff 100644 --- a/src/edid_parse.cpp +++ b/src/edid_parse.cpp @@ -30,7 +30,6 @@ extern "C" { std::regex regexLib("^([a-f0-9]{32}|[a-f0-9 ]{47})$", std::regex_constants::egrep); FILE* file; - pclog("Parse %s\n", path); try { bool bom = ini_detect_bom(path); { @@ -54,7 +53,7 @@ extern "C" return false; } - if (str.find("edid-decode") == std::string::npos) { + if (str.find("edid-decode (hex):") == std::string::npos) { return false; } } From 3d7ffdcde017c8fc3a2ea539e4b11c8baf3e1b52 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Sep 2025 13:11:30 +0200 Subject: [PATCH 21/46] EDID Parser: Fix a warning and move the whole thing to utils/. --- src/CMakeLists.txt | 1 - src/utils/CMakeLists.txt | 1 + src/{ => utils}/edid_parse.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{ => utils}/edid_parse.cpp (99%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 89a97f683..724e1fda6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,7 +48,6 @@ add_executable(86Box nvr_at.c nvr_ps2.c machine_status.c - edid_parse.cpp ) if(CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index bcbc7aafd..e4dea5d61 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -19,6 +19,7 @@ add_library(utils OBJECT cJSON.c crc.c crc32.c + edid_parse.cpp fifo.c fifo8.c ini.c diff --git a/src/edid_parse.cpp b/src/utils/edid_parse.cpp similarity index 99% rename from src/edid_parse.cpp rename to src/utils/edid_parse.cpp index 3d74245ff..5aff4e3e6 100644 --- a/src/edid_parse.cpp +++ b/src/utils/edid_parse.cpp @@ -29,7 +29,7 @@ extern "C" bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size_out) { std::regex regexLib("^([a-f0-9]{32}|[a-f0-9 ]{47})$", std::regex_constants::egrep); - FILE* file; + FILE* file = NULL; try { bool bom = ini_detect_bom(path); { From fb6dfdd21f080879bb48076079b4e430b8780db9 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 1 Sep 2025 19:37:55 +0700 Subject: [PATCH 22/46] Some BIOS changes I have forgotten --- src/machine/m_at_socket3_pci.c | 6 +++--- src/machine/m_at_socket7.c | 12 ++++++------ src/machine/m_at_socket7_3v.c | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/machine/m_at_socket3_pci.c b/src/machine/m_at_socket3_pci.c index 41fab4958..c122caa2d 100644 --- a/src/machine/m_at_socket3_pci.c +++ b/src/machine/m_at_socket3_pci.c @@ -298,10 +298,10 @@ static const device_config_t pc330_6573_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Japanese (Aptiva 510/710/Vision)", .internal_name = "aptiva510", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/aptiva510_$IMAGES.USF", "" } }, { .name = "English (PC 330, type 6573)", .internal_name = "pc330_6573", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/$IMAGES.USF", "" } }, + { .name = "Japanese (Aptiva 510/710/Vision)", .internal_name = "aptiva510", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/aptiva510_$IMAGES.USF", "" } }, { .files_no = 0 } }, }, @@ -1354,7 +1354,7 @@ static const device_config_t hot433a_config[] = { .bios = { { .name = "AMIBIOS 5 (101094) - Revision 433AUS33", .internal_name = "hot433a", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/433AUS33.ROM", "" } }, - { .name = "AwardBIOS v4.51PG - Revision 2.5 (by eSupport)", .internal_name = "hot433a_v451pg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 2.5 (by eSupport)", .internal_name = "hot433a_v451pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/2A4X5H21.BIN", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 30c9e649c..b0651a8af 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -830,9 +830,9 @@ static const device_config_t lgibmx52_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "08/21/97", .internal_name = "lgibmx52_082197", .bios_type = BIOS_NORMAL, + { .name = "PhoenixBIOS 4.05 - Revision 08/21/97", .internal_name = "lgibmx52_082197", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/lgibmx52/BIOS.ROM", "" } }, - { .name = "03/26/99", .internal_name = "lgibmx52", .bios_type = BIOS_NORMAL, + { .name = "PhoenixBIOS 4.05 - Revision 03/26/99", .internal_name = "lgibmx52", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/lgibmx52/MS5136 LG IBM OEM.ROM", "" } }, { .files_no = 0 } }, @@ -1601,9 +1601,9 @@ static const device_config_t r534f_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "06/12/1998", .internal_name = "r534f_1998", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 06/12/1998", .internal_name = "r534f_1998", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/r534f/r534f008-1998.bin", "" } }, - { .name = "03/13/2000 (Unicore)", .internal_name = "r534f", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 03/13/2000 (by Unicore Software)", .internal_name = "r534f", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/r534f/r534f008.bin", "" } }, { .files_no = 0 } }, @@ -1753,9 +1753,9 @@ static const device_config_t m5ata_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "12/23/97", .internal_name = "m5ata", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 12/23/97", .internal_name = "m5ata", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/m5ata/ATA1223.BIN", "" } }, - { .name = "05/27/98", .internal_name = "m5ata_0527b", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 05/27/98", .internal_name = "m5ata_0527b", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/m5ata/ATA0527B.BIN", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 54cc6e35b..f289b2275 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -53,7 +53,7 @@ static const device_config_t p54tp4xe_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Award Modular BIOS v4.51PG", .internal_name = "p54tp4xe", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 0302", .internal_name = "p54tp4xe", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/p54tp4xe/t15i0302.awd", "" } }, { .name = "MR BIOS V3.30", .internal_name = "p54tp4xe_mr", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/p54tp4xe/TRITON.BIO", "" } }, From 043e2b6baa6d8c2d1abecbd9006a38d4c463b889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:35:56 +0200 Subject: [PATCH 23/46] Rewrite custom EDID loading --- src/include/86box/vid_ddc.h | 7 +- src/qt/qt_settingsdisplay.cpp | 7 +- src/utils/CMakeLists.txt | 1 - src/utils/edid_parse.cpp | 119 ------------------------ src/video/CMakeLists.txt | 1 + src/video/vid_ddc.c | 168 +++++++++++++--------------------- src/video/vid_ddc_custom.c | 110 ++++++++++++++++++++++ 7 files changed, 182 insertions(+), 231 deletions(-) delete mode 100644 src/utils/edid_parse.cpp create mode 100644 src/video/vid_ddc_custom.c diff --git a/src/include/86box/vid_ddc.h b/src/include/86box/vid_ddc.h index 8d68d0adf..32c8e88c5 100644 --- a/src/include/86box/vid_ddc.h +++ b/src/include/86box/vid_ddc.h @@ -20,8 +20,9 @@ #ifndef EMU_VID_DDC_H #define EMU_VID_DDC_H -extern void *ddc_init(void *i2c); -extern void ddc_close(void *eeprom); -extern void *ddc_create_default_edid(ssize_t* size_out); +extern void *ddc_init(void *i2c); +extern void ddc_close(void *eeprom); +extern size_t ddc_create_default_edid(uint8_t **size_out); +extern size_t ddc_load_edid(char *path, uint8_t *buf, size_t size); #endif /*EMU_VID_DDC_H*/ diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index bbe64dc00..ed9ba220c 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -23,6 +23,8 @@ #include #include +#include + extern "C" { #include <86box/86box.h> #include <86box/device.h> @@ -343,11 +345,10 @@ void SettingsDisplay::on_pushButtonExportDefault_clicked() if (!str.isEmpty()) { QFile file(str); if (file.open(QFile::WriteOnly)) { - ssize_t size = 0; - auto bytes = ddc_create_default_edid(&size); + uint8_t *bytes = nullptr; + auto size = ddc_create_default_edid(&bytes); file.write((char*)bytes, size); file.close(); } } } - diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index e4dea5d61..bcbc7aafd 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -19,7 +19,6 @@ add_library(utils OBJECT cJSON.c crc.c crc32.c - edid_parse.cpp fifo.c fifo8.c ini.c diff --git a/src/utils/edid_parse.cpp b/src/utils/edid_parse.cpp deleted file mode 100644 index 5aff4e3e6..000000000 --- a/src/utils/edid_parse.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -extern "C" -{ -#include <86box/86box.h> -#include <86box/plat.h> - -extern int ini_detect_bom(const char *fn); -extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); -} - -// https://stackoverflow.com/a/64886763 -static std::vector split(const std::string str, const std::string regex_str) -{ - std::regex regexz(regex_str); - std::vector list(std::sregex_token_iterator(str.begin(), str.end(), regexz, -1), - std::sregex_token_iterator()); - return list; -} - -extern "C" -{ - bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size_out) - { - std::regex regexLib("^([a-f0-9]{32}|[a-f0-9 ]{47})$", std::regex_constants::egrep); - FILE* file = NULL; - try { - bool bom = ini_detect_bom(path); - { - // First check for "edid-decode (hex)" string. - file = plat_fopen(path, "rb"); - if (file) { - std::string str; - ssize_t size; - if (!fseek(file, 0, SEEK_END)) { - size = ftell(file); - if (size != -1) { - str.resize(size); - } - fseek(file, 0, SEEK_SET); - auto read = fread((void*)str.data(), 1, size, file); - str.resize(read); - fclose(file); - file = NULL; - - if (str.size() == 0) { - return false; - } - - if (str.find("edid-decode (hex):") == std::string::npos) { - return false; - } - } - } else { - return false; - } - } - file = plat_fopen(path, "rb"); - if (file) { - size_t size = 0; - std::string edid_decode_text; - fseek(file, 0, SEEK_END); - size = ftell(file); - fseek(file, 0, SEEK_SET); - if (bom) { - fseek(file, 3, SEEK_SET); - size -= 3; - } - edid_decode_text.resize(size); - auto err = fread((void*)edid_decode_text.data(), size, 1, file); - fclose(file); - file = NULL; - if (err == 0) { - return false; - } - std::istringstream isstream(edid_decode_text); - std::string line; - std::string edid; - while (std::getline(isstream, line)) { - if (line[line.size() - 1] == '\r') { - line.resize(line.size() - 1); - } - std::smatch matched; - if (std::regex_match(line, matched, regexLib)) { - edid.append(matched.str() + " "); - } - } - if (edid.size() >= 3) { - edid.resize(edid.size() - 1); - auto vals = split(edid, "\\s+"); - if (vals.size()) { - *size_out = vals.size(); - if (vals.size() > 256) - return false; - for (size_t i = 0; i < vals.size(); i++) { - out[i] = (uint8_t)std::strtoul(&vals[i][0], nullptr, 16); - } - return true; - } - } - } - - return false; - } catch (std::bad_alloc&) { - if (file) { - fclose(file); - file = NULL; - } - return false; - } - return false; - } -} \ No newline at end of file diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 6301956c5..4667a3b4f 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -44,6 +44,7 @@ add_library(vid OBJECT # DDC / monitor identification stuff vid_ddc.c + vid_ddc_custom.c # CARDS start here diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 6d86a25c9..aeaba3965 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -14,7 +14,6 @@ * * Copyright 2020 RichardG. */ -#include #include #include #include @@ -130,8 +129,8 @@ typedef struct { uint8_t padding[15], checksum2; } edid_t; -void* -ddc_create_default_edid(ssize_t* size_out) +size_t +ddc_create_default_edid(uint8_t **out) { edid_t *edid = malloc(sizeof(edid_t)); memset(edid, 0, sizeof(edid_t)); @@ -226,120 +225,79 @@ ddc_create_default_edid(ssize_t* size_out) edid->checksum2 += edid_bytes[c]; edid->checksum2 = 256 - edid->checksum2; - if (size_out) - *size_out = sizeof(edid_t); - - return edid; + if (out) { + *out = edid_bytes; + } + + return sizeof(edid_t); } -extern bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size); +void * +ddc_init_with_custom_edid(char *edid_path, void *i2c) +{ + uint8_t buffer[384] = { 0 }; + size_t size = ddc_load_edid(edid_path, buffer, sizeof(buffer)); + + if (size > 256) { + wchar_t errmsg[2048] = { 0 }; + wchar_t path[2048] = { 0 }; + +#ifdef _WIN32 + mbstoc16s(path, monitor_edid_path, sizeof_w(path)); +#else + mbstowcs(path, monitor_edid_path, sizeof_w(path)); +#endif + swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); + ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); + + return NULL; + } else if (size == 0) { + return NULL; + } else if (size < 128) { + size = 128; + } else if (size < 256) { + size = 256; + } + + int checksum = 0; + for (int i = 0; i < 127; i++) { + checksum += buffer[i]; + } + + buffer[127] = 256 - checksum; + + if (size == 256) { + checksum = 0; + + for (int i = 128; i < 255; i++) { + checksum += buffer[i]; + } + buffer[255] = 256 - checksum; + } + + uint8_t *edid_bytes = malloc(size); + memcpy(edid_bytes, buffer, size); + + return i2c_eeprom_init(i2c, 0x50, edid_bytes, size); +} void * ddc_init(void *i2c) { - ssize_t edid_size = 0; - uint8_t* edid_bytes = NULL; - if (monitor_edid == 1 && monitor_edid_path[0]) { - FILE* file; - { - edid_bytes = calloc(1, 256); - if (parse_edid_decode_file(monitor_edid_path, edid_bytes, &edid_size) == false) { - if (edid_size > 256) { - wchar_t errmsg[2048] = { 0 }; - wchar_t path[2048] = { 0 }; + if (monitor_edid && monitor_edid_path[0]) { + void *ret = ddc_init_with_custom_edid(monitor_edid_path, i2c); -#ifdef _WIN32 - mbstoc16s(path, monitor_edid_path, sizeof_w(path)); -#else - mbstowcs(path, monitor_edid_path, sizeof_w(path)); -#endif - swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); - ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); - } - free(edid_bytes); - } else { - goto calculate_cksum; - } + if (ret) { + return ret; } - file = plat_fopen(monitor_edid_path, "rb"); - - if (!file) - goto default_init; - - if (fseek(file, 0, SEEK_END) == -1) { - fclose(file); - goto default_init; - } - - edid_size = ftell(file); - fseek(file, 0, SEEK_SET); - - if (edid_size <= 0) { - fclose(file); - goto default_init; - } - - if (edid_size > 256) { - wchar_t errmsg[2048] = { 0 }; - wchar_t path[2048] = { 0 }; - -#ifdef _WIN32 - mbstoc16s(path, monitor_edid_path, sizeof_w(path)); -#else - mbstowcs(path, monitor_edid_path, sizeof_w(path)); -#endif - swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); - ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); - fclose(file); - goto default_init; - } - - edid_bytes = calloc(1, edid_size); - if (!edid_bytes) { - fclose(file); - goto default_init; - } - - if (fread(edid_bytes, edid_size, 1, file) <= 0) { - free(edid_bytes); - fclose(file); - goto default_init; - } - - fclose(file); -calculate_cksum: - if (edid_size < 128) { - edid_bytes = realloc(edid_bytes, 128); - edid_size = 128; - } else if (edid_size < 256) { - edid_bytes = realloc(edid_bytes, 256); - edid_size = 256; - } - - { - int checksum = 0; - for (uint8_t c = 0; c < 127; c++) - checksum += edid_bytes[c]; - edid_bytes[127] = 256 - checksum; - - if (edid_size == 256) { - checksum = 0; - - for (uint8_t c = 128; c < 255; c++) { - checksum += edid_bytes[c]; - } - edid_bytes[255] = 256 - checksum; - } - } - - return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } -default_init: - edid_size = sizeof(edid_t); - edid_bytes = ddc_create_default_edid(&edid_size); + + uint8_t *edid_bytes; + size_t edid_size = ddc_generate_default_edid(&edid_bytes); return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } + void ddc_close(void *eeprom) { diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_custom.c new file mode 100644 index 000000000..4b8e300e5 --- /dev/null +++ b/src/video/vid_ddc_custom.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include + +#define EDID_BLOCK_SIZE 128 +#define EDID_HEADER 0x00FFFFFFFFFFFF00 +#define EDID_DECODE_HEADER "edid-decode (hex):" + +static size_t +read_block(FILE *fp, uint8_t *buf) +{ + uint8_t temp[64]; + size_t read = 0; + + for (int i = 0; i < 8; i++) { + if (!fgets(temp, sizeof(temp), fp)) { + return 0; + } + + char *tok = strtok(temp, " \t\r\n"); + + for (int j = 0; j < 16; j++) { + if (!tok) { + return 0; + } + + buf[read++] = strtoul(tok, NULL, 16); + tok = strtok(NULL, " \t\r\n"); + } + } + + return read; +} + +size_t +ddc_load_edid(char *path, uint8_t *buf, size_t size) +{ + FILE *fp = fopen(path, "rb"); + size_t offset = 0; + uint8_t temp[64]; + + if (!fp) { + return 0; + } + + // Check the beginning of the file for the EDID header. + uint64_t header; + fread(&header, sizeof(header), 1, fp); + + if (header == EDID_HEADER) { + // Binary format. Read as is + fseek(fp, 0, SEEK_SET); + offset = fread(buf, 1, size, fp); + + fclose(fp); + return offset; + } + + // Reopen in text mode. + fclose(fp); + fp = fopen(path, "rt"); + + if (!fp) { + return 0; + } + + // Skip the UTF-8 BOM, if any. + if (fread(temp, 1, 3, fp) != 3) { + fclose(fp); + return 0; + }; + + if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF) { + fseek(fp, -3, SEEK_CUR); + } + + // Find the `edid-decode (hex):` header + do { + if (!fgets(temp, sizeof(temp), fp)) { + fclose(fp); + return 0; + } + } while (strncmp(temp, EDID_DECODE_HEADER, sizeof(EDID_DECODE_HEADER) - 1)); + + while (offset + EDID_BLOCK_SIZE <= size) { + // Skip any whitespace before the next block + do { + if (!fgets(temp, sizeof(temp), fp)) { + fclose(fp); + return offset; + } + } while (strspn(temp, " \t\r\n") == strlen(temp)); + + fseek(fp, -strlen(temp), SEEK_CUR); + + // Read the block + size_t block = read_block(fp, buf + offset); + + if (block != EDID_BLOCK_SIZE) { + break; + } + + offset += block; + } + + fclose(fp); + return offset; +} From 33c0f2eba87231bcb04350204e297a1fcfd0cbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:42:29 +0200 Subject: [PATCH 24/46] Fix --- src/video/vid_ddc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index aeaba3965..ba6ac2a6d 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -278,7 +278,7 @@ ddc_init_with_custom_edid(char *edid_path, void *i2c) uint8_t *edid_bytes = malloc(size); memcpy(edid_bytes, buffer, size); - return i2c_eeprom_init(i2c, 0x50, edid_bytes, size); + return i2c_eeprom_init(i2c, 0x50, edid_bytes, size, 0); } void * @@ -293,7 +293,7 @@ ddc_init(void *i2c) } uint8_t *edid_bytes; - size_t edid_size = ddc_generate_default_edid(&edid_bytes); + size_t edid_size = ddc_create_default_edid(&edid_bytes); return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } From 5fa1c1715447eac9d685c16ecabdc2407eb60a1b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Sep 2025 22:13:37 +0200 Subject: [PATCH 25/46] LPT: Impelement ECP FIFO test mode, fixes printing in ECP mode on the ASUS P/I-P55T2P4. --- src/device/lpt.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/device/lpt.c b/src/device/lpt.c index 268e4200e..f7cc6eda0 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -236,7 +236,7 @@ lpt_fifo_out_callback(void *priv) { lpt_t *dev = (lpt_t *) priv; - switch (dev->state) { + if ((dev->ecr & 0xe0) != 0xc0) switch (dev->state) { default: break; @@ -281,7 +281,7 @@ lpt_fifo_out_callback(void *priv) } } - if (dev->ecr & 0x08) { + if (((dev->ecr & 0xe0) != 0xc0) && (dev->ecr & 0x08)) { if (fifo_get_empty(dev->fifo)) { if (dev->dma_stat) { /* Now actually set the external flag. */ @@ -319,7 +319,8 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) switch (port & mask) { case 0x0000: if (dev->ecp) { - if (((dev->ecr & 0xe0) == 0x40) || ((dev->ecr & 0xe0) == 0x60)) + if (((dev->ecr & 0xe0) == 0x40) || ((dev->ecr & 0xe0) == 0x60) || + ((dev->ecr & 0xe0) == 0xc0)) /* AFIFO */ lpt_write_fifo(dev, val, 0x00); else if (!(dev->ecr & 0xc0) && (!(dev->ecr & 0x20) || !(lpt_get_ctrl_raw(dev) & 0x20)) && @@ -398,18 +399,13 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) switch (dev->ecr >> 5) { default: break; - case 2: + case 2: case 6: lpt_write_fifo(dev, val, 0x01); break; case 3: if (!(lpt_get_ctrl_raw(dev) & 0x20)) lpt_write_fifo(dev, val, 0x01); break; - case 6: - /* TFIFO */ - if (!fifo_get_full(dev->fifo)) - fifo_write_evt(val, dev->fifo); - break; } break; @@ -424,7 +420,8 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); } else { dev->state = LPT_STATE_WRITE_FIFO; - if (((dev->ecr & 0xe0) == 0x40) || (lpt_get_ctrl_raw(dev) & 0x20)) + if (((dev->ecr & 0xe0) == 0x40) || ((dev->ecr & 0xe0) == 0xc0) || + (lpt_get_ctrl_raw(dev) & 0x20)) dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; else dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; @@ -463,7 +460,8 @@ lpt_fifo_d_ready_evt(void *priv) lpt_t *dev = (lpt_t *) priv; if (!(dev->ecr & 0x08)) { - if (((dev->ecr & 0xe0) == 0x40) || (lpt_get_ctrl_raw(dev) & 0x20)) + if (((dev->ecr & 0xe0) == 0xc0) || ((dev->ecr & 0xe0) == 0x40) || + (lpt_get_ctrl_raw(dev) & 0x20)) dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; else dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; @@ -482,11 +480,13 @@ lpt_write_to_fifo(void *priv, const uint8_t val) dev->dat = val; else if (((dev->ecr & 0xe0) == 0x40) && !fifo_get_full(dev->fifo)) fifo_write_evt_tagged(0x01, val, dev->fifo); + else if (((dev->ecr & 0xe0) == 0xc0) && !fifo_get_full(dev->fifo)) + fifo_write_evt_tagged(0x01, val, dev->fifo); else if (((dev->ecr & 0xe0) == 0x60) && (lpt_get_ctrl_raw(dev) & 0x20) && !fifo_get_full(dev->fifo)) fifo_write_evt_tagged(0x01, val, dev->fifo); - if (((dev->ecr & 0x0c) == 0x08) && (dev->dma != 0xff)) { + if (((dev->ecr & 0xe0) != 0xc0) && ((dev->ecr & 0x0c) == 0x08) && (dev->dma != 0xff)) { const int ret = dma_channel_write(dev->dma, val); if (ret & DMA_OVER) @@ -565,7 +565,16 @@ lpt_read(const uint16_t port, void *priv) switch (port & mask) { case 0x0000: if (dev->ecp) { - if (!(dev->ecr & 0xc0)) + if (dev->ecr & 0xc0) { + if (((dev->ecr & 0xe0) == 0xc0) && !fifo_get_empty(dev->fifo)) { + uint8_t tag = 0x00; + ret = fifo_read_evt_tagged(&tag, dev->fifo); + } else if (((dev->ecr & 0xe0) == 0x60) && !(lpt_get_ctrl_raw(dev) & 0x20) && + !fifo_get_empty(dev->fifo)) { + uint8_t tag = 0x00; + ret = fifo_read_evt_tagged(&tag, dev->fifo); + } + } else ret = dev->dat; } else { /* DTR */ From b5e3710ac27bb19dbc3992700d200d1caa759ee9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Sep 2025 22:14:39 +0200 Subject: [PATCH 26/46] Winbond W83877F: Set ECP IRQ readout from the correct register. --- src/sio/sio_w83877.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sio/sio_w83877.c b/src/sio/sio_w83877.c index 32e7a4bc8..a7a2b4ea2 100644 --- a/src/sio/sio_w83877.c +++ b/src/sio/sio_w83877.c @@ -202,7 +202,7 @@ w83877_lpt_handler(w83877_t *dev) lpt_port_irq(dev->lpt, lpt_irq); lpt_port_dma(dev->lpt, dev->dma_map[dev->regs[0x26] & 0x03]); - lpt_set_cnfgb_readout(dev->lpt, ((dev->regs[0x26] & 0xe0) >> 2) | 0x07); + lpt_set_cnfgb_readout(dev->lpt, ((dev->regs[0x27] & 0xe0) >> 2) | 0x07); } static void From c351d5cbee5347f9113cb97a5c5f3d1756705d51 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 1 Sep 2025 23:48:50 +0200 Subject: [PATCH 27/46] MDS loader: actually honor the fread() return value, fixes CLang warnings. --- src/cdrom/cdrom_image.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 44f45bdc4..816a563d8 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -1975,7 +1975,8 @@ image_load_mds(cd_image_t *img, const char *mdsfile) success = 2; fseek(fp, 0, SEEK_SET); - fread(&mds_hdr, 1, sizeof(mds_hdr_t), fp); + if (fread(&mds_hdr, 1, sizeof(mds_hdr_t), fp) != sizeof(mds_hdr_t)) + return 0; if (memcmp(mds_hdr.file_sig, "MEDIA DESCRIPTOR", 16)) { #ifdef ENABLE_IMAGE_LOG @@ -2004,12 +2005,14 @@ image_load_mds(cd_image_t *img, const char *mdsfile) if (img->is_dvd) { if (mds_hdr.disc_struct_offs != 0x00) { fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET); - fread(&(img->dstruct.layers[0]), 1, sizeof(layer_t), fp); + if (fread(&(img->dstruct.layers[0]), 1, sizeof(layer_t), fp) != sizeof(layer_t)) + return 0; img->has_dstruct = 1; if (((img->dstruct.layers[0].f0[2] & 0x60) >> 4) == 0x01) { fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET); - fread(&(img->dstruct.layers[1]), 1, sizeof(layer_t), fp); + if (fread(&(img->dstruct.layers[1]), 1, sizeof(layer_t), fp) != sizeof(layer_t)) + return 0; img->has_dstruct++; } } @@ -2043,14 +2046,17 @@ image_load_mds(cd_image_t *img, const char *mdsfile) if (mds_hdr.dpm_blocks_offs != 0x00) { fseek(fp, mds_hdr.dpm_blocks_offs, SEEK_SET); - fread(&mds_dpm_blocks_num, 1, sizeof(uint32_t), fp); + if (fread(&mds_dpm_blocks_num, 1, sizeof(uint32_t), fp) != sizeof(uint32_t)) + return 0; if (mds_dpm_blocks_num > 0) for (int b = 0; b < mds_dpm_blocks_num; b++) { fseek(fp, mds_hdr.dpm_blocks_offs + 4 + (b * 4), SEEK_SET); - fread(&mds_dpm_block_offs, 1, sizeof(uint32_t), fp); + if (fread(&mds_dpm_block_offs, 1, sizeof(uint32_t), fp) != sizeof(uint32_t)) + return 0; fseek(fp, mds_dpm_block_offs, SEEK_SET); - fread(&mds_dpm_block, 1, sizeof(mds_dpm_block_t), fp); + if (fread(&mds_dpm_block, 1, sizeof(mds_dpm_block_t), fp) != sizeof(mds_dpm_block_t)) + return 0; /* We currently only support the bad sectors block and not (yet) actual DPM. */ if (mds_dpm_block.type == 0x00000002) { @@ -2058,7 +2064,9 @@ image_load_mds(cd_image_t *img, const char *mdsfile) img->bad_sectors_num = mds_dpm_block.entries; img->bad_sectors = (uint32_t *) malloc(img->bad_sectors_num * sizeof(uint32_t)); fseek(fp, mds_dpm_block_offs + sizeof(mds_dpm_block_t), SEEK_SET); - fread(img->bad_sectors, 1, img->bad_sectors_num * sizeof(uint32_t), fp); + int read_size = img->bad_sectors_num * sizeof(uint32_t); + if (fread(img->bad_sectors, 1, read_size, fp) != read_size) + return 0; break; } } @@ -2066,11 +2074,13 @@ image_load_mds(cd_image_t *img, const char *mdsfile) for (int s = 0; s < mds_hdr.sess_num; s++) { fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_sess_block_t)), SEEK_SET); - fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp); + if (fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp) != sizeof(mds_sess_block_t)) + return 0; for (int t = 0; t < mds_sess_block.all_blocks_num; t++) { fseek(fp, mds_sess_block.trk_blocks_offs + (t * sizeof(mds_trk_block_t)), SEEK_SET); - fread(&mds_trk_block, 1, sizeof(mds_trk_block_t), fp); + if (fread(&mds_trk_block, 1, sizeof(mds_trk_block_t), fp) != sizeof(mds_trk_block_t)) + return 0; if (last_t != -1) { /* @@ -2097,7 +2107,8 @@ image_load_mds(cd_image_t *img, const char *mdsfile) mds_trk_ex_block.trk_sectors = mds_trk_block.ex_offs; } else if (mds_trk_block.ex_offs != 0ULL) { fseek(fp, mds_trk_block.ex_offs, SEEK_SET); - fread(&mds_trk_ex_block, 1, sizeof(mds_trk_ex_block), fp); + if (fread(&mds_trk_ex_block, 1, sizeof(mds_trk_ex_block), fp) != sizeof(mds_trk_ex_block)) + return 0; } uint32_t astart = mds_trk_block.start_sect - mds_trk_ex_block.pregap; @@ -2107,20 +2118,23 @@ image_load_mds(cd_image_t *img, const char *mdsfile) if (mds_trk_block.footer_offs != 0ULL) for (uint32_t ff = 0; ff < mds_trk_block.files_num; ff++) { fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_footer_t)), SEEK_SET); - fread(&mds_footer, 1, sizeof(mds_footer_t), fp); + if (fread(&mds_footer, 1, sizeof(mds_footer_t), fp) != sizeof(mds_footer_t)) + return 0; uint16_t wfn[2048] = { 0 }; char fn[2048] = { 0 }; fseek(fp, mds_footer.fn_offs, SEEK_SET); if (mds_footer.fn_is_wide) { for (int i = 0; i < 256; i++) { - fread(&(wfn[i]), 1, 2, fp); + if (fread(&(wfn[i]), 1, 2, fp) != 2) + return 0; if (wfn[i] == 0x0000) break; } (void) utf16_to_utf8(wfn, 2048, (uint8_t *) fn, 2048); } else for (int i = 0; i < 512; i++) { - fread(&fn[i], 1, 1, fp); + if (fread(&fn[i], 1, 1, fp) != 1) + return 0; if (fn[i] == 0x00) break; } From 948e18945ba74cce09243ebe8a2b77844b714012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 00:06:41 +0200 Subject: [PATCH 28/46] Fix seeking in text mode --- src/video/vid_ddc_custom.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_custom.c index 4b8e300e5..e17f7a037 100644 --- a/src/video/vid_ddc_custom.c +++ b/src/video/vid_ddc_custom.c @@ -40,6 +40,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) FILE *fp = fopen(path, "rb"); size_t offset = 0; uint8_t temp[64]; + long pos; if (!fp) { return 0; @@ -66,6 +67,12 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) return 0; } +#ifdef _WIN32 + // Disable buffering on Windows because of a UCRT bug. + // https://developercommunity.visualstudio.com/t/fseek-ftell-fail-in-text-mode-for-unix-style-text/425878 + setvbuf(fp, NULL, _IONBF, 0); +#endif + // Skip the UTF-8 BOM, if any. if (fread(temp, 1, 3, fp) != 3) { fclose(fp); @@ -73,10 +80,10 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) }; if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF) { - fseek(fp, -3, SEEK_CUR); + rewind(fp); } - // Find the `edid-decode (hex):` header + // Find the `edid-decode (hex):` header. do { if (!fgets(temp, sizeof(temp), fp)) { fclose(fp); @@ -85,17 +92,18 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) } while (strncmp(temp, EDID_DECODE_HEADER, sizeof(EDID_DECODE_HEADER) - 1)); while (offset + EDID_BLOCK_SIZE <= size) { - // Skip any whitespace before the next block + // Skip any whitespace before the next block. do { + pos = ftell(fp); if (!fgets(temp, sizeof(temp), fp)) { fclose(fp); return offset; } } while (strspn(temp, " \t\r\n") == strlen(temp)); - fseek(fp, -strlen(temp), SEEK_CUR); + fseek(fp, pos, SEEK_SET); - // Read the block + // Read the block. size_t block = read_block(fp, buf + offset); if (block != EDID_BLOCK_SIZE) { From 8ab80ca26f768606638fd6c1075e75e06ffb6275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 00:18:36 +0200 Subject: [PATCH 29/46] Fix sign warnings --- src/video/vid_ddc_custom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_custom.c index e17f7a037..d042bdf61 100644 --- a/src/video/vid_ddc_custom.c +++ b/src/video/vid_ddc_custom.c @@ -11,7 +11,7 @@ static size_t read_block(FILE *fp, uint8_t *buf) { - uint8_t temp[64]; + char temp[64]; size_t read = 0; for (int i = 0; i < 8; i++) { @@ -39,7 +39,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) { FILE *fp = fopen(path, "rb"); size_t offset = 0; - uint8_t temp[64]; + char temp[64]; long pos; if (!fp) { From 37a1aaa72130bc4c78cc4463080a47799d2d5f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 00:30:05 +0200 Subject: [PATCH 30/46] Rename file, add copyright header --- src/video/CMakeLists.txt | 2 +- ...vid_ddc_custom.c => vid_ddc_edid_custom.c} | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) rename src/video/{vid_ddc_custom.c => vid_ddc_edid_custom.c} (82%) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 4667a3b4f..98a9cb385 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -44,7 +44,7 @@ add_library(vid OBJECT # DDC / monitor identification stuff vid_ddc.c - vid_ddc_custom.c + vid_ddc_edid_custom.c # CARDS start here diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_edid_custom.c similarity index 82% rename from src/video/vid_ddc_custom.c rename to src/video/vid_ddc_edid_custom.c index d042bdf61..de037b85e 100644 --- a/src/video/vid_ddc_custom.c +++ b/src/video/vid_ddc_edid_custom.c @@ -1,3 +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. + * + * Custom monitor EDID file loader. + * + * + * + * Authors: Cacodemon345, + * David Hrdlička, + * + * Copyright 2025 Cacodemon. + * Copyright 2025 David Hrdlička. + */ + #include #include #include From 54fc345ee5dc9bff0a11af556275113c8152fdae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 10:28:58 +0200 Subject: [PATCH 31/46] Fix warning --- src/video/vid_ddc_edid_custom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ddc_edid_custom.c b/src/video/vid_ddc_edid_custom.c index de037b85e..2febde67e 100644 --- a/src/video/vid_ddc_edid_custom.c +++ b/src/video/vid_ddc_edid_custom.c @@ -98,7 +98,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) return 0; }; - if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF) { + if ((uint8_t) temp[0] != 0xEF || (uint8_t) temp[1] != 0xBB || (uint8_t) temp[2] != 0xBF) { rewind(fp); } From 766734eb3aef059bae95932c7f25699370544ddb Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:36:41 +0200 Subject: [PATCH 32/46] 386DX: Force external cache enabled to improve performance. --- src/cpu/cpu.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ec026d95e..f169f0f3f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1080,6 +1080,9 @@ cpu_set(void) timing_jmp_rm = 12; timing_jmp_pm = 27; timing_jmp_pm_gate = 45; + + if (cpu_s->cpu_type == CPU_386DX) + cpu_cache_ext_enabled = 1; break; case CPU_486SLC: @@ -1161,6 +1164,9 @@ cpu_set(void) timing_jmp_pm_gate = 37; timing_misaligned = 3; + + if (cpu_s->cpu_type == CPU_386DX) + cpu_cache_ext_enabled = 1; break; case CPU_i486SX_SLENH: @@ -4473,13 +4479,6 @@ cpu_update_waitstates(void) if (cpu_cache_int_enabled) { /* Disable prefetch emulation */ cpu_prefetch_cycles = 0; - } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates + 1; - cpu_cycles_read = cpu_waitstates + 1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); - cpu_cycles_write = cpu_waitstates + 1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else if (cpu_cache_ext_enabled) { /* Use cache timings */ cpu_prefetch_cycles = cpu_s->cache_read_cycles; @@ -4487,6 +4486,13 @@ cpu_update_waitstates(void) cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; cpu_cycles_write = cpu_s->cache_write_cycles; cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; + } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { + /* Waitstates override */ + cpu_prefetch_cycles = cpu_waitstates + 1; + cpu_cycles_read = cpu_waitstates + 1; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); + cpu_cycles_write = cpu_waitstates + 1; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else { /* Use memory timings */ cpu_prefetch_cycles = cpu_s->mem_read_cycles; From b825aed242923d0c24730198bf2b843fd64b80fa Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:41:30 +0200 Subject: [PATCH 33/46] 386DX: Fix cache defaults to be the equivalent of 0 wait states. --- src/cpu/cpu_table.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index db8c89ebb..516de061c 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1367,8 +1367,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 3, .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 2 }, { @@ -1384,8 +1384,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1401,8 +1401,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1418,8 +1418,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1435,8 +1435,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -1461,8 +1461,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 3, .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 2 }, { @@ -1478,8 +1478,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1495,8 +1495,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { .name = "", 0 } @@ -1521,8 +1521,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1538,8 +1538,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1555,8 +1555,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -1581,8 +1581,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1598,8 +1598,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1615,8 +1615,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } From c5be7e9261a0bd9f5bc002941a13f2a7a4986177 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:45:01 +0200 Subject: [PATCH 34/46] More fixed and disabled the wait states selection on 386DX. --- src/cpu/cpu_table.c | 10 +++++----- src/qt/qt_settingsmachine.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 516de061c..3adbc7202 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -2096,7 +2096,7 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, + .cache_read_cycles = 2, .cache_write_cycles = 3, .atclk_div = 3 }, @@ -2113,8 +2113,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -2130,8 +2130,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 0063ac727..e52553196 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -281,7 +281,7 @@ SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) int cpuId = ui->comboBoxSpeed->currentData().toInt(); uint cpuType = cpuFamily->cpus[cpuId].cpu_type; - if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { + if ((cpuType >= CPU_286) && (cpuType < CPU_386DX)) { ui->comboBoxWaitStates->setEnabled(true); ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates); } else { From 5a2f9eacbf67829faa931731c1519d09895a4ea1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:46:12 +0200 Subject: [PATCH 35/46] And another fix. --- src/cpu/cpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index f169f0f3f..ff806297e 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1165,8 +1165,7 @@ cpu_set(void) timing_misaligned = 3; - if (cpu_s->cpu_type == CPU_386DX) - cpu_cache_ext_enabled = 1; + cpu_cache_ext_enabled = 1; break; case CPU_i486SX_SLENH: From d8b7b258202c9f23c92a90af60708485dd188de6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 22:47:13 +0200 Subject: [PATCH 36/46] Rename MGA DMA states to MGA_DMA_STATE in preparation for the 6.0 CPU rewrite. --- src/video/vid_mga.c | 70 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index eded49cf6..7fdc04e9e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -424,9 +424,9 @@ enum { }; enum { - DMA_STATE_IDLE = 0, - DMA_STATE_PRI, - DMA_STATE_SEC + MGA_DMA_STATE_IDLE = 0, + MGA_DMA_STATE_PRI, + MGA_DMA_STATE_SEC }; typedef struct { @@ -1600,7 +1600,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) case REG_STATUS + 2: ret = (mystique->status >> 16) & 0xff; if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY - || mystique->dma.state != DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) + || mystique->dma.state != MGA_DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) ret |= (STATUS_DWGENGSTS >> 16); break; case REG_STATUS + 3: @@ -2179,7 +2179,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_OPMODE: thread_wait_mutex(mystique->dma.lock); - mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ + mystique->dma.state = MGA_DMA_STATE_IDLE; /* Interrupt DMA. */ thread_release_mutex(mystique->dma.lock); mystique->dmamod = (val >> 2) & 3; mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); @@ -2200,10 +2200,10 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; - if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { mystique->dma.words_expected = 0; } - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; thread_release_mutex(mystique->dma.lock); break; @@ -2240,7 +2240,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); mystique->dma.pri_state = 0; mystique->dma.sec_state = 0; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; thread_release_mutex(mystique->dma.lock); break; @@ -2599,12 +2599,12 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_SECEND: mystique->dma.secend = val; - if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) - mystique->dma.state = DMA_STATE_SEC; + if (mystique->dma.state != MGA_DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) + mystique->dma.state = MGA_DMA_STATE_SEC; break; case REG_SOFTRAP: - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; @@ -2683,11 +2683,11 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) thread_wait_mutex(mystique->dma.lock); mystique->dma.primend = val; //pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend); - if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 0; mystique->status &= ~STATUS_ENDPRDMASTS; - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } @@ -2699,7 +2699,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) { mystique->dma.primaddress = mystique->dma.primend; mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; } thread_release_mutex(mystique->dma.lock); break; @@ -2935,7 +2935,7 @@ run_dma(mystique_t *mystique) return; } - if (mystique->dma.state == DMA_STATE_IDLE) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE) { if (!(mystique->status & STATUS_ENDPRDMASTS)) { /* Force this to appear. */ @@ -2945,14 +2945,14 @@ run_dma(mystique_t *mystique) return; } - while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { + while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != MGA_DMA_STATE_IDLE) { switch (atomic_load(&mystique->dma.state)) { - case DMA_STATE_PRI: + case MGA_DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; break; } if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { @@ -2965,7 +2965,7 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; break; } @@ -3000,31 +3000,31 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - if (mystique->dma.state == DMA_STATE_SEC) { + if (mystique->dma.state == MGA_DMA_STATE_SEC) { mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; } break; default: - fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + fatal("MGA_DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); } break; - case DMA_STATE_SEC: + case MGA_DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3039,11 +3039,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3073,11 +3073,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3090,11 +3090,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3110,11 +3110,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3123,7 +3123,7 @@ run_dma(mystique_t *mystique) break; default: - fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + fatal("MGA_DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); } break; @@ -3145,7 +3145,7 @@ fifo_thread(void *priv) thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); - while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { + while (!FIFO_EMPTY || mystique->dma.state != MGA_DMA_STATE_IDLE) { int words_transferred = 0; while (!FIFO_EMPTY && words_transferred < 100) { From 4063ce77398c78ee34ad3a0b80febc72f2042d5d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 23:06:29 +0200 Subject: [PATCH 37/46] Fix two CLang warnings. --- src/qt/qt_vmmanager_main.cpp | 2 +- src/qt/qt_vmmanager_mainwindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index e53e2e407..cc3904e97 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -351,7 +351,7 @@ illegal_chars: } }); - connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [this] () { + connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [] () { vmm_main_window->updateSettings(); }); diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 55e980ec9..f698f1ccd 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -130,7 +130,7 @@ VMManagerMainWindow(QWidget *parent) connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated); #ifdef Q_OS_WINDOWS connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated); - connect(this, &VMManagerMainWindow::preferencesUpdated, [this] () { vmm_dark_mode_filter->reselectDarkMode(); }); + connect(this, &VMManagerMainWindow::preferencesUpdated, [] () { vmm_dark_mode_filter->reselectDarkMode(); }); #endif { From 649f81361426a937f6418b998c77198511da9660 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Sep 2025 00:20:20 +0200 Subject: [PATCH 38/46] AT KBC: Make sure AMI KBC revisions do not support commands they are not supposed to support. --- src/device/kbc_at.c | 75 +++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 4c0ea4155..186804e22 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -975,7 +975,7 @@ write_cmd_data_ami(void *priv, uint8_t val) return 0; case 0xc1: - kbc_at_log("ATkbc: AMI MegaKey - write %02X to P1\n", val); + kbc_at_log("ATkbc: AMI - write %02X to P1\n", val); dev->p1 = val; return 0; @@ -1160,11 +1160,14 @@ write_cmd_ami(void *priv, uint8_t val) case 0xaf: /* set extended controller RAM */ if ((kbc_ven != KBC_VEN_SIEMENS) && (kbc_ven != KBC_VEN_ALI)) { - kbc_at_log("ATkbc: set extended controller RAM\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - dev->command_phase = 1; - ret = 0; + if (((kbc_ami_revision >= 'H') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + kbc_at_log("ATkbc: set extended controller RAM\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + dev->command_phase = 1; + ret = 0; + } } break; @@ -1214,27 +1217,33 @@ write_cmd_ami(void *priv, uint8_t val) break; case 0xc1: /* write P1 */ - kbc_at_log("ATkbc: AMI MegaKey - write P1\n"); + kbc_at_log("ATkbc: AMI - write P1\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; ret = 0; break; case 0xc4: - /* set KBC line P14 low */ - kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) low\n"); - dev->p1 &= 0xef; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P14 low */ + kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) low\n"); + dev->p1 &= 0xef; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xc5: - /* set KBC line P15 low */ - kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); - dev->p1 &= 0xdf; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P15 low */ + kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); + dev->p1 &= 0xdf; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xc8: @@ -1271,20 +1280,26 @@ write_cmd_ami(void *priv, uint8_t val) break; case 0xcc: - /* set KBC line P14 high */ - kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) high\n"); - dev->p1 |= 0x10; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P14 high */ + kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) high\n"); + dev->p1 |= 0x10; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xcd: /* set KBC line P15 high */ - kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); - dev->p1 |= 0x20; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); + dev->p1 |= 0x20; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xef: /* ??? - sent by AMI486 */ From 5f065614694e6e2450a67e25ee110094d47f2c73 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:49:27 +0200 Subject: [PATCH 39/46] EEPROM use changes and misc (September 3rd, 2025) 1.Move the 93cxx EEPROM implementation to the mem directory since it's used by cards which are not nics (e.g.: DC390 SCSI and S3 ELSA cards). 2. DC390 specific: remove the implementation used there and use the generic one from mem (used to be on the network directory) as well as fixing bus reset when interrupts are related. 3. S3: when the 64k size is selected in the LFB, use the SVGA 64k mapping as LFB (0xA0000). --- src/mem/CMakeLists.txt | 1 + .../net_eeprom_nmc93cxx.c => mem/nmc93cxx.c} | 9 +- src/network/CMakeLists.txt | 4 - src/network/net_rtl8139.c | 2 +- src/network/net_tulip.c | 2 +- src/scsi/scsi_pcscsi.c | 276 +++++------------- src/video/vid_s3.c | 9 +- 7 files changed, 90 insertions(+), 213 deletions(-) rename src/{network/net_eeprom_nmc93cxx.c => mem/nmc93cxx.c} (97%) diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 0e52beb4e..3984c2d02 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(mem OBJECT intel_flash.c mem.c mmu_2386.c + nmc93cxx.c rom.c row.c smram.c diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/mem/nmc93cxx.c similarity index 97% rename from src/network/net_eeprom_nmc93cxx.c rename to src/mem/nmc93cxx.c index 05fd43ed0..50905bae2 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -28,7 +28,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/nvr.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_unused.h> #ifdef ENABLE_NMC93CXX_EEPROM_LOG @@ -256,7 +256,12 @@ static void nmc93cxx_eeprom_close(void *priv) { nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv; - free(eeprom); + FILE *fp = nvr_fopen(eeprom->filename, "wb"); + if (fp) { + fwrite(eeprom->dev.data, 2, eeprom->size, fp); + fclose(fp); + } + free(priv); } uint16_t * diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 3f7ba427c..782672e98 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -28,7 +28,6 @@ list(APPEND net_sources net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c @@ -71,9 +70,6 @@ if(NETSWITCH) endif() if (UNIX) - if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set_source_files_properties(net_slirp.c PROPERTIES COMPILE_FLAGS "-I/usr/local/include") - endif() find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) find_library(VDE_LIB vdeplug) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index f1e531deb..41ce86f6b 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include "cpu.h" #include <86box/plat_unused.h> diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 883ba53ad..cbf3b704e 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -31,7 +31,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> #include <86box/bswap.h> diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index f91eef683..04c188705 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -40,11 +40,11 @@ #include <86box/pci.h> #include <86box/device.h> #include <86box/nvr.h> +#include <86box/nmc93cxx.h> #include <86box/plat.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_pcscsi.h> -#include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> #include "cpu.h" @@ -179,7 +179,6 @@ typedef struct esp_t { int BIOSBase; int MMIOBase; rom_t bios; - ati_eeprom_t eeprom; int PCIBase; uint8_t rregs[ESP_REGS]; @@ -223,9 +222,14 @@ typedef struct esp_t { uint8_t irq_state; uint8_t pos_regs[8]; + + uint8_t eeprom_inst; + uint8_t eeprom_data[128]; + + nmc93cxx_eeprom_t *eeprom; } esp_t; -static esp_t reset_state = { 0 }; +static esp_t *reset_state = NULL; #define READ_FROM_DEVICE 1 #define WRITE_TO_DEVICE 0 @@ -1534,19 +1538,19 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_BUSRESET: esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); - if (dev->mca) { - esp_lower_irq(dev); - esp_hard_reset(dev); - } else - esp_pci_soft_reset(dev); - - for (uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - } + if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); + } else { + if (dev->mca) { + esp_lower_irq(dev); + esp_hard_reset(dev); + } else + esp_pci_soft_reset(dev); } break; case CMD_TI: @@ -1994,180 +1998,6 @@ esp_bios_disable(esp_t *dev) #define EE_ADAPT_OPTION_INT13 0x04 #define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 -/*To do: make this separate from the SCSI card*/ -static void -dc390_save_eeprom(esp_t *dev) -{ - FILE *fp = nvr_fopen(dev->nvr_path, "wb"); - if (!fp) - return; - fwrite(dev->eeprom.data, 1, 128, fp); - fclose(fp); -} - -static void -dc390_write_eeprom(esp_t *dev, int ena, int clk, int dat) -{ - /*Actual EEPROM is the same as the one used by the ATI cards, the 93cxx series.*/ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t tick = eeprom->count; - uint8_t eedo = eeprom->out; - uint16_t address = eeprom->address; - uint8_t command = eeprom->opcode; - - esp_log("EEPROM CS=%02x,SK=%02x,DI=%02x,DO=%02x,tick=%d\n", - ena, clk, dat, eedo, tick); - - if (!eeprom->oldena && ena) { - esp_log("EEPROM Start chip select cycle\n"); - tick = 0; - command = 0; - address = 0; - } else if (eeprom->oldena && !ena) { - if (!eeprom->wp) { - uint8_t subcommand = address >> 4; - if (command == 0 && subcommand == 2) { - esp_log("EEPROM Erase All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (command == 3) { - esp_log("EEPROM Erase Word\n"); - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (tick >= 26) { - if (command == 1) { - esp_log("EEPROM Write Word\n"); - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } else if (command == 0 && subcommand == 1) { - esp_log("EEPROM Write All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } - } - } - eedo = 1; - esp_log("EEPROM DO read\n"); - } else if (ena && !eeprom->oldclk && clk) { - if (tick == 0) { - if (dat == 0) { - esp_log("EEPROM Got correct 1st start bit, waiting for 2nd start bit (1)\n"); - tick++; - } else { - esp_log("EEPROM Wrong 1st start bit (is 1, should be 0)\n"); - tick = 2; - } - } else if (tick == 1) { - if (dat != 0) { - esp_log("EEPROM Got correct 2nd start bit, getting command + address\n"); - tick++; - } else { - esp_log("EEPROM 1st start bit is longer than needed\n"); - } - } else if (tick < 4) { - tick++; - command <<= 1; - if (dat) - command += 1; - } else if (tick < 10) { - tick++; - address = (address << 1) | dat; - if (tick == 10) { - esp_log("EEPROM command = %02x, address = %02x (val = %04x)\n", command, - address, eeprom->data[address]); - if (command == 2) - eedo = 0; - address = address % 64; - if (command == 0) { - switch (address >> 4) { - case 0: - esp_log("EEPROM Write disable command\n"); - eeprom->wp = 1; - break; - case 1: - esp_log("EEPROM Write all command\n"); - break; - case 2: - esp_log("EEPROM Erase all command\n"); - break; - case 3: - esp_log("EEPROM Write enable command\n"); - eeprom->wp = 0; - break; - - default: - break; - } - } else { - esp_log("EEPROM Read, write or erase word\n"); - eeprom->dat = eeprom->data[address]; - } - } - } else if (tick < 26) { - tick++; - if (command == 2) { - esp_log("EEPROM Read Word\n"); - eedo = ((eeprom->dat & 0x8000) != 0); - } - eeprom->dat <<= 1; - eeprom->dat += dat; - } else { - esp_log("EEPROM Additional unneeded tick, not processed\n"); - } - } - - eeprom->count = tick; - eeprom->oldena = ena; - eeprom->oldclk = clk; - eeprom->out = eedo; - eeprom->address = address; - eeprom->opcode = command; - esp_log("EEPROM EEDO = %d\n", eeprom->out); -} - -static void -dc390_load_eeprom(esp_t *dev) -{ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t *nvr = (uint8_t *) eeprom->data; - int i; - uint16_t checksum = 0; - FILE *fp; - - eeprom->out = 1; - - fp = nvr_fopen(dev->nvr_path, "rb"); - if (fp) { - esp_log("EEPROM Load\n"); - if (fread(nvr, 1, 128, fp) != 128) - fatal("dc390_eeprom_load(): Error reading data\n"); - fclose(fp); - } else { - for (i = 0; i < 16; i++) { - nvr[i * 2] = 0x57; - nvr[i * 2 + 1] = 0x00; - } - - esp_log("EEPROM Defaults\n"); - - nvr[EE_ADAPT_SCSI_ID] = 7; - nvr[EE_MODE2] = 0x0f; - nvr[EE_TAG_CMD_NUM] = 0x04; - nvr[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; - for (i = 0; i < EE_CHKSUM1; i += 2) { - checksum += ((nvr[i] & 0xff) | (nvr[i + 1] << 8)); - esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, nvr[i]); - } - - checksum = 0x1234 - checksum; - nvr[EE_CHKSUM1] = checksum & 0xff; - nvr[EE_CHKSUM2] = checksum >> 8; - esp_log("EEPROM Checksum = %04x\n", checksum); - } -} - static uint8_t esp_pci_read(UNUSED(int func), int addr, void *priv) { @@ -2181,10 +2011,10 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) if (!dev->has_bios || dev->local) return 0x22; else { - if (dev->eeprom.out) + if (nmc93cxx_eeprom_read(dev->eeprom)) return 0x22; else { - dev->eeprom.out = 1; + dev->eeprom->dev.out = 1; return 2; } } @@ -2270,9 +2100,9 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x80) { eesk = val & 0x80 ? 1 : 0; eedi = val & 0x40 ? 1 : 0; - dc390_write_eeprom(dev, 1, eesk, eedi); + nmc93cxx_eeprom_write(dev->eeprom, 1, eesk, eedi); } else if (addr == 0xc0) - dc390_write_eeprom(dev, 0, 0, 0); + nmc93cxx_eeprom_write(dev->eeprom, 0, 0, 0); // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); return; } @@ -2371,26 +2201,35 @@ esp_pci_reset(void *priv) { esp_t *dev = (esp_t *) priv; - timer_disable(&dev->timer); + if (reset_state != NULL) { + esp_io_remove(dev, dev->PCIBase, 0x80); + esp_bios_disable(dev); + timer_stop(&dev->timer); - reset_state.bios.mapping = dev->bios.mapping; + reset_state->bios.mapping = dev->bios.mapping; + reset_state->timer = dev->timer; + reset_state->pci_slot = dev->pci_slot; - reset_state.timer = dev->timer; + *dev = *reset_state; - reset_state.pci_slot = dev->pci_slot; - - memcpy(dev, &reset_state, sizeof(esp_t)); - - esp_pci_soft_reset(dev); + esp_pci_soft_reset(dev); + esp_log("PCI Reset.\n"); + } } static void * dc390_init(const device_t *info) { esp_t *dev = calloc(1, sizeof(esp_t)); + reset_state = calloc(1, sizeof(esp_t)); const char *bios_rev = NULL; uint32_t mask = 0; uint32_t size = 0x8000; + nmc93cxx_eeprom_params_t params; + char eeprom_filename[1024] = { 0 }; + char filename[1024] = { 0 }; + uint16_t checksum = 0x0000; + uint8_t i; dev->bus = scsi_get_bus(); @@ -2434,10 +2273,40 @@ dc390_init(const device_t *info) esp_bios_disable(dev); if (!dev->local) { - sprintf(dev->nvr_path, "dc390_%i.nvr", device_get_instance()); + dev->eeprom_inst = device_get_instance(); + + snprintf(eeprom_filename, sizeof(eeprom_filename), "dc390_%d.nvr", dev->eeprom_inst); /* Load the serial EEPROM. */ - dc390_load_eeprom(dev); + for (i = 0; i < 16; i++) { + dev->eeprom_data[i * 2] = 0x57; + dev->eeprom_data[i * 2 + 1] = 0x00; + } + + esp_log("EEPROM Defaults\n"); + + dev->eeprom_data[EE_ADAPT_SCSI_ID] = 7; + dev->eeprom_data[EE_MODE2] = 0x0f; + dev->eeprom_data[EE_TAG_CMD_NUM] = 0x04; + dev->eeprom_data[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; + for (i = 0; i < EE_CHKSUM1; i += 2) { + checksum += ((dev->eeprom_data[i] & 0xff) | (dev->eeprom_data[i + 1] << 8)); + esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, dev->eeprom_data[i]); + } + + checksum = 0x1234 - checksum; + dev->eeprom_data[EE_CHKSUM1] = checksum & 0xff; + dev->eeprom_data[EE_CHKSUM2] = checksum >> 8; + + params.nwords = 64; + params.default_content = (uint16_t *) dev->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, dev->eeprom_inst); + dev->eeprom = device_add_inst_params(&nmc93cxx_device, dev->eeprom_inst, ¶ms); + if (dev->eeprom == NULL) { + free(dev); + return NULL; + } } esp_pci_hard_reset(dev); @@ -2449,7 +2318,7 @@ dc390_init(const device_t *info) scsi_bus_set_speed(dev->bus, 10000000.0); - memcpy(&reset_state, dev, sizeof(esp_t)); + *reset_state = *dev; return dev; } @@ -2622,7 +2491,7 @@ ncr53c9x_mca_init(const device_t *info) fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4f; /* MCA board ID */ + dev->pos_regs[0] = 0x4d; /* MCA board ID */ dev->pos_regs[1] = 0x7f; mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); @@ -2646,6 +2515,11 @@ esp_close(void *priv) fifo8_destroy(&dev->fifo); fifo8_destroy(&dev->cmdfifo); + if (reset_state != NULL) { + free(reset_state); + reset_state = NULL; + } + free(dev); dev = NULL; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 943441f1c..fbf329e84 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -33,7 +33,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/rom.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include <86box/plat.h> #include <86box/thread.h> @@ -4807,10 +4807,10 @@ s3_updatemapping(s3_t *s3) break; } s3->linear_base &= ~(s3->linear_size - 1); - if (s3->linear_base == 0xa0000) { + if ((s3->linear_base == 0xa0000) || (s3->linear_size == 0x10000)) { mem_mapping_disable(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } } else { @@ -5071,6 +5071,7 @@ s3_accel_in(uint16_t port, void *priv) if (FIFO_FULL) temp = 0xff; } + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x8119: case 0x9949: @@ -5127,7 +5128,7 @@ s3_accel_in(uint16_t port, void *priv) s3->data_available = 0; } } - s3_log("FIFO Status Temp=%02x.\n", temp); + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x9d48: From 7e490d53403c03f8ef0e2adaa474783bbb1a2b5c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:50:01 +0200 Subject: [PATCH 40/46] Forgot the header. --- src/include/86box/{net_eeprom_nmc93cxx.h => nmc93cxx.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/include/86box/{net_eeprom_nmc93cxx.h => nmc93cxx.h} (100%) diff --git a/src/include/86box/net_eeprom_nmc93cxx.h b/src/include/86box/nmc93cxx.h similarity index 100% rename from src/include/86box/net_eeprom_nmc93cxx.h rename to src/include/86box/nmc93cxx.h From 5618dba9d1a75c8f652111a63358c7427f42a2c0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:53:26 +0200 Subject: [PATCH 41/46] Restore FreeBSD stuff that was removed accidentally --- src/network/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 782672e98..0943a9258 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -70,6 +70,9 @@ if(NETSWITCH) endif() if (UNIX) + if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set_source_files_properties(net_slirp.c PROPERTIES COMPILE_FLAGS "-I/usr/local/include") + endif() find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) find_library(VDE_LIB vdeplug) From 15231c19aa887c44a2bbd7c5a89e2ab166377c98 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Sep 2025 00:56:12 +0200 Subject: [PATCH 42/46] Config: Save and restore the full screen state if window size and position is set to be remembered. --- src/config.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/config.c b/src/config.c index 9fce92ded..adb5069cf 100644 --- a/src/config.c +++ b/src/config.c @@ -211,6 +211,8 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); + start_in_fullscreen = ini_section_get_int(cat, "start_in_fullscreen", 0); + window_remember = ini_section_get_int(cat, "window_remember", 0); if (!window_remember && !(vid_resize & 2)) @@ -2410,6 +2412,11 @@ save_general(void) else ini_section_delete_var(cat, "window_remember"); + if (video_fullscreen) + ini_section_set_int(cat, "start_in_fullscreen", video_fullscreen); + else + ini_section_delete_var(cat, "start_in_fullscreen"); + if (vid_resize & 2) { sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y); ini_section_set_string(cat, "window_fixed_res", temp); From f4f39f28588d84d3589d7852b85b4d765bb19ccd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Sep 2025 17:21:19 -0300 Subject: [PATCH 43/46] SLiRP: Force resetting of the range number --- src/include/86box/network.h | 1 + src/network/net_slirp.c | 5 ++--- src/network/network.c | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 01454c6f9..5a6651b5b 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -105,6 +105,7 @@ typedef struct netcard_conf_t { extern netcard_conf_t net_cards_conf[NET_CARD_MAX]; extern uint16_t net_card_current; +extern int slirp_card_num; typedef int (*NETRXCB)(void *, uint8_t *, int); typedef int (*NETSETLINKSTATE)(void *, uint32_t link_state); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index e8cfd6cd7..9d8231034 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -470,13 +470,13 @@ net_slirp_thread(void *priv) } #endif -static int slirp_card_num = 2; +int slirp_card_num = 2; /* Initialize SLiRP for use. */ void * net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), char *netdrv_errbuf) { - slirp_log("SLiRP: initializing...\n"); + pclog("SLiRP: initializing with range %d...\n", slirp_card_num); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr)); slirp->card = (netcard_t *) card; @@ -639,7 +639,6 @@ net_slirp_close(void *priv) } free(slirp->pkt.data); free(slirp); - slirp_card_num--; } const netdrv_t net_slirp_drv = { diff --git a/src/network/network.c b/src/network/network.c index 9b56515e8..661da7250 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -608,6 +608,7 @@ network_reset(void) ui_sb_update_icon(SB_NETWORK, 0); ui_sb_update_icon_write(SB_NETWORK, 0); + slirp_card_num = 2; #ifdef ENABLE_NETWORK_LOG network_dump_mutex = thread_create_mutex(); #endif From d4f53316077abe14dd494e5bb6a86b2e9193084b Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Sep 2025 17:38:49 -0300 Subject: [PATCH 44/46] Fix full screen command line parameter --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index adb5069cf..d3bc0c2de 100644 --- a/src/config.c +++ b/src/config.c @@ -211,7 +211,7 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); - start_in_fullscreen = ini_section_get_int(cat, "start_in_fullscreen", 0); + start_in_fullscreen |= ini_section_get_int(cat, "start_in_fullscreen", 0); window_remember = ini_section_get_int(cat, "window_remember", 0); From bb95ffaf5f130f5beec88d4116beb46cb31d8f3f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Sep 2025 20:41:49 -0300 Subject: [PATCH 45/46] SLiRP: Remove extraneous log [skip ci] --- src/network/net_slirp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 9d8231034..9bf1f63d4 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -476,7 +476,7 @@ int slirp_card_num = 2; void * net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), char *netdrv_errbuf) { - pclog("SLiRP: initializing with range %d...\n", slirp_card_num); + slirp_log("SLiRP: initializing with range %d...\n", slirp_card_num); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr)); slirp->card = (netcard_t *) card; From 65c7dfb2eed2cab535de32a19220870d7f6d2f79 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 6 Sep 2025 02:53:30 -0500 Subject: [PATCH 46/46] Fix dynamic SCSI buffer window sizing causing SEGV --- src/include/86box/scsi_disk.h | 1 + src/scsi/scsi_disk.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index 293cc35e6..2d2371172 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -29,6 +29,7 @@ typedef struct scsi_disk_t { void * log; uint8_t * temp_buffer; + size_t temp_buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 8c09a30a1..bfa8b42cf 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -623,8 +623,15 @@ static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->temp_buffer == NULL) + if (dev->temp_buffer == NULL) { dev->temp_buffer = (uint8_t *) malloc(len); + dev->temp_buffer_sz = len; + } + if (len > dev->temp_buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->temp_buffer, len); + dev->temp_buffer = buf; + dev->temp_buffer_sz = len; + } } static void