mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge branch 'master' into feature/cdrom-ioctl
This commit is contained in:
@@ -12,3 +12,4 @@ libslirp
|
||||
fluidsynth
|
||||
qt5-static
|
||||
qt5-translations
|
||||
vulkan-headers
|
||||
|
||||
@@ -5,34 +5,11 @@ indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
||||
# Disabled for now since not all editors support setting a tab_width value different from indent_size
|
||||
# Relevant VSCode extension issue: https://github.com/editorconfig/editorconfig-vscode/issues/190
|
||||
# [*.rc]
|
||||
# indent_style = space
|
||||
# indent_size = 4
|
||||
# tab_width = 4
|
||||
|
||||
# [Makefile.*]
|
||||
# indent_style = space
|
||||
# indent_size = 4
|
||||
# tab_width = 4
|
||||
|
||||
[*.manifest]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[**/CMakeLists.txt]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.cmake]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
[*.ui]
|
||||
indent_size = 1
|
||||
|
||||
16
.gitattributes
vendored
16
.gitattributes
vendored
@@ -3,12 +3,28 @@
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
# Code
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cpp text
|
||||
*.h text
|
||||
*.hpp text
|
||||
|
||||
# CMake scripts
|
||||
CMakeLists.txt text
|
||||
*.cmake text
|
||||
|
||||
# Windows resource scripts and manifests
|
||||
*.rc text
|
||||
*.manifest text
|
||||
|
||||
# Translation files
|
||||
*.po text
|
||||
|
||||
# Qt XML files
|
||||
*.ui text
|
||||
*.ts text
|
||||
*.qrc text
|
||||
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
|
||||
114
.github/workflows/c-cpp.yml
vendored
114
.github/workflows/c-cpp.yml
vendored
@@ -1,114 +0,0 @@
|
||||
name: MSYS2 Makefile
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- .github/workflows/c-cpp.yml
|
||||
- "!**/CMakeLists.txt"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- .github/workflows/c-cpp.yml
|
||||
- "!**/CMakeLists.txt"
|
||||
|
||||
jobs:
|
||||
msys2:
|
||||
name: "Windows MSYS2 Makefile (Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# debug: n
|
||||
# dev: n
|
||||
- name: Debug
|
||||
debug: y
|
||||
dev: n
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
debug: y
|
||||
dev: y
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: n
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: y
|
||||
slug: -NDR
|
||||
environment:
|
||||
# - msystem: MSYS
|
||||
# clang: n
|
||||
# x64: y
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
clang: n
|
||||
x64: n
|
||||
- msystem: MINGW64
|
||||
prefix: mingw-w64-x86_64
|
||||
clang: n
|
||||
x64: y
|
||||
# - msystem: CLANG32
|
||||
# prefix: mingw-w64-clang-i686
|
||||
# clang: y
|
||||
# x64: n
|
||||
# - msystem: CLANG64
|
||||
# prefix: mingw-w64-clang-x86_64
|
||||
# clang: y
|
||||
# x64: y
|
||||
- msystem: UCRT64
|
||||
prefix: mingw-w64-ucrt-x86_64
|
||||
clang: n
|
||||
x64: y
|
||||
|
||||
steps:
|
||||
- name: Prepare MSYS2 environment
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false
|
||||
update: true
|
||||
msystem: ${{ matrix.environment.msystem }}
|
||||
install: >-
|
||||
make
|
||||
pacboy: >-
|
||||
gcc:p
|
||||
clang:p
|
||||
pkg-config:p
|
||||
freetype:p
|
||||
SDL2:p
|
||||
zlib:p
|
||||
libpng:p
|
||||
openal:p
|
||||
rtmidi:p
|
||||
libslirp:p
|
||||
fluidsynth:p
|
||||
libvncserver:p
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: make
|
||||
run: >-
|
||||
make -fwin/Makefile.mingw -j
|
||||
DEV_BUILD=${{ matrix.build.dev }}
|
||||
DEBUG=${{ matrix.build.debug }}
|
||||
NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
CLANG=${{ matrix.environment.clang }}
|
||||
X64=${{ matrix.environment.x64 }}
|
||||
working-directory: ./src
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
|
||||
path: src/86Box.exe
|
||||
483
.github/workflows/cmake.yml
vendored
483
.github/workflows/cmake.yml
vendored
@@ -1,483 +0,0 @@
|
||||
name: CMake
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
msys2:
|
||||
name: "Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Win32 GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
static: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt5-static:p
|
||||
# qt5-base:p
|
||||
# qt5-tools:p
|
||||
environment:
|
||||
# - msystem: MSYS
|
||||
# toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
toolchain: ./cmake/flags-gcc-i686.cmake
|
||||
- msystem: MINGW64
|
||||
prefix: mingw-w64-x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
# - msystem: CLANG32
|
||||
# prefix: mingw-w64-clang-i686
|
||||
# toolchain: ./cmake/llvm-win32-i686.cmake
|
||||
# - msystem: CLANG64
|
||||
# prefix: mingw-w64-clang-x86_64
|
||||
# toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
- msystem: UCRT64
|
||||
prefix: mingw-w64-ucrt-x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
|
||||
steps:
|
||||
- name: Prepare MSYS2 environment
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false
|
||||
update: true
|
||||
msystem: ${{ matrix.environment.msystem }}
|
||||
pacboy: >-
|
||||
ninja:p
|
||||
cmake:p
|
||||
gcc:p
|
||||
pkgconf:p
|
||||
freetype:p
|
||||
SDL2:p
|
||||
zlib:p
|
||||
libpng:p
|
||||
openal:p
|
||||
rtmidi:p
|
||||
libslirp:p
|
||||
fluidsynth:p
|
||||
libvncserver:p
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ${{ matrix.environment.toolchain }}
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D STATIC_BUILD=${{ matrix.ui.static }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
llvm-windows:
|
||||
name: "Windows vcpkg/LLVM (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }})"
|
||||
if: 0
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite'
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Win32 GUI
|
||||
qt: off
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
target:
|
||||
- name: x86
|
||||
triplet: x86-windows-static
|
||||
toolchain: ./cmake/llvm-win32-i686.cmake
|
||||
vcvars: x64_x86
|
||||
- name: x64
|
||||
triplet: x64-windows-static
|
||||
toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
vcvars: x64
|
||||
# - name: ARM
|
||||
# triplet: arm-windows-static
|
||||
# toolchain: ./cmake/llvm-win32-arm.cmake
|
||||
# vcvars: x64_arm
|
||||
- name: ARM64
|
||||
triplet: arm64-windows-static
|
||||
toolchain: ./cmake/llvm-win32-aarch64.cmake
|
||||
vcvars: x64_arm64
|
||||
exclude:
|
||||
- dynarec:
|
||||
new: off
|
||||
target:
|
||||
name: ARM64
|
||||
|
||||
steps:
|
||||
- name: Prepare VS environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.target.vcvars }}
|
||||
|
||||
- name: Add LLVM to path
|
||||
run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH
|
||||
|
||||
- name: Download Ninja
|
||||
run: >
|
||||
Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip &&
|
||||
Expand-Archive ninja-win.zip -DestinationPath .
|
||||
|
||||
- name: Setup NuGet Credentials
|
||||
run: >
|
||||
& (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2)
|
||||
sources add
|
||||
-source "https://nuget.pkg.github.com/86Box/index.json"
|
||||
-storepasswordincleartext
|
||||
-name "GitHub"
|
||||
-username "86Box"
|
||||
-password "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
- name: Fix MSVC atomic headers
|
||||
run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }}
|
||||
-D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }}
|
||||
-D VCPKG_HOST_TRIPLET=x64-windows
|
||||
-D VCPKG_USE_HOST_TOOLS=ON
|
||||
|
||||
- name: Fix Qt
|
||||
if: matrix.ui.qt == 'on'
|
||||
run: |
|
||||
$qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake"
|
||||
(Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath
|
||||
|
||||
- name: Reconfigure CMake
|
||||
if: matrix.ui.qt == 'on'
|
||||
run: |
|
||||
cmake clean build
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
linux:
|
||||
name: "Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
sudo apt update && sudo apt install
|
||||
build-essential
|
||||
ninja-build
|
||||
libfreetype-dev
|
||||
libsdl2-dev
|
||||
libpng-dev
|
||||
libc6-dev
|
||||
librtmidi-dev
|
||||
libopenal-dev
|
||||
libslirp-dev
|
||||
libfluidsynth-dev
|
||||
libvncserver-dev
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
# if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
macos11:
|
||||
name: "macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: macos-11
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
static: on
|
||||
src-packages: >-
|
||||
libsndfile
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt@5
|
||||
src-packages: >-
|
||||
libsndfile
|
||||
|
||||
steps:
|
||||
- name: Install source dependencies
|
||||
run: >-
|
||||
brew reinstall -s
|
||||
${{ matrix.ui.src-packages }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
freetype
|
||||
sdl2
|
||||
libpng
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
libvncserver
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D Qt5_ROOT=$(brew --prefix qt@5)
|
||||
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
|
||||
-D OpenAL_ROOT=$(brew --prefix openal-soft)
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
121
.github/workflows/cmake_linux.yml
vendored
Normal file
121
.github/workflows/cmake_linux.yml
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
name: CMake (Linux)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
sudo apt update && sudo apt install
|
||||
build-essential
|
||||
ninja-build
|
||||
libfreetype-dev
|
||||
libsdl2-dev
|
||||
libpng-dev
|
||||
libc6-dev
|
||||
librtmidi-dev
|
||||
libopenal-dev
|
||||
libslirp-dev
|
||||
libfluidsynth-dev
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
# if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
126
.github/workflows/cmake_macos.yml
vendored
Normal file
126
.github/workflows/cmake_macos.yml
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
name: CMake (macos)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
macos12:
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
|
||||
|
||||
runs-on: macos-12
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
static: on
|
||||
src-packages: >-
|
||||
libsndfile
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt@5
|
||||
src-packages: >-
|
||||
libsndfile
|
||||
|
||||
steps:
|
||||
- name: Install source dependencies
|
||||
run: >-
|
||||
brew reinstall -s
|
||||
${{ matrix.ui.src-packages }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
freetype
|
||||
sdl2
|
||||
libpng
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D Qt5_ROOT=$(brew --prefix qt@5)
|
||||
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
|
||||
-D OpenAL_ROOT=$(brew --prefix openal-soft)
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
163
.github/workflows/cmake_windows_llvm.yml
vendored
Normal file
163
.github/workflows/cmake_windows_llvm.yml
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
name: CMake (Windows, vcpkg/LLVM)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake_windows_llvm.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake_windows_llvm.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
llvm-windows:
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }}"
|
||||
if: 0
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite'
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Win32 GUI
|
||||
qt: off
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
target:
|
||||
- name: x86
|
||||
triplet: x86-windows-static
|
||||
toolchain: ./cmake/llvm-win32-i686.cmake
|
||||
vcvars: x64_x86
|
||||
- name: x64
|
||||
triplet: x64-windows-static
|
||||
toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
vcvars: x64
|
||||
# - name: ARM
|
||||
# triplet: arm-windows-static
|
||||
# toolchain: ./cmake/llvm-win32-arm.cmake
|
||||
# vcvars: x64_arm
|
||||
- name: ARM64
|
||||
triplet: arm64-windows-static
|
||||
toolchain: ./cmake/llvm-win32-aarch64.cmake
|
||||
vcvars: x64_arm64
|
||||
exclude:
|
||||
- dynarec:
|
||||
new: off
|
||||
target:
|
||||
name: ARM64
|
||||
|
||||
steps:
|
||||
- name: Prepare VS environment
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.target.vcvars }}
|
||||
|
||||
- name: Add LLVM to path
|
||||
run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH
|
||||
|
||||
- name: Download Ninja
|
||||
run: >
|
||||
Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip &&
|
||||
Expand-Archive ninja-win.zip -DestinationPath .
|
||||
|
||||
- name: Setup NuGet Credentials
|
||||
run: >
|
||||
& (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2)
|
||||
sources add
|
||||
-source "https://nuget.pkg.github.com/86Box/index.json"
|
||||
-storepasswordincleartext
|
||||
-name "GitHub"
|
||||
-username "86Box"
|
||||
-password "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
- name: Fix MSVC atomic headers
|
||||
run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }}
|
||||
-D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }}
|
||||
-D VCPKG_HOST_TRIPLET=x64-windows
|
||||
-D VCPKG_USE_HOST_TOOLS=ON
|
||||
|
||||
- name: Fix Qt
|
||||
if: matrix.ui.qt == 'on'
|
||||
run: |
|
||||
$qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake"
|
||||
(Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath
|
||||
|
||||
- name: Reconfigure CMake
|
||||
if: matrix.ui.qt == 'on'
|
||||
run: |
|
||||
cmake clean build
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
144
.github/workflows/cmake_windows_msys2.yml
vendored
Normal file
144
.github/workflows/cmake_windows_msys2.yml
vendored
Normal file
@@ -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: debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
static: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt5-static:p
|
||||
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@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ${{ matrix.environment.toolchain }}
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D STATIC_BUILD=${{ matrix.ui.static }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
|
||||
- name: Generate package
|
||||
run: cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
309
.github/workflows/codeql.yml
vendored
309
.github/workflows/codeql.yml
vendored
@@ -1,309 +0,0 @@
|
||||
name: CodeQL
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-msys2:
|
||||
|
||||
name: "Analyze Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Win32 GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
static: off
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt5-base:p
|
||||
qt5-tools:p
|
||||
environment:
|
||||
# - msystem: MSYS
|
||||
# toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
toolchain: ./cmake/flags-gcc-i686.cmake
|
||||
- msystem: MINGW64
|
||||
prefix: mingw-w64-x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
# - msystem: CLANG32
|
||||
# prefix: mingw-w64-clang-i686
|
||||
# toolchain: ./cmake/llvm-win32-i686.cmake
|
||||
# - msystem: CLANG64
|
||||
# prefix: mingw-w64-clang-x86_64
|
||||
# toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
- msystem: UCRT64
|
||||
prefix: mingw-w64-ucrt-x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
|
||||
steps:
|
||||
- name: Prepare MSYS2 environment
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false
|
||||
update: true
|
||||
msystem: ${{ matrix.environment.msystem }}
|
||||
pacboy: >-
|
||||
ninja:p
|
||||
cmake:p
|
||||
gcc:p
|
||||
pkgconf:p
|
||||
freetype:p
|
||||
SDL2:p
|
||||
zlib:p
|
||||
libpng:p
|
||||
openal:p
|
||||
rtmidi:p
|
||||
libslirp:p
|
||||
fluidsynth:p
|
||||
libvncserver:p
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ${{ matrix.environment.toolchain }}
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D STATIC_BUILD=${{ matrix.ui.static }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
analyze-linux:
|
||||
|
||||
name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
sudo apt update && sudo apt install
|
||||
build-essential
|
||||
ninja-build
|
||||
libfreetype-dev
|
||||
libsdl2-dev
|
||||
libpng-dev
|
||||
libc6-dev
|
||||
librtmidi-dev
|
||||
libopenal-dev
|
||||
libslirp-dev
|
||||
libfluidsynth-dev
|
||||
libvncserver-dev
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
analyze-macos11:
|
||||
|
||||
name: "Analyze macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: macos-11
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt@5
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
freetype
|
||||
sdl2
|
||||
libpng
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
libvncserver
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D Qt5_ROOT=$(brew --prefix qt@5)
|
||||
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
|
||||
-D OpenAL_ROOT=$(brew --prefix openal-soft)
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
111
.github/workflows/codeql_linux.yml
vendored
Normal file
111
.github/workflows/codeql_linux.yml
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
name: CodeQL Analysis (Linux)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-linux:
|
||||
|
||||
name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
sudo apt update && sudo apt install
|
||||
build-essential
|
||||
ninja-build
|
||||
libfreetype-dev
|
||||
libsdl2-dev
|
||||
libpng-dev
|
||||
libc6-dev
|
||||
librtmidi-dev
|
||||
libopenal-dev
|
||||
libslirp-dev
|
||||
libfluidsynth-dev
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
107
.github/workflows/codeql_macos.yml
vendored
Normal file
107
.github/workflows/codeql_macos.yml
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
name: CodeQL Analysis (macos)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-macos12:
|
||||
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
|
||||
|
||||
runs-on: macos-12
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt@5
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
freetype
|
||||
sdl2
|
||||
libpng
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D Qt5_ROOT=$(brew --prefix qt@5)
|
||||
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
|
||||
-D OpenAL_ROOT=$(brew --prefix openal-soft)
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
138
.github/workflows/codeql_windows_msys2.yml
vendored
Normal file
138
.github/workflows/codeql_windows_msys2.yml
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
name: CodeQL Analysis (Windows, msys2)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql_windows_msys2.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql_windows_msys2.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-msys2:
|
||||
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
static: off
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt5-base:p
|
||||
qt5-tools: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
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ${{ matrix.environment.toolchain }}
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D STATIC_BUILD=${{ matrix.ui.static }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -59,3 +59,6 @@ CMakeLists.txt.user
|
||||
|
||||
# MacOS Finder stuff
|
||||
.DS_Store
|
||||
|
||||
# clangd
|
||||
.cache
|
||||
|
||||
@@ -35,7 +35,7 @@ if(MUNT_EXTERNAL)
|
||||
endif()
|
||||
|
||||
project(86Box
|
||||
VERSION 4.1
|
||||
VERSION 4.2
|
||||
DESCRIPTION "Emulator of x86-based systems"
|
||||
HOMEPAGE_URL "https://86box.net"
|
||||
LANGUAGES C CXX)
|
||||
@@ -131,15 +131,19 @@ option(RTMIDI "RtMidi"
|
||||
option(FLUIDSYNTH "FluidSynth" ON)
|
||||
option(MUNT "MUNT" ON)
|
||||
option(VNC "VNC renderer" OFF)
|
||||
option(DINPUT "DirectInput" OFF)
|
||||
option(CPPTHREADS "C++11 threads" ON)
|
||||
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
|
||||
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
|
||||
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
|
||||
option(DEV_BRANCH "Development branch" OFF)
|
||||
option(QT "Qt GUI" ON)
|
||||
option(DISCORD "Discord Rich Presence support" ON)
|
||||
|
||||
if(WIN32)
|
||||
set(QT ON)
|
||||
else()
|
||||
option(QT "Qt GUI" ON)
|
||||
endif()
|
||||
|
||||
# Development branch features
|
||||
#
|
||||
# Option Description Def. Condition Otherwise
|
||||
@@ -147,18 +151,15 @@ option(DISCORD "Discord Rich Presence support"
|
||||
cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(DESKPRO386 "Compaq Deskpro 386" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
|
||||
|
||||
# Ditto but for Qt
|
||||
@@ -197,7 +198,7 @@ if(NOT EMU_BUILD_NUM)
|
||||
set(EMU_BUILD_NUM 0)
|
||||
endif()
|
||||
if(NOT EMU_COPYRIGHT_YEAR)
|
||||
set(EMU_COPYRIGHT_YEAR 2023)
|
||||
set(EMU_COPYRIGHT_YEAR 2024)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
@@ -31,7 +31,9 @@ Performance may vary depending on both host and guest configuration. Most emulat
|
||||
It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines.
|
||||
|
||||
* [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only)
|
||||
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested)
|
||||
* [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia)
|
||||
* [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python)
|
||||
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested)
|
||||
* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only)
|
||||
|
||||
It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option.
|
||||
|
||||
18
SECURITY.md
Normal file
18
SECURITY.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| >= master | :white_check_mark: |
|
||||
| < master | :x: |
|
||||
|
||||
Each version is supported in the form of patch releases until the next version is merged into master.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a vulnerability, either open an issue here on GitHub or join our Discord server. If it is
|
||||
accepted, that means we have begun working on it and it will be fixed if it is at all possible. If it
|
||||
is declined, then that means we have either determined it to not actually be a vulnerability or we
|
||||
have determined it is not feasible to fix it. On GitHub, we are going to notify you when a decision
|
||||
taken, and if accepted, when it is fixed. On Discord, you get live updates.
|
||||
@@ -26,12 +26,6 @@ then
|
||||
fi
|
||||
shift
|
||||
|
||||
# Extract version components.
|
||||
newversion_maj=$(echo "$newversion" | cut -d. -f1)
|
||||
newversion_min=$(echo "$newversion" | cut -d. -f2)
|
||||
newversion_patch=$(echo "$newversion" | cut -d. -f3)
|
||||
[ -z "$newversion_patch" ] && newversion_patch=0
|
||||
|
||||
if [ -z "${romversion}" ]; then
|
||||
# Get the latest ROM release from the GitHub API.
|
||||
romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" |
|
||||
@@ -62,12 +56,6 @@ patch_file() {
|
||||
}
|
||||
patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/'
|
||||
patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION 's/(#\s*define\s+EMU_VERSION\s+")[^"]+/\1'"$newversion"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION_MAJ 's/(#\s*define\s+EMU_VERSION_MAJ\s+)[0-9]+/\1'"$newversion_maj"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION_MIN 's/(#\s*define\s+EMU_VERSION_MIN\s+)[0-9]+/\1'"$newversion_min"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_VERSION_PATCH\s+)[0-9]+/\1'"$newversion_patch"'/'
|
||||
patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/'
|
||||
patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/'
|
||||
patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/'
|
||||
patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/'
|
||||
patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/'
|
||||
|
||||
4
debian/changelog
vendored
4
debian/changelog
vendored
@@ -1,5 +1,5 @@
|
||||
86box (4.1) UNRELEASED; urgency=medium
|
||||
86box (4.2) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump release.
|
||||
|
||||
-- Jasmine Iwanek <jriwanek@gmail.com> Mon, 16 Oct 2023 20:24:46 +0200
|
||||
-- Jasmine Iwanek <jriwanek@gmail.com> Sat, 23 Mar 2024 17:19:08 +0100
|
||||
|
||||
11
debian/control
vendored
11
debian/control
vendored
@@ -1,18 +1,21 @@
|
||||
Source: 86box
|
||||
Section: otherosfs
|
||||
Priority: optional
|
||||
Maintainer: Mariusz Kurek <mariuszkurek@protonmail.com>
|
||||
Maintainer: Jasmine Iwanek <jriwanek@gmail.com>
|
||||
Build-Depends: cmake (>= 3.21),
|
||||
debhelper-compat (= 13),
|
||||
libevdev-dev,
|
||||
libfluidsynth-dev,
|
||||
libfreetype-dev,
|
||||
libopenal-dev,
|
||||
libqt5opengl5-dev,
|
||||
librtmidi-dev,
|
||||
libsdl2-dev,
|
||||
libslirp-dev,
|
||||
libxkbcommon-x11-dev,
|
||||
ninja-build,
|
||||
qttools5-dev
|
||||
qttools5-dev,
|
||||
qtbase5-private-dev
|
||||
Standards-Version: 4.6.0
|
||||
Homepage: https://86box.net/
|
||||
#Vcs-Browser: https://salsa.debian.org/debian/86box
|
||||
@@ -26,4 +29,6 @@ Depends: ${shlibs:Depends},
|
||||
sse2-support [i386]
|
||||
Recommends: libpcap0.8-dev
|
||||
Description: An emulator for classic IBM PC clones
|
||||
#TODO: insert long description, indented with spaces
|
||||
86Box is a low level x86 emulator that runs older operating systems and software
|
||||
designed for IBM PC systems and compatibles from 1981 through
|
||||
fairly recent system designs based on the PCI bus.
|
||||
3
debian/copyright
vendored
3
debian/copyright
vendored
@@ -8,7 +8,8 @@ Copyright: <years> <put author's name and email here>
|
||||
License: GPL-2.0+
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2022 Mariusz Kurek <mariuszkurek@protonmail.com>
|
||||
Copyright: 2023 Jasmine Iwanek <jriwanek@gmail.com>
|
||||
2022 Lili Kurek <lili@lili.lgbt>
|
||||
License: GPL-2.0+
|
||||
|
||||
License: GPL-2.0+
|
||||
|
||||
5
debian/rules
vendored
5
debian/rules
vendored
@@ -25,7 +25,10 @@ endif
|
||||
dh $@ --buildsystem cmake+ninja
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR)
|
||||
dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -B .
|
||||
|
||||
override_dh_auto_build:
|
||||
dh_auto_build --buildsystem cmake+ninja
|
||||
|
||||
override_dh_auto_test:
|
||||
|
||||
|
||||
2
debian/source/format
vendored
2
debian/source/format
vendored
@@ -1 +1 @@
|
||||
3.0 (quilt)
|
||||
3.0 (native)
|
||||
|
||||
267
doc/specifications/86box-unit-tester.md
Normal file
267
doc/specifications/86box-unit-tester.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# 86Box Unit Tester device specification v1.0.0
|
||||
|
||||
By GreaseMonkey + other 86Box contributors, 2024.
|
||||
This specification, including any code samples included, has been released into the Public Domain under the Creative Commons CC0 licence version 1.0 or later, as described here: <http://creativecommons.org/publicdomain/zero/1.0>
|
||||
|
||||
The 86Box Unit Tester is a facility for allowing one to unit-test various parts of 86Box's emulation which would otherwise not be exposed to the emulated system.
|
||||
|
||||
The original purpose of this was to make it possible to analyse and verify aspects of the monitor framebuffers in order to detect and prevent regressions in certain pieces of video hardware.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Versioning
|
||||
|
||||
This specification follows the rules of Semantic Versioning 2.0.0 as documented here: <https://semver.org/spec/v2.0.0.html>
|
||||
|
||||
The format is `major.minor.patch`.
|
||||
|
||||
- Before you mess with this specification, talk to the other contributors first!
|
||||
- Any changes need to be tracked in the Version History below, mostly in the event that this document escapes into the wild and doesn't have the Git history attached to it.
|
||||
- If it clarifies something without introducing any behaviour changes (e.g. formatting changes, spelling fixes), increment the patch version.
|
||||
- If it introduces a backwards-compatible change, increment the minor version and reset the patch version to 0.
|
||||
- If it introduces a backwards-incompatible change, increment the major version and reset the minor and patch versions to 0.
|
||||
- If you make a mistake and accidentally introduce a backward-incompatible change, fix the mistake and increment the minor version.
|
||||
- To clarify, modifications to *this* section are to be classified as a *patch* version update.
|
||||
- If you understand SemVer 2.0.0, you may also do other things to the version number according to the specification.
|
||||
|
||||
And lastly, the 3 golden rules of protocol specifications:
|
||||
|
||||
1. If it's not documented, it doesn't exist.
|
||||
2. If it's not documented but somehow exists, it's a bug.
|
||||
3. If it's a bug, it needs to be fixed. (Yes, I'm talking to you. You who introduced the bug. Go fix it.)
|
||||
|
||||
The checklist:
|
||||
|
||||
- Work out what kind of version number this document needs.
|
||||
- Update the version number at the top of the file.
|
||||
- Add an entry to the "Version History" section below describing roughly what was changed.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Version History
|
||||
|
||||
Dates are based on what day it was in UTC at the time of publication.
|
||||
|
||||
New entries are placed at the top. That is, immediately following this paragraph.
|
||||
|
||||
### v1.0.0 (2024-01-08)
|
||||
Initial release. Authored by GreaseMonkey.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Conventions
|
||||
|
||||
### Integer types
|
||||
|
||||
- `i8` denotes a signed 8-bit value.
|
||||
- `u8` denotes an unsigned 8-bit value.
|
||||
- `w8` denotes an 8-bit value which wraps around.
|
||||
- `x8` denotes an 8-bit value where the signedness is irrelevant.
|
||||
- `e8` ("either") denotes an 8-bit value where the most significant bit is clear - in effect, this is a 7-bit unsigned value, and can be interepreted identically as a signed 8-bit value.
|
||||
- `u16L` denotes a little-endian unsigned 16-bit value.
|
||||
- `u16B` would denote a big-endian unsigned 16-bit value if we had any big-endian values.
|
||||
- `[N]T` denotes an array of `N` values of type `T`, whatever `N` and `T` are.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Usage
|
||||
|
||||
### Accessing the device and configuring the I/O base address
|
||||
|
||||
Find an area in I/O space where 2 addresses are confirmed (or assumed) to be unused.
|
||||
There is no need for the 2 addresses to be 2-byte-aligned.
|
||||
|
||||
Send the following sequence of bytes to port 0x80 with INTERRUPTS DISABLED:
|
||||
|
||||
'8', '6', 'B', 'o', 'x', (IOBASE & 0xFF), (IOBASE >> 8)
|
||||
|
||||
Alternatively denoted in hex:
|
||||
|
||||
38 36 42 6F 78 yy xx
|
||||
|
||||
There are no timing constraints. This is an emulator, after all.
|
||||
|
||||
To confirm that this has happened, read the status port at IOBASE+0x00.
|
||||
If it's 0xFF, then the device is most likely not present.
|
||||
Otherwise, one can potentially assume that it exists and has been configured successfully.
|
||||
(You *did* make sure that the space was unused *before* doing this, right?)
|
||||
|
||||
IOBASE is allowed to overlap the trigger port, but please don't do this!
|
||||
|
||||
### Hiding the device
|
||||
|
||||
Set the I/O base address to 0xFFFF using the above method.
|
||||
|
||||
### Executing commands
|
||||
|
||||
The ports at IOBASE+0x00 and IOBASE+0x01 are all 8 bits wide.
|
||||
|
||||
Writing to IOBASE+0x00 cancels any in-flight commands and sends a new command.
|
||||
|
||||
Reading from IOBASE+0x00 reads the status:
|
||||
|
||||
- bit 0: There is data to be read from this device
|
||||
- If one reads with this bit clear, the returned data will be 0xFF.
|
||||
- bit 1: The device is expecting data to be sent to it
|
||||
- If one writes with this bit clear, the data will be ignored.
|
||||
- bit 2: There is no command in flight
|
||||
- If this is set, then bits 0 and 1 will be clear.
|
||||
- bit 3: The previously-sent command does not exist.
|
||||
- bits 4 .. 7: Reserved, should be 0.
|
||||
|
||||
Writing to IOBASE+0x01 provides data to the device if said data is needed.
|
||||
|
||||
Reading from IOBASE+0x01 fetches the next byte data to the device if said data is needed.
|
||||
|
||||
### General flow of executing a command:
|
||||
|
||||
This is how most commands will work.
|
||||
|
||||
- Write the command to IOBASE+0x00.
|
||||
- If data needs to be written or read:
|
||||
- Read the status from IOBASE+0x00 and confirm that bit 2 is clear.
|
||||
If it is set, then the command may not exist.
|
||||
Check bit 3 if that's the case.
|
||||
- If data needs to be written:
|
||||
- Write all the data one needs to write.
|
||||
- If data needs to be read:
|
||||
- Read the status from IOBASE+0x00 and wait until bit 0 is set.
|
||||
If it is set, then the command may not exist.
|
||||
Check bit 3 if that's the case.
|
||||
- Keep reading bytes until one is satisfied.
|
||||
- Otherwise:
|
||||
- Read the status from IOBASE+0x00 and wait until any of the bottom 3 bits are set.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Command reference
|
||||
|
||||
### 0x00: No-op
|
||||
|
||||
This does nothing, takes no input, and gives no output.
|
||||
|
||||
This is an easy way to reset the status to 0x04 (no command in flight, not waiting for reads or writes, and no errors).
|
||||
|
||||
### 0x01: Capture Screen Snapshot
|
||||
|
||||
Captures a snapshot of the current screen state and stores it in the current snapshot buffer.
|
||||
|
||||
The initial state of the screen snapshot buffer has an image area of 0x0, an overscanned area of 0x0, and an image start offset of (0,0).
|
||||
|
||||
Input:
|
||||
|
||||
* u8 monitor
|
||||
- 0x00 = no monitor - clear the screen snapshot
|
||||
- 0x01 = primary monitor
|
||||
- 0x02 = secondary monitor
|
||||
- Any monitor which is not available is treated as 0x00, and clears the screen snapshot.
|
||||
|
||||
Output:
|
||||
|
||||
* `e16L` image width in pixels
|
||||
* `e16L` image height in pixels
|
||||
* `e16L` overscanned width in pixels
|
||||
* `e16L` overscanned height in pixels
|
||||
* `e16L` X offset of image start
|
||||
* `e16L` Y offset of image start
|
||||
|
||||
If there is no screen snapshot, then all values will be 0 as per the initial screen snapshot buffer state.
|
||||
|
||||
### 0x02: Read Screen Snapshot Rectangle
|
||||
|
||||
Returns a rectangular snapshot of the screen snapshot buffer as an array of 32bpp 8:8:8:8 B:G:R:X pixels.
|
||||
|
||||
Input:
|
||||
|
||||
* `e16L` w: rectangle width in pixels
|
||||
* `e16L` h: rectangle height in pixels
|
||||
* `i16L` x: X offset relative to image start
|
||||
* `i16L` y: Y offset relative to image start
|
||||
|
||||
Output:
|
||||
|
||||
* `[h][w][4]u8`: image data
|
||||
- `[y][x][0]` is the blue component, or 0x00 if the pixel is outside the snapshot area.
|
||||
- `[y][x][1]` is the green component, or 0x00 if the pixel is outside the snapshot area.
|
||||
- `[y][x][2]` is the red component, or 0x00 if the pixel is outside the snapshot area.
|
||||
- `[y][x][3]` is 0x00, or 0xFF if the pixel is outside the snapshot area.
|
||||
|
||||
### 0x03: Verify Screen Snapshot Rectangle
|
||||
|
||||
As per 0x02 "Read Screen Snapshot Rectangle", except instead of returning the pixel data, it returns a CRC-32 of the data.
|
||||
|
||||
The CRC is as per zlib's `crc32()` function. Specifically, one uses a right-shifting Galois LFSR with a polynomial of 0xEDB88320, bytes XORed against the least significant byte, the initial seed is 0xFFFFFFFF, and all bits of the output are inverted.
|
||||
|
||||
(Rationale: There are better CRCs, but this one is ubiquitous and still really good... and we don't need to protect against deliberate tampering.)
|
||||
|
||||
Input:
|
||||
|
||||
* `e16L` w: rectangle width in pixels
|
||||
* `e16L` h: rectangle height in pixels
|
||||
* `i16L` x: X offset relative to image start
|
||||
* `i16L` y: Y offset relative to image start
|
||||
|
||||
Output:
|
||||
|
||||
* `u32L` crc: CRC-32 of rectangle data
|
||||
|
||||
### 0x04: Exit 86Box
|
||||
|
||||
Exits 86Box, unless this command is disabled.
|
||||
|
||||
- If the command is enabled, then program execution terminates immediately.
|
||||
- If the command is disabled, it still counts as having executed correctly, but program execution continues. This makes it useful to show a "results" screen for a unit test.
|
||||
|
||||
Input:
|
||||
|
||||
* u8 exit code:
|
||||
- The actual exit code is clamped to no greater than the maximum valid exit code.
|
||||
- In practice, this is probably going to be 0x7F.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Implementation notes
|
||||
|
||||
### Port 0x80 sequence detection
|
||||
|
||||
In order to ensure that one can always trigger the activation sequence, there are effectively two finite state machines in action.
|
||||
|
||||
FSM1:
|
||||
- Wait for 8.
|
||||
- Wait for 6.
|
||||
- Wait for B.
|
||||
- Wait for o.
|
||||
- Wait for x.
|
||||
Once received, set FSM2 to "Wait for low byte",
|
||||
then go back to "Wait for 8".
|
||||
|
||||
If at any point an 8 arrives, jump to the "Wait for 6" step.
|
||||
|
||||
Otherwise, if any other unexpected byte arrives, jump to the "Wait for 8" step.
|
||||
|
||||
FSM2:
|
||||
- Idle.
|
||||
- Wait for low byte. Once received, store this in a temporary location.
|
||||
- Wait for high byte.
|
||||
Once received, replace IOBASE with this byte in the high byte and the temporary value in the low byte,
|
||||
then go back to "Idle".
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
## Extending the protocol
|
||||
|
||||
### Adding new commands
|
||||
|
||||
Commands 0x01 through 0x7F accept a single command byte.
|
||||
|
||||
Command bytes 0x80 through 0xFB are reserved for 16-bit command IDs, to be written in a similar way to this:
|
||||
|
||||
- Write the first command byte (0x80 through 0xFF) to the command register.
|
||||
- If this block of commands does not exist, then the command is cancelled and the status is set to 0x0C.
|
||||
- Otherwise, the status is set to 0x0
|
||||
- Write the next command byte (0x00 through 0xFF) to the data register.
|
||||
- If this block of commands does not exist, then the command is cancelled and the status is set to 0x0C.
|
||||
- Otherwise, the command exists and the status is set according to the command.
|
||||
|
||||
Command bytes 0xFC through 0xFF are reserved for if we somehow need more than 16 bits worth of command ID.
|
||||
|
||||
102
src/86box.c
102
src/86box.c
@@ -30,10 +30,10 @@
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#include <stdatomic.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <pwd.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <string.h>
|
||||
@@ -65,6 +65,8 @@
|
||||
#include <86box/machine.h>
|
||||
#include <86box/bugger.h>
|
||||
#include <86box/postcard.h>
|
||||
#include <86box/unittester.h>
|
||||
#include <86box/novell_cardkey.h>
|
||||
#include <86box/isamem.h>
|
||||
#include <86box/isartc.h>
|
||||
#include <86box/lpt.h>
|
||||
@@ -111,7 +113,7 @@
|
||||
|
||||
/* Stuff that used to be globally declared in plat.h but is now extern there
|
||||
and declared here instead. */
|
||||
int dopause; /* system is paused */
|
||||
int dopause = 1; /* system is paused */
|
||||
atomic_flag doresize; /* screen resize requested */
|
||||
volatile int is_quit; /* system exit requested */
|
||||
uint64_t timer_freq;
|
||||
@@ -172,13 +174,16 @@ char video_shader[512] = { '\0' }; /* (C) video *
|
||||
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of
|
||||
pass-through for serial ports */
|
||||
int bugger_enabled = 0; /* (C) enable ISAbugger */
|
||||
int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */
|
||||
int postcard_enabled = 0; /* (C) enable POST card */
|
||||
int unittester_enabled = 0; /* (C) enable unit tester device */
|
||||
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
|
||||
int isartc_type = 0; /* (C) enable ISA RTC card */
|
||||
int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
|
||||
int show_second_monitors = 1; /* (C) show non-primary monitors */
|
||||
int sound_is_float = 1; /* (C) sound uses FP values */
|
||||
int voodoo_enabled = 0; /* (C) video option */
|
||||
int lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */
|
||||
int ibm8514_standalone_enabled = 0; /* (C) video option */
|
||||
int xga_standalone_enabled = 0; /* (C) video option */
|
||||
uint32_t mem_size = 0; /* (C) memory size (Installed on
|
||||
@@ -201,6 +206,12 @@ int video_fullscreen_scale_maximized = 0; /* (C) Whether
|
||||
also apply when maximized. */
|
||||
int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus
|
||||
loss */
|
||||
char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */
|
||||
|
||||
int other_ide_present = 0; /* IDE controllers from non-IDE cards are
|
||||
present */
|
||||
int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are
|
||||
present */
|
||||
|
||||
/* Statistics. */
|
||||
extern int mmuflush;
|
||||
@@ -236,8 +247,8 @@ int efscrnsz_y = SCREEN_RES_Y;
|
||||
|
||||
static wchar_t mouse_msg[3][200];
|
||||
|
||||
static int do_pause_ack = 0;
|
||||
static volatile int pause_ack = 0;
|
||||
static volatile atomic_int do_pause_ack = 0;
|
||||
static volatile atomic_int pause_ack = 0;
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
static char buff[1024];
|
||||
@@ -542,7 +553,9 @@ usage:
|
||||
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
|
||||
printf("-P or --vmpath path - set 'path' to be root for vm\n");
|
||||
printf("-R or --rompath path - set 'path' to be ROM path\n");
|
||||
#ifndef USE_SDL_UI
|
||||
printf("-S or --settings - show only the settings dialog\n");
|
||||
#endif
|
||||
printf("-V or --vmname name - overrides the name of the running VM\n");
|
||||
printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n");
|
||||
printf("-Y or --donothing - do not show any UI or run the emulation\n");
|
||||
@@ -609,8 +622,10 @@ usage:
|
||||
goto usage;
|
||||
|
||||
strcpy(vm_name, argv[++c]);
|
||||
#ifndef USE_SDL_UI
|
||||
} else if (!strcasecmp(argv[c], "--settings") || !strcasecmp(argv[c], "-S")) {
|
||||
settings_only = 1;
|
||||
#endif
|
||||
} else if (!strcasecmp(argv[c], "--noconfirm") || !strcasecmp(argv[c], "-N")) {
|
||||
confirm_exit_cmdl = 0;
|
||||
} else if (!strcasecmp(argv[c], "--missing") || !strcasecmp(argv[c], "-M")) {
|
||||
@@ -945,12 +960,12 @@ pc_init_modules(void)
|
||||
|
||||
/* Load the ROMs for the selected machine. */
|
||||
if (!machine_available(machine)) {
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2063), machine_getname());
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_MACHINE), machine_getname());
|
||||
c = 0;
|
||||
machine = -1;
|
||||
while (machine_get_internal_name_ex(c) != NULL) {
|
||||
if (machine_available(c)) {
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
|
||||
ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
|
||||
machine = c;
|
||||
config_save();
|
||||
break;
|
||||
@@ -967,12 +982,12 @@ pc_init_modules(void)
|
||||
if (!video_card_available(gfxcard[0])) {
|
||||
memset(tempc, 0, sizeof(tempc));
|
||||
device_get_name(video_card_getdevice(gfxcard[0]), 0, tempc);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2064), tempc);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO), tempc);
|
||||
c = 0;
|
||||
while (video_get_internal_name(c) != NULL) {
|
||||
gfxcard[0] = -1;
|
||||
if (video_card_available(c)) {
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
|
||||
ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
|
||||
gfxcard[0] = c;
|
||||
config_save();
|
||||
break;
|
||||
@@ -988,8 +1003,8 @@ pc_init_modules(void)
|
||||
if (!video_card_available(gfxcard[1])) {
|
||||
char tempc[512] = { 0 };
|
||||
device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(IDS_2163), tempc);
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
|
||||
swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc);
|
||||
ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
|
||||
gfxcard[1] = 0;
|
||||
}
|
||||
|
||||
@@ -1042,6 +1057,7 @@ pc_send_ca(uint16_t sc)
|
||||
keyboard_input(1, 0x1D); /* Ctrl key pressed */
|
||||
keyboard_input(1, 0x38); /* Alt key pressed */
|
||||
keyboard_input(1, sc);
|
||||
usleep(50000);
|
||||
keyboard_input(0, sc);
|
||||
keyboard_input(0, 0x38); /* Alt key released */
|
||||
keyboard_input(0, 0x1D); /* Ctrl key released */
|
||||
@@ -1069,18 +1085,22 @@ pc_reset_hard_close(void)
|
||||
/* Close all the memory mappings. */
|
||||
mem_close();
|
||||
|
||||
suppress_overscan = 0;
|
||||
|
||||
/* Turn off timer processing to avoid potential segmentation faults. */
|
||||
timer_close();
|
||||
|
||||
suppress_overscan = 0;
|
||||
lpt_devices_close();
|
||||
|
||||
#ifdef UNCOMMENT_LATER
|
||||
lpt_close();
|
||||
#endif
|
||||
|
||||
nvr_save();
|
||||
nvr_close();
|
||||
|
||||
mouse_close();
|
||||
|
||||
lpt_devices_close();
|
||||
|
||||
device_close_all();
|
||||
|
||||
scsi_device_close_all();
|
||||
@@ -1121,6 +1141,9 @@ pc_reset_hard_init(void)
|
||||
* modules that are.
|
||||
*/
|
||||
|
||||
/* Reset the IDE and SCSI presences */
|
||||
other_ide_present = other_scsi_present = 0;
|
||||
|
||||
/* Mark ACPI as unavailable */
|
||||
acpi_enabled = 0;
|
||||
|
||||
@@ -1153,9 +1176,6 @@ pc_reset_hard_init(void)
|
||||
* that will be a call to device_reset_all() later !
|
||||
*/
|
||||
|
||||
if (joystick_type)
|
||||
gameport_update_joystick_type();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
sound_card_reset();
|
||||
|
||||
@@ -1163,13 +1183,14 @@ pc_reset_hard_init(void)
|
||||
/* note: PLIP LPT side has to be initialized before the network side */
|
||||
lpt_devices_init();
|
||||
|
||||
/* Reset and reconfigure the Network Card layer. */
|
||||
network_reset();
|
||||
|
||||
/* Reset and reconfigure the serial ports. */
|
||||
/* note: SLIP COM side has to be initialized before the network side */
|
||||
serial_standalone_init();
|
||||
serial_passthrough_init();
|
||||
|
||||
/* Reset and reconfigure the Network Card layer. */
|
||||
network_reset();
|
||||
|
||||
/*
|
||||
* Reset the mouse, this will attach it to any port needed.
|
||||
*/
|
||||
@@ -1199,10 +1220,13 @@ pc_reset_hard_init(void)
|
||||
/* Reset any ISA RTC cards. */
|
||||
isartc_reset();
|
||||
|
||||
/* Initialize the Voodoo cards here inorder to minmize
|
||||
/* Initialize the Voodoo cards here inorder to minimize
|
||||
the chances of the SCSI controller ending up on the bridge. */
|
||||
video_voodoo_init();
|
||||
|
||||
if (joystick_type)
|
||||
gameport_update_joystick_type(); /* installs game port if no device provides one, must be late */
|
||||
|
||||
ui_sb_update_panes();
|
||||
|
||||
if (config_changed) {
|
||||
@@ -1217,12 +1241,24 @@ pc_reset_hard_init(void)
|
||||
device_add(&bugger_device);
|
||||
if (postcard_enabled)
|
||||
device_add(&postcard_device);
|
||||
if (unittester_enabled)
|
||||
device_add(&unittester_device);
|
||||
|
||||
if (lba_enhancer_enabled)
|
||||
device_add(&lba_enhancer_device);
|
||||
|
||||
if (novell_keycard_enabled)
|
||||
device_add(&novell_keycard_device);
|
||||
|
||||
if (IS_ARCH(machine, MACHINE_BUS_PCI)) {
|
||||
pci_register_cards();
|
||||
device_reset_all(DEVICE_PCI);
|
||||
}
|
||||
|
||||
/* Mark IDE shadow drives (slaves with a present master) as such in case
|
||||
the IDE controllers present are not some form of PCI. */
|
||||
ide_drives_set_shadow();
|
||||
|
||||
/* Reset the CPU module. */
|
||||
resetx86();
|
||||
dma_reset();
|
||||
@@ -1266,17 +1302,17 @@ update_mouse_msg(void)
|
||||
mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1);
|
||||
#ifdef _WIN32
|
||||
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls",
|
||||
plat_get_string(IDS_2077));
|
||||
plat_get_string(STRING_MOUSE_CAPTURE));
|
||||
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls",
|
||||
(mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079));
|
||||
(mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB));
|
||||
wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2]));
|
||||
#else
|
||||
swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
|
||||
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu,
|
||||
plat_get_string(IDS_2077));
|
||||
plat_get_string(STRING_MOUSE_CAPTURE));
|
||||
swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls",
|
||||
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu,
|
||||
(mouse_get_buttons() > 2) ? plat_get_string(IDS_2078) : plat_get_string(IDS_2079));
|
||||
(mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB));
|
||||
swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls",
|
||||
EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu);
|
||||
#endif
|
||||
@@ -1359,9 +1395,9 @@ _ui_window_title(void *s)
|
||||
void
|
||||
ack_pause(void)
|
||||
{
|
||||
if (do_pause_ack) {
|
||||
do_pause_ack = 0;
|
||||
pause_ack = 1;
|
||||
if (atomic_load(&do_pause_ack)) {
|
||||
atomic_store(&do_pause_ack, 0);
|
||||
atomic_store(&pause_ack, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1579,12 +1615,14 @@ get_actual_size_y(void)
|
||||
void
|
||||
do_pause(int p)
|
||||
{
|
||||
if (p)
|
||||
int old_p = dopause;
|
||||
|
||||
if ((p == 1) && !old_p)
|
||||
do_pause_ack = p;
|
||||
dopause = p;
|
||||
if (p) {
|
||||
while (!pause_ack)
|
||||
dopause = !!p;
|
||||
if ((p == 1) && !old_p) {
|
||||
while (!atomic_load(&pause_ack))
|
||||
;
|
||||
}
|
||||
pause_ack = 0;
|
||||
atomic_store(&pause_ack, 0);
|
||||
}
|
||||
|
||||
@@ -226,8 +226,7 @@ endif()
|
||||
|
||||
if (QT)
|
||||
add_subdirectory(qt)
|
||||
elseif(WIN32)
|
||||
add_subdirectory(win)
|
||||
else()
|
||||
add_compile_definitions(USE_SDL_UI)
|
||||
add_subdirectory(unix)
|
||||
endif()
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# Prefix for localizing the general Makefile.mingw for local
|
||||
# settings, so we can avoid changing the main one for all of
|
||||
# our local setups.
|
||||
#
|
||||
# Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
|
||||
#########################################################################
|
||||
# Anything here will override defaults in Makefile.MinGW. #
|
||||
#########################################################################
|
||||
|
||||
|
||||
# Name of the executable.
|
||||
#PROG := 86box.exe
|
||||
|
||||
|
||||
# Various compile-time options.
|
||||
# -DROM_TRACE=0xc800 traces ROM access from segment C800
|
||||
# -DIO_TRACE=0x66 traces I/O on port 0x66
|
||||
# -DIO_CATCH enables I/O range catch logs
|
||||
STUFF :=
|
||||
|
||||
# Add feature selections here.
|
||||
# -DANSI_CFG forces the config file to ANSI encoding.
|
||||
# Root logging:
|
||||
# -DENABLE_ACPI_LOG=N sets logging level at N.
|
||||
# -DENABLE_APM_LOG=N sets logging level at N.
|
||||
# -DENABLE_BUGGER_LOG=N sets logging level at N.
|
||||
# -DENABLE_CONFIG_LOG=N sets logging level at N.
|
||||
# -DENABLE_DDMA_LOG=N sets logging level at N.
|
||||
# -DENABLE_DEVICE_LOG=N sets logging level at N.
|
||||
# -DENABLE_DMA_LOG=N sets logging level at N.
|
||||
# -DENABLE_IO_LOG=N sets logging level at N.
|
||||
# -DENABLE_IOAPIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_ISAMEM_LOG=N sets logging level at N.
|
||||
# -DENABLE_ISARTC_LOG=N sets logging level at N.
|
||||
# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_KEYBOARD_XT_LOG=N sets logging level at N.
|
||||
# -DENABLE_LM75_LOG=N sets logging level at N.
|
||||
# -DENABLE_LM78_LOG=N sets logging level at N.
|
||||
# -DENABLE_MEM_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_PS2_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_SERIAL_LOG=N sets logging level at N.
|
||||
# -DENABLE_NVR_LOG=N sets logging level at N.
|
||||
# -DENABLE_PC_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCI_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIT_LOG=N sets logging level at N.
|
||||
# -DENABLE_POSTCARD_LOG=N sets logging level at N.
|
||||
# -DENABLE_ROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_SERIAL_LOG=N sets logging level at N.
|
||||
# -DENABLE_SMBUS_LOG=N sets logging level at N.
|
||||
# -DENABLE_SMBUS_PIIX4_LOG=N sets logging level at N.
|
||||
# -DENABLE_SPD_LOG=N sets logging level at N.
|
||||
# -DENABLE_USB_LOG=N sets logging level at N.
|
||||
# -DENABLE_VNC_LOG=N sets logging level at N.
|
||||
# -DENABLE_VNC_KEYMAP_LOG=N sets logging level at N.
|
||||
# cdrom/ logging:
|
||||
# -DENABLE_CDROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_CDROM_IMAGE_BACKEND_LOG=N sets logging level at N.
|
||||
# chipset/ logging:
|
||||
# -DENABLE_I420EX_LOG=N sets logging level at N.
|
||||
# -DENABLE_NEAT_LOG=N sets logging level at N.
|
||||
# -DENABLE_OPTI495_LOG=N sets logging level at N.
|
||||
# -DENABLE_OPTI895_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIIX_LOG=N sets logging level at N.
|
||||
# -DENABLE_SIO_LOG=N sets logging level at N.
|
||||
# -DENABLE_SIS_85C496_LOG=N sets logging level at N.
|
||||
# codegen/, codegen_new/, cpu/ logging:
|
||||
# -DENABLE_X86SEG_LOG=N sets logging level at N.
|
||||
# cpu/ logging:
|
||||
# -DENABLE_386_LOG=N sets logging level at N.
|
||||
# -DENABLE_386_COMMON_LOG=N sets logging level at N.
|
||||
# -DENABLE_386_DYNAREC_LOG=N sets logging level at N.
|
||||
# -DENABLE_808X_LOG=N sets logging level at N.
|
||||
# -DENABLE_CPU_LOG=N sets logging level at N.
|
||||
# -DENABLE_FPU_LOG=N sets logging level at N.
|
||||
# disk/ logging:
|
||||
# -DENABLE_ESDI_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_ESDI_MCA_LOG=N sets logging level at N.
|
||||
# -DENABLE_HDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_IDE_LOG=N sets logging level at N.
|
||||
# -DENABLE_MO_LOG=N sets logging level at N.
|
||||
# -DENABLE_SFF_LOG=N sets logging level at N.
|
||||
# -DENABLE_ST506_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_ST506_XT_LOG=N sets logging level at N.
|
||||
# -DENABLE_XTA_LOG=N sets logging level at N.
|
||||
# -DENABLE_ZIP_LOG=N sets logging level at N.
|
||||
# floppy/ logging:
|
||||
# -DENABLE_D86F_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDD_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDI_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDI2RAW_LOG=N sets logging level at N.
|
||||
# -DENABLE_IMD_LOG=N sets logging level at N.
|
||||
# -DENABLE_IMG_LOG=N sets logging level at N.
|
||||
# -DENABLE_JSON_LOG=N sets logging level at N.
|
||||
# -DENABLE_MFM_LOG=N sets logging level at N.
|
||||
# -DENABLE_TD0_LOG=N sets logging level at N.
|
||||
# machine/ logging:
|
||||
# -DENABLE_AMSTRAD_LOG=N sets logging level at N.
|
||||
# -DENABLE_EUROPC_LOG=N sets logging level at N.
|
||||
# -DENABLE_M24VID_LOG=N sets logging level at N.
|
||||
# -DENABLE_MACHINE_LOG=N sets logging level at N.
|
||||
# -DENABLE_PS1_HDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_PS2_MCA_LOG=N sets logging level at N.
|
||||
# -DENABLE_TANDY_LOG=N sets logging level at N.
|
||||
# -DENABLE_T1000_LOG=N sets logging level at N.
|
||||
# -DENABLE_T3100E_LOG=N sets logging level at N.
|
||||
# network/ logging:
|
||||
# -DENABLE_3COM503_LOG=N sets logging level at N.
|
||||
# -DENABLE_DP8390_LOG=N sets logging level at N.
|
||||
# -DENABLE_NETWORK_LOG=N sets logging level at N.
|
||||
# -DENABLE_NE2K_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCAP_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCNET_LOG=N sets logging level at N.
|
||||
# -DENABLE_SLIRP_LOG=N sets logging level at N.
|
||||
# -DENABLE_WD_LOG=N sets logging level at N.
|
||||
# printer/ logging:
|
||||
# -DENABLE_ESCP_LOG=N sets logging level at N.
|
||||
# scsi/ logging:
|
||||
# -DENABLE_AHA154X_LOG=N sets logging level at N.
|
||||
# -DENABLE_BUSLOGIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_NCR5380_LOG=N sets logging level at N.
|
||||
# -DENABLE_NCR53C8XX_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
|
||||
# -DENABLE_SPOCK_LOG=N sets logging level at N.
|
||||
# -DENABLE_X54X_LOG=N sets logging level at N.
|
||||
# sound/ logging:
|
||||
# -DENABLE_ADLIB_LOG=N sets logging level at N.
|
||||
# -DENABLE_AUDIOPCI_LOG=N sets logging level at N.
|
||||
# -DENABLE_EMU8K_LOG=N sets logging level at N.
|
||||
# -DENABLE_MPU401_LOG=N sets logging level at N.
|
||||
# -DENABLE_PAS16_LOG=N sets logging level at N.
|
||||
# -DENABLE_SB_LOG=N sets logging level at N.
|
||||
# -DENABLE_SB_DSP_LOG=N sets logging level at N.
|
||||
# -DENABLE_SOUND_LOG=N sets logging level at N.
|
||||
# video/ logging:
|
||||
# -DENABLE_ATI28800_LOG=N sets logging level at N.
|
||||
# -DENABLE_MACH64_LOG=N sets logging level at N.
|
||||
# -DENABLE_COMPAQ_CGA_LOG=N sets logging level at N.
|
||||
# -DENABLE_ET4000W32_LOG=N sets logging level at N.
|
||||
# -DENABLE_HT216_LOG=N sets logging level at N.
|
||||
# -DENABLE_ICD2061_LOG=N sets logging level at N.
|
||||
# -DENABLE_IM1024_LOG=N sets logging level at N.
|
||||
# -DENABLE_PGC_LOG=N sets logging level at N.
|
||||
# -DENABLE_S3_VIRGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_VID_TABLE_LOG=N sets logging level at N.
|
||||
# -DENABLE_VIDEO_LOG=N sets logging level at N.
|
||||
# -DENABLE_VOODOO_LOG=N sets logging level at N.
|
||||
# win/ logging:
|
||||
# -DENABLE_WIN_LOG=N sets logging level at N.
|
||||
# -DENABLE_DISCORD_LOG=N sets logging level at N.
|
||||
# -DENABLE_DYNLD_LOG=N sets logging level at N.
|
||||
# -DENABLE_JOYSTICK_LOG=N sets logging level at N.
|
||||
# -DENABLE_SDL_LOG=N sets logging level at N.
|
||||
# -DENABLE_SETTINGS_LOG=N sets logging level at N.
|
||||
EXTRAS :=
|
||||
|
||||
|
||||
AUTODEP := n
|
||||
DEBUG := n
|
||||
OPTIM := n
|
||||
X64 := n
|
||||
RELEASE := n
|
||||
USB := n
|
||||
VNC := n
|
||||
RDP := n
|
||||
DEV_BUILD := n
|
||||
DEV_BRANCH := n
|
||||
CIRRUS := n
|
||||
NE1000 := n
|
||||
NV_RIVA := n
|
||||
OPENAL := y
|
||||
FLUIDSYNTH := y
|
||||
MUNT := y
|
||||
PAS16 := n
|
||||
DYNAREC := y
|
||||
|
||||
|
||||
#########################################################################
|
||||
# Include the master Makefile.MinGW for the rest. #
|
||||
#########################################################################
|
||||
include win/Makefile.mingw
|
||||
|
||||
|
||||
# End of Makefile.local.
|
||||
920
src/acpi.c
920
src/acpi.c
File diff suppressed because it is too large
Load Diff
@@ -442,7 +442,7 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING)) {
|
||||
if (!dev->sound_on || (dev->cd_status != CD_STATUS_PLAYING) || dev->audio_muted_soft) {
|
||||
cdrom_log("CD-ROM %i: Audio callback while not playing\n", dev->id);
|
||||
if (dev->cd_status == CD_STATUS_PLAYING)
|
||||
dev->seek_pos += (len >> 11);
|
||||
@@ -557,6 +557,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
|
||||
len += pos;
|
||||
}
|
||||
|
||||
dev->audio_muted_soft = 0;
|
||||
/* Do this at this point, since it's at this point that we know the
|
||||
actual LBA position to start playing from. */
|
||||
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
|
||||
@@ -578,6 +579,7 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
|
||||
int m = 0;
|
||||
int s = 0;
|
||||
int f = 0;
|
||||
uint32_t pos2 = 0;
|
||||
|
||||
if (dev->cd_status == CD_STATUS_DATA_ONLY)
|
||||
return 0;
|
||||
@@ -614,8 +616,21 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Unlike standard commands, if there's a data track on an Audio CD (mixed mode)
|
||||
the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */
|
||||
pos2 = pos - 1;
|
||||
if (pos2 == 0xffffffff)
|
||||
pos2 = pos + 1;
|
||||
|
||||
/* Do this at this point, since it's at this point that we know the
|
||||
actual LBA position to start playing from. */
|
||||
if (!(dev->ops->track_type(dev, pos2) & CD_TRACK_AUDIO)) {
|
||||
cdrom_log("CD-ROM %i: Track Search: LBA %08X not on an audio track\n", dev->id, pos);
|
||||
dev->audio_muted_soft = 1;
|
||||
if (dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)
|
||||
dev->audio_muted_soft = 0;
|
||||
} else
|
||||
dev->audio_muted_soft = 0;
|
||||
|
||||
cdrom_log("Track Search Toshiba: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos);
|
||||
dev->cd_buflen = 0;
|
||||
dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED;
|
||||
return 1;
|
||||
@@ -641,6 +656,15 @@ cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit)
|
||||
|
||||
dev->seek_pos = pos;
|
||||
|
||||
dev->audio_muted_soft = 0;
|
||||
/* Do this at this point, since it's at this point that we know the
|
||||
actual LBA position to start playing from. */
|
||||
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
|
||||
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
|
||||
cdrom_stop(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->cd_buflen = 0;
|
||||
dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED;
|
||||
return 1;
|
||||
@@ -662,6 +686,7 @@ cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos)
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
dev->cd_end = pos;
|
||||
|
||||
dev->audio_muted_soft = 0;
|
||||
dev->cd_buflen = 0;
|
||||
dev->cd_status = CD_STATUS_PLAYING;
|
||||
return 1;
|
||||
@@ -703,10 +728,7 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
|
||||
break;
|
||||
}
|
||||
|
||||
cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status);
|
||||
|
||||
/* Unlike standard commands, if there's a data track on an Audio CD (mixed mode)
|
||||
the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */
|
||||
cdrom_log("Toshiba Play Audio: Muted?=%d, LBA=%08X.\n", dev->audio_muted_soft, pos);
|
||||
dev->cd_buflen = 0;
|
||||
dev->cd_status = CD_STATUS_PLAYING;
|
||||
return 1;
|
||||
@@ -750,6 +772,7 @@ cdrom_audio_scan(cdrom_t *dev, uint32_t pos, int type)
|
||||
break;
|
||||
}
|
||||
|
||||
dev->audio_muted_soft = 0;
|
||||
/* Do this at this point, since it's at this point that we know the
|
||||
actual LBA position to start playing from. */
|
||||
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
|
||||
@@ -987,6 +1010,11 @@ cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
|
||||
else
|
||||
ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op;
|
||||
|
||||
/*If a valid audio track is detected with audio on, unmute it.*/
|
||||
if (dev->ops->track_type(dev, dev->seek_pos) & CD_TRACK_AUDIO)
|
||||
dev->audio_muted_soft = 0;
|
||||
|
||||
cdrom_log("SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d.\n", dev->seek_pos, dev->cd_end, dev->audio_muted_soft);
|
||||
b[0] = subc.attr;
|
||||
b[1] = bin2bcd(subc.track);
|
||||
b[2] = bin2bcd(subc.index);
|
||||
@@ -1496,8 +1524,9 @@ static void
|
||||
read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len)
|
||||
{
|
||||
uint8_t *bb = rbuf;
|
||||
const int offset = (!!(mode2 & 0x03)) ? 24 : 16;
|
||||
|
||||
dev->ops->read_sector(dev, CD_READ_DATA, rbuf + 16, lba);
|
||||
dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
|
||||
|
||||
/* Sync bytes */
|
||||
bb[0] = 0;
|
||||
@@ -1932,8 +1961,18 @@ cdrom_hard_reset(void)
|
||||
|
||||
dev->cd_status = CD_STATUS_EMPTY;
|
||||
|
||||
if (dev->host_drive == 200)
|
||||
if (dev->host_drive == 200) {
|
||||
#ifdef _WIN32
|
||||
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/'))
|
||||
dev->image_path[strlen(dev->image_path) - 1] = '\\';
|
||||
#else
|
||||
if ((strlen(dev->image_path) >= 1) &&
|
||||
(dev->image_path[strlen(dev->image_path) - 1] == '\\'))
|
||||
dev->image_path[strlen(dev->image_path) - 1] = '/';
|
||||
#endif
|
||||
|
||||
cdrom_image_open(dev, dev->image_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2022,6 +2061,15 @@ cdrom_reload(uint8_t id)
|
||||
if (dev->prev_host_drive == 200) {
|
||||
/* Reload a previous image. */
|
||||
strcpy(dev->image_path, dev->prev_image_path);
|
||||
|
||||
#ifdef _WIN32
|
||||
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/'))
|
||||
dev->image_path[strlen(dev->image_path) - 1] = '\\';
|
||||
#else
|
||||
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\'))
|
||||
dev->image_path[strlen(dev->image_path) - 1] = '/';
|
||||
#endif
|
||||
|
||||
cdrom_image_open(dev, dev->image_path);
|
||||
|
||||
cdrom_insert(id);
|
||||
|
||||
@@ -70,12 +70,12 @@ cdrom_image_backend_log(const char *fmt, ...)
|
||||
static int
|
||||
bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
{
|
||||
track_file_t *tf = (track_file_t *) priv;
|
||||
track_file_t *tf;
|
||||
|
||||
cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n",
|
||||
tf->fp, seek, count);
|
||||
|
||||
if (tf->fp == NULL)
|
||||
if ((tf = (track_file_t *) priv)->fp == NULL)
|
||||
return 0;
|
||||
|
||||
if (fseeko64(tf->fp, seek, SEEK_SET) == -1) {
|
||||
@@ -98,16 +98,15 @@ bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
static uint64_t
|
||||
bin_get_length(void *priv)
|
||||
{
|
||||
off64_t len;
|
||||
track_file_t *tf = (track_file_t *) priv;
|
||||
track_file_t *tf;
|
||||
|
||||
cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp);
|
||||
|
||||
if (tf->fp == NULL)
|
||||
if ((tf = (track_file_t *) priv)->fp == NULL)
|
||||
return 0;
|
||||
|
||||
fseeko64(tf->fp, 0, SEEK_END);
|
||||
len = ftello64(tf->fp);
|
||||
const off64_t len = ftello64(tf->fp);
|
||||
cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len);
|
||||
|
||||
return len;
|
||||
@@ -248,26 +247,20 @@ cdi_set_device(cd_img_t *cdi, const char *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: This never returns anything other than 1, should it even be an int? */
|
||||
int
|
||||
void
|
||||
cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
*st_track = 1;
|
||||
*end = cdi->tracks_num - 1;
|
||||
FRAMES_TO_MSF(cdi->tracks[*end].start + 150, &lead_out->min, &lead_out->sec, &lead_out->fr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* TODO: This never returns anything other than 1, should it even be an int? */
|
||||
int
|
||||
void
|
||||
cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out)
|
||||
{
|
||||
*st_track = 1;
|
||||
*end = cdi->tracks_num - 1;
|
||||
*lead_out = cdi->tracks[*end].start;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -286,12 +279,11 @@ int
|
||||
cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
{
|
||||
const track_t *trk = &cdi->tracks[track - 1];
|
||||
int pos = trk->start + 150;
|
||||
|
||||
if ((track < 1) || (track > cdi->tracks_num))
|
||||
return 0;
|
||||
|
||||
pos = trk->start + 150;
|
||||
const int pos = trk->start + 150;
|
||||
|
||||
FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr);
|
||||
|
||||
@@ -320,9 +312,6 @@ cdi_get_audio_track_info_lba(cd_img_t *cdi, UNUSED(int end), int track, int *tra
|
||||
int
|
||||
cdi_get_track(cd_img_t *cdi, uint32_t sector)
|
||||
{
|
||||
const track_t *cur;
|
||||
const track_t *next;
|
||||
|
||||
/* There must be at least two tracks - data and lead out. */
|
||||
if (cdi->tracks_num < 2)
|
||||
return -1;
|
||||
@@ -330,8 +319,8 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector)
|
||||
/* This has a problem - the code skips the last track, which is
|
||||
lead out - is that correct? */
|
||||
for (int i = 0; i < (cdi->tracks_num - 1); i++) {
|
||||
cur = &cdi->tracks[i];
|
||||
next = &cdi->tracks[i + 1];
|
||||
const track_t *cur = &cdi->tracks[i];
|
||||
const track_t *next = &cdi->tracks[i + 1];
|
||||
|
||||
/* Take into account cue sheets that do not start on sector 0. */
|
||||
if ((i == 0) && (sector < cur->start))
|
||||
@@ -348,16 +337,15 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector)
|
||||
int
|
||||
cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos)
|
||||
{
|
||||
int cur_track = cdi_get_track(cdi, sector);
|
||||
const track_t *trk;
|
||||
const int cur_track = cdi_get_track(cdi, sector);
|
||||
|
||||
if (cur_track < 1)
|
||||
return 0;
|
||||
|
||||
*track = (uint8_t) cur_track;
|
||||
trk = &cdi->tracks[*track - 1];
|
||||
*attr = trk->attr;
|
||||
*index = 1;
|
||||
*track = (uint8_t) cur_track;
|
||||
const track_t *trk = &cdi->tracks[*track - 1];
|
||||
*attr = trk->attr;
|
||||
*index = 1;
|
||||
|
||||
FRAMES_TO_MSF(sector + 150, &abs_pos->min, &abs_pos->sec, &abs_pos->fr);
|
||||
|
||||
@@ -370,16 +358,11 @@ cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track,
|
||||
int
|
||||
cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
{
|
||||
size_t length;
|
||||
int track = cdi_get_track(cdi, sector) - 1;
|
||||
uint64_t sect = (uint64_t) sector;
|
||||
uint64_t seek;
|
||||
track_t *trk;
|
||||
int track_is_raw;
|
||||
int ret;
|
||||
const int track = cdi_get_track(cdi, sector) - 1;
|
||||
const uint64_t sect = (uint64_t) sector;
|
||||
int raw_size;
|
||||
int cooked_size;
|
||||
uint64_t offset = 0ULL;
|
||||
uint64_t offset;
|
||||
int m = 0;
|
||||
int s = 0;
|
||||
int f = 0;
|
||||
@@ -387,10 +370,10 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
if (track < 0)
|
||||
return 0;
|
||||
|
||||
trk = &cdi->tracks[track];
|
||||
track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
|
||||
const track_t *trk = &cdi->tracks[track];
|
||||
const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
|
||||
|
||||
seek = trk->skip + ((sect - trk->start) * trk->sector_size);
|
||||
const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size);
|
||||
|
||||
if (track_is_raw)
|
||||
raw_size = trk->sector_size;
|
||||
@@ -405,7 +388,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
} else
|
||||
cooked_size = COOKED_SECTOR_SIZE;
|
||||
|
||||
length = (raw ? raw_size : cooked_size);
|
||||
const size_t length = (raw ? raw_size : cooked_size);
|
||||
|
||||
if (trk->mode2 && (trk->form >= 1))
|
||||
offset = 24ULL;
|
||||
@@ -414,7 +397,7 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
|
||||
if (raw && !track_is_raw) {
|
||||
memset(buffer, 0x00, 2448);
|
||||
ret = trk->file->read(trk->file, buffer + offset, seek, length);
|
||||
const int ret = trk->file->read(trk->file, buffer + offset, seek, length);
|
||||
if (!ret)
|
||||
return 0;
|
||||
/* Construct the rest of the raw sector. */
|
||||
@@ -422,32 +405,28 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
buffer += 12;
|
||||
FRAMES_TO_MSF(sector + 150, &m, &s, &f);
|
||||
/* These have to be BCD. */
|
||||
buffer[12] = CDROM_BCD(m & 0xff);
|
||||
buffer[13] = CDROM_BCD(s & 0xff);
|
||||
buffer[14] = CDROM_BCD(f & 0xff);
|
||||
buffer[0] = CDROM_BCD(m & 0xff);
|
||||
buffer[1] = CDROM_BCD(s & 0xff);
|
||||
buffer[2] = CDROM_BCD(f & 0xff);
|
||||
/* Data, should reflect the actual sector type. */
|
||||
buffer[15] = trk->mode2 ? 2 : 1;
|
||||
buffer[3] = trk->mode2 ? 2 : 1;
|
||||
return 1;
|
||||
} else if (!raw && track_is_raw)
|
||||
return trk->file->read(trk->file, buffer, seek + offset, length);
|
||||
else {
|
||||
else
|
||||
return trk->file->read(trk->file, buffer, seek, length);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num)
|
||||
{
|
||||
int sector_size;
|
||||
int success = 1;
|
||||
uint8_t *buf;
|
||||
uint32_t buf_len;
|
||||
|
||||
/* TODO: This fails to account for Mode 2. Shouldn't we have a function
|
||||
to get sector size? */
|
||||
sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
buf_len = num * sector_size;
|
||||
buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t));
|
||||
const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
const uint32_t buf_len = num * sector_size;
|
||||
uint8_t *buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t));
|
||||
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i);
|
||||
@@ -455,7 +434,9 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3
|
||||
break;
|
||||
/* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an
|
||||
audio track. */
|
||||
if (raw && sector < cdi->tracks[0].length && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[i * sector_size + 2068]))
|
||||
if (raw && (sector < cdi->tracks[0].length) &&
|
||||
!cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) &&
|
||||
*(uint64_t *) &(buf[(i * sector_size) + 2068]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -470,16 +451,13 @@ cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint3
|
||||
int
|
||||
cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector)
|
||||
{
|
||||
int track = cdi_get_track(cdi, sector) - 1;
|
||||
track_t *trk;
|
||||
uint64_t s = (uint64_t) sector;
|
||||
uint64_t seek;
|
||||
const int track = cdi_get_track(cdi, sector) - 1;
|
||||
|
||||
if (track < 0)
|
||||
return 0;
|
||||
|
||||
trk = &cdi->tracks[track];
|
||||
seek = trk->skip + ((s - trk->start) * trk->sector_size);
|
||||
const track_t *trk = &cdi->tracks[track];
|
||||
const uint64_t seek = trk->skip + (((uint64_t) sector - trk->start) * trk->sector_size);
|
||||
if (trk->sector_size != 2448)
|
||||
return 0;
|
||||
|
||||
@@ -489,26 +467,24 @@ cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector)
|
||||
int
|
||||
cdi_get_sector_size(cd_img_t *cdi, uint32_t sector)
|
||||
{
|
||||
int track = cdi_get_track(cdi, sector) - 1;
|
||||
const track_t *trk;
|
||||
const int track = cdi_get_track(cdi, sector) - 1;
|
||||
|
||||
if (track < 0)
|
||||
return 0;
|
||||
|
||||
trk = &cdi->tracks[track];
|
||||
const track_t *trk = &cdi->tracks[track];
|
||||
return trk->sector_size;
|
||||
}
|
||||
|
||||
int
|
||||
cdi_is_mode2(cd_img_t *cdi, uint32_t sector)
|
||||
{
|
||||
int track = cdi_get_track(cdi, sector) - 1;
|
||||
const track_t *trk;
|
||||
const int track = cdi_get_track(cdi, sector) - 1;
|
||||
|
||||
if (track < 0)
|
||||
return 0;
|
||||
|
||||
trk = &cdi->tracks[track];
|
||||
const track_t *trk = &cdi->tracks[track];
|
||||
|
||||
return !!(trk->mode2);
|
||||
}
|
||||
@@ -516,13 +492,12 @@ cdi_is_mode2(cd_img_t *cdi, uint32_t sector)
|
||||
int
|
||||
cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector)
|
||||
{
|
||||
int track = cdi_get_track(cdi, sector) - 1;
|
||||
const track_t *trk;
|
||||
const int track = cdi_get_track(cdi, sector) - 1;
|
||||
|
||||
if (track < 0)
|
||||
return 0;
|
||||
|
||||
trk = &cdi->tracks[track];
|
||||
const track_t *trk = &cdi->tracks[track];
|
||||
|
||||
return trk->form;
|
||||
}
|
||||
@@ -533,10 +508,12 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form)
|
||||
uint8_t pvd[COOKED_SECTOR_SIZE];
|
||||
uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */
|
||||
|
||||
if ((!mode2 || (form == 0)) && (sector_size == RAW_SECTOR_SIZE))
|
||||
seek += 16;
|
||||
if (mode2 && (form >= 1))
|
||||
seek += 24;
|
||||
if (sector_size == RAW_SECTOR_SIZE) {
|
||||
if (!mode2 || (form == 0))
|
||||
seek += 16;
|
||||
else
|
||||
seek += 24;
|
||||
}
|
||||
|
||||
file->read(file, pvd, seek, COOKED_SECTOR_SIZE);
|
||||
|
||||
@@ -591,7 +568,7 @@ cdi_load_iso(cd_img_t *cdi, const char *filename)
|
||||
/* Try to detect ISO type. */
|
||||
trk.form = 0;
|
||||
trk.mode2 = 0;
|
||||
/* TODO: Merge the first and last cases since they result in the same thing. */
|
||||
|
||||
if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0, 0))
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
else if (cdi_can_read_pvd(trk.file, 2336, 1, 0)) {
|
||||
@@ -601,9 +578,17 @@ cdi_load_iso(cd_img_t *cdi, const char *filename)
|
||||
trk.sector_size = 2324;
|
||||
trk.mode2 = 1;
|
||||
trk.form = 2;
|
||||
} else if (cdi_can_read_pvd(trk.file, 2328, 1, 2)) {
|
||||
trk.sector_size = 2328;
|
||||
trk.mode2 = 1;
|
||||
trk.form = 2;
|
||||
} else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) {
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
trk.mode2 = 1;
|
||||
} else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 1)) {
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
trk.mode2 = 1;
|
||||
trk.form = 1;
|
||||
} else {
|
||||
/* We use 2048 mode 1 as the default. */
|
||||
trk.sector_size = COOKED_SECTOR_SIZE;
|
||||
@@ -754,17 +739,12 @@ static int
|
||||
cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap)
|
||||
{
|
||||
/* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */
|
||||
uint64_t skip;
|
||||
uint64_t temp;
|
||||
track_t *prev = NULL;
|
||||
|
||||
/* Skip *MUST* be calculated even if prestart is 0. */
|
||||
if (prestart >= 0) {
|
||||
if (prestart > cur->start)
|
||||
return 0;
|
||||
skip = cur->start - prestart;
|
||||
} else
|
||||
skip = 0ULL;
|
||||
if (prestart > cur->start)
|
||||
return 0;
|
||||
const uint64_t skip = cur->start - prestart;
|
||||
|
||||
if ((cdi->tracks != NULL) && (cdi->tracks_num != 0))
|
||||
prev = &cdi->tracks[cdi->tracks_num - 1];
|
||||
@@ -793,7 +773,7 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
|
||||
*total_pregap += cur_pregap;
|
||||
cur->start += *total_pregap;
|
||||
} else {
|
||||
temp = prev->file->get_length(prev->file) - (prev->skip);
|
||||
const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip);
|
||||
prev->length = temp / ((uint64_t) prev->sector_size);
|
||||
if ((temp % prev->sector_size) != 0)
|
||||
prev->length++;
|
||||
@@ -823,8 +803,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
{
|
||||
track_t trk;
|
||||
char pathname[MAX_FILENAME_LENGTH];
|
||||
char filename[MAX_FILENAME_LENGTH];
|
||||
char temp[MAX_FILENAME_LENGTH];
|
||||
uint64_t shift = 0ULL;
|
||||
uint64_t prestart = 0ULL;
|
||||
uint64_t cur_pregap = 0ULL;
|
||||
@@ -836,7 +814,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
int can_add_track = 0;
|
||||
FILE *fp;
|
||||
char buf[MAX_LINE_LENGTH];
|
||||
char ansi[MAX_FILENAME_LENGTH];
|
||||
char *line;
|
||||
char *command;
|
||||
char *type;
|
||||
@@ -877,7 +854,7 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
}
|
||||
}
|
||||
|
||||
success = cdi_cue_get_keyword(&command, &line);
|
||||
(void) cdi_cue_get_keyword(&command, &line);
|
||||
|
||||
if (!strcmp(command, "TRACK")) {
|
||||
if (can_add_track)
|
||||
@@ -980,6 +957,9 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(command, "FILE")) {
|
||||
char filename[MAX_FILENAME_LENGTH];
|
||||
char ansi[MAX_FILENAME_LENGTH];
|
||||
|
||||
if (can_add_track)
|
||||
success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap);
|
||||
else
|
||||
@@ -1002,7 +982,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
|
||||
error = 1;
|
||||
|
||||
if (!strcmp(type, "BINARY")) {
|
||||
memset(temp, 0, MAX_FILENAME_LENGTH * sizeof(char));
|
||||
path_append_filename(filename, pathname, ansi);
|
||||
trk.file = track_file_init(filename, &error);
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@ add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali14
|
||||
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
|
||||
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
|
||||
opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
|
||||
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c
|
||||
sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c
|
||||
umc_hb4.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
|
||||
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c
|
||||
sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c
|
||||
sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c
|
||||
via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c
|
||||
umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
|
||||
|
||||
if(OLIVETTI)
|
||||
target_sources(chipset PRIVATE olivetti_eva.c)
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
|
||||
#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | \
|
||||
((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
|
||||
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
|
||||
|
||||
#ifdef ENABLE_ALI1489_LOG
|
||||
@@ -64,19 +65,14 @@ ali1489_log(const char *fmt, ...)
|
||||
|
||||
typedef struct ali1489_t {
|
||||
uint8_t index;
|
||||
uint8_t ide_index;
|
||||
uint8_t ide_chip_id;
|
||||
uint8_t pci_slot;
|
||||
uint8_t regs[256];
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t ide_regs[256];
|
||||
|
||||
port_92_t *port_92;
|
||||
smram_t *smram;
|
||||
} ali1489_t;
|
||||
|
||||
static void ali1489_ide_handler(ali1489_t *dev);
|
||||
|
||||
static void
|
||||
ali1489_shadow_recalc(ali1489_t *dev)
|
||||
{
|
||||
@@ -85,7 +81,8 @@ ali1489_shadow_recalc(ali1489_t *dev)
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (dev->regs[0x13] & (1 << i)) {
|
||||
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
|
||||
0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
0xc0000 + (i << 14), 0xc3fff + (i << 14),
|
||||
!!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE);
|
||||
} else {
|
||||
ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14));
|
||||
@@ -96,7 +93,8 @@ ali1489_shadow_recalc(ali1489_t *dev)
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (dev->regs[0x14] & (1 << i)) {
|
||||
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
|
||||
0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
0xe0000 + (i << 15), 0xe7fff + (i << 15),
|
||||
!!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
|
||||
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE);
|
||||
shadowbios |= !!(dev->regs[0x14] & 0x10);
|
||||
shadowbios_write |= !!(dev->regs[0x14] & 0x20);
|
||||
@@ -142,25 +140,9 @@ ali1489_smram_recalc(ali1489_t *dev)
|
||||
static void
|
||||
ali1489_defaults(ali1489_t *dev)
|
||||
{
|
||||
memset(dev->ide_regs, 0x00, 256);
|
||||
memset(dev->pci_conf, 0x00, 256);
|
||||
memset(dev->regs, 0x00, 256);
|
||||
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
|
||||
/* IDE registers */
|
||||
dev->ide_regs[0x00] = 0x57;
|
||||
dev->ide_regs[0x01] = 0x02;
|
||||
dev->ide_regs[0x08] = 0xff;
|
||||
dev->ide_regs[0x09] = 0x41;
|
||||
dev->ide_regs[0x0c] = 0x02;
|
||||
dev->ide_regs[0x0e] = 0x02;
|
||||
dev->ide_regs[0x10] = 0x02;
|
||||
dev->ide_regs[0x12] = 0x02;
|
||||
dev->ide_regs[0x34] = 0xff;
|
||||
dev->ide_regs[0x35] = 0x01;
|
||||
|
||||
/* PCI registers */
|
||||
dev->pci_conf[0x00] = 0xb9;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
@@ -203,8 +185,6 @@ ali1489_defaults(ali1489_t *dev)
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
|
||||
ali1489_ide_handler(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -385,7 +365,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x44: /* PCI INTx Sensitivity Register */
|
||||
/* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */
|
||||
/* TODO: When doing the IRQ and PCI IRQ rewrite,
|
||||
bits 0 to 3 toggle edge/level output. */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
default:
|
||||
@@ -464,121 +445,6 @@ ali1489_pci_read(UNUSED(int func), int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ali1489_ide_handler(ali1489_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
if (dev->ide_regs[0x01] & 0x01) {
|
||||
ide_pri_enable();
|
||||
if (!(dev->ide_regs[0x35] & 0x40))
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ali1489_ide_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0xf4: /* Usually it writes 30h here */
|
||||
dev->ide_chip_id = val;
|
||||
break;
|
||||
|
||||
case 0xf8:
|
||||
dev->ide_index = val;
|
||||
break;
|
||||
|
||||
case 0xfc:
|
||||
if (dev->ide_chip_id != 0x30)
|
||||
break;
|
||||
|
||||
switch (dev->ide_index) {
|
||||
case 0x01: /* IDE Configuration Register */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x8f;
|
||||
ali1489_ide_handler(dev);
|
||||
break;
|
||||
case 0x02: /* DBA Data Byte Cative Count for IDE-1 */
|
||||
case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */
|
||||
case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */
|
||||
case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */
|
||||
case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */
|
||||
case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */
|
||||
case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */
|
||||
case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */
|
||||
case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */
|
||||
case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */
|
||||
case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */
|
||||
case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */
|
||||
case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */
|
||||
case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */
|
||||
case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */
|
||||
case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */
|
||||
case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */
|
||||
case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */
|
||||
case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */
|
||||
case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x1f;
|
||||
break;
|
||||
case 0x07: /* Buffer Mode Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val;
|
||||
break;
|
||||
case 0x09: /* IDEPE1 IDE Port Enable Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0xc3;
|
||||
break;
|
||||
case 0x0a: /* Buffer Mode Register 2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x4f;
|
||||
break;
|
||||
case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */
|
||||
case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */
|
||||
case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */
|
||||
case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x03;
|
||||
break;
|
||||
case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */
|
||||
case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */
|
||||
case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
|
||||
case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
|
||||
dev->ide_regs[dev->ide_index] = val & 0x1f;
|
||||
break;
|
||||
case 0x35: /* IDEPE3 IDE Port Enable Register 3 */
|
||||
dev->ide_regs[dev->ide_index] = val;
|
||||
ali1489_ide_handler(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
ali1489_ide_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const ali1489_t *dev = (ali1489_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0xf4:
|
||||
ret = dev->ide_chip_id;
|
||||
break;
|
||||
case 0xfc:
|
||||
ret = dev->ide_regs[dev->ide_index];
|
||||
ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ali1489_reset(void *priv)
|
||||
{
|
||||
@@ -612,19 +478,10 @@ ali1489_init(UNUSED(const device_t *info))
|
||||
23h Data Port */
|
||||
io_sethandler(0x0022, 0x0002, ali1489_read, NULL, NULL, ali1489_write, NULL, NULL, dev);
|
||||
|
||||
/* M1489 IDE controller
|
||||
F4h Chip ID we write always 30h onto it
|
||||
F8h Index Port
|
||||
FCh Data Port
|
||||
*/
|
||||
io_sethandler(0x0f4, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0f8, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
|
||||
|
||||
/* Dummy M1489 PCI device */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
device_add(&ide_ali1489_device);
|
||||
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
dev->smram = smram_add();
|
||||
|
||||
@@ -197,6 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
soft_reset_pci = !!(val & 0x80);
|
||||
pci_set_mirq_level(PCI_MIRQ0, !(val & 0x10));
|
||||
pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10));
|
||||
ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]);
|
||||
pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]);
|
||||
@@ -417,6 +418,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
|
||||
|
||||
case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */
|
||||
dev->pci_conf[addr] = val & 0x1f;
|
||||
pci_set_mirq_level(PCI_MIRQ1, !(val & 0x10));
|
||||
pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10));
|
||||
ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]);
|
||||
pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]);
|
||||
@@ -489,12 +491,10 @@ static void
|
||||
ali5229_ide_irq_handler(ali1543_t *dev)
|
||||
{
|
||||
int ctl = 0;
|
||||
int ch = 0;
|
||||
int bit = 0;
|
||||
|
||||
if (dev->ide_conf[0x52] & 0x10) {
|
||||
ctl ^= 1;
|
||||
ch ^= 1;
|
||||
bit ^= 5;
|
||||
}
|
||||
|
||||
@@ -706,7 +706,7 @@ ali5229_chip_reset(ali1543_t *dev)
|
||||
ali5229_write(0, 0x09, 0xfa, dev);
|
||||
ali5229_write(0, 0x52, 0x00, dev);
|
||||
|
||||
ali5229_write(0, 0x50, 0x00, dev);
|
||||
ali5229_write(0, 0x50, 0x02, dev);
|
||||
|
||||
sff_set_slot(dev->ide_controller[0], dev->ide_slot);
|
||||
sff_set_slot(dev->ide_controller[1], dev->ide_slot);
|
||||
@@ -719,7 +719,7 @@ static void
|
||||
ali5229_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1543_t *dev = (ali1543_t *) priv;
|
||||
ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val);
|
||||
ali1543_log("M5229: [W] dev->ide_conf[%02x] = %02x\n", addr, val);
|
||||
|
||||
if (func > 0)
|
||||
return;
|
||||
@@ -758,6 +758,10 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
|
||||
ali5229_ide_irq_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* LT - Latency Timer */
|
||||
dev->ide_conf[addr] = val;
|
||||
break;
|
||||
|
||||
/* Primary Base Address */
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
@@ -778,9 +782,9 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
|
||||
/* Datasheet erratum: the PCI BAR's actually have different sizes. */
|
||||
if (addr == 0x20)
|
||||
dev->ide_conf[addr] = (val & 0xe0) | 0x01;
|
||||
else if ((addr & 0x43) == 0x00)
|
||||
else if ((addr & 0x07) == 0x00)
|
||||
dev->ide_conf[addr] = (val & 0xf8) | 0x01;
|
||||
else if ((addr & 0x43) == 0x40)
|
||||
else if ((addr & 0x07) == 0x04)
|
||||
dev->ide_conf[addr] = (val & 0xfc) | 0x01;
|
||||
else
|
||||
dev->ide_conf[addr] = val;
|
||||
@@ -889,13 +893,15 @@ ali5229_read(int func, int addr, void *priv)
|
||||
if (dev->ide_dev_enable && (func == 0)) {
|
||||
ret = dev->ide_conf[addr];
|
||||
if ((addr == 0x09) && !(dev->ide_conf[0x50] & 0x02))
|
||||
ret &= 0x0f;
|
||||
ret = (ret & 0x0f) | 0x80;
|
||||
else if (addr == 0x50)
|
||||
ret = (ret & 0xfe) | (dev->ide_dev_enable ? 0x01 : 0x00);
|
||||
else if (addr == 0x75)
|
||||
ret = ide_read_ali_75();
|
||||
else if (addr == 0x76)
|
||||
ret = ide_read_ali_76();
|
||||
|
||||
ali1543_log("M5229: [R] dev->ide_conf[%02x] = %02x\n", addr, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -984,7 +990,7 @@ static void
|
||||
ali7101_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1543_t *dev = (ali1543_t *) priv;
|
||||
ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val);
|
||||
ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val);
|
||||
|
||||
if (func > 0)
|
||||
return;
|
||||
@@ -1408,65 +1414,78 @@ ali7101_read(int func, int addr, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->pmu_dev_enable && (func == 0)) {
|
||||
if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9))
|
||||
return 0xff;
|
||||
|
||||
/* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pmu_conf[addr];
|
||||
break;
|
||||
case 0x42:
|
||||
ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00);
|
||||
break;
|
||||
case 0x43:
|
||||
ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x7f:
|
||||
ret = 0x80;
|
||||
break;
|
||||
case 0xbc:
|
||||
ret = inb(0x70);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->pmu_conf[0x77] & 0x10) {
|
||||
if (!(dev->pmu_conf[0xc9] & 0x01) || (addr < 0x40) || (addr == 0xc9)) {
|
||||
/* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pmu_conf[addr];
|
||||
break;
|
||||
case 0x10 ... 0x13:
|
||||
if (dev->pmu_conf[0x5b] & 0x02)
|
||||
ret = 0x00;
|
||||
else
|
||||
ret = dev->pmu_conf[addr];
|
||||
break;
|
||||
case 0x14 ... 0x17:
|
||||
if (dev->pmu_conf[0x5b] & 0x04)
|
||||
ret = 0x00;
|
||||
else
|
||||
ret = dev->pmu_conf[addr];
|
||||
break;
|
||||
case 0x42:
|
||||
dev->pmu_conf[addr] &= 0xe0;
|
||||
ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00);
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pmu_conf[addr] &= 0xef;
|
||||
acpi_ali_soft_smi_status_write(dev->acpi, 0);
|
||||
ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00;
|
||||
break;
|
||||
case 0x7f:
|
||||
ret = 0x80;
|
||||
break;
|
||||
case 0xbc:
|
||||
ret = inb(0x70);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x48:
|
||||
dev->pmu_conf[addr] = 0x00;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pmu_conf[addr] &= 0x60;
|
||||
break;
|
||||
case 0x4a:
|
||||
dev->pmu_conf[addr] &= 0xc7;
|
||||
break;
|
||||
if (dev->pmu_conf[0x77] & 0x10) {
|
||||
switch (addr) {
|
||||
case 0x42:
|
||||
dev->pmu_conf[addr] &= 0xe0;
|
||||
break;
|
||||
case 0x43:
|
||||
dev->pmu_conf[addr] &= 0xef;
|
||||
acpi_ali_soft_smi_status_write(dev->acpi, 0);
|
||||
break;
|
||||
|
||||
case 0x4e:
|
||||
dev->pmu_conf[addr] &= 0xfa;
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->pmu_conf[addr] &= 0xfe;
|
||||
break;
|
||||
case 0x48:
|
||||
dev->pmu_conf[addr] = 0x00;
|
||||
break;
|
||||
case 0x49:
|
||||
dev->pmu_conf[addr] &= 0x60;
|
||||
break;
|
||||
case 0x4a:
|
||||
dev->pmu_conf[addr] &= 0xc7;
|
||||
break;
|
||||
|
||||
case 0x74:
|
||||
dev->pmu_conf[addr] &= 0xcc;
|
||||
break;
|
||||
case 0x4e:
|
||||
dev->pmu_conf[addr] &= 0xfa;
|
||||
break;
|
||||
case 0x4f:
|
||||
dev->pmu_conf[addr] &= 0xfe;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case 0x74:
|
||||
dev->pmu_conf[addr] &= 0xcc;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ali1543_log("M7101: [R] dev->pmu_conf[%02x] = %02x\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -471,7 +471,8 @@ ali6117_init(const device_t *info)
|
||||
|
||||
dev->local = info->local;
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
if (!(dev->local & 0x08))
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
ali6117_setup(dev);
|
||||
|
||||
|
||||
@@ -311,8 +311,10 @@ contaq_82c59x_close(void *priv)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) priv;
|
||||
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
if (dev->green) {
|
||||
smram_del(dev->smram[1]);
|
||||
smram_del(dev->smram[0]);
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -493,16 +493,40 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x52: /* Cache Control Register */
|
||||
switch (dev->type) {
|
||||
default:
|
||||
/*
|
||||
420TX/ZX:
|
||||
Bit 7-6: 0, 0 = 64 kB,
|
||||
0, 1 = 128 kB,
|
||||
1, 0 = 256 kB,
|
||||
1, 1 = 512 kB.
|
||||
Bit 5: 1 = L2 cache present, 0 = L2 cache absent.
|
||||
Bit 1: 1 = Write back cache, 0 = write through cache.
|
||||
Bit 0: 1 = L2 cache enable, 0 = L2 cache disable.
|
||||
*/
|
||||
case INTEL_420TX:
|
||||
case INTEL_420ZX:
|
||||
case INTEL_430NX:
|
||||
regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1f);
|
||||
cpu_cache_ext_enabled = val & 0x01;
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_430LX:
|
||||
regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1b);
|
||||
cpu_cache_ext_enabled = val & 0x01;
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_430FX:
|
||||
case INTEL_430VX:
|
||||
case INTEL_430TX:
|
||||
regs[0x52] = (val & 0xfb);
|
||||
regs[0x52] = (regs[0x52] & 0x04) | (val & 0xfb);
|
||||
cpu_cache_ext_enabled = ((val & 0x03) == 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_430NX:
|
||||
case INTEL_430HX:
|
||||
regs[0x52] = val;
|
||||
cpu_cache_ext_enabled = ((val & 0x03) == 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_440FX:
|
||||
regs[0x52] = val;
|
||||
break;
|
||||
@@ -1522,6 +1546,8 @@ i4x0_read(int func, int addr, void *priv)
|
||||
with the addition of bits 3 and 0. */
|
||||
if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)))
|
||||
ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06);
|
||||
else if ((func == 0) && (addr == 0x52) && (dev->type == INTEL_430TX) && !strcmp(machine_get_internal_name(), "tomahawk"))
|
||||
ret = 0xb2;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1628,7 +1654,7 @@ i4x0_init(const device_t *info)
|
||||
0x00 = None, 0x01 = 64 kB, 0x41 = 128 kB, 0x81 = 256 kB, 0xc1 = 512 kB,
|
||||
If bit 0 is set, then if bit 2 is also set, the cache is write back,
|
||||
otherwise it's write through. */
|
||||
regs[0x52] = 0xc3; /* 512 kB writeback cache */
|
||||
regs[0x52] = 0xe0; /* 512 kB writeback cache */
|
||||
regs[0x57] = 0x31;
|
||||
regs[0x59] = 0x0f;
|
||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02;
|
||||
|
||||
@@ -8,19 +8,14 @@
|
||||
*
|
||||
* Implementation of the Intel 450KX Mars Chipset.
|
||||
*
|
||||
* i450GX is way more popular of an option but needs more stuff.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021-2024 Miran Grca.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
|
||||
/*
|
||||
Note: i450KX PB manages PCI memory access with MC manages DRAM memory access.
|
||||
Due to 86Box limitations we can't manage them seperately thus it is dev branch till then.
|
||||
|
||||
i450GX is way more popular of an option but needs more stuff.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -97,17 +92,18 @@ i450kx_smram_recalc(i450kx_t *dev, int bus)
|
||||
const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
|
||||
uint32_t addr;
|
||||
uint32_t size;
|
||||
int enable = bus ? !(regs[0x57] & 0x08) : (regs[0x57] & 0x08);
|
||||
|
||||
smram_disable(dev->smram[bus]);
|
||||
|
||||
addr = ((uint32_t) regs[0xb8] << 16) | ((uint32_t) regs[0xb9] << 24);
|
||||
size = (((uint32_t) ((regs[0xbb] >> 4) & 0x0f)) << 16) + 0x00010000;
|
||||
|
||||
if ((addr != 0x00000000) && !!(regs[0x57] & 0x08)) {
|
||||
if ((addr != 0x00000000) && enable) {
|
||||
if (bus)
|
||||
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, !!(regs[0x57] & 8), 0, 1);
|
||||
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, 0, enable);
|
||||
else
|
||||
smram_enable_ex(dev->smram[bus], addr, addr, size, !!(regs[0x57] & 8), 0, 1, 0);
|
||||
smram_enable_ex(dev->smram[bus], addr, addr, size, 0, 0, enable, 0);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
@@ -118,10 +114,8 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus)
|
||||
{
|
||||
const uint8_t *regs = bus ? dev->pb_pci_conf : dev->mc_pci_conf;
|
||||
|
||||
#if 0
|
||||
// int state = (regs[0x58] & 0x02) ? (MEM_READ_EXTANY | MEM_WRITE_EXTANY) : (MEM_READ_DISABLED | MEM_WRITE_DISABLED);
|
||||
#endif
|
||||
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
int state = (regs[0x58] & 0x02) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
|
||||
(MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if (bus)
|
||||
mem_set_mem_state_bus_both(0x000a0000, 0x00020000, state);
|
||||
@@ -136,10 +130,10 @@ pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *) priv;
|
||||
|
||||
// pclog("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
i450kx_log("i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
if (func == 0) {
|
||||
i450kx_log("[%04X:%08X] i450KX-PB: [W] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
|
||||
addr, val);
|
||||
|
||||
if (func == 0)
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pb_pci_conf[addr] = (dev->pb_pci_conf[addr] & 0x04) | (val & 0x53);
|
||||
@@ -373,6 +367,7 @@ pb_write(int func, int addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -381,10 +376,12 @@ pb_read(int func, int addr, void *priv)
|
||||
const i450kx_t *dev = (i450kx_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
if (func == 0) {
|
||||
ret = dev->pb_pci_conf[addr];
|
||||
|
||||
// pclog("i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
|
||||
i450kx_log("[%04X:%08X] i450KX-PB: [R] dev->pb_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
|
||||
addr, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -407,10 +404,10 @@ mc_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *) priv;
|
||||
|
||||
// pclog("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
i450kx_log("i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, val, inb(0x80));
|
||||
if (func == 0) {
|
||||
i450kx_log("[%04X:%08X] i450KX-MC: [W] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
|
||||
addr, val);
|
||||
|
||||
if (func == 0)
|
||||
switch (addr) {
|
||||
case 0x4c:
|
||||
dev->mc_pci_conf[addr] = val & 0xdf;
|
||||
@@ -600,6 +597,7 @@ mc_write(int func, int addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -608,10 +606,12 @@ mc_read(int func, int addr, void *priv)
|
||||
const i450kx_t *dev = (i450kx_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
if (func == 0) {
|
||||
ret = dev->mc_pci_conf[addr];
|
||||
|
||||
// pclog("i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X POST: %02X\n", addr, ret, inb(0x80));
|
||||
i450kx_log("[%04X:%08X] i450KX-MC: [R] dev->mc_pci_conf[%02X] = %02X\n", CS, cpu_state.pc,
|
||||
addr, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -622,10 +622,6 @@ i450kx_reset(void *priv)
|
||||
i450kx_t *dev = (i450kx_t *) priv;
|
||||
uint32_t i;
|
||||
|
||||
#if 0
|
||||
// pclog("i450KX: i450kx_reset()\n");
|
||||
#endif
|
||||
|
||||
/* Defaults PB */
|
||||
dev->pb_pci_conf[0x00] = 0x86;
|
||||
dev->pb_pci_conf[0x01] = 0x80;
|
||||
|
||||
@@ -597,6 +597,12 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
|
||||
if (dev->type == 3) {
|
||||
if (val & 0x20)
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
|
||||
else
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
|
||||
}
|
||||
piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled");
|
||||
}
|
||||
break;
|
||||
@@ -1006,11 +1012,11 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0xc0:
|
||||
if (dev->type <= 4)
|
||||
fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20);
|
||||
fregs[0xc0] = (fregs[0xc0] & 0x40) | (val & 0xbf);
|
||||
break;
|
||||
case 0xc1:
|
||||
if (dev->type <= 4)
|
||||
fregs[0xc1] &= ~val;
|
||||
fregs[0xc1] = (fregs[0xc0] & ~(val & 0x8f)) | (val & 0x20);
|
||||
break;
|
||||
case 0xff:
|
||||
if (dev->type == 4) {
|
||||
@@ -1572,7 +1578,16 @@ piix_init(const device_t *info)
|
||||
dev->acpi = device_add(&acpi_intel_device);
|
||||
acpi_set_slot(dev->acpi, dev->pci_slot);
|
||||
acpi_set_nvr(dev->acpi, dev->nvr);
|
||||
acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd);
|
||||
/*
|
||||
TriGem Richmond:
|
||||
- Bit 5: Manufacturing jumper, must be set;
|
||||
- Bit 4: CMOS clear jumper, must be clear;
|
||||
- Bit 0: Password switch, must be clear.
|
||||
*/
|
||||
if (!strcmp(machine_get_internal_name(), "richmond"))
|
||||
acpi_set_gpireg2_default(dev->acpi, 0xee);
|
||||
else
|
||||
acpi_set_gpireg2_default(dev->acpi, (dev->type > 4) ? 0xf1 : 0xdd);
|
||||
acpi_set_trap_update(dev->acpi, piix_trap_update, dev);
|
||||
|
||||
dev->ddma = device_add(&ddma_device);
|
||||
|
||||
@@ -646,7 +646,8 @@ neat_read(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
ret = dev->regs[dev->indx];
|
||||
if ((dev->indx >= 0x60) && (dev->indx <= 0x6f))
|
||||
ret = dev->regs[dev->indx];
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -673,13 +674,14 @@ neat_init(UNUSED(const device_t *info))
|
||||
{
|
||||
neat_t *dev;
|
||||
uint8_t dram_mode = 0;
|
||||
uint8_t i;
|
||||
|
||||
/* Create an instance. */
|
||||
dev = (neat_t *) malloc(sizeof(neat_t));
|
||||
memset(dev, 0x00, sizeof(neat_t));
|
||||
|
||||
/* Initialize some of the registers to specific defaults. */
|
||||
for (uint8_t i = REG_RA0; i <= REG_RB11; i++) {
|
||||
for (i = REG_RA0; i <= REG_RB11; i++) {
|
||||
dev->indx = i;
|
||||
neat_write(0x0023, 0x00, dev);
|
||||
}
|
||||
|
||||
@@ -66,15 +66,17 @@ typedef struct ems_page_t {
|
||||
} ems_page_t;
|
||||
|
||||
typedef struct scat_t {
|
||||
int type;
|
||||
uint8_t max_reg;
|
||||
uint8_t reg_2xA;
|
||||
|
||||
int indx;
|
||||
uint8_t regs[256];
|
||||
uint8_t reg_2xA;
|
||||
uint8_t regs[256];
|
||||
|
||||
uint32_t xms_bound;
|
||||
|
||||
int external_is_RAS;
|
||||
int type;
|
||||
int indx;
|
||||
|
||||
int external_is_RAS;
|
||||
|
||||
ems_page_t null_page;
|
||||
ems_page_t page[32];
|
||||
@@ -1233,7 +1235,8 @@ scat_in(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = dev->regs[dev->indx];
|
||||
if (dev->indx <= dev->max_reg)
|
||||
ret = dev->regs[dev->indx];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1393,6 +1396,8 @@ scat_init(const device_t *info)
|
||||
|
||||
sx = (dev->type == 32) ? 1 : 0;
|
||||
|
||||
dev->max_reg = sx ? 0x64 : 0x4f;
|
||||
|
||||
for (uint32_t i = 0; i < sizeof(dev->regs); i++)
|
||||
dev->regs[i] = 0xff;
|
||||
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
@@ -41,7 +42,7 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5511_LOG
|
||||
@@ -63,570 +64,53 @@ sis_5511_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5511_t {
|
||||
uint8_t index;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
uint8_t regs[16];
|
||||
uint8_t states[7];
|
||||
void *h2p;
|
||||
|
||||
uint8_t slic_regs[4096];
|
||||
void *p2i;
|
||||
void *ide;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[2][256];
|
||||
|
||||
mem_mapping_t slic_mapping;
|
||||
|
||||
sff8038i_t *bm[2];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
void *pit;
|
||||
nvr_t *nvr;
|
||||
|
||||
uint8_t (*pit_read_reg)(void *priv, uint8_t reg);
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5511_t;
|
||||
|
||||
static void
|
||||
sis_5511_shadow_recalc(sis_5511_t *dev)
|
||||
sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x80; i <= 0x86; i++) {
|
||||
if (i == 0x86) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5511_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5511_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_smram_recalc(sis_5511_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x65] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00) switch (addr) {
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= 0xb0;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
/* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC.
|
||||
The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h.
|
||||
The latter (bit 6) means the chipset intercepts all odd FXh to 64h.
|
||||
Bit 5 sets fast reset latency. This should be fixed on the other SiS
|
||||
chipsets as well. */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5e:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
if ((dev->pci_conf[0x68] & 1) && (val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x69] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x61 ... 0x64:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5511_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x6a ... 0x6e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x70: /* DRAM Bank Register 0-0 */
|
||||
case 0x72: /* DRAM Bank Register 0-1 */
|
||||
case 0x74: /* DRAM Bank Register 1-0 */
|
||||
case 0x76: /* DRAM Bank Register 1-1 */
|
||||
case 0x78: /* DRAM Bank Register 2-0 */
|
||||
case 0x7a: /* DRAM Bank Register 2-1 */
|
||||
case 0x7c: /* DRAM Bank Register 3-0 */
|
||||
case 0x7e: /* DRAM Bank Register 3-1 */
|
||||
spd_write_drbs(dev->regs, 0x70, 0x7e, 0x82);
|
||||
break;
|
||||
|
||||
case 0x71: /* DRAM Bank Register 0-0 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x75: /* DRAM Bank Register 1-0 */
|
||||
case 0x79: /* DRAM Bank Register 2-0 */
|
||||
case 0x7d: /* DRAM Bank Register 3-0 */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x73: /* DRAM Bank Register 0-1 */
|
||||
case 0x77: /* DRAM Bank Register 1-1 */
|
||||
case 0x7b: /* DRAM Bank Register 2-1 */
|
||||
case 0x7f: /* DRAM Bank Register 3-1 */
|
||||
dev->pci_conf[addr] = val & 0x83;
|
||||
break;
|
||||
|
||||
case 0x80 ... 0x85:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x90 ... 0x93: /* 5512 General Purpose Register Index */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000000:
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
dev->slic_regs[addr] = val;
|
||||
break;
|
||||
case 0x00000010:
|
||||
case 0x00000018:
|
||||
case 0x00000028:
|
||||
case 0x00000038:
|
||||
dev->slic_regs[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x00000030:
|
||||
dev->slic_regs[addr] = val & 0x0f;
|
||||
mem_mapping_set_addr(&dev->slic_mapping,
|
||||
(((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000);
|
||||
break;
|
||||
}
|
||||
if (func == 0x00)
|
||||
sis_5511_host_to_pci_write(addr, val, dev->h2p);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5511_read(UNUSED(int func), int addr, void *priv)
|
||||
sis_5511_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = dev->pci_conf[addr];
|
||||
ret = sis_5511_host_to_pci_read(addr, dev->h2p);
|
||||
|
||||
sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5511_slic_read(uint32_t addr, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
ret = dev->slic_regs[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
|
||||
{
|
||||
sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status */
|
||||
dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30);
|
||||
break;
|
||||
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x41: /* INTA# Remapping Control Register */
|
||||
case 0x42: /* INTB# Remapping Control Register */
|
||||
case 0x43: /* INTC# Remapping Control Register */
|
||||
case 0x44: /* INTD# Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f));
|
||||
break;
|
||||
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x60: /* MIRQ0 Remapping Control Register */
|
||||
case 0x61: /* MIRQ1 Remapping Control Register */
|
||||
sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val);
|
||||
dev->pci_conf_sb[0][addr] = val & 0xcf;
|
||||
if (val & 0x80)
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
|
||||
break;
|
||||
|
||||
case 0x62: /* On-board Device DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x63: /* IDEIRQ Remapping Control Register */
|
||||
sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val);
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_mirq_routing(PCI_MIRQ2, val & 0xf);
|
||||
break;
|
||||
|
||||
case 0x64: /* GPIO0 Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x80;
|
||||
break;
|
||||
|
||||
case 0x66: /* GPIO0 Output Mode Control Register */
|
||||
case 0x67: /* GPIO0 Output Mode Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6a: /* GPIO Status Register */
|
||||
dev->pci_conf_sb[0][addr] |= (val & 0x10);
|
||||
dev->pci_conf_sb[0][addr] &= ~(val & 0x01);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_irq_handler(sis_5511_t *dev)
|
||||
{
|
||||
if (dev->pci_conf_sb[1][0x09] & 0x01) {
|
||||
/* Primary IDE is native. */
|
||||
sis_5511_log("Primary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Primary IDE is legacy. */
|
||||
sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
|
||||
}
|
||||
|
||||
if (dev->pci_conf_sb[1][0x09] & 0x04) {
|
||||
/* Secondary IDE is native. */
|
||||
sis_5511_log("Secondary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Secondary IDE is legacy. */
|
||||
sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_handler(sis_5511_t *dev)
|
||||
{
|
||||
uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01;
|
||||
|
||||
uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe;
|
||||
uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe;
|
||||
uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe;
|
||||
uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe;
|
||||
|
||||
uint16_t current_pri_base;
|
||||
uint16_t current_pri_side;
|
||||
uint16_t current_sec_base;
|
||||
uint16_t current_sec_side;
|
||||
|
||||
/* Primary Channel Programming */
|
||||
current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr;
|
||||
current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr;
|
||||
|
||||
/* Secondary Channel Programming */
|
||||
current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr;
|
||||
current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr;
|
||||
|
||||
sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n");
|
||||
ide_pri_disable();
|
||||
sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n");
|
||||
ide_sec_disable();
|
||||
|
||||
if (ide_io_on) {
|
||||
/* Primary Channel Setup */
|
||||
if (dev->pci_conf_sb[1][0x4a] & 0x02) {
|
||||
sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base);
|
||||
ide_set_base(0, current_pri_base);
|
||||
sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side);
|
||||
ide_set_side(0, current_pri_side);
|
||||
|
||||
sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n");
|
||||
ide_pri_enable();
|
||||
|
||||
sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
|
||||
}
|
||||
|
||||
/* Secondary Channel Setup */
|
||||
if (dev->pci_conf_sb[1][0x4a] & 0x04) {
|
||||
sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base);
|
||||
ide_set_base(1, current_sec_base);
|
||||
sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side);
|
||||
ide_set_side(1, current_sec_side);
|
||||
|
||||
sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n");
|
||||
ide_sec_enable();
|
||||
|
||||
sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
|
||||
}
|
||||
}
|
||||
|
||||
sff_bus_master_handler(dev->bm[0], ide_io_on,
|
||||
((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0);
|
||||
sff_bus_master_handler(dev->bm[1], ide_io_on,
|
||||
((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev)
|
||||
{
|
||||
sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x05;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x06: /* Status low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x20;
|
||||
break;
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38);
|
||||
break;
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05);
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x0d: /* Latency Timer */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
/* Primary Base Address */
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
fallthrough;
|
||||
|
||||
/* Secondary Base Address */
|
||||
case 0x18:
|
||||
case 0x19:
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
fallthrough;
|
||||
|
||||
/* Bus Mastering Base Address */
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
if (addr == 0x20)
|
||||
dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01;
|
||||
else
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x30: /* Expansion ROM Base Address */
|
||||
case 0x31: /* Expansion ROM Base Address */
|
||||
case 0x32: /* Expansion ROM Base Address */
|
||||
case 0x33: /* Expansion ROM Base Address */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
case 0x49: /* IDE Command Active Time Control */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x9e;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control Register 1 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
switch (func) {
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev);
|
||||
break;
|
||||
case 1:
|
||||
sis_5513_ide_write(addr, val, dev);
|
||||
break;
|
||||
}
|
||||
sis_5511_log("SiS 5513: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
else if (func == 0x01)
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -635,258 +119,21 @@ sis_5513_read(int func, int addr, void *priv)
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00) {
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pci_conf_sb[func][addr];
|
||||
break;
|
||||
case 0x4c ... 0x4f:
|
||||
ret = pic_read_icw(0, addr & 0x03);
|
||||
break;
|
||||
case 0x50 ... 0x53:
|
||||
ret = pic_read_icw(1, addr & 0x03);
|
||||
break;
|
||||
case 0x54 ... 0x55:
|
||||
ret = pic_read_ocw(0, addr & 0x01);
|
||||
break;
|
||||
case 0x56 ... 0x57:
|
||||
ret = pic_read_ocw(1, addr & 0x01);
|
||||
break;
|
||||
case 0x58 ... 0x5f:
|
||||
ret = dev->pit_read_reg(dev->pit, addr & 0x07);
|
||||
break;
|
||||
}
|
||||
if (func == 0x00)
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
else if (func == 0x01)
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
|
||||
sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret);
|
||||
} else if (func == 0x01) {
|
||||
ret = dev->pci_conf_sb[func][addr];
|
||||
|
||||
sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret);
|
||||
}
|
||||
sis_5511_log("SiS 5513: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val - 0x50;
|
||||
break;
|
||||
case 0x23:
|
||||
sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x00:
|
||||
dev->regs[dev->index] = val & 0xed;
|
||||
switch (val >> 6) {
|
||||
case 0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nvr_bank_set(0, !!(val & 0x08), dev->nvr);
|
||||
break;
|
||||
case 0x01:
|
||||
dev->regs[dev->index] = val & 0xf4;
|
||||
break;
|
||||
case 0x03:
|
||||
dev->regs[dev->index] = val & 3;
|
||||
break;
|
||||
case 0x04: /* BIOS Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[dev->index] = val;
|
||||
outb(0x70, val);
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5513_isa_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x23) {
|
||||
if (dev->index == 0x05)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
|
||||
sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_reset(void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
/* SiS 5511 */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x11;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x20;
|
||||
dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00;
|
||||
dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = 0x00;
|
||||
dev->pci_conf[0x67] = 0xff;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = 0x00;
|
||||
dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff;
|
||||
dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff;
|
||||
dev->pci_conf[0x6f] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04;
|
||||
dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04;
|
||||
dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80;
|
||||
dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5511_smram_recalc(dev);
|
||||
sis_5511_shadow_recalc(dev);
|
||||
|
||||
flushmmucache();
|
||||
|
||||
memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t));
|
||||
dev->slic_regs[0x18] = 0x0f;
|
||||
|
||||
mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000);
|
||||
|
||||
/* SiS 5513 */
|
||||
dev->pci_conf_sb[0][0x00] = 0x39;
|
||||
dev->pci_conf_sb[0][0x01] = 0x10;
|
||||
dev->pci_conf_sb[0][0x02] = 0x08;
|
||||
dev->pci_conf_sb[0][0x03] = 0x00;
|
||||
dev->pci_conf_sb[0][0x04] = 0x07;
|
||||
dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00;
|
||||
dev->pci_conf_sb[0][0x07] = 0x02;
|
||||
dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
dev->pci_conf_sb[0][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[0][0x40] = 0x00;
|
||||
dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80;
|
||||
dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80;
|
||||
dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x80;
|
||||
dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x80;
|
||||
dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x51] = 0x80;
|
||||
dev->pci_conf_sb[0][0x62] = 0x00;
|
||||
dev->pci_conf_sb[0][0x63] = 0x80;
|
||||
dev->pci_conf_sb[0][0x64] = 0x00;
|
||||
dev->pci_conf_sb[0][0x65] = 0x80;
|
||||
dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00;
|
||||
dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00;
|
||||
dev->pci_conf_sb[0][0x6a] = 0x04;
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
|
||||
pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED);
|
||||
pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED);
|
||||
pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED);
|
||||
|
||||
dev->regs[0x00] = dev->regs[0x01] = 0x00;
|
||||
dev->regs[0x03] = dev->regs[0x04] = 0x00;
|
||||
dev->regs[0x05] = 0x00;
|
||||
dev->regs[0x08] = dev->regs[0x09] = 0x00;
|
||||
dev->regs[0x0a] = dev->regs[0x0b] = 0x00;
|
||||
|
||||
cpu_set_isa_speed(7159091);
|
||||
nvr_bank_set(0, 0, dev->nvr);
|
||||
|
||||
/* SiS 5513 IDE Controller */
|
||||
dev->pci_conf_sb[1][0x00] = 0x39;
|
||||
dev->pci_conf_sb[1][0x01] = 0x10;
|
||||
dev->pci_conf_sb[1][0x02] = 0x13;
|
||||
dev->pci_conf_sb[1][0x03] = 0x55;
|
||||
dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00;
|
||||
dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00;
|
||||
dev->pci_conf_sb[1][0x08] = 0x00;
|
||||
dev->pci_conf_sb[1][0x09] = 0x8a;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[1][0x0f] = 0x00;
|
||||
dev->pci_conf_sb[1][0x10] = 0xf1;
|
||||
dev->pci_conf_sb[1][0x11] = 0x01;
|
||||
dev->pci_conf_sb[1][0x14] = 0xf5;
|
||||
dev->pci_conf_sb[1][0x15] = 0x03;
|
||||
dev->pci_conf_sb[1][0x18] = 0x71;
|
||||
dev->pci_conf_sb[1][0x19] = 0x01;
|
||||
dev->pci_conf_sb[1][0x1c] = 0x75;
|
||||
dev->pci_conf_sb[1][0x1d] = 0x03;
|
||||
dev->pci_conf_sb[1][0x20] = 0x01;
|
||||
dev->pci_conf_sb[1][0x21] = 0xf0;
|
||||
dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00;
|
||||
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
|
||||
sff_bus_master_reset(dev->bm[0]);
|
||||
sff_bus_master_reset(dev->bm[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_close(void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -894,55 +141,18 @@ static void *
|
||||
sis_5511_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t));
|
||||
uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1));
|
||||
|
||||
memset(dev, 0, sizeof(sis_5511_t));
|
||||
|
||||
/* Device 0: SiS 5511 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5513 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot);
|
||||
|
||||
/* SLiC Memory Mapped Registers */
|
||||
mem_mapping_add(&dev->slic_mapping,
|
||||
0xffc00000, 0x00001000,
|
||||
sis_5511_slic_read,
|
||||
NULL,
|
||||
NULL,
|
||||
sis_5511_slic_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL,
|
||||
dev);
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
/* Ports 22h-23h: SiS 5513 ISA */
|
||||
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev);
|
||||
dev->h2p = device_add_linked(&sis_5511_h2p_device, dev->sis);
|
||||
|
||||
/* MIRQ */
|
||||
pci_enable_mirq(0);
|
||||
pci_enable_mirq(1);
|
||||
|
||||
/* IDEIRQ */
|
||||
pci_enable_mirq(2);
|
||||
|
||||
/* Port 92h */
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
|
||||
/* SFF IDE */
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* PIT */
|
||||
dev->pit = device_find_first_priv(DEVICE_PIT);
|
||||
dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg;
|
||||
|
||||
/* NVR */
|
||||
dev->nvr = device_add(&at_mb_nvr_device);
|
||||
|
||||
sis_5511_reset(dev);
|
||||
dev->p2i = device_add_linked(&sis_5513_p2i_device, dev->sis);
|
||||
dev->ide = device_add_linked(&sis_5513_ide_device, dev->sis);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -954,7 +164,7 @@ const device_t sis_5511_device = {
|
||||
.local = 0,
|
||||
.init = sis_5511_init,
|
||||
.close = sis_5511_close,
|
||||
.reset = sis_5511_reset,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
|
||||
461
src/chipset/sis_5511_h2p.c
Normal file
461
src/chipset/sis_5511_h2p.c
Normal file
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5511 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5511_HOST_TO_PCI_LOG
|
||||
int sis_5511_host_to_pci_do_log = ENABLE_SIS_5511_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5511_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5511_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5511_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5511_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
uint8_t slic_regs[4096];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
|
||||
mem_mapping_t slic_mapping;
|
||||
} sis_5511_host_to_pci_t;
|
||||
|
||||
static void
|
||||
sis_5511_shadow_recalc(sis_5511_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x80; i <= 0x86; i++) {
|
||||
if (i == 0x86) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5511_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5511_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5511_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_smram_recalc(sis_5511_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x65] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
sis_5511_host_to_pci_log("SiS 5511 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= 0xb0;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
/* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC.
|
||||
The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h.
|
||||
The latter (bit 6) means the chipset intercepts all odd FXh to 64h.
|
||||
Bit 5 sets fast reset latency. This should be fixed on the other SiS
|
||||
chipsets as well. */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5e:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
if ((dev->pci_conf[0x68] & 1) && (val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x69] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x61 ... 0x64:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5511_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x6a ... 0x6e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x70: /* DRAM Bank Register 0-0 */
|
||||
case 0x72: /* DRAM Bank Register 0-1 */
|
||||
case 0x74: /* DRAM Bank Register 1-0 */
|
||||
case 0x76: /* DRAM Bank Register 1-1 */
|
||||
case 0x78: /* DRAM Bank Register 2-0 */
|
||||
case 0x7a: /* DRAM Bank Register 2-1 */
|
||||
case 0x7c: /* DRAM Bank Register 3-0 */
|
||||
case 0x7e: /* DRAM Bank Register 3-1 */
|
||||
spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82);
|
||||
break;
|
||||
|
||||
case 0x71: /* DRAM Bank Register 0-0 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x75: /* DRAM Bank Register 1-0 */
|
||||
case 0x79: /* DRAM Bank Register 2-0 */
|
||||
case 0x7d: /* DRAM Bank Register 3-0 */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x73: /* DRAM Bank Register 0-1 */
|
||||
case 0x77: /* DRAM Bank Register 1-1 */
|
||||
case 0x7b: /* DRAM Bank Register 2-1 */
|
||||
case 0x7f: /* DRAM Bank Register 3-1 */
|
||||
dev->pci_conf[addr] = val & 0x83;
|
||||
break;
|
||||
|
||||
case 0x80 ... 0x85:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x90 ... 0x93: /* 5512 General Purpose Register Index */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5511_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5511_host_to_pci_log("SiS 5511 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000000:
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
dev->slic_regs[addr] = val;
|
||||
break;
|
||||
case 0x00000010:
|
||||
case 0x00000018:
|
||||
case 0x00000028:
|
||||
case 0x00000038:
|
||||
dev->slic_regs[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x00000030:
|
||||
dev->slic_regs[addr] = val & 0x0f;
|
||||
mem_mapping_set_addr(&dev->slic_mapping,
|
||||
(((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5511_slic_read(uint32_t addr, void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
ret = dev->slic_regs[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x11;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x20;
|
||||
dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00;
|
||||
dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = 0x00;
|
||||
dev->pci_conf[0x67] = 0xff;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = 0x00;
|
||||
dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff;
|
||||
dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff;
|
||||
dev->pci_conf[0x6f] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04;
|
||||
dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04;
|
||||
dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80;
|
||||
dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00;
|
||||
dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5511_smram_recalc(dev);
|
||||
sis_5511_shadow_recalc(dev);
|
||||
|
||||
flushmmucache();
|
||||
|
||||
memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t));
|
||||
dev->slic_regs[0x18] = 0x0f;
|
||||
|
||||
mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5511_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) calloc(1, sizeof(sis_5511_host_to_pci_t));
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* SLiC Memory Mapped Registers */
|
||||
mem_mapping_add(&dev->slic_mapping,
|
||||
0xffc00000, 0x00001000,
|
||||
sis_5511_slic_read,
|
||||
NULL,
|
||||
NULL,
|
||||
sis_5511_slic_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL,
|
||||
dev);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
sis_5511_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5511_h2p_device = {
|
||||
.name = "SiS 5511 Host to PCI bridge",
|
||||
.internal_name = "sis_5511_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5511_host_to_pci_init,
|
||||
.close = sis_5511_host_to_pci_close,
|
||||
.reset = sis_5511_host_to_pci_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
505
src/chipset/sis_5513_ide.c
Normal file
505
src/chipset/sis_5513_ide.c
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5513 IDE controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5513_IDE_LOG
|
||||
int sis_5513_ide_do_log = ENABLE_SIS_5513_IDE_LOG;
|
||||
|
||||
static void
|
||||
sis_5513_ide_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5513_ide_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5513_ide_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5513_ide_t {
|
||||
uint8_t rev;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5513_ide_t;
|
||||
|
||||
static void
|
||||
sis_5513_ide_irq_handler(sis_5513_ide_t *dev)
|
||||
{
|
||||
if (dev->pci_conf[0x09] & 0x01) {
|
||||
/* Primary IDE is native. */
|
||||
sis_5513_ide_log("Primary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Primary IDE is legacy. */
|
||||
sis_5513_ide_log("Primary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_LEGACY);
|
||||
}
|
||||
|
||||
if (dev->pci_conf[0x09] & 0x04) {
|
||||
/* Secondary IDE is native. */
|
||||
sis_5513_ide_log("Secondary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Secondary IDE is legacy. */
|
||||
sis_5513_ide_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_handler(sis_5513_ide_t *dev)
|
||||
{
|
||||
uint8_t ide_io_on = dev->pci_conf[0x04] & 0x01;
|
||||
|
||||
uint16_t native_base_pri_addr = (dev->pci_conf[0x11] | dev->pci_conf[0x10] << 8) & 0xfffe;
|
||||
uint16_t native_side_pri_addr = (dev->pci_conf[0x15] | dev->pci_conf[0x14] << 8) & 0xfffe;
|
||||
uint16_t native_base_sec_addr = (dev->pci_conf[0x19] | dev->pci_conf[0x18] << 8) & 0xfffe;
|
||||
uint16_t native_side_sec_addr = (dev->pci_conf[0x1c] | dev->pci_conf[0x1b] << 8) & 0xfffe;
|
||||
|
||||
uint16_t current_pri_base;
|
||||
uint16_t current_pri_side;
|
||||
uint16_t current_sec_base;
|
||||
uint16_t current_sec_side;
|
||||
|
||||
/* Primary Channel Programming */
|
||||
current_pri_base = (!(dev->pci_conf[0x09] & 1)) ? 0x01f0 : native_base_pri_addr;
|
||||
current_pri_side = (!(dev->pci_conf[0x09] & 1)) ? 0x03f6 : native_side_pri_addr;
|
||||
|
||||
/* Secondary Channel Programming */
|
||||
current_sec_base = (!(dev->pci_conf[0x09] & 4)) ? 0x0170 : native_base_sec_addr;
|
||||
current_sec_side = (!(dev->pci_conf[0x09] & 4)) ? 0x0376 : native_side_sec_addr;
|
||||
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Disabling primary IDE...\n");
|
||||
ide_pri_disable();
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Disabling secondary IDE...\n");
|
||||
ide_sec_disable();
|
||||
|
||||
if (ide_io_on) {
|
||||
/* Primary Channel Setup */
|
||||
if (dev->pci_conf[0x4a] & 0x02) {
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base);
|
||||
ide_set_base(0, current_pri_base);
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side);
|
||||
ide_set_side(0, current_pri_side);
|
||||
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Enabling primary IDE...\n");
|
||||
ide_pri_enable();
|
||||
|
||||
sis_5513_ide_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
|
||||
}
|
||||
|
||||
/* Secondary Channel Setup */
|
||||
if (dev->pci_conf[0x4a] & 0x04) {
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base);
|
||||
ide_set_base(1, current_sec_base);
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side);
|
||||
ide_set_side(1, current_sec_side);
|
||||
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Enabling secondary IDE...\n");
|
||||
ide_sec_enable();
|
||||
|
||||
sis_5513_ide_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
|
||||
}
|
||||
}
|
||||
|
||||
sff_bus_master_handler(dev->sis->bm[0], ide_io_on,
|
||||
((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 0);
|
||||
sff_bus_master_handler(dev->sis->bm[1], ide_io_on,
|
||||
((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 8);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5513_ide_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
|
||||
sis_5513_ide_log("SiS 5513 IDE: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf[addr] = val & 0x05;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x06: /* Status low byte */
|
||||
dev->pci_conf[addr] = val & 0x20;
|
||||
break;
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x38);
|
||||
break;
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
switch (dev->rev) {
|
||||
case 0xd0:
|
||||
if (dev->sis->ide_bits_1_3_writable)
|
||||
val |= 0x0a;
|
||||
fallthrough;
|
||||
case 0x00:
|
||||
case 0xd1:
|
||||
val &= 0xbf;
|
||||
fallthrough;
|
||||
case 0xc0:
|
||||
switch (val & 0x0a) {
|
||||
case 0x00:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x85) | (val & 0x4a);
|
||||
break;
|
||||
case 0x02:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x84) | (val & 0x4b);
|
||||
break;
|
||||
case 0x08:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x81) | (val & 0x4e);
|
||||
break;
|
||||
case 0x0a:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x80) | (val & 0x4f);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x0d: /* Latency Timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
/* Primary Base Address */
|
||||
case 0x10 ... 0x11:
|
||||
case 0x14 ... 0x15:
|
||||
fallthrough;
|
||||
|
||||
/* Secondary Base Address */
|
||||
case 0x18 ... 0x19:
|
||||
case 0x1c ... 0x1d:
|
||||
fallthrough;
|
||||
|
||||
/* Bus Mastering Base Address */
|
||||
case 0x20 ... 0x21:
|
||||
if (addr == 0x20)
|
||||
dev->pci_conf[addr] = (val & 0xe0) | 0x01;
|
||||
else if ((addr & 0x07) == 0x00)
|
||||
dev->pci_conf[addr] = (val & 0xf8) | 0x01;
|
||||
else if ((addr & 0x07) == 0x04)
|
||||
dev->pci_conf[addr] = (val & 0xfc) | 0x01;
|
||||
else
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x2c ... 0x2f:
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x30 ... 0x33: /* Expansion ROM Base Address */
|
||||
#ifdef DATASHEET
|
||||
dev->pci_conf[addr] = val;
|
||||
#else
|
||||
if (dev->rev == 0x00)
|
||||
dev->pci_conf[addr] = val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
|
||||
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
|
||||
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val & 0xe7;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x49: /* IDE Command Active Time Control */
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
switch (dev->rev) {
|
||||
case 0x00:
|
||||
dev->pci_conf[addr] = val & 0x9e;
|
||||
break;
|
||||
case 0xc0:
|
||||
dev->pci_conf[addr] = val & 0xaf;
|
||||
break;
|
||||
case 0xd0:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control Register 1 */
|
||||
if (dev->rev >= 0xc0)
|
||||
dev->pci_conf[addr] = val;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5513_ide_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pci_conf[addr];
|
||||
break;
|
||||
case 0x09:
|
||||
ret = dev->pci_conf[addr];
|
||||
if (dev->rev >= 0xc0) {
|
||||
if (dev->pci_conf[0x09] & 0x40)
|
||||
ret |= ((dev->pci_conf[0x4a] & 0x06) << 3);
|
||||
if ((dev->rev == 0xd0) && dev->sis->ide_bits_1_3_writable)
|
||||
ret |= 0x0a;
|
||||
}
|
||||
break;
|
||||
case 0x3d:
|
||||
if (dev->rev >= 0xc0)
|
||||
ret = (dev->pci_conf[0x09] & 0x05) ? PCI_INTA : 0x00;
|
||||
else
|
||||
ret = (((dev->pci_conf[0x4b] & 0xc0) == 0xc0) ||
|
||||
(dev->pci_conf[0x09] & 0x05)) ? PCI_INTA : 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5513_ide_log("SiS 5513 IDE: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_reset(void *priv)
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x13;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = dev->pci_conf[0x07] = 0x00;
|
||||
dev->pci_conf[0x08] = (dev->rev == 0xd1) ? 0xd0 : dev->rev;
|
||||
dev->pci_conf[0x09] = 0x8a;
|
||||
dev->pci_conf[0x0a] = dev->pci_conf[0x0b] = 0x01;
|
||||
dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x80;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = 0xf1;
|
||||
dev->pci_conf[0x11] = 0x01;
|
||||
dev->pci_conf[0x14] = 0xf5;
|
||||
dev->pci_conf[0x15] = 0x03;
|
||||
dev->pci_conf[0x18] = 0x71;
|
||||
dev->pci_conf[0x19] = 0x01;
|
||||
dev->pci_conf[0x1c] = 0x75;
|
||||
dev->pci_conf[0x1d] = 0x03;
|
||||
dev->pci_conf[0x20] = 0x01;
|
||||
dev->pci_conf[0x21] = 0xf0;
|
||||
dev->pci_conf[0x22] = dev->pci_conf[0x23] = 0x00;
|
||||
dev->pci_conf[0x24] = dev->pci_conf[0x25] = 0x00;
|
||||
dev->pci_conf[0x26] = dev->pci_conf[0x27] = 0x00;
|
||||
dev->pci_conf[0x28] = dev->pci_conf[0x29] = 0x00;
|
||||
dev->pci_conf[0x2a] = dev->pci_conf[0x2b] = 0x00;
|
||||
switch (dev->rev) {
|
||||
case 0x00:
|
||||
case 0xd0:
|
||||
case 0xd1:
|
||||
dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00;
|
||||
break;
|
||||
case 0xc0:
|
||||
#ifdef DATASHEET
|
||||
dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00;
|
||||
#else
|
||||
/* The only Linux lspci listing I could find of this chipset,
|
||||
shows a subsystem of 0058:0000. */
|
||||
dev->pci_conf[0x2c] = 0x58;
|
||||
dev->pci_conf[0x2d] = 0x00;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
dev->pci_conf[0x2e] = dev->pci_conf[0x2f] = 0x00;
|
||||
dev->pci_conf[0x30] = dev->pci_conf[0x31] = 0x00;
|
||||
dev->pci_conf[0x32] = dev->pci_conf[0x33] = 0x00;
|
||||
dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00;
|
||||
dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00;
|
||||
dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00;
|
||||
dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00;
|
||||
dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00;
|
||||
dev->pci_conf[0x4a] = 0x06;
|
||||
dev->pci_conf[0x4b] = 0x00;
|
||||
dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00;
|
||||
dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00;
|
||||
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
|
||||
sff_bus_master_reset(dev->sis->bm[0]);
|
||||
sff_bus_master_reset(dev->sis->bm[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_close(void *priv)
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5513_ide_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) calloc(1, sizeof(sis_5513_ide_t));
|
||||
|
||||
dev->rev = info->local;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* SFF IDE */
|
||||
dev->sis->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->sis->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
sis_5513_ide_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5513_ide_device = {
|
||||
.name = "SiS 5513 IDE controller",
|
||||
.internal_name = "sis_5513_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5572_ide_device = {
|
||||
.name = "SiS 5572 IDE controller",
|
||||
.internal_name = "sis_5572_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xc0,
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5582_ide_device = {
|
||||
.name = "SiS 5582 IDE controller",
|
||||
.internal_name = "sis_5582_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xd0,
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5591_5600_ide_device = {
|
||||
.name = "SiS 5591/(5)600 IDE controller",
|
||||
.internal_name = "sis_5591_5600_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xd1, /* D0, but we need to distinguish them. */
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
1383
src/chipset/sis_5513_p2i.c
Normal file
1383
src/chipset/sis_5513_p2i.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,13 +6,11 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5571 Chipset.
|
||||
* Implementation of the SiS 5571/5572 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021-2023 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@@ -25,37 +23,26 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
/* Shadow RAM */
|
||||
#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
|
||||
/* IDE Flags (1 Native / 0 Compatibility)*/
|
||||
#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1)
|
||||
#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4)
|
||||
#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8)
|
||||
#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2)
|
||||
#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8)
|
||||
#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2)
|
||||
#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8))
|
||||
|
||||
#ifdef ENABLE_SIS_5571_LOG
|
||||
int sis_5571_do_log = ENABLE_SIS_5571_LOG;
|
||||
|
||||
@@ -75,649 +62,83 @@ sis_5571_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5571_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t usb_irq_state;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[3][256];
|
||||
void *h2p;
|
||||
void *p2i;
|
||||
void *ide;
|
||||
void *usb;
|
||||
|
||||
port_92_t *port_92;
|
||||
sff8038i_t *ide_drive[2];
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5571_t;
|
||||
|
||||
static void
|
||||
sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev)
|
||||
sis_5571_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (cur_reg != 0x76) {
|
||||
mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE);
|
||||
mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE);
|
||||
} else
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE);
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
flushmmucache_nopc();
|
||||
sis_5571_log("SiS 5571: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5571_host_to_pci_write(addr, val, dev->h2p);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5571_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = sis_5571_host_to_pci_read(addr, dev->h2p);
|
||||
|
||||
sis_5571_log("SiS 5571: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_smm_recalc(sis_5571_t *dev)
|
||||
sis_5572_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
smram_disable_all();
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) {
|
||||
sis_5571_log("SiS 5572: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
break;
|
||||
case 0x02:
|
||||
smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x03:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_ide_handler(sis_5571_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
if (dev->pci_conf_sb[1][4] & 1) {
|
||||
if (dev->pci_conf_sb[1][0x4a] & 4) {
|
||||
ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0);
|
||||
ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6);
|
||||
ide_pri_enable();
|
||||
}
|
||||
if (dev->pci_conf_sb[1][0x4a] & 2) {
|
||||
ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170);
|
||||
ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376);
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_bm_handler(sis_5571_t *dev)
|
||||
{
|
||||
sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE);
|
||||
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - low byte */
|
||||
case 0x05: /* Command - high byte */
|
||||
dev->pci_conf[addr] |= val;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= val & 0xbe;
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: /* Host Interface and DRAM arbiter */
|
||||
dev->pci_conf[addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x51: /* CACHE */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
break;
|
||||
|
||||
case 0x53: /* DRAM */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x54: /* FP/EDO */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0x56: /* MDLE delay */
|
||||
case 0x57: /* SDRAM */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x59: /* Buffer strength and current rating */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x60: /* Undocumented */
|
||||
case 0x61: /* Undocumented */
|
||||
case 0x62: /* Undocumented */
|
||||
case 0x63: /* Undocumented */
|
||||
case 0x64: /* Undocumented */
|
||||
case 0x65: /* Undocumented */
|
||||
case 0x66: /* Undocumented */
|
||||
case 0x67: /* Undocumented */
|
||||
case 0x68: /* Undocumented */
|
||||
case 0x69: /* Undocumented */
|
||||
case 0x6a: /* Undocumented */
|
||||
case 0x6b: /* Undocumented */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76: /* Attribute of shadow RAM for BIOS area */
|
||||
dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8);
|
||||
sis_5571_shadow_recalc(addr, dev);
|
||||
sis_5571_smm_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xcc;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x90: /* PMU control register */
|
||||
case 0x91: /* Address trap for green function */
|
||||
case 0x92:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93: /* STPCLK# and APM SMI control */
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x9d] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94: /* 6x86 and Green function control */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95: /* Test mode control */
|
||||
case 0x96: /* Time slot and Programmable 10-bit I/O port definition */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x97: /* programmable 10-bit I/O port address */
|
||||
case 0x98: /* Programmable 16-bit I/O port */
|
||||
case 0x99:
|
||||
case 0x9a:
|
||||
case 0x9b:
|
||||
case 0x9c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9d:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x9e: /* STPCLK# Assertion Timer */
|
||||
case 0x9f: /* STPCLK# De-assertion Timer */
|
||||
case 0xa0:
|
||||
case 0xa1:
|
||||
case 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa3: /* SMRAM access control and Power supply control */
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5571_smm_recalc(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
memory_pci_bridge_read(UNUSED(int func), int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]);
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
static void
|
||||
pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
switch (func) {
|
||||
case 0: /* Bridge */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[0][addr] |= val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status */
|
||||
dev->pci_conf_sb[0][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x41: /* INTA# Remapping Control Register */
|
||||
case 0x42: /* INTB# Remapping Control Register */
|
||||
case 0x43: /* INTC# Remapping Control Register */
|
||||
case 0x44: /* INTD# Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xec;
|
||||
switch ((val & 0xc0) >> 6) {
|
||||
case 0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x47: /* DMA Clock and Wait State Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3e;
|
||||
break;
|
||||
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x61: /* MIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x62: /* On-board Device DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x0f;
|
||||
dma_set_drq((val & 0x07), 1);
|
||||
break;
|
||||
|
||||
case 0x63: /* IDEIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
if (val & 0x80) {
|
||||
sff_set_irq_line(dev->ide_drive[0], val & 0x0f);
|
||||
sff_set_irq_line(dev->ide_drive[1], val & 0x0f);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x64: /* GPIO Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x1b;
|
||||
break;
|
||||
|
||||
case 0x66: /* GPIO Output Mode Control Register */
|
||||
case 0x67: /* GPIO Output Mode Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x68: /* USBIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x1b;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x6b:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6c:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */
|
||||
case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xde;
|
||||
break;
|
||||
|
||||
case 0x71: /* Type-F DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x72: /* SMI Triggered By IRQ/GPIO Control */
|
||||
case 0x73: /* SMI Triggered By IRQ/GPIO Control */
|
||||
dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val;
|
||||
break;
|
||||
|
||||
case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */
|
||||
case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */
|
||||
case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
|
||||
case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
case 1: /* IDE Controller */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x05;
|
||||
sis_5571_ide_handler(dev);
|
||||
sis_5571_bm_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf_sb[1][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xcf;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Latency Time */
|
||||
case 0x10: /* Primary Channel Base Address Register */
|
||||
case 0x11: /* Primary Channel Base Address Register */
|
||||
case 0x12: /* Primary Channel Base Address Register */
|
||||
case 0x13: /* Primary Channel Base Address Register */
|
||||
case 0x14: /* Primary Channel Base Address Register */
|
||||
case 0x15: /* Primary Channel Base Address Register */
|
||||
case 0x16: /* Primary Channel Base Address Register */
|
||||
case 0x17: /* Primary Channel Base Address Register */
|
||||
case 0x18: /* Secondary Channel Base Address Register */
|
||||
case 0x19: /* Secondary Channel Base Address Register */
|
||||
case 0x1a: /* Secondary Channel Base Address Register */
|
||||
case 0x1b: /* Secondary Channel Base Address Register */
|
||||
case 0x1c: /* Secondary Channel Base Address Register */
|
||||
case 0x1d: /* Secondary Channel Base Address Register */
|
||||
case 0x1e: /* Secondary Channel Base Address Register */
|
||||
case 0x1f: /* Secondary Channel Base Address Register */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x20: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x21: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x22: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x23: /* Bus Master IDE Control Register Base Address */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5571_bm_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x30: /* Expansion ROM Base Address */
|
||||
case 0x31: /* Expansion ROM Base Address */
|
||||
case 0x32: /* Expansion ROM Base Address */
|
||||
case 0x33: /* Expansion ROM Base Address */
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
case 0x49: /* IDE Command Active Time Control */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xaf;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control register 1 */
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
case 2: /* USB Controller */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf_sb[2][addr] = val;
|
||||
ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1);
|
||||
break;
|
||||
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf_sb[2][addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf_sb[2][addr] &= val & 0xc0;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf_sb[2][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x10: /* Memory Space Base Address Register */
|
||||
case 0x11: /* Memory Space Base Address Register */
|
||||
case 0x12: /* Memory Space Base Address Register */
|
||||
case 0x13: /* Memory Space Base Address Register */
|
||||
dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff);
|
||||
ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1);
|
||||
break;
|
||||
|
||||
case 0x14: /* IO Space Base Address Register */
|
||||
case 0x15: /* IO Space Base Address Register */
|
||||
case 0x16: /* IO Space Base Address Register */
|
||||
case 0x17: /* IO Space Base Address Register */
|
||||
case 0x3c: /* Interrupt Line */
|
||||
dev->pci_conf_sb[2][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
sis_5572_usb_write(addr, val, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pci_isa_bridge_read(int func, int addr, void *priv)
|
||||
sis_5572_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (func) {
|
||||
case 0:
|
||||
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]);
|
||||
return dev->pci_conf_sb[0][addr];
|
||||
case 1:
|
||||
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]);
|
||||
return dev->pci_conf_sb[1][addr];
|
||||
case 2:
|
||||
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]);
|
||||
return dev->pci_conf_sb[2][addr];
|
||||
|
||||
default:
|
||||
return 0xff;
|
||||
case 0x00:
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = sis_5572_usb_read(addr, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_reset(void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
sis_5571_log("SiS 5572: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
/* Memory/PCI Bridge */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x71;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0xfd;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x9e] = 0xff;
|
||||
dev->pci_conf[0x9f] = 0xff;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
|
||||
/* PCI to ISA bridge */
|
||||
dev->pci_conf_sb[0][0x00] = 0x39;
|
||||
dev->pci_conf_sb[0][0x01] = 0x10;
|
||||
dev->pci_conf_sb[0][0x02] = 0x08;
|
||||
dev->pci_conf_sb[0][0x04] = 0xfd;
|
||||
dev->pci_conf_sb[0][0x08] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
|
||||
/* IDE Controller */
|
||||
dev->pci_conf_sb[1][0x00] = 0x39;
|
||||
dev->pci_conf_sb[1][0x01] = 0x10;
|
||||
dev->pci_conf_sb[1][0x02] = 0x13;
|
||||
dev->pci_conf_sb[1][0x03] = 0x55;
|
||||
dev->pci_conf_sb[1][0x08] = 0xc0;
|
||||
dev->pci_conf_sb[1][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[1][0x4a] = 0x06;
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
|
||||
sff_bus_master_reset(dev->ide_drive[0]);
|
||||
sff_bus_master_reset(dev->ide_drive[1]);
|
||||
|
||||
/* USB Controller */
|
||||
dev->pci_conf_sb[2][0x00] = 0x39;
|
||||
dev->pci_conf_sb[2][0x01] = 0x10;
|
||||
dev->pci_conf_sb[2][0x02] = 0x01;
|
||||
dev->pci_conf_sb[2][0x03] = 0x70;
|
||||
dev->pci_conf_sb[2][0x08] = 0xb0;
|
||||
dev->pci_conf_sb[2][0x09] = 0x10;
|
||||
dev->pci_conf_sb[2][0x0a] = 0x03;
|
||||
dev->pci_conf_sb[2][0x0b] = 0xc0;
|
||||
dev->pci_conf_sb[2][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[2][0x14] = 0x01;
|
||||
dev->pci_conf_sb[2][0x3d] = 0x01;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -725,34 +146,25 @@ sis_5571_close(void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5571_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t));
|
||||
memset(dev, 0x00, sizeof(sis_5571_t));
|
||||
sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot);
|
||||
/* Device 0: SiS 5571 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5571_read, sis_5571_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5572 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5572_read, sis_5572_write, dev, &dev->sb_slot);
|
||||
|
||||
/* MIRQ */
|
||||
pci_enable_mirq(0);
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
/* Port 92 & SMRAM */
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* SFF IDE */
|
||||
dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
/* USB */
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
sis_5571_reset(dev);
|
||||
dev->h2p = device_add_linked(&sis_5571_h2p_device, dev->sis);
|
||||
dev->p2i = device_add_linked(&sis_5572_p2i_device, dev->sis);
|
||||
dev->ide = device_add_linked(&sis_5572_ide_device, dev->sis);
|
||||
dev->usb = device_add_linked(&sis_5572_usb_device, dev->sis);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -764,7 +176,7 @@ const device_t sis_5571_device = {
|
||||
.local = 0,
|
||||
.init = sis_5571_init,
|
||||
.close = sis_5571_close,
|
||||
.reset = sis_5571_reset,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
|
||||
458
src/chipset/sis_5571_h2p.c
Normal file
458
src/chipset/sis_5571_h2p.c
Normal file
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5571 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5571_HOST_TO_PCI_LOG
|
||||
int sis_5571_host_to_pci_do_log = ENABLE_SIS_5571_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5571_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5571_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5571_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5571_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
} sis_5571_host_to_pci_t;
|
||||
|
||||
static void
|
||||
sis_5571_shadow_recalc(sis_5571_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x70; i <= 0x76; i++) {
|
||||
if (i == 0x76) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5571_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5571_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5571_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0xa3] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
|
||||
sis_5571_host_to_pci_log("SiS 5571 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - low byte */
|
||||
case 0x05: /* Command - high byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02);
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xb8);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: /* Host Interface and DRAM arbiter */
|
||||
dev->pci_conf[addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x51: /* CACHE */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
break;
|
||||
|
||||
case 0x53: /* DRAM */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x54: /* FP/EDO */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0x56: /* MDLE delay */
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x57: /* SDRAM */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x59: /* Buffer strength and current rating */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
/* Undocumented - DRAM bank registers, the exact layout is currently unknown. */
|
||||
case 0x60 ... 0x6b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x75:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5571_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5571_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xcc;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
/* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */
|
||||
break;
|
||||
|
||||
case 0x84 ... 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x90: /* PMU control register */
|
||||
case 0x91: /* Address trap for green function */
|
||||
case 0x92:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93: /* STPCLK# and APM SMI control */
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x9d] |= 0x01;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94: /* 6x86 and Green function control */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95: /* Test mode control */
|
||||
case 0x96: /* Time slot and Programmable 10-bit I/O port definition */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x97: /* programmable 10-bit I/O port address */
|
||||
case 0x98: /* Programmable 16-bit I/O port */
|
||||
case 0x99 ... 0x9c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9d:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x9e: /* STPCLK# Assertion Timer */
|
||||
case 0x9f: /* STPCLK# De-assertion Timer */
|
||||
case 0xa0 ... 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa3: /* SMRAM access control and Power supply control */
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5571_smram_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5571_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x71;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x00;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
|
||||
dev->pci_conf[0x50] = 0x00;
|
||||
dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x00;
|
||||
dev->pci_conf[0x53] = 0x00;
|
||||
dev->pci_conf[0x54] = 0x54;
|
||||
dev->pci_conf[0x55] = 0x54;
|
||||
dev->pci_conf[0x56] = 0x03;
|
||||
dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = 0x00;
|
||||
dev->pci_conf[0x5a] = 0x00;
|
||||
|
||||
/* Undocumented DRAM bank registers. */
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80;
|
||||
dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6b] = 0x80;
|
||||
|
||||
dev->pci_conf[0x70] = 0x00;
|
||||
dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = 0x00;
|
||||
dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = 0x00;
|
||||
dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = 0x00;
|
||||
|
||||
dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = 0x00;
|
||||
dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = 0x00;
|
||||
dev->pci_conf[0x7b] = 0x00;
|
||||
|
||||
dev->pci_conf[0x80] = 0x00;
|
||||
dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = 0x00;
|
||||
dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = 0x00;
|
||||
dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
dev->pci_conf[0x87] = 0x00;
|
||||
|
||||
dev->pci_conf[0x8c] = 0x00;
|
||||
dev->pci_conf[0x8d] = 0x00;
|
||||
dev->pci_conf[0x8e] = 0x00;
|
||||
dev->pci_conf[0x8f] = 0x00;
|
||||
|
||||
dev->pci_conf[0x90] = 0x00;
|
||||
dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = 0x00;
|
||||
dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = 0x00;
|
||||
dev->pci_conf[0x95] = 0x00;
|
||||
dev->pci_conf[0x96] = 0x00;
|
||||
dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = 0x00;
|
||||
dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = 0x00;
|
||||
dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0x9c] = 0x00;
|
||||
dev->pci_conf[0x9d] = 0x00;
|
||||
dev->pci_conf[0x9e] = 0xff;
|
||||
dev->pci_conf[0x9f] = 0xff;
|
||||
|
||||
dev->pci_conf[0xa0] = 0xff;
|
||||
dev->pci_conf[0xa1] = 0x00;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
dev->pci_conf[0xa3] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5571_smram_recalc(dev);
|
||||
sis_5571_shadow_recalc(dev);
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5571_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) calloc(1, sizeof(sis_5571_host_to_pci_t));
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
sis_5571_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5571_h2p_device = {
|
||||
.name = "SiS 5571 Host to PCI bridge",
|
||||
.internal_name = "sis_5571_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5571_host_to_pci_init,
|
||||
.close = sis_5571_host_to_pci_close,
|
||||
.reset = sis_5571_host_to_pci_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
772
src/chipset/sis_5571_old.c
Normal file
772
src/chipset/sis_5571_old.c
Normal file
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5571 Chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
/* Shadow RAM */
|
||||
#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
|
||||
/* IDE Flags (1 Native / 0 Compatibility)*/
|
||||
#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1)
|
||||
#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4)
|
||||
#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8)
|
||||
#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2)
|
||||
#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8)
|
||||
#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2)
|
||||
#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8))
|
||||
|
||||
#ifdef ENABLE_SIS_5571_LOG
|
||||
int sis_5571_do_log = ENABLE_SIS_5571_LOG;
|
||||
|
||||
static void
|
||||
sis_5571_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5571_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5571_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5571_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t usb_irq_state;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[3][256];
|
||||
|
||||
port_92_t *port_92;
|
||||
sff8038i_t *ide_drive[2];
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
} sis_5571_t;
|
||||
|
||||
static void
|
||||
sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev)
|
||||
{
|
||||
if (cur_reg != 0x76) {
|
||||
mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE);
|
||||
mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE);
|
||||
} else
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_smm_recalc(sis_5571_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) {
|
||||
case 0x00:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x01:
|
||||
smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x02:
|
||||
smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x03:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_ide_handler(sis_5571_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
if (dev->pci_conf_sb[1][4] & 1) {
|
||||
if (dev->pci_conf_sb[1][0x4a] & 4) {
|
||||
ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0);
|
||||
ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6);
|
||||
ide_pri_enable();
|
||||
}
|
||||
if (dev->pci_conf_sb[1][0x4a] & 2) {
|
||||
ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170);
|
||||
ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376);
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_bm_handler(sis_5571_t *dev)
|
||||
{
|
||||
sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE);
|
||||
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - low byte */
|
||||
case 0x05: /* Command - high byte */
|
||||
dev->pci_conf[addr] |= val;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= val & 0xbe;
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: /* Host Interface and DRAM arbiter */
|
||||
dev->pci_conf[addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x51: /* CACHE */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
break;
|
||||
|
||||
case 0x53: /* DRAM */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x54: /* FP/EDO */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0x56: /* MDLE delay */
|
||||
case 0x57: /* SDRAM */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x59: /* Buffer strength and current rating */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x60: /* Undocumented */
|
||||
case 0x61: /* Undocumented */
|
||||
case 0x62: /* Undocumented */
|
||||
case 0x63: /* Undocumented */
|
||||
case 0x64: /* Undocumented */
|
||||
case 0x65: /* Undocumented */
|
||||
case 0x66: /* Undocumented */
|
||||
case 0x67: /* Undocumented */
|
||||
case 0x68: /* Undocumented */
|
||||
case 0x69: /* Undocumented */
|
||||
case 0x6a: /* Undocumented */
|
||||
case 0x6b: /* Undocumented */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76: /* Attribute of shadow RAM for BIOS area */
|
||||
dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8);
|
||||
sis_5571_shadow_recalc(addr, dev);
|
||||
sis_5571_smm_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xcc;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x90: /* PMU control register */
|
||||
case 0x91: /* Address trap for green function */
|
||||
case 0x92:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93: /* STPCLK# and APM SMI control */
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x9d] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94: /* 6x86 and Green function control */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95: /* Test mode control */
|
||||
case 0x96: /* Time slot and Programmable 10-bit I/O port definition */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x97: /* programmable 10-bit I/O port address */
|
||||
case 0x98: /* Programmable 16-bit I/O port */
|
||||
case 0x99:
|
||||
case 0x9a:
|
||||
case 0x9b:
|
||||
case 0x9c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9d:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x9e: /* STPCLK# Assertion Timer */
|
||||
case 0x9f: /* STPCLK# De-assertion Timer */
|
||||
case 0xa0:
|
||||
case 0xa1:
|
||||
case 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa3: /* SMRAM access control and Power supply control */
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5571_smm_recalc(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
memory_pci_bridge_read(UNUSED(int func), int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]);
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
static void
|
||||
pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
switch (func) {
|
||||
case 0: /* Bridge */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[0][addr] |= val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status */
|
||||
dev->pci_conf_sb[0][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x41: /* INTA# Remapping Control Register */
|
||||
case 0x42: /* INTB# Remapping Control Register */
|
||||
case 0x43: /* INTC# Remapping Control Register */
|
||||
case 0x44: /* INTD# Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xec;
|
||||
switch ((val & 0xc0) >> 6) {
|
||||
case 0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x47: /* DMA Clock and Wait State Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3e;
|
||||
break;
|
||||
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x61: /* MIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x62: /* On-board Device DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x0f;
|
||||
dma_set_drq((val & 0x07), 1);
|
||||
break;
|
||||
|
||||
case 0x63: /* IDEIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
if (val & 0x80) {
|
||||
sff_set_irq_line(dev->ide_drive[0], val & 0x0f);
|
||||
sff_set_irq_line(dev->ide_drive[1], val & 0x0f);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x64: /* GPIO Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x1b;
|
||||
break;
|
||||
|
||||
case 0x66: /* GPIO Output Mode Control Register */
|
||||
case 0x67: /* GPIO Output Mode Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x68: /* USBIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x1b;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x6b:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6c:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */
|
||||
case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xde;
|
||||
break;
|
||||
|
||||
case 0x71: /* Type-F DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x72: /* SMI Triggered By IRQ/GPIO Control */
|
||||
case 0x73: /* SMI Triggered By IRQ/GPIO Control */
|
||||
dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val;
|
||||
break;
|
||||
|
||||
case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */
|
||||
case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */
|
||||
case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
|
||||
case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
case 1: /* IDE Controller */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x05;
|
||||
sis_5571_ide_handler(dev);
|
||||
sis_5571_bm_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf_sb[1][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xcf;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Latency Time */
|
||||
case 0x10: /* Primary Channel Base Address Register */
|
||||
case 0x11: /* Primary Channel Base Address Register */
|
||||
case 0x12: /* Primary Channel Base Address Register */
|
||||
case 0x13: /* Primary Channel Base Address Register */
|
||||
case 0x14: /* Primary Channel Base Address Register */
|
||||
case 0x15: /* Primary Channel Base Address Register */
|
||||
case 0x16: /* Primary Channel Base Address Register */
|
||||
case 0x17: /* Primary Channel Base Address Register */
|
||||
case 0x18: /* Secondary Channel Base Address Register */
|
||||
case 0x19: /* Secondary Channel Base Address Register */
|
||||
case 0x1a: /* Secondary Channel Base Address Register */
|
||||
case 0x1b: /* Secondary Channel Base Address Register */
|
||||
case 0x1c: /* Secondary Channel Base Address Register */
|
||||
case 0x1d: /* Secondary Channel Base Address Register */
|
||||
case 0x1e: /* Secondary Channel Base Address Register */
|
||||
case 0x1f: /* Secondary Channel Base Address Register */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x20: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x21: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x22: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x23: /* Bus Master IDE Control Register Base Address */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5571_bm_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x30: /* Expansion ROM Base Address */
|
||||
case 0x31: /* Expansion ROM Base Address */
|
||||
case 0x32: /* Expansion ROM Base Address */
|
||||
case 0x33: /* Expansion ROM Base Address */
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
case 0x49: /* IDE Command Active Time Control */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xaf;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control register 1 */
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
case 2: /* USB Controller */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf_sb[2][addr] = val;
|
||||
ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1);
|
||||
break;
|
||||
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf_sb[2][addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf_sb[2][addr] &= val & 0xc0;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf_sb[2][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x10: /* Memory Space Base Address Register */
|
||||
case 0x11: /* Memory Space Base Address Register */
|
||||
case 0x12: /* Memory Space Base Address Register */
|
||||
case 0x13: /* Memory Space Base Address Register */
|
||||
dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff);
|
||||
ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1);
|
||||
break;
|
||||
|
||||
case 0x14: /* IO Space Base Address Register */
|
||||
case 0x15: /* IO Space Base Address Register */
|
||||
case 0x16: /* IO Space Base Address Register */
|
||||
case 0x17: /* IO Space Base Address Register */
|
||||
case 0x3c: /* Interrupt Line */
|
||||
dev->pci_conf_sb[2][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pci_isa_bridge_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
switch (func) {
|
||||
case 0:
|
||||
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]);
|
||||
return dev->pci_conf_sb[0][addr];
|
||||
case 1:
|
||||
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]);
|
||||
return dev->pci_conf_sb[1][addr];
|
||||
case 2:
|
||||
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]);
|
||||
return dev->pci_conf_sb[2][addr];
|
||||
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_reset(void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
/* Memory/PCI Bridge */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x71;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0xfd;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x9e] = 0xff;
|
||||
dev->pci_conf[0x9f] = 0xff;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
|
||||
/* PCI to ISA bridge */
|
||||
dev->pci_conf_sb[0][0x00] = 0x39;
|
||||
dev->pci_conf_sb[0][0x01] = 0x10;
|
||||
dev->pci_conf_sb[0][0x02] = 0x08;
|
||||
dev->pci_conf_sb[0][0x04] = 0xfd;
|
||||
dev->pci_conf_sb[0][0x08] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
|
||||
/* IDE Controller */
|
||||
dev->pci_conf_sb[1][0x00] = 0x39;
|
||||
dev->pci_conf_sb[1][0x01] = 0x10;
|
||||
dev->pci_conf_sb[1][0x02] = 0x13;
|
||||
dev->pci_conf_sb[1][0x03] = 0x55;
|
||||
dev->pci_conf_sb[1][0x08] = 0xc0;
|
||||
dev->pci_conf_sb[1][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[1][0x4a] = 0x06;
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
|
||||
sff_bus_master_reset(dev->ide_drive[0]);
|
||||
sff_bus_master_reset(dev->ide_drive[1]);
|
||||
|
||||
/* USB Controller */
|
||||
dev->pci_conf_sb[2][0x00] = 0x39;
|
||||
dev->pci_conf_sb[2][0x01] = 0x10;
|
||||
dev->pci_conf_sb[2][0x02] = 0x01;
|
||||
dev->pci_conf_sb[2][0x03] = 0x70;
|
||||
dev->pci_conf_sb[2][0x08] = 0xb0;
|
||||
dev->pci_conf_sb[2][0x09] = 0x10;
|
||||
dev->pci_conf_sb[2][0x0a] = 0x03;
|
||||
dev->pci_conf_sb[2][0x0b] = 0xc0;
|
||||
dev->pci_conf_sb[2][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[2][0x14] = 0x01;
|
||||
dev->pci_conf_sb[2][0x3d] = 0x01;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_close(void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5571_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) malloc(sizeof(sis_5571_t));
|
||||
memset(dev, 0x00, sizeof(sis_5571_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot);
|
||||
|
||||
/* MIRQ */
|
||||
pci_enable_mirq(0);
|
||||
|
||||
/* Port 92 & SMRAM */
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* SFF IDE */
|
||||
dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
/* USB */
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
sis_5571_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5571_device = {
|
||||
.name = "SiS 5571",
|
||||
.internal_name = "sis_5571",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5571_init,
|
||||
.close = sis_5571_close,
|
||||
.reset = sis_5571_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
323
src/chipset/sis_5572_usb.c
Normal file
323
src/chipset/sis_5572_usb.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5572 USB controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5572_USB_LOG
|
||||
int sis_5572_usb_do_log = ENABLE_SIS_5572_USB_LOG;
|
||||
|
||||
static void
|
||||
sis_5572_usb_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5572_usb_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5572_usb_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5572_usb_t {
|
||||
uint8_t rev;
|
||||
|
||||
uint8_t usb_unk_regs[256];
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
uint16_t usb_unk_base;
|
||||
|
||||
usb_t *usb;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5572_usb_t;
|
||||
|
||||
/* SiS 5572 unknown I/O port (second USB PCI BAR). */
|
||||
static void
|
||||
sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
addr = (addr - dev->usb_unk_base) & 0x07;
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val);
|
||||
|
||||
dev->usb_unk_regs[addr] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5572_usb_unk_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->usb_unk_base) & 0x07;
|
||||
|
||||
ret = dev->usb_unk_regs[addr & 0x07];
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sis_5572_usb_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (dev->sis->usb_enabled) switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
if (dev->rev == 0xb0)
|
||||
dev->pci_conf[addr] = val & 0x47;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0x57;
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_removehandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
if (dev->pci_conf[0x04] & 0x01)
|
||||
io_sethandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
ohci_update_mem_mapping(dev->usb,
|
||||
dev->pci_conf[0x11], dev->pci_conf[0x12],
|
||||
dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02);
|
||||
break;
|
||||
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Latency Timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x11 ... 0x13: /* Memory Space Base Address Register */
|
||||
dev->pci_conf[addr] = val & ((addr == 0x11) ? 0xf0 : 0xff);
|
||||
ohci_update_mem_mapping(dev->usb,
|
||||
dev->pci_conf[0x11], dev->pci_conf[0x12],
|
||||
dev->pci_conf[0x13], dev->pci_conf[4] & 0x02);
|
||||
break;
|
||||
|
||||
case 0x14 ... 0x15: /* IO Space Base Address Register */
|
||||
if (dev->rev == 0xb0) {
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_removehandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
dev->pci_conf[addr] = val;
|
||||
dev->usb_unk_base = (dev->pci_conf[0x14] & 0xf8) |
|
||||
(dev->pci_conf[0x15] << 8);
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_sethandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2c ... 0x2f:
|
||||
if (dev->rev == 0x11)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x3c: /* Interrupt Line */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5572_usb_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->sis->usb_enabled) {
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5572_usb_reset(void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x01;
|
||||
dev->pci_conf[0x03] = 0x70;
|
||||
dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = (dev->rev == 0xb0) ? 0x00 : 0x80;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = dev->rev;
|
||||
dev->pci_conf[0x09] = 0x10;
|
||||
dev->pci_conf[0x0a] = 0x03;
|
||||
dev->pci_conf[0x0b] = 0x0c;
|
||||
dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = 0x00;
|
||||
dev->pci_conf[0x11] = 0x00;
|
||||
dev->pci_conf[0x12] = 0x00;
|
||||
dev->pci_conf[0x13] = 0x00;
|
||||
if (dev->rev == 0xb0) {
|
||||
dev->pci_conf[0x14] = 0x01;
|
||||
dev->pci_conf[0x15] = 0x00;
|
||||
dev->pci_conf[0x16] = 0x00;
|
||||
dev->pci_conf[0x17] = 0x00;
|
||||
} else if (dev->rev == 0x11) {
|
||||
dev->pci_conf[0x2c] = 0x00;
|
||||
dev->pci_conf[0x2d] = 0x00;
|
||||
dev->pci_conf[0x2e] = 0x00;
|
||||
dev->pci_conf[0x2f] = 0x00;
|
||||
}
|
||||
dev->pci_conf[0x3c] = 0x00;
|
||||
dev->pci_conf[0x3d] = PCI_INTA;
|
||||
dev->pci_conf[0x3e] = 0x00;
|
||||
dev->pci_conf[0x3f] = 0x00;
|
||||
|
||||
if (dev->rev == 0xb0) {
|
||||
ohci_update_mem_mapping(dev->usb,
|
||||
dev->pci_conf[0x11], dev->pci_conf[0x12],
|
||||
dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02);
|
||||
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_removehandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->usb_unk_base = 0x0000;
|
||||
|
||||
memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5572_usb_close(void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5572_usb_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) calloc(1, sizeof(sis_5572_usb_t));
|
||||
|
||||
dev->rev = info->local;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* USB */
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
sis_5572_usb_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5572_usb_device = {
|
||||
.name = "SiS 5572 USB controller",
|
||||
.internal_name = "sis_5572_usb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xb0,
|
||||
.init = sis_5572_usb_init,
|
||||
.close = sis_5572_usb_close,
|
||||
.reset = sis_5572_usb_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5582_usb_device = {
|
||||
.name = "SiS 5582 USB controller",
|
||||
.internal_name = "sis_5582_usb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xe0,
|
||||
.init = sis_5572_usb_init,
|
||||
.close = sis_5572_usb_close,
|
||||
.reset = sis_5572_usb_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5595_usb_device = {
|
||||
.name = "SiS 5595 USB controller",
|
||||
.internal_name = "sis_5595_usb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x11,
|
||||
.init = sis_5572_usb_init,
|
||||
.close = sis_5572_usb_close,
|
||||
.reset = sis_5572_usb_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
184
src/chipset/sis_5581.c
Normal file
184
src/chipset/sis_5581.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5581/5582 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5581_LOG
|
||||
int sis_5581_do_log = ENABLE_SIS_5581_LOG;
|
||||
|
||||
static void
|
||||
sis_5581_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5581_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5581_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5581_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
void *h2p;
|
||||
void *p2i;
|
||||
void *ide;
|
||||
void *usb;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5581_t;
|
||||
|
||||
static void
|
||||
sis_5581_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
|
||||
sis_5581_log("SiS 5581: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5581_host_to_pci_write(addr, val, dev->h2p);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5581_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = sis_5581_host_to_pci_read(addr, dev->h2p);
|
||||
|
||||
sis_5581_log("SiS 5581: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5582_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
|
||||
sis_5581_log("SiS 5582: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
break;
|
||||
case 0x02:
|
||||
sis_5572_usb_write(addr, val, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5582_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = sis_5572_usb_read(addr, dev->usb);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5581_log("SiS 5582: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_close(void *priv)
|
||||
{
|
||||
sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5581_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5581_t *dev = (sis_5581_t *) calloc(1, sizeof(sis_5581_t));
|
||||
|
||||
/* Device 0: SiS 5581 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5581_read, sis_5581_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5582 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5582_read, sis_5582_write, dev, &dev->sb_slot);
|
||||
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
dev->p2i = device_add_linked(&sis_5582_p2i_device, dev->sis);
|
||||
dev->h2p = device_add_linked(&sis_5581_h2p_device, dev->sis);
|
||||
dev->ide = device_add_linked(&sis_5582_ide_device, dev->sis);
|
||||
dev->usb = device_add_linked(&sis_5582_usb_device, dev->sis);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5581_device = {
|
||||
.name = "SiS 5581",
|
||||
.internal_name = "sis_5581",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5581_init,
|
||||
.close = sis_5581_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
552
src/chipset/sis_5581_h2p.c
Normal file
552
src/chipset/sis_5581_h2p.c
Normal file
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5581 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5581_HOST_TO_PCI_LOG
|
||||
int sis_5581_host_to_pci_do_log = ENABLE_SIS_5581_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5581_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5581_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5581_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t installed;
|
||||
uint8_t code;
|
||||
uint32_t phys_size;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct sis_5581_io_trap_t {
|
||||
void *priv;
|
||||
void *trap;
|
||||
uint8_t flags, mask;
|
||||
uint8_t *sts_reg, sts_mask;
|
||||
uint16_t addr;
|
||||
} sis_5581_io_trap_t;
|
||||
|
||||
typedef struct sis_5581_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
|
||||
sis_5581_io_trap_t io_traps[10];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
} sis_5581_host_to_pci_t;
|
||||
|
||||
static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b };
|
||||
|
||||
static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */
|
||||
0x01000000, /* 16 MB */
|
||||
0x02000000, /* 32 MB */
|
||||
0x04000000, /* 64 MB */
|
||||
0x08000000, /* 128 MB */
|
||||
0x10000000, /* 256 MB */
|
||||
0x20000000 }; /* 512 MB */
|
||||
|
||||
static void
|
||||
sis_5581_shadow_recalc(sis_5581_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x70; i <= 0x76; i++) {
|
||||
if (i == 0x76) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5581_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5581_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5581_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val),
|
||||
void *priv)
|
||||
{
|
||||
sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv;
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) trap->priv;
|
||||
|
||||
trap->sts_reg[0x04] |= trap->sts_mask;
|
||||
|
||||
if (trap->sts_reg[0x00] & trap->sts_mask)
|
||||
acpi_sis5582_pmu_event(dev->sis->acpi);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv;
|
||||
|
||||
if ((addr & trap->mask) == (trap->addr & trap->mask))
|
||||
sis_5581_trap_io(size, addr, write, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_t enable,
|
||||
uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask,
|
||||
uint16_t addr, uint16_t size)
|
||||
{
|
||||
sis_5581_io_trap_t *trap = &dev->io_traps[trap_id];
|
||||
|
||||
/* Set up Device I/O traps dynamically. */
|
||||
if (enable && !trap->trap) {
|
||||
trap->priv = (void *) dev;
|
||||
trap->flags = flags;
|
||||
trap->mask = mask;
|
||||
trap->addr = addr;
|
||||
if (flags & 0x08)
|
||||
trap->trap = io_trap_add(sis_5581_trap_io_mask, trap);
|
||||
else
|
||||
trap->trap = io_trap_add(sis_5581_trap_io, trap);
|
||||
trap->sts_reg = sts_reg;
|
||||
trap->sts_mask = sts_mask;
|
||||
}
|
||||
|
||||
/* Remap I/O trap. */
|
||||
io_trap_remap(trap->trap, enable, addr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_update(void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
uint8_t trap_id = 0;
|
||||
uint8_t *fregs = dev->pci_conf;
|
||||
uint16_t temp;
|
||||
uint8_t mask;
|
||||
uint8_t on;
|
||||
|
||||
on = fregs[0x9a];
|
||||
|
||||
temp = ((fregs[0x96] & 0x02) | (fregs[0x97] << 2)) & 0x03ff;
|
||||
mask = ~((1 << ((fregs[0x96] >> 3) & 0x07)) - 1);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x40, 0x08, mask, &(fregs[0x9c]), 0x40, temp, 0x80);
|
||||
|
||||
temp = fregs[0x98] | (fregs[0x99] << 8);
|
||||
mask = 0xff;
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x20, 0x08, mask, &(fregs[0x9c]), 0x20, temp, 0x80);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x378, 0x08);
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x278, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x9c]), 0x08, 0x3f8, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x04, 0x00, 0xff, &(fregs[0x9c]), 0x04, 0x2f8, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x00, 0xff, &(fregs[0x9c]), 0x02, 0x1f0, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x01, 0x00, 0xff, &(fregs[0x9c]), 0x01, 0x170, 0x08);
|
||||
|
||||
on = fregs[0x9b];
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x064, 0x01);
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x060, 0x01);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_smram_recalc(sis_5581_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0xa3] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
|
||||
sis_5581_host_to_pci_log("SiS 5581 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfc) | (val & 0x03);
|
||||
break;
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x02;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xb8);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
case 0x50:
|
||||
case 0x54:
|
||||
case 0x56 ... 0x57:
|
||||
case 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xeb;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x62:
|
||||
dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = dev->ram_banks[0].installed |
|
||||
(dev->ram_banks[1].installed << 1) |
|
||||
(dev->ram_banks[2].installed << 2);
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x75:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5581_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5581_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xde;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
/* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */
|
||||
break;
|
||||
|
||||
case 0x84 ... 0x86:
|
||||
case 0x88 ... 0x8b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x8c ... 0x92:
|
||||
case 0x9e ... 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (val & 0x02) {
|
||||
dev->pci_conf[0x9d] |= 0x01;
|
||||
if (dev->pci_conf[0x9b] & 0x01)
|
||||
acpi_sis5582_pmu_event(dev->sis->acpi);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95:
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x96:
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
sis_5581_trap_update(dev);
|
||||
break;
|
||||
case 0x97 ... 0x9b:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5581_trap_update(dev);
|
||||
break;
|
||||
|
||||
case 0x9c ... 0x9d:
|
||||
dev->pci_conf[addr] &= ~val;
|
||||
break;
|
||||
|
||||
case 0xa3:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5581_smram_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5581_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x97;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x02;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0xff;
|
||||
dev->pci_conf[0x0e] = dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x00;
|
||||
dev->pci_conf[0x53] = 0x38;
|
||||
dev->pci_conf[0x54] = 0x54;
|
||||
dev->pci_conf[0x55] = 0x00;
|
||||
dev->pci_conf[0x56] = 0x80;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = 0x00;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = dev->pci_conf[0x87] = 0x00;
|
||||
dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00;
|
||||
dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00;
|
||||
dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = dev->pci_conf[0x95] = 0x00;
|
||||
dev->pci_conf[0x96] = dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00;
|
||||
dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0xff;
|
||||
dev->pci_conf[0xa0] = 0xff;
|
||||
dev->pci_conf[0xa1] = 0x00;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
dev->pci_conf[0xa3] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5581_shadow_recalc(dev);
|
||||
|
||||
sis_5581_trap_update(dev);
|
||||
|
||||
sis_5581_smram_recalc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5581_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) calloc(1, sizeof(sis_5581_host_to_pci_t));
|
||||
uint32_t total_mem = mem_size << 10;
|
||||
ram_bank_t *rb;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* Calculate the physical RAM banks. */
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
rb = &(dev->ram_banks[i]);
|
||||
uint32_t size = 0x00000000;
|
||||
uint8_t index = 0;
|
||||
for (int8_t j = 6; j >= 0; j--) {
|
||||
uint32_t *bs = &(bank_sizes[j]);
|
||||
if (*bs <= total_mem) {
|
||||
size = *bs;
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (size != 0x00000000) {
|
||||
rb->installed = 1;
|
||||
rb->code = bank_codes[index];
|
||||
rb->phys_size = size;
|
||||
total_mem -= size;
|
||||
} else
|
||||
rb->installed = 0;
|
||||
}
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
sis_5581_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5581_h2p_device = {
|
||||
.name = "SiS 5581 Host to PCI bridge",
|
||||
.internal_name = "sis_5581_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5581_host_to_pci_init,
|
||||
.close = sis_5581_host_to_pci_close,
|
||||
.reset = sis_5581_host_to_pci_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
210
src/chipset/sis_5591.c
Normal file
210
src/chipset/sis_5591.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5591/5592 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5591_LOG
|
||||
int sis_5591_do_log = ENABLE_SIS_5591_LOG;
|
||||
|
||||
static void
|
||||
sis_5591_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5591_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5591_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5591_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
void *h2p;
|
||||
void *p2i;
|
||||
void *ide;
|
||||
void *usb;
|
||||
void *pmu;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5591_t;
|
||||
|
||||
static void
|
||||
sis_5591_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
|
||||
sis_5591_log("SiS 5591: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5591_host_to_pci_write(addr, val, dev->h2p);
|
||||
else if (func == 0x01)
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5591_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = sis_5591_host_to_pci_read(addr, dev->h2p);
|
||||
else if (func == 0x01)
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
|
||||
sis_5591_log("SiS 5591: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
|
||||
sis_5591_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
sis_5595_pmu_write(addr, val, dev->pmu);
|
||||
break;
|
||||
case 0x02:
|
||||
sis_5572_usb_write(addr, val, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5595_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
ret = sis_5595_pmu_read(addr, dev->pmu);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = sis_5572_usb_read(addr, dev->usb);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5591_log("SiS 5592: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_close(void *priv)
|
||||
{
|
||||
sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5591_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5591_t *dev = (sis_5591_t *) calloc(1, sizeof(sis_5591_t));
|
||||
|
||||
/* Device 0: SiS 5591 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5591_read, sis_5591_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5595 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot);
|
||||
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis);
|
||||
if (info->local)
|
||||
dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis);
|
||||
else
|
||||
dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis);
|
||||
dev->h2p = device_add_linked(&sis_5591_h2p_device, dev->sis);
|
||||
dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis);
|
||||
if (info->local)
|
||||
dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis);
|
||||
else
|
||||
dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5591_1997_device = {
|
||||
.name = "SiS 5591 (1997)",
|
||||
.internal_name = "sis_5591_1997",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = sis_5591_init,
|
||||
.close = sis_5591_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5591_device = {
|
||||
.name = "SiS 5591",
|
||||
.internal_name = "sis_5591",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5591_init,
|
||||
.close = sis_5591_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
493
src/chipset/sis_5591_h2p.c
Normal file
493
src/chipset/sis_5591_h2p.c
Normal file
@@ -0,0 +1,493 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5591 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5591_HOST_TO_PCI_LOG
|
||||
int sis_5591_host_to_pci_do_log = ENABLE_SIS_5591_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5591_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5591_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5591_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t installed;
|
||||
uint8_t code;
|
||||
uint32_t phys_size;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct sis_5591_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
uint8_t states[7];
|
||||
uint8_t states_bus[7];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
|
||||
agpgart_t *agpgart;
|
||||
} sis_5591_host_to_pci_t;
|
||||
|
||||
static uint8_t bank_codes[6] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a };
|
||||
|
||||
static uint32_t bank_sizes[6] = { 0x00800000, /* 8 MB */
|
||||
0x01000000, /* 16 MB */
|
||||
0x02000000, /* 32 MB */
|
||||
0x04000000, /* 64 MB */
|
||||
0x08000000, /* 128 MB */
|
||||
0x10000000 }; /* 256 MB */
|
||||
|
||||
static void
|
||||
sis_5591_shadow_recalc(sis_5591_host_to_pci_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t state;
|
||||
uint8_t val;
|
||||
|
||||
for (uint8_t i = 0x70; i <= 0x76; i++) {
|
||||
if (i == 0x76) {
|
||||
val = dev->pci_conf[i];
|
||||
if ((dev->states[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_cpu_both(0xf0000, 0x10000, state);
|
||||
sis_5591_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
|
||||
dev->states[i & 0x0f] = val;
|
||||
}
|
||||
|
||||
if (!(dev->pci_conf[0x76] & 0x08))
|
||||
val &= 0x5f;
|
||||
if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_bus_both(0xf0000, 0x10000, state);
|
||||
sis_5591_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
|
||||
dev->states_bus[i & 0x0f] = val;
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
val = dev->pci_conf[i];
|
||||
if ((dev->states[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_cpu_both(base, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
|
||||
dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0x0f) | (val & 0xf0);
|
||||
}
|
||||
if ((dev->states[i & 0x0f] ^ val) & 0x0a) {
|
||||
state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_cpu_both(base + 0x4000, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
|
||||
dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0xf0) | (val & 0x0f);
|
||||
}
|
||||
|
||||
if (!(dev->pci_conf[0x76] & 0x08))
|
||||
val &= 0x55;
|
||||
if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_bus_both(base, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
|
||||
dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0x0f) | (val & 0xf0);
|
||||
}
|
||||
if ((dev->states_bus[i & 0x0f] ^ val) & 0x0a) {
|
||||
state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_bus_both(base + 0x4000, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
|
||||
dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0xf0) | (val & 0x0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_smram_recalc(sis_5591_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x68] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_mask_bar(uint8_t *regs, void *agpgart)
|
||||
{
|
||||
uint32_t bar;
|
||||
uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x00000000 } ;
|
||||
|
||||
/* Make sure the aperture's base is aligned to its size. */
|
||||
bar = (regs[0x13] << 24) | (regs[0x12] << 16);
|
||||
bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000);
|
||||
regs[0x12] = (bar >> 16) & 0xff;
|
||||
regs[0x13] = (bar >> 24) & 0xff;
|
||||
|
||||
if (!agpgart)
|
||||
return;
|
||||
|
||||
/* Map aperture and GART. */
|
||||
agpgart_set_aperture(agpgart,
|
||||
bar,
|
||||
sizes[(regs[0x94] >> 4) & 0x07],
|
||||
!!(regs[0x94] & 0x02));
|
||||
if (regs[0x94] & 0x01)
|
||||
agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24));
|
||||
else
|
||||
agpgart_set_gart(agpgart, 0x00000000);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
|
||||
sis_5591_host_to_pci_log("SiS 5591 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02);
|
||||
break;
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->pci_conf[addr] = val & 0xc0;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x80);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x62:
|
||||
dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = dev->ram_banks[0].installed |
|
||||
(dev->ram_banks[1].installed << 1) |
|
||||
(dev->ram_banks[2].installed << 2);
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5591_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x75:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5591_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5591_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
case 0x50:
|
||||
case 0x52:
|
||||
case 0x54 ... 0x5a:
|
||||
case 0x5c ... 0x5f:
|
||||
case 0x64 ... 0x65:
|
||||
case 0x69 ... 0x6c:
|
||||
case 0x77 ... 0x7b:
|
||||
case 0x80 ... 0x8d:
|
||||
case 0x90:
|
||||
case 0x97 ... 0xab:
|
||||
case 0xb0:
|
||||
case 0xc8 ... 0xcb:
|
||||
case 0xd4 ... 0xda:
|
||||
case 0xe0 ... 0xe3:
|
||||
case 0xef:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x91 ... 0x93:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
case 0x94:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
|
||||
case 0xb2:
|
||||
dev->pci_conf[addr] &= ~(val & 0x01);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5591_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5591_host_to_pci_log("SiS 5591 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x91;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x10;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x02;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0xff;
|
||||
dev->pci_conf[0x0e] = 0x80;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00;
|
||||
dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00;
|
||||
dev->pci_conf[0x34] = 0xc0;
|
||||
dev->pci_conf[0x50] = 0x00;
|
||||
dev->pci_conf[0x51] = 0x18;
|
||||
dev->pci_conf[0x52] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = 0x0e;
|
||||
dev->pci_conf[0x56] = 0x40;
|
||||
dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = 0x50;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00;
|
||||
dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00;
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = 0x00;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
|
||||
dev->pci_conf[0x6c] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff;
|
||||
dev->pci_conf[0x86] = 0xff;
|
||||
dev->pci_conf[0x87] = 0x00;
|
||||
dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00;
|
||||
dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00;
|
||||
dev->pci_conf[0x8c] = dev->pci_conf[0x8d] = 0x00;
|
||||
dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00;
|
||||
dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0x00;
|
||||
dev->pci_conf[0xa0] = dev->pci_conf[0xa1] = 0x00;
|
||||
dev->pci_conf[0xa2] = dev->pci_conf[0xa3] = 0x00;
|
||||
dev->pci_conf[0xa4] = dev->pci_conf[0xa5] = 0x00;
|
||||
dev->pci_conf[0xa6] = dev->pci_conf[0xa7] = 0x00;
|
||||
dev->pci_conf[0xa8] = dev->pci_conf[0xa9] = 0x00;
|
||||
dev->pci_conf[0xaa] = dev->pci_conf[0xab] = 0x00;
|
||||
dev->pci_conf[0xb0] = dev->pci_conf[0xb2] = 0x00;
|
||||
dev->pci_conf[0xc0] = 0x02;
|
||||
dev->pci_conf[0xc1] = 0x00;
|
||||
dev->pci_conf[0xc2] = 0x10;
|
||||
dev->pci_conf[0xc3] = 0x00;
|
||||
dev->pci_conf[0xc4] = 0x03;
|
||||
dev->pci_conf[0xc5] = 0x02;
|
||||
dev->pci_conf[0xc6] = 0x00;
|
||||
dev->pci_conf[0xc7] = 0x1f;
|
||||
dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00;
|
||||
dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00;
|
||||
dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00;
|
||||
dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00;
|
||||
dev->pci_conf[0xd8] = dev->pci_conf[0xd9] = 0x00;
|
||||
dev->pci_conf[0xda] = 0x00;
|
||||
dev->pci_conf[0xe0] = dev->pci_conf[0xe1] = 0x00;
|
||||
dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00;
|
||||
dev->pci_conf[0xef] = 0x00;
|
||||
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5591_shadow_recalc(dev);
|
||||
|
||||
sis_5591_smram_recalc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5591_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) calloc(1, sizeof(sis_5591_host_to_pci_t));
|
||||
uint32_t total_mem = mem_size << 10;
|
||||
ram_bank_t *rb;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* Calculate the physical RAM banks. */
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
rb = &(dev->ram_banks[i]);
|
||||
uint32_t size = 0x00000000;
|
||||
uint8_t index = 0;
|
||||
for (int8_t j = 5; j >= 0; j--) {
|
||||
uint32_t *bs = &(bank_sizes[j]);
|
||||
if (*bs <= total_mem) {
|
||||
size = *bs;
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (size != 0x00000000) {
|
||||
rb->installed = 1;
|
||||
rb->code = bank_codes[index];
|
||||
rb->phys_size = size;
|
||||
total_mem -= size;
|
||||
} else
|
||||
rb->installed = 0;
|
||||
}
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
device_add(&sis_5xxx_agp_device);
|
||||
dev->agpgart = device_add(&agpgart_device);
|
||||
|
||||
sis_5591_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5591_h2p_device = {
|
||||
.name = "SiS 5591 Host to PCI bridge",
|
||||
.internal_name = "sis_5591_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5591_host_to_pci_init,
|
||||
.close = sis_5591_host_to_pci_close,
|
||||
.reset = sis_5591_host_to_pci_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
454
src/chipset/sis_5595_pmu.c
Normal file
454
src/chipset/sis_5595_pmu.c
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5572 USB controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5595_PMU_LOG
|
||||
int sis_5595_pmu_do_log = ENABLE_SIS_5595_PMU_LOG;
|
||||
|
||||
static void
|
||||
sis_5595_pmu_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5595_pmu_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5595_pmu_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5595_pmu_io_trap_t {
|
||||
void *priv;
|
||||
void *trap;
|
||||
uint8_t flags, mask;
|
||||
uint8_t *sts_reg, sts_mask;
|
||||
uint16_t addr;
|
||||
} sis_5595_pmu_io_trap_t;
|
||||
|
||||
typedef struct sis_5595_pmu_t {
|
||||
uint8_t is_1997;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
sis_5595_pmu_io_trap_t io_traps[22];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5595_pmu_t;
|
||||
|
||||
static void
|
||||
sis_5595_pmu_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val),
|
||||
void *priv)
|
||||
{
|
||||
sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv;
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv;
|
||||
|
||||
trap->sts_reg[0x04] |= trap->sts_mask;
|
||||
|
||||
if (trap->sts_reg[0x00] & trap->sts_mask)
|
||||
acpi_sis5595_pmu_event(dev->sis->acpi);
|
||||
|
||||
if (trap->sts_reg[0x20] & trap->sts_mask)
|
||||
acpi_update_irq(dev->sis->acpi);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_trap_io_ide(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv;
|
||||
|
||||
/* IDE traps are per drive, not per channel. */
|
||||
if (ide_drives[trap->flags & 0x03]->selected)
|
||||
sis_5595_pmu_trap_io(size, addr, write, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv;
|
||||
|
||||
if ((addr & trap->mask) == (trap->addr & trap->mask))
|
||||
sis_5595_pmu_trap_io(size, addr, write, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_trap_io_ide_bm(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5595_pmu_io_trap_t *trap = (sis_5595_pmu_io_trap_t *) priv;
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) trap->priv;
|
||||
|
||||
if (trap->flags & 0x01) {
|
||||
dev->pci_conf[0x67] |= 0x01;
|
||||
dev->pci_conf[0x64] |= 0x08;
|
||||
} else {
|
||||
dev->pci_conf[0x67] |= 0x02;
|
||||
dev->pci_conf[0x64] |= 0x10;
|
||||
}
|
||||
acpi_sis5595_pmu_event(dev->sis->acpi);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_trap_update_devctl(sis_5595_pmu_t *dev, uint8_t trap_id, uint8_t enable,
|
||||
uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask,
|
||||
uint16_t addr, uint16_t size)
|
||||
{
|
||||
sis_5595_pmu_io_trap_t *trap = &dev->io_traps[trap_id];
|
||||
|
||||
/* Set up Device I/O traps dynamically. */
|
||||
if (enable && !trap->trap) {
|
||||
trap->priv = (void *) dev;
|
||||
trap->flags = flags;
|
||||
trap->mask = mask;
|
||||
trap->addr = addr;
|
||||
if (flags & 0x10)
|
||||
trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide_bm, trap);
|
||||
else if (flags & 0x08)
|
||||
trap->trap = io_trap_add(sis_5595_pmu_trap_io_mask, trap);
|
||||
else if (flags & 0x04)
|
||||
trap->trap = io_trap_add(sis_5595_pmu_trap_io_ide, trap);
|
||||
else
|
||||
trap->trap = io_trap_add(sis_5595_pmu_trap_io, trap);
|
||||
trap->sts_reg = sts_reg;
|
||||
trap->sts_mask = sts_mask;
|
||||
}
|
||||
|
||||
/* Remap I/O trap. */
|
||||
io_trap_remap(trap->trap, enable, addr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_trap_update(void *priv)
|
||||
{
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv;
|
||||
uint8_t trap_id = 0;
|
||||
uint8_t *fregs = dev->pci_conf;
|
||||
uint16_t temp;
|
||||
uint8_t mask;
|
||||
uint8_t on;
|
||||
|
||||
temp = (fregs[0x7e] | (fregs[0x7f] << 8)) & 0xffe0;
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
fregs[0x7e] & 0x08, 0x10, 0xff, NULL, 0xff, temp, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
fregs[0x7e] & 0x04, 0x10, 0xff, NULL, 0xff, temp + 8, 0x08);
|
||||
|
||||
on = fregs[0x63] | fregs[0x83];
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x04, 0xff, &(fregs[0x63]), 0x02, 0x1f0, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x01, 0x06, 0xff, &(fregs[0x63]), 0x01, 0x170, 0x08);
|
||||
|
||||
on = fregs[0x62] | fregs[0x82];
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x064, 0x01);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x80, 0x00, 0xff, &(fregs[0x62]), 0x80, 0x060, 0x01);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x40, 0x00, 0xff, &(fregs[0x62]), 0x40, 0x3f8, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x20, 0x00, 0xff, &(fregs[0x62]), 0x20, 0x2f8, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x378, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x62]), 0x10, 0x278, 0x08);
|
||||
|
||||
temp = (fregs[0x5c] | (fregs[0x5d] << 8)) & 0x03ff;
|
||||
mask = fregs[0x5d] >> 2;
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x04, 0x08, mask, &(fregs[0x62]), 0x04, temp, 0x40);
|
||||
|
||||
temp = fregs[0x5e] | (fregs[0x5f] << 8);
|
||||
|
||||
if (dev->is_1997) {
|
||||
mask = fregs[0x4d] & 0x1f;
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x20);
|
||||
} else {
|
||||
mask = fregs[0x4d];
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x08, mask, &(fregs[0x62]), 0x02, temp, 0x100);
|
||||
}
|
||||
|
||||
on = fregs[0x61] | fregs[0x81];
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x40, 0x00, 0xff, &(fregs[0x61]), 0x40, 0x3b0, 0x30);
|
||||
|
||||
switch ((fregs[0x4c] >> 6) & 0x03) {
|
||||
case 0x00:
|
||||
temp = 0xf40;
|
||||
break;
|
||||
case 0x01:
|
||||
temp = 0xe80;
|
||||
break;
|
||||
case 0x02:
|
||||
temp = 0x604;
|
||||
break;
|
||||
default:
|
||||
temp = 0x530;
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x61]), 0x10, temp, 0x08);
|
||||
|
||||
switch ((fregs[0x4c] >> 4) & 0x03) {
|
||||
case 0x00:
|
||||
temp = 0x280;
|
||||
break;
|
||||
case 0x01:
|
||||
temp = 0x260;
|
||||
break;
|
||||
case 0x02:
|
||||
temp = 0x240;
|
||||
break;
|
||||
default:
|
||||
temp = 0x220;
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x61]), 0x08, temp, 0x14);
|
||||
|
||||
switch ((fregs[0x4c] >> 2) & 0x03) {
|
||||
case 0x00:
|
||||
temp = 0x330;
|
||||
break;
|
||||
case 0x01:
|
||||
temp = 0x320;
|
||||
break;
|
||||
case 0x02:
|
||||
temp = 0x310;
|
||||
break;
|
||||
default:
|
||||
temp = 0x300;
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x04, 0x00, 0xff, &(fregs[0x61]), 0x04, temp, 0x04);
|
||||
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x200, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x00, 0xff, &(fregs[0x61]), 0x02, 0x388, 0x04);
|
||||
|
||||
on = fregs[0x60] | fregs[0x80];
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x3f0, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x20, 0x00, 0xff, &(fregs[0x60]), 0x20, 0x370, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x05, 0xff, &(fregs[0x60]), 0x10, 0x1f0, 0x08);
|
||||
sis_5595_pmu_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x07, 0xff, &(fregs[0x60]), 0x08, 0x170, 0x08);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5595_pmu_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv;
|
||||
|
||||
sis_5595_pmu_log("SiS 5595 PMU: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (dev->sis->usb_enabled) switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x40 ... 0x4b:
|
||||
case 0x50 ... 0x5b:
|
||||
case 0x68 ... 0x7b:
|
||||
case 0x7d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x4c ... 0x4d:
|
||||
case 0x5c ... 0x63:
|
||||
case 0x7e ... 0x7f:
|
||||
case 0x80 ... 0x83:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5595_pmu_trap_update(dev);
|
||||
break;
|
||||
case 0x64 ... 0x67:
|
||||
dev->pci_conf[addr] &= ~val;
|
||||
break;
|
||||
case 0x7c:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (val & 0x02) {
|
||||
dev->pci_conf[0x64] |= 0x04;
|
||||
if (dev->pci_conf[0x60] & 0x04)
|
||||
acpi_sis5595_pmu_event(dev->sis->acpi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5595_pmu_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5595_pmu_log("SiS 5595 PMU: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_reset(void *priv)
|
||||
{
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x09;
|
||||
dev->pci_conf[0x03] = 0x00;
|
||||
dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0xff;
|
||||
dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x80;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00;
|
||||
dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00;
|
||||
dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00;
|
||||
dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00;
|
||||
dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00;
|
||||
dev->pci_conf[0x4a] = dev->pci_conf[0x4b] = 0x00;
|
||||
dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00;
|
||||
dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00;
|
||||
dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00;
|
||||
dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00;
|
||||
dev->pci_conf[0x5a] = dev->pci_conf[0x5b] = 0x00;
|
||||
dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00;
|
||||
dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00;
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = dev->pci_conf[0x63] = 0x00;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
|
||||
dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00;
|
||||
dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00;
|
||||
dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00;
|
||||
dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
|
||||
sis_5595_pmu_trap_update(dev);
|
||||
acpi_update_irq(dev->sis->acpi);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_pmu_close(void *priv)
|
||||
{
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5595_pmu_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5595_pmu_t *dev = (sis_5595_pmu_t *) calloc(1, sizeof(sis_5595_pmu_t));
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
dev->sis->pmu_regs = dev->pci_conf;
|
||||
|
||||
dev->is_1997 = info->local;
|
||||
|
||||
sis_5595_pmu_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5595_1997_pmu_device = {
|
||||
.name = "SiS 5595 (1997) PMU",
|
||||
.internal_name = "sis_5595_1997_pmu",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x01,
|
||||
.init = sis_5595_pmu_init,
|
||||
.close = sis_5595_pmu_close,
|
||||
.reset = sis_5595_pmu_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5595_pmu_device = {
|
||||
.name = "SiS 5595 PMU",
|
||||
.internal_name = "sis_5595_pmu",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5595_pmu_init,
|
||||
.close = sis_5595_pmu_close,
|
||||
.reset = sis_5595_pmu_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
96
src/chipset/sis_55xx.c
Normal file
96
src/chipset/sis_55xx.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 55xx common structure.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#ifdef ENABLE_SIS_55XX_COMMON_LOG
|
||||
int sis_55xx_common_do_log = ENABLE_SIS_55XX_COMMON_LOG;
|
||||
|
||||
static void
|
||||
sis_55xx_common_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_55xx_common_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_55xx_common_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
sis_55xx_common_close(void *priv)
|
||||
{
|
||||
sis_55xx_common_t *dev = (sis_55xx_common_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_55xx_common_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_55xx_common_t *dev = (sis_55xx_common_t *) calloc(1, sizeof(sis_55xx_common_t));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_55xx_common_device = {
|
||||
.name = "SiS 55xx Common Structure",
|
||||
.internal_name = "sis_55xx_common",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_55xx_common_init,
|
||||
.close = sis_55xx_common_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
210
src/chipset/sis_5600.c
Normal file
210
src/chipset/sis_5600.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS (5)600 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5600_LOG
|
||||
int sis_5600_do_log = ENABLE_SIS_5600_LOG;
|
||||
|
||||
static void
|
||||
sis_5600_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5600_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5600_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5600_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
void *h2p;
|
||||
void *p2i;
|
||||
void *ide;
|
||||
void *usb;
|
||||
void *pmu;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5600_t;
|
||||
|
||||
static void
|
||||
sis_5600_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5600_t *dev = (sis_5600_t *) priv;
|
||||
|
||||
sis_5600_log("SiS 5600: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5600_host_to_pci_write(addr, val, dev->h2p);
|
||||
else if (func == 0x01)
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5600_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5600_t *dev = (sis_5600_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = sis_5600_host_to_pci_read(addr, dev->h2p);
|
||||
else if (func == 0x01)
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
|
||||
sis_5600_log("SiS 5600: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5600_t *dev = (sis_5600_t *) priv;
|
||||
|
||||
sis_5600_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
sis_5595_pmu_write(addr, val, dev->pmu);
|
||||
break;
|
||||
case 0x02:
|
||||
sis_5572_usb_write(addr, val, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5595_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5600_t *dev = (sis_5600_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
ret = sis_5595_pmu_read(addr, dev->pmu);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = sis_5572_usb_read(addr, dev->usb);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5600_log("SiS 5602: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5600_close(void *priv)
|
||||
{
|
||||
sis_5600_t *dev = (sis_5600_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5600_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5600_t *dev = (sis_5600_t *) calloc(1, sizeof(sis_5600_t));
|
||||
|
||||
/* Device 0: SiS 5600 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5600_read, sis_5600_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5595 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot);
|
||||
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis);
|
||||
if (info->local)
|
||||
dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis);
|
||||
else
|
||||
dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis);
|
||||
dev->h2p = device_add_linked(&sis_5600_h2p_device, dev->sis);
|
||||
dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis);
|
||||
if (info->local)
|
||||
dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis);
|
||||
else
|
||||
dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5600_1997_device = {
|
||||
.name = "SiS (5)600 (1997)",
|
||||
.internal_name = "sis_5600_1997",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = sis_5600_init,
|
||||
.close = sis_5600_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5600_device = {
|
||||
.name = "SiS (5)600",
|
||||
.internal_name = "sis_5600",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5600_init,
|
||||
.close = sis_5600_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
434
src/chipset/sis_5600_h2p.c
Normal file
434
src/chipset/sis_5600_h2p.c
Normal file
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS (5)600 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5600_HOST_TO_PCI_LOG
|
||||
int sis_5600_host_to_pci_do_log = ENABLE_SIS_5600_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5600_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5600_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5600_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t installed;
|
||||
uint8_t code;
|
||||
uint32_t phys_size;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct sis_5600_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
|
||||
agpgart_t *agpgart;
|
||||
} sis_5600_host_to_pci_t;
|
||||
|
||||
static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b };
|
||||
|
||||
static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */
|
||||
0x01000000, /* 16 MB */
|
||||
0x02000000, /* 32 MB */
|
||||
0x04000000, /* 64 MB */
|
||||
0x08000000, /* 128 MB */
|
||||
0x10000000, /* 256 MB */
|
||||
0x20000000 }; /* 512 MB */
|
||||
|
||||
static void
|
||||
sis_5600_shadow_recalc(sis_5600_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
state = (dev->pci_conf[0x70] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[0x72] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
if (((dev->pci_conf[0x70] ^ dev->states[0]) & (1 << i)) ||
|
||||
((dev->pci_conf[0x72] ^ dev->states[2]) & (1 << i))) {
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
base = 0x000e0000 + (i << 14);
|
||||
state = (dev->pci_conf[0x71] & (1 << i)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[0x73] & (1 << i)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << i)) ||
|
||||
((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << i))) {
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
|
||||
base = 0x000f0000;
|
||||
state = (dev->pci_conf[0x71] & (1 << 4)) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[0x73] & (1 << 4)) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
if (((dev->pci_conf[0x71] ^ dev->states[1]) & (1 << 4)) ||
|
||||
((dev->pci_conf[0x73] ^ dev->states[3]) & (1 << 4))) {
|
||||
mem_set_mem_state_both(base, 0x10000, state);
|
||||
sis_5600_host_to_pci_log("%08X-%08X\n", base, base + 0xffff);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
dev->states[i] = dev->pci_conf[0x70 + i];
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5600_smram_recalc(sis_5600_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x6a] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x6a] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x6a] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5600_mask_bar(uint8_t *regs, void *agpgart)
|
||||
{
|
||||
uint32_t bar;
|
||||
uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x00000000 } ;
|
||||
|
||||
/* Make sure the aperture's base is aligned to its size. */
|
||||
bar = (regs[0x13] << 24) | (regs[0x12] << 16);
|
||||
bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000);
|
||||
regs[0x12] = (bar >> 16) & 0xff;
|
||||
regs[0x13] = (bar >> 24) & 0xff;
|
||||
|
||||
if (!agpgart)
|
||||
return;
|
||||
|
||||
/* Map aperture and GART. */
|
||||
agpgart_set_aperture(agpgart,
|
||||
bar,
|
||||
sizes[(regs[0x94] >> 4) & 0x07],
|
||||
!!(regs[0x94] & 0x02));
|
||||
if (regs[0x94] & 0x01)
|
||||
agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24));
|
||||
else
|
||||
agpgart_set_gart(agpgart, 0x00000000);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5600_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv;
|
||||
|
||||
sis_5600_host_to_pci_log("SiS 5600 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02);
|
||||
break;
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & ~(val & 0x70)) | (val & 0x01);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
case 0x50 ... 0x5a:
|
||||
case 0x64 ... 0x69:
|
||||
case 0x6b ... 0x6c:
|
||||
case 0x74 ... 0x75:
|
||||
case 0x77 ... 0x80:
|
||||
case 0x82 ... 0x8f:
|
||||
case 0x97 ... 0x9b:
|
||||
case 0xc8 ... 0xcb:
|
||||
case 0xd4 ... 0xd8:
|
||||
case 0xda:
|
||||
case 0xe0:
|
||||
case 0xe2 ... 0xe3:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->pci_conf[addr] = val & 0xc0;
|
||||
sis_5600_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5600_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x62:
|
||||
dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = dev->ram_banks[0].installed |
|
||||
(dev->ram_banks[1].installed << 1) |
|
||||
(dev->ram_banks[2].installed << 2);
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5600_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x73:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5600_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x91 ... 0x93:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5600_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
case 0x94:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
sis_5600_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5600_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5600_host_to_pci_log("SiS 5600 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5600_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x00;
|
||||
dev->pci_conf[0x03] = 0x56;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x10;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x10;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0xff;
|
||||
dev->pci_conf[0x0e] = 0x80;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00;
|
||||
dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00;
|
||||
dev->pci_conf[0x34] = 0xc0;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x02;
|
||||
dev->pci_conf[0x52] = dev->pci_conf[0x53] = 0x00;
|
||||
dev->pci_conf[0x54] = dev->pci_conf[0x55] = 0x00;
|
||||
dev->pci_conf[0x56] = dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = dev->pci_conf[0x59] = 0x00;
|
||||
dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = 0x00;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = dev->pci_conf[0x67] = 0x00;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
|
||||
dev->pci_conf[0x6c] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00;
|
||||
dev->pci_conf[0x7c] = dev->pci_conf[0x7d] = 0x00;
|
||||
dev->pci_conf[0x7e] = dev->pci_conf[0x7f] = 0x00;
|
||||
dev->pci_conf[0x80] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff;
|
||||
dev->pci_conf[0x86] = 0xff;
|
||||
dev->pci_conf[0x87] = 0x00;
|
||||
dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00;
|
||||
dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00;
|
||||
dev->pci_conf[0x8c] = 0x00;
|
||||
dev->pci_conf[0x8d] = 0x62;
|
||||
dev->pci_conf[0x8e] = dev->pci_conf[0x8f] = 0x00;
|
||||
dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0xc0] = 0x02;
|
||||
dev->pci_conf[0xc1] = 0x00;
|
||||
dev->pci_conf[0xc2] = 0x10;
|
||||
dev->pci_conf[0xc3] = 0x00;
|
||||
dev->pci_conf[0xc4] = 0x03;
|
||||
dev->pci_conf[0xc5] = 0x02;
|
||||
dev->pci_conf[0xc6] = 0x00;
|
||||
dev->pci_conf[0xc7] = 0x1f;
|
||||
dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00;
|
||||
dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00;
|
||||
dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00;
|
||||
dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00;
|
||||
dev->pci_conf[0xd8] = dev->pci_conf[0xda] = 0x00;
|
||||
dev->pci_conf[0xe0] = 0x00;
|
||||
dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00;
|
||||
|
||||
sis_5600_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
|
||||
cpu_cache_ext_enabled = 1;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5600_shadow_recalc(dev);
|
||||
|
||||
sis_5600_smram_recalc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5600_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5600_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5600_host_to_pci_t *dev = (sis_5600_host_to_pci_t *) calloc(1, sizeof(sis_5600_host_to_pci_t));
|
||||
uint32_t total_mem = mem_size << 10;
|
||||
ram_bank_t *rb;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* Calculate the physical RAM banks. */
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
rb = &(dev->ram_banks[i]);
|
||||
uint32_t size = 0x00000000;
|
||||
uint8_t index = 0;
|
||||
for (int8_t j = 6; j >= 0; j--) {
|
||||
uint32_t *bs = &(bank_sizes[j]);
|
||||
if (*bs <= total_mem) {
|
||||
size = *bs;
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (size != 0x00000000) {
|
||||
rb->installed = 1;
|
||||
rb->code = bank_codes[index];
|
||||
rb->phys_size = size;
|
||||
total_mem -= size;
|
||||
} else
|
||||
rb->installed = 0;
|
||||
}
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
device_add(&sis_5xxx_agp_device);
|
||||
dev->agpgart = device_add(&agpgart_device);
|
||||
|
||||
sis_5600_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5600_h2p_device = {
|
||||
.name = "SiS (5)600 Host to PCI bridge",
|
||||
.internal_name = "sis_5600_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5600_host_to_pci_init,
|
||||
.close = sis_5600_host_to_pci_close,
|
||||
.reset = sis_5600_host_to_pci_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -123,7 +123,7 @@ sis_85c497_isa_read(uint16_t port, void *priv)
|
||||
const sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port == 0x23)
|
||||
if ((port == 0x23) && (dev->cur_reg < 0xc0))
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
else if (port == 0x33)
|
||||
ret = 0x3c /*random_generate()*/;
|
||||
@@ -388,8 +388,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x67: /* Miscellaneous Control */
|
||||
dev->pci_conf[addr] = val & 0xf9;
|
||||
if (valxor & 0x60)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40));
|
||||
cpu_cpurst_on_sr = ((val & 0xa0) == 0x80) && !(dev->pci_conf[0xc6] & 0x08);
|
||||
break;
|
||||
|
||||
/* 86C497 Specific Registers (80h ~ FFh) */
|
||||
@@ -480,6 +479,8 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0xc6: /* 85C497 Post / INIT Configuration */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
cpu_cpurst_on_sr = ((dev->pci_conf[0x67] & 0xa0) == 0x80) && !(val & 0x08);
|
||||
soft_reset_pci = !!(val & 0x04);
|
||||
break;
|
||||
case 0xc8:
|
||||
case 0xc9:
|
||||
@@ -608,12 +609,18 @@ sis_85c496_reset(void *priv)
|
||||
sis_85c49x_pci_write(0, 0xd0, 0x78, dev);
|
||||
sis_85c49x_pci_write(0, 0xd4, 0x00, dev);
|
||||
|
||||
dev->pci_conf[0x67] = 0x00;
|
||||
dev->pci_conf[0xc6] = 0x00;
|
||||
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
|
||||
nvr_bank_set(0, 0, dev->nvr);
|
||||
|
||||
sis_85c497_isa_reset(dev);
|
||||
|
||||
cpu_cpurst_on_sr = 0;
|
||||
soft_reset_pci = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -174,9 +174,7 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
|
||||
case 0x23:
|
||||
if ((dev->cur_reg >= dev->reg_base) && (dev->cur_reg <= dev->reg_last)) {
|
||||
valxor = val ^ dev->regs[rel_reg];
|
||||
if (rel_reg == 0x19)
|
||||
dev->regs[rel_reg] &= ~val;
|
||||
else if (rel_reg == 0x00)
|
||||
if (rel_reg == 0x00)
|
||||
dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0);
|
||||
else
|
||||
dev->regs[rel_reg] = val;
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 85C50x Chipset.
|
||||
* Implementation of the SiS 85C50x and 550x Chipsets.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020-2021 Tiseno100.
|
||||
* Copyright 2020-2021 Miran Grca.
|
||||
* Copyright 2020-2024 Miran Grca.
|
||||
* Copyright 2020-2024 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@@ -27,16 +25,21 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/apm.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/port_92.h>
|
||||
|
||||
#include <86box/spd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_85C50X_LOG
|
||||
@@ -58,17 +61,23 @@ sis_85c50x_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_85c50x_t {
|
||||
uint8_t index;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t index;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t type;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[256];
|
||||
uint8_t regs[256];
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[256];
|
||||
uint8_t pci_conf_ide[256];
|
||||
uint8_t regs[256];
|
||||
uint32_t states[13];
|
||||
|
||||
smram_t *smram[2];
|
||||
port_92_t *port_92;
|
||||
void *pit;
|
||||
nvr_t *nvr;
|
||||
|
||||
uint8_t (*pit_read_reg)(void *priv, uint8_t reg);
|
||||
} sis_85c50x_t;
|
||||
|
||||
static void
|
||||
@@ -77,23 +86,59 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
|
||||
uint32_t base;
|
||||
uint32_t can_read;
|
||||
uint32_t can_write;
|
||||
uint32_t state;
|
||||
|
||||
can_read = (dev->pci_conf[0x53] & 0x40) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
can_write = (dev->pci_conf[0x53] & 0x20) ? MEM_WRITE_EXTANY : MEM_WRITE_INTERNAL;
|
||||
if (!can_read)
|
||||
can_write = MEM_WRITE_EXTANY;
|
||||
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write);
|
||||
shadowbios = 1;
|
||||
shadowbios_write = 1;
|
||||
state = can_read | can_write;
|
||||
if (dev->states[12] != state) {
|
||||
mem_set_mem_state_both(0x000f0000, 0x00010000, state);
|
||||
sis_85c50x_log("F0000-FFFFF: R%c, W%c\n",
|
||||
(dev->pci_conf[0x53] & 0x40) ? 'I' : 'E',
|
||||
(dev->pci_conf[0x53] & 0x20) ? 'P' : 'I');
|
||||
dev->states[12] = state;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
base = 0xe0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x54] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xd0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x55] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0xc0000 + (i << 14);
|
||||
mem_set_mem_state_both(base, 0x4000, (dev->pci_conf[0x56] & (1 << (7 - i))) ? (can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY));
|
||||
base = 0x000e0000 + (i << 14);
|
||||
state = (dev->pci_conf[0x54] & (0x80 >> i)) ?
|
||||
(can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
if (dev->states[8 + i] != state) {
|
||||
mem_set_mem_state_both(base, 0x00004000, state);
|
||||
sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff,
|
||||
(dev->pci_conf[0x543 & (0x80 >> i)) ?
|
||||
((dev->pci_conf[0x54] & 0x40) ? 'I' : 'D') : 'E',
|
||||
(dev->pci_conf[0x54] & (0x80 >> i)) ?
|
||||
((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E');
|
||||
dev->states[8 + i] = state;
|
||||
}
|
||||
|
||||
base = 0x000d0000 + (i << 14);
|
||||
state = (dev->pci_conf[0x55] & (0x80 >> i)) ?
|
||||
(can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
if (dev->states[4 + i] != state) {
|
||||
mem_set_mem_state_both(base, 0x00004000, state);
|
||||
sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff,
|
||||
(dev->pci_conf[0x55] & (0x80 >> i)) ?
|
||||
((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E',
|
||||
(dev->pci_conf[0x55] & (0x80 >> i)) ?
|
||||
((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E');
|
||||
dev->states[4 + i] = state;
|
||||
}
|
||||
|
||||
base = 0x000c0000 + (i << 14);
|
||||
state = (dev->pci_conf[0x56] & (0x80 >> i)) ?
|
||||
(can_read | can_write) : (MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
if (dev->states[i] != state) {
|
||||
mem_set_mem_state_both(base, 0x00004000, state);
|
||||
sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff,
|
||||
(dev->pci_conf[0x56] & (0x80 >> i)) ?
|
||||
((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E',
|
||||
(dev->pci_conf[0x56] & (0x80 >> i)) ?
|
||||
((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E');
|
||||
dev->states[i] = state;
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
@@ -117,27 +162,35 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev)
|
||||
break;
|
||||
case 0x01:
|
||||
host_base |= 0x000b0000;
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x10000 - 1);
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n",
|
||||
host_base, host_base + 0x10000 - 1);
|
||||
smram_enable(dev->smram[0], host_base, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xb0000,
|
||||
0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x02:
|
||||
host_base |= 0x000a0000;
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x10000 - 1);
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n",
|
||||
host_base, host_base + 0x10000 - 1);
|
||||
smram_enable(dev->smram[0], host_base, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000,
|
||||
0x10000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x04:
|
||||
host_base |= 0x000a0000;
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n", host_base, host_base + 0x8000 - 1);
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000A0000-000AFFFF\n",
|
||||
host_base, host_base + 0x8000 - 1);
|
||||
smram_enable(dev->smram[0], host_base, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000,
|
||||
0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
case 0x06:
|
||||
host_base |= 0x000b0000;
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n", host_base, host_base + 0x8000 - 1);
|
||||
sis_85c50x_log("SiS 50x SMRAM: %08X-%08X -> 000B0000-000BFFFF\n",
|
||||
host_base, host_base + 0x8000 - 1);
|
||||
smram_enable(dev->smram[0], host_base, 0xb0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000, 0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
smram_enable(dev->smram[1], host_base ^ 0x00100000, 0xa0000,
|
||||
0x8000, (dev->pci_conf[0x65] & 0x10), 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -160,7 +213,10 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = ((dev->pci_conf[addr] & 0xf9) & ~(val & 0xf8)) | (val & 0x06);
|
||||
break;
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (dev->type & 1)
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
else
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x51: /* Cache */
|
||||
dev->pci_conf[addr] = val;
|
||||
@@ -176,8 +232,6 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_85c50x_shadow_recalc(dev);
|
||||
if (addr == 0x54)
|
||||
sis_85c50x_smm_recalc(dev);
|
||||
break;
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
@@ -204,6 +258,7 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val;
|
||||
kbc_at_set_fast_reset(!!(val & 0x40));
|
||||
break;
|
||||
case 0x60: /* SMI */
|
||||
if ((dev->pci_conf[0x68] & 0x01) && !(dev->pci_conf[addr] & 0x02) && (val & 0x02)) {
|
||||
@@ -223,6 +278,31 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= ~val;
|
||||
break;
|
||||
case 0x70 ... 0x77:
|
||||
if (dev->type & 1)
|
||||
spd_write_drbs(dev->pci_conf, 0x70, 0x77, 2);
|
||||
break;
|
||||
case 0x78:
|
||||
case 0x7c ... 0x7e:
|
||||
if (dev->type & 1)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
case 0x79:
|
||||
if (dev->type & 1) {
|
||||
spd_write_drbs(dev->pci_conf, 0xf8, 0xff, 4);
|
||||
dev->pci_conf[addr] = 0x00;
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
if (dev->pci_conf[0xf8 + i] & 0x80) dev->pci_conf[addr] |= (1 << i);
|
||||
}
|
||||
break;
|
||||
case 0x7a:
|
||||
if (dev->type & 1)
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
case 0x7b:
|
||||
if (dev->type & 1)
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -235,14 +315,33 @@ sis_85c50x_read(int func, int addr, void *priv)
|
||||
const sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = dev->pci_conf[addr];
|
||||
if (func == 0x00) {
|
||||
if (addr >= 0xf8)
|
||||
ret = 0x00;
|
||||
else
|
||||
ret = dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
sis_85c50x_log("85C501: [R] (%02X, %02X) = %02X\n", func, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_85c50x_ide_recalc(sis_85c50x_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_set_base(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0170 : 0x01f0);
|
||||
ide_set_side(0, (dev->pci_conf_ide[0x40] & 0x80) ? 0x0376 : 0x03f6);
|
||||
ide_pri_enable();
|
||||
|
||||
ide_sec_disable();
|
||||
ide_set_base(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x01f0 : 0x0170);
|
||||
ide_set_side(1, (dev->pci_conf_ide[0x40] & 0x80) ? 0x03f6 : 0x0376);
|
||||
if (dev->pci_conf_ide[0x41] & 0x01)
|
||||
ide_sec_enable();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -250,38 +349,46 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv)
|
||||
|
||||
sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x07: /* Status */
|
||||
dev->pci_conf_sb[addr] &= ~(val & 0x30);
|
||||
break;
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
/* INTA/B/C/D# Remapping Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf);
|
||||
break;
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[addr] = val;
|
||||
break;
|
||||
if (func == 0x00) switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[addr] = val & 0x0f;
|
||||
break;
|
||||
case 0x07: /* Status */
|
||||
dev->pci_conf_sb[addr] &= ~(val & 0x30);
|
||||
break;
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x3f;
|
||||
break;
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
/* INTA/B/C/D# Remapping Control Register */
|
||||
dev->pci_conf_sb[addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA + (addr - 0x41), val & 0xf);
|
||||
break;
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01)) switch (addr) {
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
dev->pci_conf_ide[addr] = val;
|
||||
sis_85c50x_ide_recalc(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -290,8 +397,42 @@ sis_85c50x_sb_read(int func, int addr, void *priv)
|
||||
const sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
if (func == 0x00) switch (addr) {
|
||||
default:
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
break;
|
||||
case 0x4c ... 0x4f:
|
||||
if (dev->type & 2)
|
||||
ret = pic_read_icw(0, addr & 0x03);
|
||||
else
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
break;
|
||||
case 0x50 ... 0x53:
|
||||
if (dev->type & 2)
|
||||
ret = pic_read_icw(1, addr & 0x03);
|
||||
else
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
break;
|
||||
case 0x54 ... 0x55:
|
||||
if (dev->type & 2)
|
||||
ret = pic_read_ocw(0, addr & 0x01);
|
||||
else
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
break;
|
||||
case 0x56 ... 0x57:
|
||||
if (dev->type & 2)
|
||||
ret = pic_read_ocw(1, addr & 0x01);
|
||||
else
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
break;
|
||||
case 0x58 ... 0x5f:
|
||||
if (dev->type & 2)
|
||||
ret = dev->pit_read_reg(dev->pit, addr & 0x07);
|
||||
else
|
||||
ret = dev->pci_conf_sb[addr];
|
||||
break;
|
||||
} else if ((dev->type & 2) && !(dev->regs[0x81] & 0x02) && (func == 0x01))
|
||||
ret = dev->pci_conf_ide[addr];
|
||||
|
||||
sis_85c50x_log("85C503: [W] (%02X, %02X) = %02X\n", func, addr, ret);
|
||||
|
||||
@@ -313,10 +454,39 @@ sis_85c50x_isa_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x23:
|
||||
switch (dev->index) {
|
||||
case 0x80:
|
||||
dev->regs[dev->index] = val & 0xe7;
|
||||
if (dev->type & 2) {
|
||||
dev->regs[dev->index] = val;
|
||||
nvr_bank_set(0, !!(val & 0x08), dev->nvr);
|
||||
} else
|
||||
dev->regs[dev->index] = val & 0xe7;
|
||||
switch (val >> 6) {
|
||||
case 0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x81:
|
||||
dev->regs[dev->index] = val & 0xf4;
|
||||
if (dev->type & 2)
|
||||
dev->regs[dev->index] = val & 0xf6;
|
||||
else
|
||||
dev->regs[dev->index] = val & 0xf4;
|
||||
break;
|
||||
case 0x82:
|
||||
if (dev->type & 2)
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x83:
|
||||
if (dev->type & 2)
|
||||
dev->regs[dev->index] = val & 0x03;
|
||||
break;
|
||||
case 0x84:
|
||||
case 0x88:
|
||||
@@ -394,6 +564,12 @@ sis_85c50x_reset(void *priv)
|
||||
sis_85c50x_write(0, 0x68, 0x00, dev);
|
||||
sis_85c50x_write(0, 0x69, 0xff, dev);
|
||||
|
||||
if (dev->type & 1) {
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
dev->pci_conf[0x70 + i] = 0x00;
|
||||
dev->pci_conf[0x79] = 0x00;
|
||||
}
|
||||
|
||||
/* South Bridge (SiS 85C503) */
|
||||
dev->pci_conf_sb[0x00] = 0x39;
|
||||
dev->pci_conf_sb[0x01] = 0x10;
|
||||
@@ -407,10 +583,51 @@ sis_85c50x_reset(void *priv)
|
||||
dev->pci_conf_sb[0x09] = 0x00;
|
||||
dev->pci_conf_sb[0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0x0b] = 0x06;
|
||||
if (dev->type & 2)
|
||||
dev->pci_conf_sb[0x0e] = 0x80;
|
||||
sis_85c50x_sb_write(0, 0x41, 0x80, dev);
|
||||
sis_85c50x_sb_write(0, 0x42, 0x80, dev);
|
||||
sis_85c50x_sb_write(0, 0x43, 0x80, dev);
|
||||
sis_85c50x_sb_write(0, 0x44, 0x80, dev);
|
||||
|
||||
if (dev->type & 2) {
|
||||
/* IDE (SiS 5503) */
|
||||
dev->pci_conf_ide[0x00] = 0x39;
|
||||
dev->pci_conf_ide[0x01] = 0x10;
|
||||
dev->pci_conf_ide[0x02] = 0x01;
|
||||
dev->pci_conf_ide[0x03] = 0x06;
|
||||
dev->pci_conf_ide[0x04] = 0x89;
|
||||
dev->pci_conf_ide[0x05] = 0x00;
|
||||
dev->pci_conf_ide[0x06] = 0x00;
|
||||
dev->pci_conf_ide[0x07] = 0x00;
|
||||
dev->pci_conf_ide[0x08] = 0x00;
|
||||
dev->pci_conf_ide[0x09] = 0x00;
|
||||
dev->pci_conf_ide[0x0a] = 0x01;
|
||||
dev->pci_conf_ide[0x0b] = 0x01;
|
||||
dev->pci_conf_ide[0x0c] = 0x00;
|
||||
dev->pci_conf_ide[0x0d] = 0x00;
|
||||
dev->pci_conf_ide[0x0e] = 0x80;
|
||||
dev->pci_conf_ide[0x0f] = 0x00;
|
||||
dev->pci_conf_ide[0x10] = 0x71;
|
||||
dev->pci_conf_ide[0x11] = 0x01;
|
||||
dev->pci_conf_ide[0x14] = 0xf1;
|
||||
dev->pci_conf_ide[0x15] = 0x01;
|
||||
dev->pci_conf_ide[0x18] = 0x71;
|
||||
dev->pci_conf_ide[0x19] = 0x03;
|
||||
dev->pci_conf_ide[0x1c] = 0xf1;
|
||||
dev->pci_conf_ide[0x1d] = 0x03;
|
||||
dev->pci_conf_ide[0x20] = 0x01;
|
||||
dev->pci_conf_ide[0x24] = 0x01;
|
||||
dev->pci_conf_ide[0x40] = 0x00;
|
||||
dev->pci_conf_ide[0x41] = 0x40;
|
||||
|
||||
sis_85c50x_ide_recalc(dev);
|
||||
}
|
||||
|
||||
cpu_set_isa_speed(7159091);
|
||||
|
||||
if (dev->type & 2)
|
||||
nvr_bank_set(0, 0, dev->nvr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -426,8 +643,10 @@ sis_85c50x_close(void *priv)
|
||||
static void *
|
||||
sis_85c50x_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t));
|
||||
memset(dev, 0x00, sizeof(sis_85c50x_t));
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) calloc(1, sizeof(sis_85c50x_t));
|
||||
uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1));
|
||||
|
||||
dev->type = info->local;
|
||||
|
||||
/* 501/502 (Northbridge) */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot);
|
||||
@@ -441,6 +660,17 @@ sis_85c50x_init(UNUSED(const device_t *info))
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
|
||||
if (dev->type & 2) {
|
||||
/* PIT */
|
||||
dev->pit = device_find_first_priv(DEVICE_PIT);
|
||||
dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg;
|
||||
|
||||
/* NVR */
|
||||
dev->nvr = device_add(&at_mb_nvr_device);
|
||||
|
||||
device_add(&ide_pci_2ch_device);
|
||||
}
|
||||
|
||||
sis_85c50x_reset(dev);
|
||||
|
||||
return dev;
|
||||
@@ -459,3 +689,45 @@ const device_t sis_85c50x_device = {
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_550x_85c503_device = {
|
||||
.name = "SiS 550x",
|
||||
.internal_name = "sis_550x",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = sis_85c50x_init,
|
||||
.close = sis_85c50x_close,
|
||||
.reset = sis_85c50x_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_85c50x_5503_device = {
|
||||
.name = "SiS 85C50x",
|
||||
.internal_name = "sis_85c50x",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 2,
|
||||
.init = sis_85c50x_init,
|
||||
.close = sis_85c50x_close,
|
||||
.reset = sis_85c50x_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_550x_device = {
|
||||
.name = "SiS 550x",
|
||||
.internal_name = "sis_550x",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 3,
|
||||
.init = sis_85c50x_init,
|
||||
.close = sis_85c50x_close,
|
||||
.reset = sis_85c50x_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -79,17 +79,14 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define IDE_BIT 0x01
|
||||
|
||||
#ifdef ENABLE_UMC_8886_LOG
|
||||
int umc_8886_do_log = ENABLE_UMC_8886_LOG;
|
||||
|
||||
@@ -108,18 +105,6 @@ umc_8886_log(const char *fmt, ...)
|
||||
# define umc_8886_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* PCI IRQ Flags */
|
||||
#define INTA (PCI_INTA + (2 * !(addr & 1)))
|
||||
#define INTB (PCI_INTB + (2 * !(addr & 1)))
|
||||
#define IRQRECALCA (((val & 0xf0) != 0) ? ((val & 0xf0) >> 4) : PCI_IRQ_DISABLED)
|
||||
#define IRQRECALCB (((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED)
|
||||
|
||||
/* Disable Internal IDE Flag needed for the AF or BF Southbridge variant */
|
||||
#define HAS_IDE dev->has_ide
|
||||
|
||||
/* Southbridge Revision */
|
||||
#define SB_ID dev->sb_id
|
||||
|
||||
typedef struct umc_8886_t {
|
||||
uint8_t max_func; /* Last function number */
|
||||
uint8_t pci_slot;
|
||||
@@ -128,19 +113,24 @@ typedef struct umc_8886_t {
|
||||
|
||||
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
|
||||
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
int has_ide; /* Check if Southbridge Revision is AF or F */
|
||||
uint16_t sb_id; /* Southbridge Revision */
|
||||
uint16_t ide_id; /* IDE Revision */
|
||||
|
||||
int has_ide; /* Check if Southbridge Revision is F, AF, or BF */
|
||||
} umc_8886_t;
|
||||
|
||||
static void
|
||||
umc_8886_ide_handler(int status)
|
||||
umc_8886_ide_handler(umc_8886_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
|
||||
if (status) {
|
||||
ide_pri_enable();
|
||||
ide_sec_enable();
|
||||
if (dev->pci_conf_sb[1][0x04] & 0x01) {
|
||||
if (dev->pci_conf_sb[1][0x40] & 0x80)
|
||||
ide_pri_enable();
|
||||
|
||||
if (dev->pci_conf_sb[1][0x40] & 0x40)
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,6 +138,7 @@ static void
|
||||
umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
umc_8886_t *dev = (umc_8886_t *) priv;
|
||||
int irq_routing;
|
||||
|
||||
if (func <= dev->max_func)
|
||||
switch (func) {
|
||||
@@ -155,8 +146,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
umc_8886_log("UM8886: dev->regs[%02x] = %02x POST %02x\n", addr, val, inb(0x80));
|
||||
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x04 ... 0x05:
|
||||
case 0x0c ... 0x0d:
|
||||
case 0x40 ... 0x42:
|
||||
case 0x45:
|
||||
case 0x50 ... 0x55:
|
||||
case 0x57:
|
||||
case 0x70 ... 0x76:
|
||||
case 0x80 ... 0x82:
|
||||
case 0x90 ... 0x92:
|
||||
case 0xa0 ... 0xa1:
|
||||
case 0xa5 ... 0xa8:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
@@ -164,46 +164,31 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf_sb[func][addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x43:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) :
|
||||
PCI_IRQ_DISABLED;
|
||||
pci_set_irq_routing(PCI_INTA, irq_routing);
|
||||
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) :
|
||||
PCI_IRQ_DISABLED;
|
||||
pci_set_irq_routing(PCI_INTB, irq_routing);
|
||||
break;
|
||||
case 0x44:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
pci_set_irq_routing(INTA, IRQRECALCA);
|
||||
pci_set_irq_routing(INTB, IRQRECALCB);
|
||||
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) :
|
||||
PCI_IRQ_DISABLED;
|
||||
pci_set_irq_routing(PCI_INTC, irq_routing);
|
||||
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) :
|
||||
PCI_IRQ_DISABLED;
|
||||
pci_set_irq_routing(PCI_INTD, irq_routing);
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */
|
||||
case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */
|
||||
/* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
|
||||
@@ -220,16 +205,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
case 0x70 ... 0x76:
|
||||
case 0x80:
|
||||
case 0x81:
|
||||
case 0x90 ... 0x92:
|
||||
case 0xa0 ... 0xa1:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa2:
|
||||
@@ -243,7 +218,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
picint(1 << ((dev->pci_conf_sb[0][0x46] & 0x80) ? 15 : 10));
|
||||
else
|
||||
smi_raise();
|
||||
dev->pci_conf_sb[0][0xa3] |= 0x04;
|
||||
}
|
||||
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
@@ -254,10 +228,6 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2));
|
||||
break;
|
||||
|
||||
case 0xa5 ... 0xa8:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -269,7 +239,8 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
switch (addr) {
|
||||
case 0x04:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
umc_8886_ide_handler(val & 1);
|
||||
if (dev->ide_id == 0x673a)
|
||||
umc_8886_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
@@ -277,9 +248,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x3c:
|
||||
case 0x41 ... 0x4b:
|
||||
case 0x54 ... 0x59:
|
||||
if (dev->ide_id == 0x673a)
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
if (dev->ide_id == 0x673a) {
|
||||
dev->pci_conf_sb[func][addr] = val;
|
||||
umc_8886_ide_handler(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -311,47 +290,73 @@ umc_8886_reset(void *priv)
|
||||
memset(dev->pci_conf_sb[0], 0x00, sizeof(dev->pci_conf_sb[0]));
|
||||
memset(dev->pci_conf_sb[1], 0x00, sizeof(dev->pci_conf_sb[1]));
|
||||
|
||||
dev->pci_conf_sb[0][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[0][1] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[0][2] = (SB_ID & 0xff); /* 8886xx */
|
||||
dev->pci_conf_sb[0][3] = ((SB_ID >> 8) & 0xff);
|
||||
|
||||
dev->pci_conf_sb[0][4] = 0x0f;
|
||||
dev->pci_conf_sb[0][7] = 2;
|
||||
|
||||
dev->pci_conf_sb[0][8] = 0x0e;
|
||||
|
||||
dev->pci_conf_sb[0][0x00] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[0][0x01] = 0x10;
|
||||
dev->pci_conf_sb[0][0x02] = (dev->sb_id & 0xff); /* 8886xx */
|
||||
dev->pci_conf_sb[0][0x03] = ((dev->sb_id >> 8) & 0xff);
|
||||
dev->pci_conf_sb[0][0x04] = 0x0f;
|
||||
dev->pci_conf_sb[0][0x07] = 0x02;
|
||||
dev->pci_conf_sb[0][0x08] = 0x0e;
|
||||
dev->pci_conf_sb[0][0x09] = 0x00;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
|
||||
dev->pci_conf_sb[0][0x40] = 1;
|
||||
dev->pci_conf_sb[0][0x41] = 6;
|
||||
dev->pci_conf_sb[0][0x42] = 8;
|
||||
dev->pci_conf_sb[0][0x43] = 0x9a;
|
||||
dev->pci_conf_sb[0][0x44] = 0xbc;
|
||||
dev->pci_conf_sb[0][0x45] = 4;
|
||||
dev->pci_conf_sb[0][0x40] = 0x01;
|
||||
dev->pci_conf_sb[0][0x41] = 0x06;
|
||||
dev->pci_conf_sb[0][0x42] = 0x08;
|
||||
dev->pci_conf_sb[0][0x43] = 0x00;
|
||||
dev->pci_conf_sb[0][0x44] = 0x00;
|
||||
dev->pci_conf_sb[0][0x45] = 0x04;
|
||||
dev->pci_conf_sb[0][0x46] = 0x00;
|
||||
dev->pci_conf_sb[0][0x47] = 0x40;
|
||||
dev->pci_conf_sb[0][0x50] = 1;
|
||||
dev->pci_conf_sb[0][0x51] = 3;
|
||||
dev->pci_conf_sb[0][0x50] = 0x01;
|
||||
dev->pci_conf_sb[0][0x51] = 0x03;
|
||||
dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00;
|
||||
dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00;
|
||||
dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00;
|
||||
dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00;
|
||||
dev->pci_conf_sb[0][0x82] = 0x00;
|
||||
dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00;
|
||||
dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00;
|
||||
dev->pci_conf_sb[0][0xa4] = 0x00;
|
||||
dev->pci_conf_sb[0][0xa8] = 0x20;
|
||||
|
||||
if (HAS_IDE) {
|
||||
dev->pci_conf_sb[1][0] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[1][1] = 0x10;
|
||||
if (dev->has_ide) {
|
||||
dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */
|
||||
dev->pci_conf_sb[1][0x01] = 0x10;
|
||||
dev->pci_conf_sb[1][0x02] = (dev->ide_id & 0xff); /* 8886xx IDE */
|
||||
dev->pci_conf_sb[1][0x03] = ((dev->ide_id >> 8) & 0xff);
|
||||
dev->pci_conf_sb[1][0x04] = 0x05; /* Start with Internal IDE Enabled */
|
||||
dev->pci_conf_sb[1][0x08] = 0x10;
|
||||
dev->pci_conf_sb[1][0x09] = 0x8f;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x10] = 0xf1;
|
||||
dev->pci_conf_sb[1][0x11] = 0x01;
|
||||
dev->pci_conf_sb[1][0x14] = 0xf5;
|
||||
dev->pci_conf_sb[1][0x15] = 0x03;
|
||||
dev->pci_conf_sb[1][0x18] = 0x71;
|
||||
dev->pci_conf_sb[1][0x19] = 0x01;
|
||||
dev->pci_conf_sb[1][0x1c] = 0x75;
|
||||
dev->pci_conf_sb[1][0x1d] = 0x03;
|
||||
dev->pci_conf_sb[1][0x20] = 0x01;
|
||||
dev->pci_conf_sb[1][0x21] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[1][2] = 0x3a; /* 8886BF IDE */
|
||||
dev->pci_conf_sb[1][3] = 0x67;
|
||||
if (dev->ide_id == 0x673a) {
|
||||
dev->pci_conf_sb[1][0x40] = 0xc0;
|
||||
dev->pci_conf_sb[1][0x41] = 0x00;
|
||||
dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00;
|
||||
dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00;
|
||||
dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00;
|
||||
dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00;
|
||||
dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00;
|
||||
dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00;
|
||||
dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00;
|
||||
dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00;
|
||||
|
||||
dev->pci_conf_sb[1][4] = 1; /* Start with Internal IDE Enabled */
|
||||
umc_8886_ide_handler(dev);
|
||||
|
||||
dev->pci_conf_sb[1][8] = 0x10;
|
||||
|
||||
dev->pci_conf_sb[1][0x09] = 0x0f;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 1;
|
||||
|
||||
umc_8886_ide_handler(1);
|
||||
picintc(1 << 14);
|
||||
picintc(1 << 15);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */
|
||||
@@ -375,17 +380,28 @@ umc_8886_init(const device_t *info)
|
||||
umc_8886_t *dev = (umc_8886_t *) malloc(sizeof(umc_8886_t));
|
||||
memset(dev, 0, sizeof(umc_8886_t));
|
||||
|
||||
dev->has_ide = !!(info->local == 0x886a);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */
|
||||
|
||||
/* Add IDE if UM8886AF variant */
|
||||
if (HAS_IDE)
|
||||
device_add(&ide_pci_2ch_device);
|
||||
|
||||
dev->max_func = (HAS_IDE) ? 1 : 0;
|
||||
/* Device 12: UMC 8886xx */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot);
|
||||
|
||||
/* Get the Southbridge Revision */
|
||||
SB_ID = info->local;
|
||||
dev->sb_id = info->local & 0xffff;
|
||||
|
||||
/* IDE Revision */
|
||||
dev->ide_id = info->local >> 16;
|
||||
|
||||
dev->has_ide = (dev->ide_id != 0x0000);
|
||||
|
||||
dev->max_func = 0;
|
||||
|
||||
/* Add IDE if this is the UM8886AF or UM8886BF. */
|
||||
if (dev->ide_id == 0x673a) {
|
||||
/* UM8886BF */
|
||||
device_add(&ide_pci_2ch_device);
|
||||
dev->max_func = 1;
|
||||
} else if (dev->ide_id == 0x1001) {
|
||||
/* UM8886AF */
|
||||
device_add(&ide_um8673f_device);
|
||||
}
|
||||
|
||||
umc_8886_reset(dev);
|
||||
|
||||
@@ -396,7 +412,7 @@ const device_t umc_8886f_device = {
|
||||
.name = "UMC 8886F",
|
||||
.internal_name = "umc_8886f",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x8886,
|
||||
.local = 0x00008886,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
@@ -407,10 +423,24 @@ const device_t umc_8886f_device = {
|
||||
};
|
||||
|
||||
const device_t umc_8886af_device = {
|
||||
.name = "UMC 8886AF/8886BF",
|
||||
.name = "UMC 8886AF",
|
||||
.internal_name = "umc_8886af",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x886a,
|
||||
.local = 0x1001886a,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t umc_8886bf_device = {
|
||||
.name = "UMC 8886BF",
|
||||
.internal_name = "umc_8886bf",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x673a888a,
|
||||
.init = umc_8886_init,
|
||||
.close = umc_8886_close,
|
||||
.reset = umc_8886_reset,
|
||||
|
||||
241
src/chipset/umc_8890.c
Normal file
241
src/chipset/umc_8890.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the UMC 8890 Chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021-2024 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
#include <86box/apm.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_UMC_8890_LOG
|
||||
int umc_8890_do_log = ENABLE_UMC_8890_LOG;
|
||||
|
||||
static void
|
||||
umc_8890_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (umc_8890_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define umc_8890_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct umc_8890_t {
|
||||
uint8_t pci_slot;
|
||||
|
||||
uint8_t pci_conf[256]; /* PCI Registers */
|
||||
|
||||
int mem_state[2];
|
||||
|
||||
uint32_t smram_base;
|
||||
|
||||
smram_t *smram; /* SMRAM Handler */
|
||||
} umc_8890_t;
|
||||
|
||||
static void
|
||||
um8890_shadow(umc_8890_t *dev)
|
||||
{
|
||||
uint8_t flag;
|
||||
uint16_t state;
|
||||
|
||||
flag = (dev->pci_conf[0x5f] & 0x0c) >> 2;
|
||||
state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) :
|
||||
(MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0x0c) {
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, state);
|
||||
dev->mem_state[1] = (dev->mem_state[1] & 0xf0) | (dev->pci_conf[0x5f] & 0x0f);
|
||||
}
|
||||
|
||||
flag = (dev->pci_conf[0x5f] & 0xc0) >> 6;
|
||||
state = (flag & 1) ? (MEM_READ_INTERNAL | ((flag & 2) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) :
|
||||
(MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if ((dev->mem_state[1] ^ dev->pci_conf[0x5f]) & 0xc0) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
dev->mem_state[1] = (dev->mem_state[1] & 0x0f) | (dev->pci_conf[0x5f] & 0xf0);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
state = (dev->pci_conf[0x5d] & (1 << i)) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) :
|
||||
(MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if ((dev->mem_state[0] ^ dev->pci_conf[0x5d]) & (1 << i)) {
|
||||
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, state);
|
||||
dev->mem_state[0] = (dev->mem_state[0] & ~(1 << i)) | (dev->pci_conf[0x5d] & (1 << i));
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
um8890_smram(umc_8890_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
/* Bit 4, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled
|
||||
in SMM, and is always set to A0000-BFFFF. */
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
um8890_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
|
||||
if (func == 0) switch (addr) {
|
||||
case 0x04 ... 0x05:
|
||||
case 0x0c ... 0x0d:
|
||||
case 0x40 ... 0x5b:
|
||||
case 0x60 ... 0x63:
|
||||
case 0x66 ... 0xff:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x5c ... 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
um8890_shadow(dev);
|
||||
break;
|
||||
|
||||
/* Register 64h, 16-bit:
|
||||
Bit 12: SMRAM enabled outside SMM (1 = yes, 0 = no);
|
||||
Bit 10: ???? (set by Award BIOS);
|
||||
Bits 7- 0: SMM handler offset to SMBASE, shifted to the right by 14.
|
||||
*/
|
||||
case 0x64: case 0x65:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (addr == 0x65)
|
||||
um8890_smram(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
umc_8890_log("UM8890: dev->regs[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80));
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
um8890_read(int func, int addr, void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0)
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
umc_8890_reset(void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
|
||||
/* Defaults */
|
||||
dev->pci_conf[0x00] = 0x60; /* UMC */
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x91; /* 8891F */
|
||||
dev->pci_conf[0x03] = 0x88;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x01;
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = 0x00;
|
||||
dev->pci_conf[0x5e] = 0x00;
|
||||
dev->pci_conf[0x5f] = 0x00;
|
||||
dev->pci_conf[0x64] = 0x00;
|
||||
dev->pci_conf[0x65] = 0x00;
|
||||
|
||||
um8890_shadow(dev);
|
||||
|
||||
um8890_smram(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
umc_8890_close(void *priv)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *)priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
umc_8890_init(const device_t *info)
|
||||
{
|
||||
umc_8890_t *dev = (umc_8890_t *) calloc(1, sizeof(umc_8890_t));
|
||||
|
||||
/* Device 0: UMC 8890 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, um8890_read, um8890_write, dev, &dev->pci_slot);
|
||||
|
||||
/* Port 92 */
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
umc_8890_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t umc_8890_device = {
|
||||
.name = "UMC 8890(8891BF/8892BF)",
|
||||
.internal_name = "umc_8890",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x886a,
|
||||
.init = umc_8890_init,
|
||||
.close = umc_8890_close,
|
||||
.reset = umc_8890_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -14,13 +14,11 @@
|
||||
* Note 2: Additional information were also used from all
|
||||
* around the web.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021-2024 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -75,15 +73,24 @@
|
||||
Bit 3: CC000-CFFFF Read Enable
|
||||
Bit 2: C8000-CBFFF Read Enable
|
||||
Bit 1: C0000-C7FFF Read Enable
|
||||
Bit 0: Enable C0000-DFFFF Shadow Segment Bits
|
||||
Bit 0: E0000-EFFFF Read Enable
|
||||
|
||||
Register 55:
|
||||
Bit 7: E0000-FFFF Read Enable
|
||||
Bit 7: F0000-FFFF Read Enable
|
||||
Bit 6: Shadow Write Status (1: Write Protect/0: Write)
|
||||
|
||||
Register 56h & 57h: DRAM Bank 0 Configuration
|
||||
Register 58h & 59h: DRAM Bank 1 Configuration
|
||||
|
||||
Register 5A:
|
||||
Bit 2: Detrubo
|
||||
|
||||
Register 5C:
|
||||
Bits 7-0: SMRAM base A27-A20
|
||||
|
||||
Register 5D:
|
||||
Bits 3-0: SMRAM base A31-A28
|
||||
|
||||
Register 60:
|
||||
Bit 5: If set and SMRAM is enabled, data cycles go to PCI and code cycles go to DRAM
|
||||
Bit 0: SMRAM Local Access Enable - if set, SMRAM is also enabled outside SMM
|
||||
@@ -129,14 +136,15 @@ hb4_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct hb4_t {
|
||||
uint8_t shadow;
|
||||
uint8_t shadow_read;
|
||||
uint8_t shadow_write;
|
||||
uint8_t pci_slot;
|
||||
|
||||
uint8_t pci_conf[256]; /* PCI Registers */
|
||||
|
||||
int mem_state[9];
|
||||
smram_t *smram[3]; /* SMRAM Handlers */
|
||||
|
||||
uint32_t smram_base;
|
||||
|
||||
smram_t *smram; /* SMRAM Handler */
|
||||
} hb4_t;
|
||||
|
||||
static int shadow_bios[4] = { (MEM_READ_EXTANY | MEM_WRITE_INTERNAL), (MEM_READ_EXTANY | MEM_WRITE_EXTANY),
|
||||
@@ -167,7 +175,8 @@ hb4_shadow_bios_low(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_bios[(dev->pci_conf[0x55] >> 6) & (dev->shadow | 0x01)];
|
||||
/* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */
|
||||
state = shadow_bios[dev->pci_conf[0x55] >> 6];
|
||||
|
||||
if (state != dev->mem_state[7]) {
|
||||
mem_set_mem_state_both(0xe0000, 0x10000, state);
|
||||
@@ -185,7 +194,8 @@ hb4_shadow_main(hb4_t *dev)
|
||||
int n = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> (i + 2)) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[i + 1]) {
|
||||
n++;
|
||||
@@ -202,7 +212,8 @@ hb4_shadow_video(hb4_t *dev)
|
||||
{
|
||||
int state;
|
||||
|
||||
state = shadow_read[dev->shadow && ((dev->pci_conf[0x54] >> 1) & 0x01)] | shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] |
|
||||
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
|
||||
|
||||
if (state != dev->mem_state[0]) {
|
||||
mem_set_mem_state_both(0xc0000, 0x8000, state);
|
||||
@@ -232,22 +243,26 @@ static void
|
||||
hb4_smram(hb4_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
if (dev->smram_base != 0x00000000)
|
||||
umc_smram_recalc(dev->smram_base >> 12, 0);
|
||||
|
||||
dev->smram_base = ((uint32_t) dev->pci_conf[0x5c]) << 20;
|
||||
dev->smram_base |= ((uint32_t) (dev->pci_conf[0x5d] & 0x0f)) << 28;
|
||||
dev->smram_base |= 0x000a0000;
|
||||
|
||||
/* Bit 0, if set, enables SMRAM access outside SMM. SMRAM appears to be always enabled
|
||||
in SMM, and is always set to A0000-BFFFF. */
|
||||
smram_enable(dev->smram[0], 0x000a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
/* There's a mirror of the SMRAM at 0E0A0000, mapped to A0000. */
|
||||
smram_enable(dev->smram[1], 0x0e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
/* There's another mirror of the SMRAM at 4E0A0000, mapped to A0000. */
|
||||
smram_enable(dev->smram[2], 0x4e0a0000, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
smram_enable(dev->smram, dev->smram_base, 0x000a0000, 0x20000, dev->pci_conf[0x60] & 0x01, 1);
|
||||
|
||||
/* Bit 5 seems to set data to go to PCI and code to DRAM. The Samsung SPC7700P-LW uses
|
||||
this. */
|
||||
if (dev->pci_conf[0x60] & 0x20) {
|
||||
if (dev->pci_conf[0x60] & 0x01)
|
||||
mem_set_mem_state_smram_ex(0, 0x000a0000, 0x20000, 0x02);
|
||||
mem_set_mem_state_smram_ex(1, 0x000a0000, 0x20000, 0x02);
|
||||
mem_set_mem_state_smram_ex(0, dev->smram_base, 0x20000, 0x02);
|
||||
mem_set_mem_state_smram_ex(1, dev->smram_base, 0x20000, 0x02);
|
||||
}
|
||||
|
||||
umc_smram_recalc(dev->smram_base >> 12, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -278,38 +293,27 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x51 ... 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_log("HB53: %02X\n", val);
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->shadow_read = (val & 0x80);
|
||||
dev->shadow_write = (val & 0x40);
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
case 0x54:
|
||||
dev->shadow = (val & 0x01) << 1;
|
||||
case 0x54 ... 0x55:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_shadow(dev);
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x5f:
|
||||
case 0x56 ... 0x5b:
|
||||
case 0x5e ... 0x5f:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5c ... 0x5d:
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val;
|
||||
hb4_smram(dev);
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
case 0x61 ... 0x62:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -336,30 +340,35 @@ hb4_reset(void *priv)
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
memset(dev->pci_conf, 0x00, sizeof(dev->pci_conf));
|
||||
|
||||
dev->pci_conf[0] = 0x60; /* UMC */
|
||||
dev->pci_conf[1] = 0x10;
|
||||
|
||||
dev->pci_conf[2] = 0x81; /* 8881x */
|
||||
dev->pci_conf[3] = 0x88;
|
||||
|
||||
dev->pci_conf[7] = 2;
|
||||
|
||||
dev->pci_conf[8] = 4;
|
||||
|
||||
dev->pci_conf[0x00] = 0x60; /* UMC */
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x81; /* 8881x */
|
||||
dev->pci_conf[0x03] = 0x88;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x04;
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
|
||||
dev->pci_conf[0x51] = 1;
|
||||
dev->pci_conf[0x52] = 1;
|
||||
dev->pci_conf[0x5a] = 4;
|
||||
dev->pci_conf[0x5c] = 0xc0;
|
||||
dev->pci_conf[0x50] = 0x00;
|
||||
dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x01;
|
||||
dev->pci_conf[0x53] = 0x00;
|
||||
dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = 0x00;
|
||||
dev->pci_conf[0x56] = 0x00;
|
||||
dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = 0x00;
|
||||
dev->pci_conf[0x5a] = 0x04;
|
||||
dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = 0x20;
|
||||
dev->pci_conf[0x5f] = 0xff;
|
||||
dev->pci_conf[0x60] = 0x00;
|
||||
dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = 0x00;
|
||||
|
||||
hb4_write(0, 0x54, 0x00, dev);
|
||||
hb4_write(0, 0x55, 0x00, dev);
|
||||
hb4_write(0, 0x60, 0x80, dev);
|
||||
hb4_shadow(dev);
|
||||
hb4_smram(dev);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
@@ -372,6 +381,7 @@ hb4_close(void *priv)
|
||||
{
|
||||
hb4_t *dev = (hb4_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -387,10 +397,9 @@ hb4_init(UNUSED(const device_t *info))
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram[0] = smram_add();
|
||||
dev->smram[1] = smram_add();
|
||||
dev->smram[2] = smram_add();
|
||||
dev->smram = smram_add();
|
||||
|
||||
dev->smram_base = 0x000a0000;
|
||||
hb4_reset(dev);
|
||||
|
||||
return dev;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -671,9 +671,10 @@ ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb
|
||||
ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static double fp_imm = v; \
|
||||
static uint64_t *fptr = (uint64_t *) &fp_imm; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \
|
||||
FP_LOAD_IMM_Q(*fptr); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ static void
|
||||
build_load_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset;
|
||||
uint8_t *misaligned_offset = NULL;
|
||||
|
||||
/*In - ESI = address
|
||||
Out - ECX = data, ESI = abrt*/
|
||||
@@ -161,7 +161,7 @@ static void
|
||||
build_store_routine(codeblock_t *block, int size, int is_float)
|
||||
{
|
||||
uint8_t *branch_offset;
|
||||
uint8_t *misaligned_offset;
|
||||
uint8_t *misaligned_offset = NULL;
|
||||
|
||||
/*In - ECX = data, ESI = address
|
||||
Out - ESI = abrt
|
||||
|
||||
279
src/config.c
279
src/config.c
@@ -77,6 +77,7 @@
|
||||
#include <86box/plat_dir.h>
|
||||
#include <86box/ui.h>
|
||||
#include <86box/snd_opl.h>
|
||||
#include <86box/version.h>
|
||||
|
||||
static int cx;
|
||||
static int cy;
|
||||
@@ -139,8 +140,6 @@ 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);
|
||||
|
||||
status_icons_fullscreen = !!ini_section_get_int(cat, "status_icons_fullscreen", 0);
|
||||
|
||||
window_remember = ini_section_get_int(cat, "window_remember", 0);
|
||||
|
||||
if (!window_remember && !(vid_resize & 2))
|
||||
@@ -211,6 +210,12 @@ load_general(void)
|
||||
ini_section_delete_var(cat, "window_coordinates");
|
||||
|
||||
do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0);
|
||||
|
||||
p = ini_section_get_string(cat, "uuid", NULL);
|
||||
if (p != NULL)
|
||||
strncpy(uuid, p, sizeof(uuid) - 1);
|
||||
else
|
||||
strncpy(uuid, "", sizeof(uuid) - 1);
|
||||
}
|
||||
|
||||
/* Load monitor section. */
|
||||
@@ -244,25 +249,82 @@ load_machine(void)
|
||||
{
|
||||
ini_section_t cat = ini_find_section(config, "Machine");
|
||||
const char *p;
|
||||
const char *migrate_from = NULL;
|
||||
int c;
|
||||
int i;
|
||||
int j;
|
||||
int speed;
|
||||
double multi;
|
||||
|
||||
p = ini_section_get_string(cat, "machine", NULL);
|
||||
if (p != NULL)
|
||||
machine = machine_get_machine_from_internal_name(p);
|
||||
else
|
||||
if (p != NULL) {
|
||||
migrate_from = p;
|
||||
/* Migrate renamed machines. */
|
||||
if (!strcmp(p, "430nx"))
|
||||
machine = machine_get_machine_from_internal_name("586ip");
|
||||
else if (!strcmp(p, "586mc1"))
|
||||
machine = machine_get_machine_from_internal_name("586is");
|
||||
else {
|
||||
machine = machine_get_machine_from_internal_name(p);
|
||||
migrate_from = NULL;
|
||||
}
|
||||
} else
|
||||
machine = 0;
|
||||
|
||||
if (machine >= machine_count())
|
||||
machine = machine_count() - 1;
|
||||
|
||||
cpu_override = ini_section_get_int(cat, "cpu_override", 0);
|
||||
cpu_f = NULL;
|
||||
p = ini_section_get_string(cat, "cpu_family", NULL);
|
||||
/* Copy NVR files when migrating a machine to a new internal name. */
|
||||
if (migrate_from) {
|
||||
char old_fn[256];
|
||||
strcpy(old_fn, migrate_from);
|
||||
strcat(old_fn, ".");
|
||||
c = strlen(old_fn);
|
||||
char new_fn[256];
|
||||
strcpy(new_fn, machines[machine].internal_name);
|
||||
strcat(new_fn, ".");
|
||||
i = strlen(new_fn);
|
||||
|
||||
/* Iterate through NVR files. */
|
||||
DIR *dirp = opendir(nvr_path("."));
|
||||
if (dirp) {
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dirp))) {
|
||||
/* Check if this file corresponds to the old name. */
|
||||
if (strncmp(entry->d_name, old_fn, c))
|
||||
continue;
|
||||
|
||||
/* Add extension to the new name. */
|
||||
strcpy(&new_fn[i], &entry->d_name[c]);
|
||||
|
||||
/* Only copy if a file with the new name doesn't already exist. */
|
||||
FILE *g = nvr_fopen(new_fn, "rb");
|
||||
if (!g) {
|
||||
FILE *f = nvr_fopen(entry->d_name, "rb");
|
||||
g = nvr_fopen(new_fn, "wb");
|
||||
|
||||
uint8_t buf[4096];
|
||||
while ((j = fread(buf, 1, sizeof(buf), f)))
|
||||
fwrite(buf, 1, j, g);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
fclose(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cpu_override = ini_section_get_int(cat, "cpu_override", 0);
|
||||
cpu_override_interpreter = ini_section_get_int(cat, "cpu_override_interpreter", 0);
|
||||
cpu_f = NULL;
|
||||
p = ini_section_get_string(cat, "cpu_family", NULL);
|
||||
if (p) {
|
||||
cpu_f = cpu_get_family(p);
|
||||
/* Migrate CPU family changes. */
|
||||
if ((!strcmp(machines[machine].internal_name, "deskpro386") ||
|
||||
!strcmp(machines[machine].internal_name, "deskpro386_05_1988")))
|
||||
cpu_f = cpu_get_family("i386dx_deskpro386");
|
||||
else
|
||||
cpu_f = cpu_get_family(p);
|
||||
|
||||
if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */
|
||||
cpu_f = NULL;
|
||||
@@ -609,9 +671,9 @@ load_network(void)
|
||||
if (nc->net_type == NET_TYPE_PCAP) {
|
||||
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
|
||||
if (network_ndev == 1)
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
|
||||
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC));
|
||||
else if (network_dev_to_id(p) == -1)
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
|
||||
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC));
|
||||
strcpy(nc->host_dev_name, "none");
|
||||
} else
|
||||
strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1);
|
||||
@@ -656,9 +718,9 @@ load_network(void)
|
||||
if (nc->net_type == NET_TYPE_PCAP) {
|
||||
if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) {
|
||||
if (network_ndev == 1)
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2130);
|
||||
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_NO_DEVICES), plat_get_string(STRING_PCAP_ERROR_DESC));
|
||||
else if (network_dev_to_id(p) == -1)
|
||||
ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2096, (wchar_t *) IDS_2130);
|
||||
ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_PCAP_ERROR_INVALID_DEVICE), plat_get_string(STRING_PCAP_ERROR_DESC));
|
||||
strcpy(nc->host_dev_name, "none");
|
||||
} else
|
||||
strncpy(nc->host_dev_name, p, sizeof(nc->host_dev_name) - 1);
|
||||
@@ -683,7 +745,6 @@ load_ports(void)
|
||||
char *p;
|
||||
char temp[512];
|
||||
int c;
|
||||
int d;
|
||||
|
||||
memset(temp, 0, sizeof(temp));
|
||||
|
||||
@@ -706,14 +767,6 @@ load_ports(void)
|
||||
p = ini_section_get_string(cat, temp, "none");
|
||||
lpt_ports[c].device = lpt_device_get_from_internal_name(p);
|
||||
}
|
||||
|
||||
/* Legacy config compatibility. */
|
||||
d = ini_section_get_int(cat, "lpt_enabled", 2);
|
||||
if (d < 2) {
|
||||
for (c = 0; c < PARALLEL_MAX; c++)
|
||||
lpt_ports[c].enabled = d;
|
||||
}
|
||||
ini_section_delete_var(cat, "lpt_enabled");
|
||||
}
|
||||
|
||||
/* Load "Storage Controllers" section. */
|
||||
@@ -721,13 +774,14 @@ static void
|
||||
load_storage_controllers(void)
|
||||
{
|
||||
ini_section_t cat = ini_find_section(config, "Storage controllers");
|
||||
ini_section_t migration_cat;
|
||||
char *p;
|
||||
char temp[512];
|
||||
int c;
|
||||
int min = 0;
|
||||
int free_p = 0;
|
||||
|
||||
for (c = min; c < SCSI_BUS_MAX; c++) {
|
||||
for (c = min; c < SCSI_CARD_MAX; c++) {
|
||||
sprintf(temp, "scsicard_%d", c + 1);
|
||||
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
@@ -754,17 +808,16 @@ load_storage_controllers(void)
|
||||
}
|
||||
free_p = 1;
|
||||
}
|
||||
if (!strcmp(p, "mfm_xt"))
|
||||
hdc_current = hdc_get_from_internal_name("st506_xt");
|
||||
else if (!strcmp(p, "mfm_xt_dtc5150x"))
|
||||
hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x");
|
||||
else if (!strcmp(p, "mfm_at"))
|
||||
hdc_current = hdc_get_from_internal_name("st506_at");
|
||||
else if (!strcmp(p, "vlb_isa"))
|
||||
hdc_current = hdc_get_from_internal_name("ide_vlb");
|
||||
else if (!strcmp(p, "vlb_isa_2ch"))
|
||||
hdc_current = hdc_get_from_internal_name("ide_vlb_2ch");
|
||||
else
|
||||
/* Migrate renamed and merged cards. */
|
||||
if (!strcmp(p, "xtide_plus")) {
|
||||
hdc_current = hdc_get_from_internal_name("xtide");
|
||||
migration_cat = ini_find_or_create_section(config, "PC/XT XTIDE");
|
||||
ini_section_set_string(migration_cat, "bios", "xt_plus");
|
||||
} else if (!strcmp(p, "xtide_at_386")) {
|
||||
hdc_current = hdc_get_from_internal_name("xtide_at");
|
||||
migration_cat = ini_find_or_create_section(config, "PC/AT XTIDE");
|
||||
ini_section_set_string(migration_cat, "bios", "at_386");
|
||||
} else
|
||||
hdc_current = hdc_get_from_internal_name(p);
|
||||
|
||||
if (free_p) {
|
||||
@@ -822,6 +875,8 @@ load_storage_controllers(void)
|
||||
path_normalize(cart_fns[c]);
|
||||
}
|
||||
}
|
||||
|
||||
lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0);
|
||||
}
|
||||
|
||||
/* Load "Hard Disks" section. */
|
||||
@@ -1104,13 +1159,13 @@ load_floppy_and_cdrom_drives(void)
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 255)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 255 "
|
||||
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 "
|
||||
"(fdd_image_history[%i][%i])\n", c, i);
|
||||
else
|
||||
snprintf(fdd_image_history[c][i], 255, "%s", p);
|
||||
snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
|
||||
} else
|
||||
snprintf(fdd_image_history[c][i], 255, "%s%s%s", usr_path,
|
||||
snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(fdd_image_history[c][i]);
|
||||
}
|
||||
@@ -1220,13 +1275,13 @@ load_floppy_and_cdrom_drives(void)
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 "
|
||||
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 "
|
||||
"(cdrom[%i].image_history[%i])\n", c, i);
|
||||
else
|
||||
snprintf(cdrom[c].image_history[i], 511, "%s", p);
|
||||
snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
|
||||
} else
|
||||
snprintf(cdrom[c].image_history[i], 511, "%s%s%s", usr_path,
|
||||
snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(cdrom[c].image_history[i]);
|
||||
}
|
||||
@@ -1353,13 +1408,13 @@ load_other_removable_devices(void)
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 "
|
||||
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("load_other_removable_devices(): strlen(p) > 2047 "
|
||||
"(zip_drives[%i].image_history[%i])\n", c, i);
|
||||
else
|
||||
snprintf(zip_drives[c].image_history[i], 511, "%s", p);
|
||||
snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
|
||||
} else
|
||||
snprintf(zip_drives[c].image_history[i], 511, "%s%s%s", usr_path,
|
||||
snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(zip_drives[c].image_history[i]);
|
||||
}
|
||||
@@ -1469,13 +1524,13 @@ load_other_removable_devices(void)
|
||||
p = ini_section_get_string(cat, temp, NULL);
|
||||
if (p) {
|
||||
if (path_abs(p)) {
|
||||
if (strlen(p) > 511)
|
||||
fatal("load_other_removable_devices(): strlen(p) > 511 "
|
||||
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
|
||||
fatal("load_other_removable_devices(): strlen(p) > 2047 "
|
||||
"(mo_drives[%i].image_history[%i])\n", c, i);
|
||||
else
|
||||
snprintf(mo_drives[c].image_history[i], 511, "%s", p);
|
||||
snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
|
||||
} else
|
||||
snprintf(mo_drives[c].image_history[i], 511, "%s%s%s", usr_path,
|
||||
snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
|
||||
path_get_slash(usr_path), p);
|
||||
path_normalize(mo_drives[c].image_history[i]);
|
||||
}
|
||||
@@ -1514,8 +1569,10 @@ load_other_peripherals(void)
|
||||
char *p;
|
||||
char temp[512];
|
||||
|
||||
bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0);
|
||||
postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0);
|
||||
bugger_enabled = !!ini_section_get_int(cat, "bugger_enabled", 0);
|
||||
postcard_enabled = !!ini_section_get_int(cat, "postcard_enabled", 0);
|
||||
unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0);
|
||||
novell_keycard_enabled = !!ini_section_get_int(cat, "novell_keycard_enabled", 0);
|
||||
|
||||
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
|
||||
sprintf(temp, "isamem%d_type", c);
|
||||
@@ -1532,7 +1589,8 @@ load_other_peripherals(void)
|
||||
void
|
||||
config_load(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
ini_section_t c;
|
||||
|
||||
config_log("Loading config file '%s'..\n", cfg_path);
|
||||
|
||||
@@ -1560,6 +1618,8 @@ config_load(void)
|
||||
dpi_scale = 1;
|
||||
do_auto_pause = 0;
|
||||
|
||||
cpu_override_interpreter = 0;
|
||||
|
||||
fpu_type = fpu_get_type(cpu_f, cpu, "none");
|
||||
gfxcard[0] = video_get_video_from_internal_name("cga");
|
||||
vid_api = plat_vidapi("default");
|
||||
@@ -1622,6 +1682,23 @@ config_load(void)
|
||||
load_other_removable_devices(); /* Other removable devices */
|
||||
load_other_peripherals(); /* Other peripherals */
|
||||
|
||||
/* Migrate renamed device configurations. */
|
||||
c = ini_find_section(config, "MDA");
|
||||
if (c != NULL)
|
||||
ini_rename_section(c, "IBM MDA");
|
||||
c = ini_find_section(config, "CGA");
|
||||
if (c != NULL)
|
||||
ini_rename_section(c, "IBM CGA");
|
||||
c = ini_find_section(config, "EGA");
|
||||
if (c != NULL)
|
||||
ini_rename_section(c, "IBM EGA");
|
||||
c = ini_find_section(config, "3DFX Voodoo Graphics");
|
||||
if (c != NULL)
|
||||
ini_rename_section(c, "3Dfx Voodoo Graphics");
|
||||
c = ini_find_section(config, "3dfx Voodoo Banshee");
|
||||
if (c != NULL)
|
||||
ini_rename_section(c, "3Dfx Voodoo Banshee");
|
||||
|
||||
/* Mark the configuration as changed. */
|
||||
config_changed = 1;
|
||||
|
||||
@@ -1784,11 +1861,6 @@ save_general(void)
|
||||
else
|
||||
ini_section_delete_var(cat, "open_dir_usr_path");
|
||||
|
||||
if (status_icons_fullscreen)
|
||||
ini_section_set_int(cat, "status_icons_fullscreen", status_icons_fullscreen);
|
||||
else
|
||||
ini_section_delete_var(cat, "status_icons_fullscreen");
|
||||
|
||||
if (video_framerate != -1)
|
||||
ini_section_set_int(cat, "video_gl_framerate", video_framerate);
|
||||
else
|
||||
@@ -1807,6 +1879,20 @@ save_general(void)
|
||||
else
|
||||
ini_section_delete_var(cat, "do_auto_pause");
|
||||
|
||||
char cpu_buf[128] = { 0 };
|
||||
plat_get_cpu_string(cpu_buf, 128);
|
||||
ini_section_set_string(cat, "host_cpu", cpu_buf);
|
||||
|
||||
if (EMU_BUILD_NUM != 0)
|
||||
ini_section_set_int(cat, "emu_build_num", EMU_BUILD_NUM);
|
||||
else
|
||||
ini_section_delete_var(cat, "emu_build_num");
|
||||
|
||||
if (strnlen(uuid, sizeof(uuid) - 1) > 0)
|
||||
ini_section_set_string(cat, "uuid", uuid);
|
||||
else
|
||||
ini_section_delete_var(cat, "uuid");
|
||||
|
||||
ini_delete_section_if_empty(config, cat);
|
||||
}
|
||||
|
||||
@@ -1845,11 +1931,6 @@ save_machine(void)
|
||||
{
|
||||
ini_section_t cat = ini_find_or_create_section(config, "Machine");
|
||||
const char *p;
|
||||
int c;
|
||||
int i = 0;
|
||||
int legacy_mfg;
|
||||
int legacy_cpu = -1;
|
||||
int closest_legacy_cpu = -1;
|
||||
|
||||
p = machine_get_internal_name();
|
||||
ini_section_set_string(cat, "machine", p);
|
||||
@@ -1861,62 +1942,15 @@ save_machine(void)
|
||||
ini_section_set_int(cat, "cpu_override", cpu_override);
|
||||
else
|
||||
ini_section_delete_var(cat, "cpu_override");
|
||||
if (cpu_override_interpreter)
|
||||
ini_section_set_int(cat, "cpu_override_interpreter", cpu_override);
|
||||
else
|
||||
ini_section_delete_var(cat, "cpu_override_interpreter");
|
||||
|
||||
/* Downgrade compatibility with the previous CPU model system. */
|
||||
ini_section_delete_var(cat, "cpu_manufacturer");
|
||||
ini_section_delete_var(cat, "cpu");
|
||||
|
||||
/* Look for a machine entry on the legacy table. */
|
||||
c = 0;
|
||||
while (cpu_legacy_table[c].machine) {
|
||||
if (!strcmp(p, cpu_legacy_table[c].machine))
|
||||
break;
|
||||
c++;
|
||||
}
|
||||
if (cpu_legacy_table[c].machine) {
|
||||
/* Look for a corresponding CPU entry. */
|
||||
const cpu_legacy_table_t *legacy_table_entry;
|
||||
for (legacy_mfg = 0; legacy_mfg < 4; legacy_mfg++) {
|
||||
if (!cpu_legacy_table[c].tables[legacy_mfg])
|
||||
continue;
|
||||
|
||||
i = 0;
|
||||
while (cpu_legacy_table[c].tables[legacy_mfg][i].family) {
|
||||
legacy_table_entry = &cpu_legacy_table[c].tables[legacy_mfg][i];
|
||||
|
||||
/* Match the family name, speed and multiplier. */
|
||||
if (!strcmp(cpu_f->internal_name, legacy_table_entry->family)) {
|
||||
if ((legacy_table_entry->rspeed == cpu_f->cpus[cpu].rspeed) &&
|
||||
(legacy_table_entry->multi == cpu_f->cpus[cpu].multi)) {
|
||||
/* Exact speed/multiplier match. */
|
||||
legacy_cpu = i;
|
||||
break;
|
||||
} else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) &&
|
||||
(closest_legacy_cpu == -1))
|
||||
/* Closest speed match. */
|
||||
closest_legacy_cpu = i;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Use the closest speed match if no exact match was found. */
|
||||
if ((legacy_cpu == -1) && (closest_legacy_cpu > -1)) {
|
||||
legacy_cpu = closest_legacy_cpu;
|
||||
break;
|
||||
} else if (legacy_cpu > -1) /* exact match found */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set legacy values if a match was found. */
|
||||
if (legacy_cpu > -1) {
|
||||
if (legacy_mfg)
|
||||
ini_section_set_int(cat, "cpu_manufacturer", legacy_mfg);
|
||||
if (legacy_cpu)
|
||||
ini_section_set_int(cat, "cpu", legacy_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
if (cpu_waitstates == 0)
|
||||
ini_section_delete_var(cat, "cpu_waitstates");
|
||||
else
|
||||
@@ -2245,7 +2279,7 @@ save_storage_controllers(void)
|
||||
|
||||
ini_section_delete_var(cat, "scsicard");
|
||||
|
||||
for (c = 0; c < SCSI_BUS_MAX; c++) {
|
||||
for (c = 0; c < SCSI_CARD_MAX; c++) {
|
||||
sprintf(temp, "scsicard_%d", c + 1);
|
||||
|
||||
if (scsi_card_current[c] == 0)
|
||||
@@ -2329,6 +2363,11 @@ save_storage_controllers(void)
|
||||
else
|
||||
ini_section_set_string(cat, temp, cart_fns[c]);
|
||||
}
|
||||
|
||||
if (lba_enhancer_enabled == 0)
|
||||
ini_section_delete_var(cat, "lba_enhancer_enabled");
|
||||
else
|
||||
ini_section_set_int(cat, "lba_enhancer_enabled", 1);
|
||||
}
|
||||
|
||||
/* Save "Other Peripherals" section. */
|
||||
@@ -2348,6 +2387,16 @@ save_other_peripherals(void)
|
||||
else
|
||||
ini_section_set_int(cat, "postcard_enabled", postcard_enabled);
|
||||
|
||||
if (unittester_enabled == 0)
|
||||
ini_section_delete_var(cat, "unittester_enabled");
|
||||
else
|
||||
ini_section_set_int(cat, "unittester_enabled", unittester_enabled);
|
||||
|
||||
if (novell_keycard_enabled == 0)
|
||||
ini_section_delete_var(cat, "novell_keycard_enabled");
|
||||
else
|
||||
ini_section_set_int(cat, "novell_keycard_enabled", novell_keycard_enabled);
|
||||
|
||||
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
|
||||
sprintf(temp, "isamem%d_type", c);
|
||||
if (isamem_type[c] == 0)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/gdbstub.h>
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
@@ -240,6 +241,7 @@ exec386_2386(int32_t cycs)
|
||||
cycdiff = 0;
|
||||
oldcyc = cycles;
|
||||
while (cycdiff < cycle_period) {
|
||||
int ins_fetch_fault = 0;
|
||||
ins_cycles = cycles;
|
||||
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
@@ -259,6 +261,13 @@ exec386_2386(int32_t cycs)
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
ol = opcode_length[fetchdat & 0xff];
|
||||
CHECK_READ_CS(MIN(ol, 4));
|
||||
ins_fetch_fault = cpu_386_check_instruction_fault();
|
||||
|
||||
/* Breakpoint fault has priority over other faults. */
|
||||
if (ins_fetch_fault) {
|
||||
ins_fetch_fault = 0;
|
||||
cpu_state.abrt = 1;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_LOG
|
||||
@@ -267,10 +276,14 @@ exec386_2386(int32_t cycs)
|
||||
#endif
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
trap |= !!(cpu_state.flags & T_FLAG);
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
cpu_state.eflags &= ~(RF_FLAG);
|
||||
if (opcode == 0xf0)
|
||||
in_lock = 1;
|
||||
x86_2386_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
in_lock = 0;
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
@@ -311,12 +324,13 @@ exec386_2386(int32_t cycs)
|
||||
}
|
||||
} else if (trap) {
|
||||
flags_rebuild();
|
||||
if (trap & 2) dr[6] |= 0x8000;
|
||||
if (trap & 1) dr[6] |= 0x4000;
|
||||
trap = 0;
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
#endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
dr[6] |= 0x4000;
|
||||
x86_int(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ int smm_in_hlt = 0;
|
||||
int smi_block = 0;
|
||||
|
||||
int prefetch_prefixes = 0;
|
||||
int rf_flag_no_clear = 0;
|
||||
|
||||
int tempc;
|
||||
int oldcpl;
|
||||
@@ -119,6 +120,53 @@ int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /*
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 1, 1, 1, 1, /* 0xex */
|
||||
1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3 }; /* 0xfx */
|
||||
|
||||
/* 0 = no, 1 = always, 2 = depends on second opcode, 3 = depends on mod/rm */
|
||||
int lock_legal[256] = { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 2, /* 0x0x */
|
||||
1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x1x */
|
||||
1, 1, 1, 1, 1, 1, 4, 0, 1, 1, 1, 1, 1, 1, 4, 0, /* 0x2x */
|
||||
1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, /* 0x3x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */
|
||||
0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */
|
||||
3, 3, 3, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xax */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xbx */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */
|
||||
0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3 }; /* 0xfx */
|
||||
|
||||
int lock_legal_0f[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x4x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x5x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x6x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x7x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x8x */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9x */
|
||||
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* 0xax */
|
||||
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, /* 0xbx */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xcx */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xdx */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xex */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* 0xfx */
|
||||
|
||||
/* (modrm >> 3) & 0x07 */
|
||||
int lock_legal_ba[8] = { 0, 0, 0, 0, 1, 1, 1, 1 };
|
||||
|
||||
/* Also applies to 81, 82, and 83 */
|
||||
int lock_legal_80[8] = { 1, 1, 1, 1, 1, 1, 1, 0 };
|
||||
|
||||
/* Also applies to F7 */
|
||||
int lock_legal_f6[8] = { 0, 0, 1, 1, 0, 0, 0, 0 };
|
||||
|
||||
/* Also applies to FF */
|
||||
int lock_legal_fe[8] = { 1, 1, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
uint32_t addr64;
|
||||
uint32_t addr64_2;
|
||||
uint32_t addr64a[8];
|
||||
@@ -127,9 +175,9 @@ uint32_t addr64a_2[8];
|
||||
static pc_timer_t *cpu_fast_off_timer = NULL;
|
||||
static double cpu_fast_off_period = 0.0;
|
||||
|
||||
#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF)
|
||||
#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF)
|
||||
#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF)
|
||||
#define AMD_SYSCALL_EIP (msr.amd_star & 0xFFFFFFFF)
|
||||
#define AMD_SYSCALL_SB ((msr.amd_star >> 32) & 0xFFFF)
|
||||
#define AMD_SYSRET_SB ((msr.amd_star >> 48) & 0xFFFF)
|
||||
|
||||
/* These #define's and enum have been borrowed from Bochs. */
|
||||
/* SMM feature masks */
|
||||
@@ -375,6 +423,50 @@ x386_common_log(const char *fmt, ...)
|
||||
# define x386_common_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
int
|
||||
is_lock_legal(uint32_t fetchdat)
|
||||
{
|
||||
int legal;
|
||||
fetch_dat_t fetch_dat;
|
||||
|
||||
fetch_dat.fd = fetchdat;
|
||||
|
||||
legal = lock_legal[fetch_dat.b[0]];
|
||||
if (legal == 1)
|
||||
legal = 1; // ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
|
||||
else if (legal == 2) {
|
||||
legal = lock_legal_0f[fetch_dat.b[1]];
|
||||
if (legal == 1)
|
||||
legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,reg is illegal */
|
||||
else if (legal == 3) {
|
||||
legal = lock_legal_ba[(fetch_dat.b[2] >> 3) & 0x07];
|
||||
if (legal == 1)
|
||||
legal = ((fetch_dat.b[2] >> 6) != 0x03); /* reg,imm is illegal */
|
||||
}
|
||||
} else if (legal == 3) switch(fetch_dat.b[0]) {
|
||||
case 0x80 ... 0x83:
|
||||
legal = lock_legal_80[(fetch_dat.b[1] >> 3) & 0x07];
|
||||
if (legal == 1)
|
||||
legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
|
||||
break;
|
||||
case 0xf6 ... 0xf7:
|
||||
legal = lock_legal_f6[(fetch_dat.b[1] >> 3) & 0x07];
|
||||
if (legal == 1)
|
||||
legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
|
||||
break;
|
||||
case 0xfe ... 0xff:
|
||||
legal = lock_legal_fe[(fetch_dat.b[1] >> 3) & 0x07];
|
||||
if (legal == 1)
|
||||
legal = ((fetch_dat.b[1] >> 6) != 0x03); /* reg is illegal */
|
||||
break;
|
||||
default:
|
||||
legal = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return legal;
|
||||
}
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
@@ -1411,7 +1503,7 @@ x86_int(int num)
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
|
||||
if (msw & 1)
|
||||
is486 ? pmodeint(num, 0) : pmodeint_2386(num, 0);
|
||||
cpu_use_exec ? pmodeint(num, 0) : pmodeint_2386(num, 0);
|
||||
else {
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
@@ -1444,7 +1536,7 @@ x86_int(int num)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
|
||||
cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1461,7 +1553,7 @@ x86_int_sw(int num)
|
||||
cycles -= timing_int;
|
||||
|
||||
if (msw & 1)
|
||||
is486 ? pmodeint(num, 1) : pmodeint_2386(num, 1);
|
||||
cpu_use_exec ? pmodeint(num, 1) : pmodeint_2386(num, 1);
|
||||
else {
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
@@ -1486,12 +1578,15 @@ x86_int_sw(int num)
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
is486 ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
|
||||
cpu_use_exec ? loadcs(readmemw(0, addr + 2)) : loadcs_2386(readmemw(0, addr + 2));
|
||||
cycles -= timing_int_rm;
|
||||
}
|
||||
}
|
||||
|
||||
trap = 0;
|
||||
if (cpu_use_exec)
|
||||
trap = 0;
|
||||
else
|
||||
trap &= ~1;
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
@@ -1528,13 +1623,16 @@ x86_int_sw_rm(int num)
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = new_pc;
|
||||
is486 ? loadcs(new_cs) : loadcs_2386(new_cs);
|
||||
cpu_use_exec ? loadcs(new_cs) : loadcs_2386(new_cs);
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
oxpc = cpu_state.pc;
|
||||
#endif
|
||||
|
||||
cycles -= timing_int_rm;
|
||||
trap = 0;
|
||||
if (cpu_use_exec)
|
||||
trap = 0;
|
||||
else
|
||||
trap &= ~1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
return 0;
|
||||
@@ -1551,6 +1649,13 @@ checkio(uint32_t port, int mask)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
if (!(tr.access & 0x08)) {
|
||||
if ((CPL) > (IOPL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpl_override = 1;
|
||||
t = readmemw(tr.base, 0x66);
|
||||
|
||||
@@ -1655,6 +1760,37 @@ cpu_386_flags_rebuild(void)
|
||||
flags_rebuild();
|
||||
}
|
||||
|
||||
extern uint64_t mmutranslate_noabrt_2386(uint32_t addr, int rw);
|
||||
int
|
||||
cpu_386_check_instruction_fault(void)
|
||||
{
|
||||
int i = 0;
|
||||
int fault = 0;
|
||||
/* Report no fault if RF is set. */
|
||||
if (cpu_state.eflags & RF_FLAG)
|
||||
return 0;
|
||||
|
||||
/* Make sure breakpoints are enabled. */
|
||||
if (!(dr[7] & 0xFF))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int breakpoint_enabled = !!(dr[7] & (0x3 << (2 * i))) && !(dr[7] & (0x30000 << (4 * i)));
|
||||
uint32_t translated_addr = 0xffffffff;
|
||||
if (!breakpoint_enabled)
|
||||
continue;
|
||||
|
||||
translated_addr = dr[i];
|
||||
|
||||
if ((cs + cpu_state.pc) == (uint32_t)translated_addr) {
|
||||
dr[6] |= (1 << i);
|
||||
fault = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
||||
int
|
||||
sysenter(uint32_t fetchdat)
|
||||
{
|
||||
|
||||
@@ -225,19 +225,37 @@ int checkio(uint32_t port, int mask);
|
||||
static __inline uint8_t
|
||||
fastreadb(uint32_t a)
|
||||
{
|
||||
return readmembl_2386(a);
|
||||
uint8_t ret;
|
||||
read_type = 1;
|
||||
ret = readmembl_2386(a);
|
||||
read_type = 4;
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline uint16_t
|
||||
fastreadw(uint32_t a)
|
||||
{
|
||||
return readmemwl_2386(a);
|
||||
uint16_t ret;
|
||||
read_type = 1;
|
||||
ret = readmemwl_2386(a);
|
||||
read_type = 4;
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
fastreadl(uint32_t a)
|
||||
{
|
||||
return readmemll_2386(a);
|
||||
uint32_t ret;
|
||||
read_type = 1;
|
||||
ret = readmemll_2386(a);
|
||||
read_type = 4;
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static __inline uint8_t
|
||||
@@ -342,31 +360,41 @@ extern int opcode_length[256];
|
||||
static __inline uint16_t
|
||||
fastreadw_fetch(uint32_t a)
|
||||
{
|
||||
uint16_t val;
|
||||
uint16_t ret;
|
||||
|
||||
if ((a & 0xFFF) > 0xFFE) {
|
||||
val = fastreadb(a);
|
||||
if (opcode_length[val & 0xff] > 1)
|
||||
val |= ((uint16_t) fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
ret = fastreadb(a);
|
||||
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1))
|
||||
ret |= ((uint16_t) fastreadb(a + 1) << 8);
|
||||
} else if (cpu_state.abrt)
|
||||
ret = 0;
|
||||
else {
|
||||
read_type = 1;
|
||||
ret = readmemwl_2386(a);
|
||||
read_type = 4;
|
||||
}
|
||||
|
||||
return readmemwl_2386(a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
fastreadl_fetch(uint32_t a)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t ret;
|
||||
|
||||
if (cpu_16bitbus || ((a & 0xFFF) > 0xFFC)) {
|
||||
val = fastreadw_fetch(a);
|
||||
if (opcode_length[val & 0xff] > 2)
|
||||
val |= ((uint32_t) fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
ret = fastreadw_fetch(a);
|
||||
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 2))
|
||||
ret |= ((uint32_t) fastreadw(a + 2) << 16);
|
||||
} else if (cpu_state.abrt)
|
||||
ret = 0;
|
||||
else {
|
||||
read_type = 1;
|
||||
ret = readmemll_2386(a);
|
||||
read_type = 4;
|
||||
}
|
||||
|
||||
return readmemll_2386(a);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static __inline uint16_t
|
||||
@@ -674,3 +702,8 @@ seteaq(uint64_t v)
|
||||
cpu_state.pc += 2
|
||||
|
||||
#endif
|
||||
|
||||
/* Resume Flag handling. */
|
||||
extern int rf_flag_no_clear;
|
||||
|
||||
int cpu_386_check_instruction_fault(void);
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
int cpu_override_dynarec = 0;
|
||||
int inrecomp = 0;
|
||||
int cpu_block_end = 0;
|
||||
int cpu_end_block_after_ins = 0;
|
||||
@@ -268,6 +269,12 @@ exec386_dynarec_int(void)
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
if (trap == 2) {
|
||||
/* Handle the T bit in the new TSS first. */
|
||||
CPU_BLOCK_END();
|
||||
goto block_ended;
|
||||
}
|
||||
|
||||
while (!cpu_block_end) {
|
||||
# ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
@@ -321,13 +328,14 @@ exec386_dynarec_int(void)
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
block_ended:
|
||||
if (!cpu_state.abrt && trap) {
|
||||
dr[6] |= (trap == 2) ? 0x8000 : 0x4000;
|
||||
trap = 0;
|
||||
# ifndef USE_NEW_DYNAREC
|
||||
oldcs = CS;
|
||||
# endif
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
dr[6] |= 0x4000;
|
||||
x86_int(1);
|
||||
}
|
||||
|
||||
@@ -542,7 +550,7 @@ exec386_dynarec_dyn(void)
|
||||
# endif
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.flags & T_FLAG)
|
||||
if ((cpu_state.flags & T_FLAG) || (trap == 2))
|
||||
CPU_BLOCK_END();
|
||||
if (smi_line)
|
||||
CPU_BLOCK_END();
|
||||
@@ -711,7 +719,7 @@ exec386_dynarec(int32_t cycs)
|
||||
cycles_old = cycles;
|
||||
oldtsc = tsc;
|
||||
tsc_old = tsc;
|
||||
if (!CACHE_ON()) /*Interpret block*/
|
||||
if ((!CACHE_ON()) || cpu_override_dynarec) /*Interpret block*/
|
||||
{
|
||||
exec386_dynarec_int();
|
||||
} else {
|
||||
|
||||
@@ -181,8 +181,16 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#ifndef OPS_286_386
|
||||
# include "x86_ops_cyrix.h"
|
||||
#endif
|
||||
#include "x86_ops_flag.h"
|
||||
#include "x86_ops_fpu.h"
|
||||
#ifdef OPS_286_386
|
||||
# include "x86_ops_flag_2386.h"
|
||||
#else
|
||||
# include "x86_ops_flag.h"
|
||||
#endif
|
||||
#ifdef OPS_286_386
|
||||
# include "x86_ops_fpu_2386.h"
|
||||
#else
|
||||
# include "x86_ops_fpu.h"
|
||||
#endif
|
||||
#include "x86_ops_inc_dec.h"
|
||||
#include "x86_ops_int.h"
|
||||
#include "x86_ops_io.h"
|
||||
@@ -200,7 +208,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
# include "x86_ops_mmx_shift.h"
|
||||
#endif
|
||||
#include "x86_ops_mov.h"
|
||||
#include "x86_ops_mov_ctrl.h"
|
||||
#ifdef OPS_286_386
|
||||
# include "x86_ops_mov_ctrl_2386.h"
|
||||
#else
|
||||
# include "x86_ops_mov_ctrl.h"
|
||||
#endif
|
||||
#include "x86_ops_mov_seg.h"
|
||||
#include "x86_ops_movx.h"
|
||||
#ifndef OPS_286_386
|
||||
@@ -208,7 +220,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
#endif
|
||||
#include "x86_ops_mul.h"
|
||||
#include "x86_ops_pmode.h"
|
||||
#include "x86_ops_prefix.h"
|
||||
#ifdef OPS_286_386
|
||||
# include "x86_ops_prefix_2386.h"
|
||||
#else
|
||||
# include "x86_ops_prefix.h"
|
||||
#endif
|
||||
#ifdef IS_DYNAREC
|
||||
# include "x86_ops_rep_dyn.h"
|
||||
#else
|
||||
@@ -218,7 +234,11 @@ extern void x386_dynarec_log(const char *fmt, ...);
|
||||
# include "x86_ops_rep.h"
|
||||
# endif
|
||||
#endif
|
||||
#include "x86_ops_ret.h"
|
||||
#ifdef OPS_286_386
|
||||
# include "x86_ops_ret_2386.h"
|
||||
#else
|
||||
# include "x86_ops_ret.h"
|
||||
#endif
|
||||
#include "x86_ops_set.h"
|
||||
#include "x86_ops_stack.h"
|
||||
#ifdef OPS_286_386
|
||||
@@ -629,7 +649,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
|
||||
// clang-format off
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
@@ -644,14 +664,14 @@ const OpFn OP_TABLE(386_0f)[1024] = {
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
@@ -666,14 +686,14 @@ const OpFn OP_TABLE(386_0f)[1024] = {
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
@@ -688,14 +708,14 @@ const OpFn OP_TABLE(386_0f)[1024] = {
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, ILLEGAL, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
@@ -710,7 +730,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, ILLEGAL, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||
/*b0*/ ILLEGAL, ILLEGAL, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
112
src/cpu/808x.c
112
src/cpu/808x.c
@@ -56,7 +56,6 @@ static uint32_t *opseg[4];
|
||||
static x86seg *_opseg[4];
|
||||
|
||||
static int noint = 0;
|
||||
static int in_lock = 0;
|
||||
static int cpu_alu_op, pfq_size;
|
||||
|
||||
static uint32_t cpu_src = 0, cpu_dest = 0;
|
||||
@@ -545,7 +544,6 @@ reset_808x(int hard)
|
||||
{
|
||||
biu_cycles = 0;
|
||||
in_rep = 0;
|
||||
in_lock = 0;
|
||||
completed = 1;
|
||||
repeating = 0;
|
||||
clear_lock = 0;
|
||||
@@ -563,9 +561,10 @@ reset_808x(int hard)
|
||||
_opseg[3] = &cpu_state.seg_ds;
|
||||
|
||||
pfq_size = (is8086) ? 6 : 4;
|
||||
pfq_clear();
|
||||
}
|
||||
|
||||
pfq_clear();
|
||||
|
||||
load_cs(0xFFFF);
|
||||
cpu_state.pc = 0;
|
||||
if (is_nec)
|
||||
@@ -1222,34 +1221,48 @@ static void
|
||||
add(int bits)
|
||||
{
|
||||
int size_mask = (1 << bits) - 1;
|
||||
int special_case = 0;
|
||||
uint32_t temp_src = cpu_src;
|
||||
|
||||
if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG))
|
||||
special_case = 1;
|
||||
|
||||
cpu_data = cpu_dest + cpu_src;
|
||||
if ((cpu_alu_op == 2) && (cpu_state.flags & C_FLAG))
|
||||
cpu_src--;
|
||||
set_apzs(bits);
|
||||
set_of_add(bits);
|
||||
|
||||
/* Anything - FF with carry on is basically anything + 0x100: value stays
|
||||
unchanged but carry goes on. */
|
||||
if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG))
|
||||
if (special_case)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
set_cf((cpu_src & size_mask) > (cpu_data & size_mask));
|
||||
set_cf((temp_src & size_mask) > (cpu_data & size_mask));
|
||||
}
|
||||
|
||||
static void
|
||||
sub(int bits)
|
||||
{
|
||||
int size_mask = (1 << bits) - 1;
|
||||
int special_case = 0;
|
||||
uint32_t temp_src = cpu_src;
|
||||
|
||||
if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG))
|
||||
special_case = 1;
|
||||
|
||||
cpu_data = cpu_dest - cpu_src;
|
||||
if ((cpu_alu_op == 3) && (cpu_state.flags & C_FLAG))
|
||||
cpu_src--;
|
||||
set_apzs(bits);
|
||||
set_of_sub(bits);
|
||||
|
||||
/* Anything - FF with carry on is basically anything - 0x100: value stays
|
||||
unchanged but carry goes on. */
|
||||
if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG))
|
||||
if (special_case)
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
set_cf((cpu_src & size_mask) > (cpu_dest & size_mask));
|
||||
set_cf((temp_src & size_mask) > (cpu_dest & size_mask));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3183,31 +3196,66 @@ execx86(int cycs)
|
||||
if (!hasfpu)
|
||||
geteaw();
|
||||
else
|
||||
switch (opcode) {
|
||||
case 0xD8:
|
||||
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xD9:
|
||||
ops_fpu_8087_d9[rmdat & 0xff]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xDA:
|
||||
ops_fpu_8087_da[rmdat & 0xff]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xDB:
|
||||
ops_fpu_8087_db[rmdat & 0xff]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xDC:
|
||||
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xDD:
|
||||
ops_fpu_8087_dd[rmdat & 0xff]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xDE:
|
||||
ops_fpu_8087_de[rmdat & 0xff]((uint32_t) rmdat);
|
||||
break;
|
||||
case 0xDF:
|
||||
ops_fpu_8087_df[rmdat & 0xff]((uint32_t) rmdat);
|
||||
break;
|
||||
if (fpu_softfloat) {
|
||||
switch (opcode) {
|
||||
case 0xD8:
|
||||
ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xD9:
|
||||
ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDA:
|
||||
ops_sf_fpu_8087_da[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDB:
|
||||
ops_sf_fpu_8087_db[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDC:
|
||||
ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xDD:
|
||||
ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDE:
|
||||
ops_sf_fpu_8087_de[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDF:
|
||||
ops_sf_fpu_8087_df[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (opcode) {
|
||||
case 0xD8:
|
||||
ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xD9:
|
||||
ops_fpu_8087_d9[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDA:
|
||||
ops_fpu_8087_da[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDB:
|
||||
ops_fpu_8087_db[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDC:
|
||||
ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat);
|
||||
break;
|
||||
case 0xDD:
|
||||
ops_fpu_8087_dd[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDE:
|
||||
ops_fpu_8087_de[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
case 0xDF:
|
||||
ops_fpu_8087_df[rmdat & 0xff](rmdat);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on
|
||||
the 286+ core, but not here. */
|
||||
|
||||
1460
src/cpu/cpu.c
1460
src/cpu/cpu.c
File diff suppressed because it is too large
Load Diff
253
src/cpu/cpu.h
253
src/cpu/cpu.h
@@ -86,42 +86,33 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
CPU_PKG_8088 = (1 << 0),
|
||||
CPU_PKG_8088_EUROPC = (1 << 1),
|
||||
CPU_PKG_8086 = (1 << 2),
|
||||
CPU_PKG_188 = (1 << 3),
|
||||
CPU_PKG_186 = (1 << 4),
|
||||
CPU_PKG_286 = (1 << 5),
|
||||
CPU_PKG_386SX = (1 << 6),
|
||||
CPU_PKG_386DX = (1 << 7),
|
||||
CPU_PKG_M6117 = (1 << 8),
|
||||
CPU_PKG_386SLC_IBM = (1 << 9),
|
||||
CPU_PKG_486SLC = (1 << 10),
|
||||
CPU_PKG_486SLC_IBM = (1 << 11),
|
||||
CPU_PKG_486BL = (1 << 12),
|
||||
CPU_PKG_486DLC = (1 << 13),
|
||||
CPU_PKG_SOCKET1 = (1 << 14),
|
||||
CPU_PKG_SOCKET3 = (1 << 15),
|
||||
CPU_PKG_SOCKET3_PC330 = (1 << 16),
|
||||
CPU_PKG_STPC = (1 << 17),
|
||||
CPU_PKG_SOCKET4 = (1 << 18),
|
||||
CPU_PKG_SOCKET5_7 = (1 << 19),
|
||||
CPU_PKG_SOCKET8 = (1 << 20),
|
||||
CPU_PKG_SLOT1 = (1 << 21),
|
||||
CPU_PKG_SLOT2 = (1 << 22),
|
||||
CPU_PKG_SLOTA = (1 << 23),
|
||||
CPU_PKG_SOCKET370 = (1 << 24),
|
||||
CPU_PKG_SOCKETA = (1 << 25),
|
||||
CPU_PKG_EBGA368 = (1 << 26)
|
||||
CPU_PKG_8088 = (1 << 0),
|
||||
CPU_PKG_8088_EUROPC = (1 << 1),
|
||||
CPU_PKG_8086 = (1 << 2),
|
||||
CPU_PKG_188 = (1 << 3),
|
||||
CPU_PKG_186 = (1 << 4),
|
||||
CPU_PKG_286 = (1 << 5),
|
||||
CPU_PKG_386SX = (1 << 6),
|
||||
CPU_PKG_386DX = (1 << 7),
|
||||
CPU_PKG_386DX_DESKPRO386 = (1 << 8),
|
||||
CPU_PKG_M6117 = (1 << 9),
|
||||
CPU_PKG_386SLC_IBM = (1 << 10),
|
||||
CPU_PKG_486SLC = (1 << 11),
|
||||
CPU_PKG_486SLC_IBM = (1 << 12),
|
||||
CPU_PKG_486BL = (1 << 13),
|
||||
CPU_PKG_486DLC = (1 << 14),
|
||||
CPU_PKG_SOCKET1 = (1 << 15),
|
||||
CPU_PKG_SOCKET3 = (1 << 16),
|
||||
CPU_PKG_SOCKET3_PC330 = (1 << 17),
|
||||
CPU_PKG_STPC = (1 << 18),
|
||||
CPU_PKG_SOCKET4 = (1 << 19),
|
||||
CPU_PKG_SOCKET5_7 = (1 << 20),
|
||||
CPU_PKG_SOCKET8 = (1 << 21),
|
||||
CPU_PKG_SLOT1 = (1 << 22),
|
||||
CPU_PKG_SLOT2 = (1 << 23),
|
||||
CPU_PKG_SOCKET370 = (1 << 24)
|
||||
};
|
||||
|
||||
#define MANU_INTEL 0
|
||||
#define MANU_AMD 1
|
||||
#define MANU_CYRIX 2
|
||||
#define MANU_IDT 3
|
||||
#define MANU_NEC 4
|
||||
#define MANU_IBM 5
|
||||
|
||||
#define CPU_SUPPORTS_DYNAREC 1
|
||||
#define CPU_REQUIRES_DYNAREC 2
|
||||
#define CPU_ALTERNATE_XTAL 4
|
||||
@@ -165,17 +156,6 @@ typedef struct {
|
||||
const CPU *cpus;
|
||||
} cpu_family_t;
|
||||
|
||||
typedef struct {
|
||||
const char *family;
|
||||
const uint32_t rspeed;
|
||||
const double multi;
|
||||
} cpu_legacy_table_t;
|
||||
|
||||
typedef struct {
|
||||
const char *machine;
|
||||
const cpu_legacy_table_t **tables;
|
||||
} cpu_legacy_machine_t;
|
||||
|
||||
#define C_FLAG 0x0001
|
||||
#define P_FLAG 0x0004
|
||||
#define A_FLAG 0x0010
|
||||
@@ -194,6 +174,7 @@ typedef struct {
|
||||
#define VIP_FLAG 0x0010 /* in EFLAGS */
|
||||
#define VID_FLAG 0x0020 /* in EFLAGS */
|
||||
|
||||
#define EM_FLAG 0x00004 /* in CR0 */
|
||||
#define WP_FLAG 0x10000 /* in CR0 */
|
||||
|
||||
#define CR4_VME (1 << 0) /* Virtual 8086 Mode Extensions */
|
||||
@@ -246,103 +227,97 @@ typedef union {
|
||||
} MMX_REG;
|
||||
|
||||
typedef struct {
|
||||
/* IDT WinChip and WinChip 2 MSR's */
|
||||
uint32_t tr1; /* 0x00000002, 0x0000000e */
|
||||
uint32_t tr12; /* 0x00000002, 0x0000000e */
|
||||
uint32_t cesr; /* 0x00000011 */
|
||||
/* IBM 386SLC/486SLC/486BL MSRs */
|
||||
uint64_t ibm_por; /* 0x00001000 - 386SLC and later */
|
||||
uint64_t ibm_crcr; /* 0x00001001 - 386SLC and later */
|
||||
uint64_t ibm_por2; /* 0x00001002 - 486SLC and later */
|
||||
uint64_t ibm_pcr; /* 0x00001004 - 486BL3 */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */
|
||||
uint64_t ecx79; /* 0x00000079 */
|
||||
/* IDT WinChip C6/2/VIA Cyrix III MSRs */
|
||||
uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */
|
||||
uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */
|
||||
uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */
|
||||
uint64_t mcr[8]; /* 0x00000110 - 0x00000117 (IDT) */
|
||||
uint32_t mcr_ctrl; /* 0x00000120 (IDT) */
|
||||
|
||||
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t ecx83; /* 0x00000083 - AMD K5 and K6 MSR's. */
|
||||
/* AMD K5/K6 MSRs */
|
||||
uint64_t amd_aar; /* 0x00000082 - all K5 */
|
||||
uint64_t amd_hwcr; /* 0x00000083 - all K5 and all K6 */
|
||||
uint64_t amd_watmcr; /* 0x00000085 - K5 Model 1 and later */
|
||||
uint64_t amd_wapmrr; /* 0x00000086 - K5 Model 1 and later */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t ecx8x[4]; /* 0x00000088 - 0x0000008b */
|
||||
uint64_t ia32_pmc[8]; /* 0x000000c1 - 0x000000c8 */
|
||||
uint64_t mtrr_cap; /* 0x000000fe */
|
||||
uint64_t amd_efer; /* 0xc0000080 - all K5 and all K6 */
|
||||
uint64_t amd_star; /* 0xc0000081 - K6-2 and later */
|
||||
uint64_t amd_whcr; /* 0xc0000082 - all K5 and all K6 */
|
||||
uint64_t amd_uwccr; /* 0xc0000085 - K6-2C and later */
|
||||
uint64_t amd_epmr; /* 0xc0000086 - K6-III+/2+ only */
|
||||
uint64_t amd_psor; /* 0xc0000087 - K6-2C and later */
|
||||
uint64_t amd_pfir; /* 0xc0000088 - K6-2C and later */
|
||||
uint64_t amd_l2aar; /* 0xc0000089 - K6-III and later */
|
||||
|
||||
/* IDT WinChip and WinChip 2 MSR's that are also on the VIA Cyrix III */
|
||||
uint32_t fcr; /* 0x00000107 (IDT), 0x00001107 (VIA) */
|
||||
uint64_t fcr2; /* 0x00000108 (IDT), 0x00001108 (VIA) */
|
||||
uint64_t fcr3; /* 0x00000108 (IDT), 0x00001108 (VIA) */
|
||||
/* Pentium/Pentium MMX MSRs */
|
||||
uint64_t mcar; /* 0x00000000 - also on K5 and (R/W) K6 */
|
||||
uint64_t mctr; /* 0x00000001 - also on K5 and (R/W) K6 */
|
||||
uint32_t tr1; /* 0x00000002 - also on WinChip C6/2 */
|
||||
uint32_t tr2; /* 0x00000004 - reserved on PMMX */
|
||||
uint32_t tr3; /* 0x00000005 */
|
||||
uint32_t tr4; /* 0x00000006 */
|
||||
uint32_t tr5; /* 0x00000007 */
|
||||
uint32_t tr6; /* 0x00000008 */
|
||||
uint32_t tr7; /* 0x00000009 */
|
||||
uint32_t tr9; /* 0x0000000b */
|
||||
uint32_t tr10; /* 0x0000000c */
|
||||
uint32_t tr11; /* 0x0000000d */
|
||||
uint32_t tr12; /* 0x0000000e - also on WinChip C6/2 and K6 */
|
||||
uint32_t cesr; /* 0x00000011 - also on WinChip C6/2 and Cx6x86MX */
|
||||
uint64_t pmc[2]; /* 0x00000012, 0x00000013 - also on WinChip C6/2 and Cx6x86MX */
|
||||
uint32_t fp_last_xcpt; /* 0x8000001b - undocumented */
|
||||
uint32_t probe_ctl; /* 0x8000001d - undocumented */
|
||||
uint32_t ecx8000001e; /* 0x8000001e - undocumented */
|
||||
uint32_t ecx8000001f; /* 0x8000001f - undocumented */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t ecx116; /* 0x00000116 */
|
||||
uint64_t ecx11x[4]; /* 0x00000118 - 0x0000011b */
|
||||
uint64_t ecx11e; /* 0x0000011e */
|
||||
/* Pentium Pro/II MSRs */
|
||||
uint64_t apic_base; /* 0x0000001b */
|
||||
uint32_t test_ctl; /* 0x00000033 */
|
||||
uint64_t bios_updt; /* 0x00000079 */
|
||||
|
||||
/* Pentium II Klamath and Pentium II Deschutes MSR's */
|
||||
uint16_t sysenter_cs; /* 0x00000174 - SYSENTER/SYSEXIT MSR's */
|
||||
uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */
|
||||
uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */
|
||||
uint64_t bbl_cr_dx[4]; /* 0x00000088 - 0x0000008b */
|
||||
uint64_t perfctr[2]; /* 0x000000c1, 0x000000c2 */
|
||||
uint64_t mtrr_cap; /* 0x000000fe */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */
|
||||
uint64_t ecx186; /* 0x00000186, 0x00000187 */
|
||||
uint64_t ecx187; /* 0x00000186, 0x00000187 */
|
||||
uint64_t bbl_cr_addr; /* 0x00000116 */
|
||||
uint64_t bbl_cr_decc; /* 0x00000118 */
|
||||
uint64_t bbl_cr_ctl; /* 0x00000119 */
|
||||
uint64_t bbl_cr_trig; /* 0x0000011a */
|
||||
uint64_t bbl_cr_busy; /* 0x0000011b */
|
||||
uint64_t bbl_cr_ctl3; /* 0x0000011e */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t debug_ctl; /* 0x000001d9 - Debug Registers Control */
|
||||
uint64_t ecx1e0; /* 0x000001e0 */
|
||||
uint16_t sysenter_cs; /* 0x00000174 - Pentium II and later */
|
||||
uint32_t sysenter_esp; /* 0x00000175 - Pentium II and later */
|
||||
uint32_t sysenter_eip; /* 0x00000176 - Pentium II and later */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also
|
||||
on the VIA Cyrix III */
|
||||
uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f */
|
||||
uint64_t mcg_ctl; /* 0x0000017b */
|
||||
uint64_t evntsel[2]; /* 0x00000186, 0x00000187 */
|
||||
|
||||
uint32_t debug_ctl; /* 0x000001d9 */
|
||||
uint32_t rob_cr_bkuptmpdr6; /* 0x000001e0 */
|
||||
|
||||
/* MTTR-related MSRs also present on the VIA Cyrix III */
|
||||
uint64_t mtrr_physbase[8]; /* 0x00000200 - 0x0000020f (ECX & 0) */
|
||||
uint64_t mtrr_physmask[8]; /* 0x00000200 - 0x0000020f (ECX & 1) */
|
||||
uint64_t mtrr_fix64k_8000; /* 0x00000250 */
|
||||
uint64_t mtrr_fix16k_8000; /* 0x00000258 */
|
||||
uint64_t mtrr_fix16k_a000; /* 0x00000259 */
|
||||
uint64_t mtrr_fix4k[8]; /* 0x00000268 - 0x0000026f */
|
||||
uint64_t mtrr_deftype; /* 0x000002ff */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t pat; /* 0x00000277 */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's that are also
|
||||
on the VIA Cyrix III */
|
||||
uint64_t mtrr_deftype; /* 0x000002ff */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */
|
||||
uint64_t pat; /* 0x00000277 - Pentium II Deschutes and later */
|
||||
uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 */
|
||||
uint64_t ecx570; /* 0x00000570 */
|
||||
|
||||
/* IBM 386SLC, 486SLC, and 486BL MSR's */
|
||||
uint64_t ibm_por; /* 0x00001000 - Processor Operation Register */
|
||||
uint64_t ibm_crcr; /* 0x00001001 - Cache Region Control Register */
|
||||
|
||||
/* IBM 486SLC and 486BL MSR's */
|
||||
uint64_t ibm_por2; /* 0x00001002 - Processor Operation Register */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t ecx1002ff; /* 0x001002ff - MSR used by some Intel AMI boards */
|
||||
|
||||
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t amd_efer; /* 0xc0000080 */
|
||||
|
||||
/* AMD K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t star; /* 0xc0000081 */
|
||||
|
||||
/* AMD K5, 5k86, K6, K6-2, K6-2C, K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t amd_whcr; /* 0xc0000082 */
|
||||
|
||||
/* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t amd_uwccr; /* 0xc0000085 */
|
||||
|
||||
/* AMD K6-2P and K6-3P MSR's */
|
||||
uint64_t amd_epmr; /* 0xc0000086 */
|
||||
|
||||
/* AMD K6-2C, K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t amd_psor; /* 0xc0000087, 0xc0000088 */
|
||||
uint64_t amd_pfir; /* 0xc0000087, 0xc0000088 */
|
||||
|
||||
/* K6-3, K6-2P, and K6-3P MSR's */
|
||||
uint64_t amd_l2aar; /* 0xc0000089 */
|
||||
|
||||
/* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */
|
||||
uint64_t ecxf0f00250; /* 0xf0f00250 - Some weird long MSR's used by i686 AMI & some Phoenix BIOSes */
|
||||
uint64_t ecxf0f00258; /* 0xf0f00258 */
|
||||
uint64_t ecxf0f00259; /* 0xf0f00259 */
|
||||
/* Other/Unclassified MSRs */
|
||||
uint64_t ecx20; /* 0x00000020, really 0x40000020, but we filter out the top 18 bits
|
||||
like a real Deschutes does. */
|
||||
} msr_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -530,7 +505,6 @@ extern cpu_state_t cpu_state;
|
||||
extern fpu_state_t fpu_state;
|
||||
|
||||
extern const cpu_family_t cpu_families[];
|
||||
extern const cpu_legacy_machine_t cpu_legacy_table[];
|
||||
extern cpu_family_t *cpu_f;
|
||||
extern CPU *cpu_s;
|
||||
extern int cpu_override;
|
||||
@@ -544,8 +518,9 @@ extern int cpu_multi;
|
||||
extern double cpu_dmulti;
|
||||
extern double fpu_multi;
|
||||
extern double cpu_busspeed;
|
||||
extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
|
||||
penalties when crossing 8-byte boundaries*/
|
||||
extern int cpu_cyrix_alignment; /* Cyrix 5x86/6x86 only has data misalignment
|
||||
penalties when crossing 8-byte boundaries. */
|
||||
extern int cpu_cpurst_on_sr; /* SiS 551x and 5571: Issue CPURST on soft reset. */
|
||||
|
||||
extern int is8086;
|
||||
extern int is186;
|
||||
@@ -608,7 +583,6 @@ extern double bus_timing;
|
||||
extern double isa_timing;
|
||||
extern double pci_timing;
|
||||
extern double agp_timing;
|
||||
extern uint64_t pmc[2];
|
||||
extern uint16_t temp_seg_data[4];
|
||||
extern uint16_t cs_msr;
|
||||
extern uint32_t esp_msr;
|
||||
@@ -789,6 +763,11 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg);
|
||||
#define SMHR_VALID (1 << 0)
|
||||
#define SMHR_ADDR_MASK (0xfffffffc)
|
||||
|
||||
typedef union {
|
||||
uint32_t fd;
|
||||
uint8_t b[4];
|
||||
} fetch_dat_t;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t base;
|
||||
@@ -810,6 +789,7 @@ extern int hlt_reset_pending;
|
||||
extern cyrix_t cyrix;
|
||||
|
||||
extern int prefetch_prefixes;
|
||||
extern int cpu_use_exec;
|
||||
|
||||
extern uint8_t use_custom_nmi_vector;
|
||||
extern uint32_t custom_nmi_vector;
|
||||
@@ -834,9 +814,24 @@ extern void nmi_raise(void);
|
||||
extern MMX_REG *MMP[8];
|
||||
extern uint16_t *MMEP[8];
|
||||
|
||||
extern int cpu_block_end;
|
||||
extern int cpu_override_dynarec;
|
||||
|
||||
extern void mmx_init(void);
|
||||
extern void prefetch_flush(void);
|
||||
|
||||
extern void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32);
|
||||
|
||||
extern int lock_legal[256];
|
||||
extern int lock_legal_0f[256];
|
||||
extern int lock_legal_ba[8];
|
||||
extern int lock_legal_80[8];
|
||||
extern int lock_legal_f6[8];
|
||||
extern int lock_legal_fe[8];
|
||||
|
||||
extern int in_lock;
|
||||
extern int cpu_override_interpreter;
|
||||
|
||||
extern int is_lock_legal(uint32_t fetchdat);
|
||||
|
||||
#endif /*EMU_CPU_H*/
|
||||
|
||||
1044
src/cpu/cpu_table.c
1044
src/cpu/cpu_table.c
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,11 @@ these four paragraphs for those parts of this code that are retained.
|
||||
* Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
* ==========================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <86box/86box.h>
|
||||
#include "../cpu.h"
|
||||
|
||||
#include "softfloatx80.h"
|
||||
#include "softfloat-round-pack.h"
|
||||
#include "softfloat-macros.h"
|
||||
@@ -305,6 +310,18 @@ int floatx80_compare(floatx80 a, floatx80 b, int quiet, struct float_status_t *s
|
||||
float_class_t aClass = floatx80_class(a);
|
||||
float_class_t bClass = floatx80_class(b);
|
||||
|
||||
if (fpu_type < FPU_287XL) {
|
||||
if ((aClass == float_positive_inf) && (bClass == float_negative_inf))
|
||||
{
|
||||
return float_relation_equal;
|
||||
}
|
||||
|
||||
if ((aClass == float_negative_inf) && (bClass == float_positive_inf))
|
||||
{
|
||||
return float_relation_equal;
|
||||
}
|
||||
}
|
||||
|
||||
if (aClass == float_SNaN || bClass == float_SNaN)
|
||||
{
|
||||
/* unsupported reported as SNaN */
|
||||
|
||||
@@ -80,6 +80,8 @@ int hlt_reset_pending;
|
||||
|
||||
int fpu_cycles = 0;
|
||||
|
||||
int in_lock = 0;
|
||||
|
||||
#ifdef ENABLE_X86_LOG
|
||||
void dumpregs(int);
|
||||
|
||||
@@ -270,11 +272,19 @@ reset_common(int hard)
|
||||
cr0 = 1 << 30;
|
||||
else
|
||||
cr0 = 0;
|
||||
if (is386 && !is486 && (fpu_type == FPU_387))
|
||||
cr0 |= 0x10;
|
||||
cpu_cache_int_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
cr4 = 0;
|
||||
cpu_state.eflags = 0;
|
||||
cgate32 = 0;
|
||||
if (is386 && !is486) {
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
dr[i] = 0x00000000;
|
||||
dr[6] = 0xffff1ff0;
|
||||
dr[7] = 0x00000400;
|
||||
}
|
||||
if (is286) {
|
||||
if (is486)
|
||||
loadcs(0xF000);
|
||||
@@ -342,6 +352,10 @@ reset_common(int hard)
|
||||
|
||||
if (!is286)
|
||||
reset_808x(hard);
|
||||
|
||||
in_lock = 0;
|
||||
|
||||
cpu_cpurst_on_sr = 0;
|
||||
}
|
||||
|
||||
/* Hard reset. */
|
||||
|
||||
323
src/cpu/x86_ops_flag_2386.h
Normal file
323
src/cpu/x86_ops_flag_2386.h
Normal file
@@ -0,0 +1,323 @@
|
||||
static int
|
||||
opCMC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags ^= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opCLC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opCLD(uint32_t fetchdat)
|
||||
{
|
||||
cpu_state.flags &= ~D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opCLI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp) {
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opSTC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opSTD(uint32_t fetchdat)
|
||||
{
|
||||
cpu_state.flags |= D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opSTI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp) {
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) {
|
||||
if (cpu_state.eflags & VIP_FLAG) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
} else
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
cpu_state.flags |= I_FLAG;
|
||||
|
||||
/*First instruction after STI will always execute, regardless of whether
|
||||
there is a pending interrupt*/
|
||||
cpu_end_block_after_ins = 2;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opSAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opLAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
AH = cpu_state.flags & 0xff;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opPUSHF(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint16_t temp;
|
||||
|
||||
flags_rebuild();
|
||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||
if (cpu_state.eflags & VIF_FLAG)
|
||||
temp |= I_FLAG;
|
||||
PUSH_W(temp);
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
flags_rebuild();
|
||||
PUSH_W(cpu_state.flags);
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int
|
||||
opPUSHFD(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_CR4_mask & CR4_VME)
|
||||
tempw = cpu_state.eflags & 0x3c;
|
||||
else if (CPUID)
|
||||
tempw = cpu_state.eflags & 0x24;
|
||||
else
|
||||
tempw = cpu_state.eflags & 4;
|
||||
flags_rebuild();
|
||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opPOPF_186(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(msw & 1))
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPOPF_286(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(msw & 1))
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPOPF(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint32_t old_esp = ESP;
|
||||
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt) {
|
||||
|
||||
ESP = old_esp;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
|
||||
ESP = old_esp;
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (tempw & I_FLAG)
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
} else {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
tempw = POP_W();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1))
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opPOPFD(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ;
|
||||
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
templ = POP_L();
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1))
|
||||
cpu_state.flags = (templ & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
|
||||
else
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
|
||||
|
||||
templ &= (is486 || isibm486) ? 0x3c0000 : 0;
|
||||
templ |= ((cpu_state.eflags & 3) << 16);
|
||||
if (cpu_CR4_mask & CR4_VME)
|
||||
cpu_state.eflags = (templ >> 16) & 0x3f;
|
||||
else if (CPUID)
|
||||
cpu_state.eflags = (templ >> 16) & 0x27;
|
||||
else if (is486 || isibm486)
|
||||
cpu_state.eflags = (templ >> 16) & 7;
|
||||
else
|
||||
cpu_state.eflags = (templ >> 16) & 3;
|
||||
|
||||
flags_extract();
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0);
|
||||
|
||||
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
|
||||
codegen_flags_changed = 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
113
src/cpu/x86_ops_fpu_2386.h
Normal file
113
src/cpu/x86_ops_fpu_2386.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
static int
|
||||
opESCAPE_d8_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_d8_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_d9_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_d9_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_da_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_da_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_db_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_db_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_dc_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_dc_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_dd_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_dd_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_de_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_de_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_df_a16(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_df_a32(uint32_t fetchdat)
|
||||
{
|
||||
return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opWAIT(uint32_t fetchdat)
|
||||
{
|
||||
if ((cr0 & 0xa) == 0xa) {
|
||||
x86_int(7);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!cpu_use_dynarec && fpu_softfloat) {
|
||||
#endif
|
||||
if (fpu_softfloat) {
|
||||
if (fpu_state.swd & FPU_SW_Summary) {
|
||||
if (cr0 & 0x20) {
|
||||
x86_int(16);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ opF6_a16(uint32_t fetchdat)
|
||||
if (dst && !(tempw & 0xff00)) {
|
||||
AH = src16 % dst;
|
||||
AL = (src16 / dst) & 0xff;
|
||||
if (!cpu_iscyrix) {
|
||||
if (!cpu_iscyrix && !is6117) {
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
@@ -149,7 +149,7 @@ opF6_a16(uint32_t fetchdat)
|
||||
if (dst && ((int) temps == tempws2)) {
|
||||
AH = (tempws % (int) ((int8_t) dst)) & 0xff;
|
||||
AL = tempws2 & 0xff;
|
||||
if (!cpu_iscyrix) {
|
||||
if (!cpu_iscyrix && !is6117) {
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
@@ -246,7 +246,7 @@ opF6_a32(uint32_t fetchdat)
|
||||
if (dst && !(tempw & 0xff00)) {
|
||||
AH = src16 % dst;
|
||||
AL = (src16 / dst) & 0xff;
|
||||
if (!cpu_iscyrix) {
|
||||
if (!cpu_iscyrix && !is6117) {
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
@@ -266,7 +266,7 @@ opF6_a32(uint32_t fetchdat)
|
||||
if (dst && ((int) temps == tempws2)) {
|
||||
AH = (tempws % (int) ((int8_t) dst)) & 0xff;
|
||||
AL = tempws2 & 0xff;
|
||||
if (!cpu_iscyrix) {
|
||||
if (!cpu_iscyrix && !is6117) {
|
||||
flags_rebuild();
|
||||
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
@@ -366,7 +366,7 @@ opF7_w_a16(uint32_t fetchdat)
|
||||
if (dst && !(templ2 & 0xffff0000)) {
|
||||
DX = templ % dst;
|
||||
AX = (templ / dst) & 0xffff;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp16(AX); /*Not a Cyrix*/
|
||||
} else {
|
||||
x86_int(0);
|
||||
@@ -383,7 +383,7 @@ opF7_w_a16(uint32_t fetchdat)
|
||||
if ((dst != 0) && ((int) temps16 == tempws2)) {
|
||||
DX = tempws % (int) ((int16_t) dst);
|
||||
AX = tempws2 & 0xffff;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp16(AX); /*Not a Cyrix*/
|
||||
} else {
|
||||
x86_int(0);
|
||||
@@ -479,7 +479,7 @@ opF7_w_a32(uint32_t fetchdat)
|
||||
if (dst && !(templ2 & 0xffff0000)) {
|
||||
DX = templ % dst;
|
||||
AX = (templ / dst) & 0xffff;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp16(AX); /*Not a Cyrix*/
|
||||
} else {
|
||||
// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins);
|
||||
@@ -497,7 +497,7 @@ opF7_w_a32(uint32_t fetchdat)
|
||||
if ((dst != 0) && ((int) temps16 == tempws2)) {
|
||||
DX = tempws % (int) ((int16_t) dst);
|
||||
AX = tempws2 & 0xffff;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp16(AX); /*Not a Cyrix*/
|
||||
} else {
|
||||
x86_int(0);
|
||||
@@ -587,7 +587,7 @@ opF7_l_a16(uint32_t fetchdat)
|
||||
case 0x30: /*DIV EAX,l*/
|
||||
if (divl(dst))
|
||||
return 1;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp32(EAX); /*Not a Cyrix*/
|
||||
CLOCK_CYCLES((is486) ? 40 : 38);
|
||||
PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
@@ -595,7 +595,7 @@ opF7_l_a16(uint32_t fetchdat)
|
||||
case 0x38: /*IDIV EAX,l*/
|
||||
if (idivl((int32_t) dst))
|
||||
return 1;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp32(EAX); /*Not a Cyrix*/
|
||||
CLOCK_CYCLES(43);
|
||||
PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0);
|
||||
@@ -680,7 +680,7 @@ opF7_l_a32(uint32_t fetchdat)
|
||||
case 0x30: /*DIV EAX,l*/
|
||||
if (divl(dst))
|
||||
return 1;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp32(EAX); /*Not a Cyrix*/
|
||||
CLOCK_CYCLES((is486) ? 40 : 38);
|
||||
PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
@@ -688,7 +688,7 @@ opF7_l_a32(uint32_t fetchdat)
|
||||
case 0x38: /*IDIV EAX,l*/
|
||||
if (idivl((int32_t) dst))
|
||||
return 1;
|
||||
if (!cpu_iscyrix)
|
||||
if (!cpu_iscyrix && !is6117)
|
||||
setznp32(EAX); /*Not a Cyrix*/
|
||||
CLOCK_CYCLES(43);
|
||||
PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1);
|
||||
@@ -726,6 +726,25 @@ opHLT(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef OPS_286_386
|
||||
static int
|
||||
opLOCK(uint32_t fetchdat)
|
||||
{
|
||||
int legal;
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
cpu_state.pc++;
|
||||
|
||||
legal = is_lock_legal(fetchdat);
|
||||
|
||||
ILLEGAL_ON(legal == 0);
|
||||
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
opLOCK(uint32_t fetchdat)
|
||||
{
|
||||
@@ -740,6 +759,7 @@ opLOCK(uint32_t fetchdat)
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
opBOUND_w_a16(uint32_t fetchdat)
|
||||
|
||||
500
src/cpu/x86_ops_mov_ctrl_2386.h
Normal file
500
src/cpu/x86_ops_mov_ctrl_2386.h
Normal file
@@ -0,0 +1,500 @@
|
||||
static int
|
||||
opMOV_r_CRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
cpu_state.regs[cpu_rm].l = cr0;
|
||||
if (is486 || isibm486)
|
||||
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
|
||||
else {
|
||||
if (is386)
|
||||
cpu_state.regs[cpu_rm].l |= 0x7fffffe0;
|
||||
else
|
||||
cpu_state.regs[cpu_rm].l |= 0x7ffffff0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.regs[cpu_rm].l = cr2;
|
||||
break;
|
||||
case 3:
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
cpu_state.regs[cpu_rm].l = cr0;
|
||||
if (is486 || isibm486)
|
||||
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
|
||||
else {
|
||||
if (is386)
|
||||
cpu_state.regs[cpu_rm].l |= 0x7fffffe0;
|
||||
else
|
||||
cpu_state.regs[cpu_rm].l |= 0x7ffffff0;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cpu_state.regs[cpu_rm].l = cr2;
|
||||
break;
|
||||
case 3:
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0 ... 3:
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
|
||||
break;
|
||||
case 4:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 6:
|
||||
cpu_state.regs[cpu_rm].l = dr[6];
|
||||
break;
|
||||
case 5:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 7:
|
||||
cpu_state.regs[cpu_rm].l = dr[7];
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_r_DRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0 ... 3:
|
||||
cpu_state.regs[cpu_rm].l = dr[cpu_reg];
|
||||
break;
|
||||
case 4:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 6:
|
||||
cpu_state.regs[cpu_rm].l = dr[6];
|
||||
break;
|
||||
case 5:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 7:
|
||||
cpu_state.regs[cpu_rm].l = dr[7];
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_CRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
|
||||
flushmmucache();
|
||||
/* Make sure CPL = 0 when switching from real mode to protected mode. */
|
||||
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
|
||||
cpu_state.seg_cs.access &= 0x9f;
|
||||
cr0 = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_16bitbus)
|
||||
cr0 |= 0x10;
|
||||
if (!(cr0 & 0x80000000))
|
||||
mmu_perm = 4;
|
||||
if (hascache && !(cr0 & (1 << 30)))
|
||||
cpu_cache_int_enabled = 1;
|
||||
else
|
||||
cpu_cache_int_enabled = 0;
|
||||
if (hascache && ((cr0 ^ old_cr0) & (1 << 30)))
|
||||
cpu_update_waitstates();
|
||||
if (cr0 & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
break;
|
||||
case 2:
|
||||
cr2 = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 3:
|
||||
cr3 = cpu_state.regs[cpu_rm].l;
|
||||
flushmmucache();
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE))
|
||||
flushmmucache();
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0:
|
||||
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
|
||||
flushmmucache();
|
||||
/* Make sure CPL = 0 when switching from real mode to protected mode. */
|
||||
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
|
||||
cpu_state.seg_cs.access &= 0x9f;
|
||||
cr0 = cpu_state.regs[cpu_rm].l;
|
||||
if (cpu_16bitbus)
|
||||
cr0 |= 0x10;
|
||||
if (!(cr0 & 0x80000000))
|
||||
mmu_perm = 4;
|
||||
if (hascache && !(cr0 & (1 << 30)))
|
||||
cpu_cache_int_enabled = 1;
|
||||
else
|
||||
cpu_cache_int_enabled = 0;
|
||||
if (hascache && ((cr0 ^ old_cr0) & (1 << 30)))
|
||||
cpu_update_waitstates();
|
||||
if (cr0 & 1)
|
||||
cpu_cur_status |= CPU_STATUS_PMODE;
|
||||
else
|
||||
cpu_cur_status &= ~CPU_STATUS_PMODE;
|
||||
break;
|
||||
case 2:
|
||||
cr2 = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 3:
|
||||
cr3 = cpu_state.regs[cpu_rm].l;
|
||||
flushmmucache();
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4)) {
|
||||
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE))
|
||||
flushmmucache();
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0 ... 3:
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 4:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 6:
|
||||
dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f);
|
||||
break;
|
||||
case 5:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 7:
|
||||
dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400;
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL > 0) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if ((dr[7] & 0x2000) && !(cpu_state.eflags & RF_FLAG)) {
|
||||
trap |= 1;
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
switch (cpu_reg) {
|
||||
case 0 ... 3:
|
||||
dr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
break;
|
||||
case 4:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 6:
|
||||
dr[6] = (dr[6] & 0xffff0ff0) | (cpu_state.regs[cpu_rm].l & 0x0000f00f);
|
||||
break;
|
||||
case 5:
|
||||
if (cr4 & 0x8) {
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
fallthrough;
|
||||
case 7:
|
||||
dr[7] = cpu_state.regs[cpu_rm].l | 0x00000400;
|
||||
break;
|
||||
default:
|
||||
x86illegal();
|
||||
return 1;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opMOV_r_TRx(void)
|
||||
{
|
||||
#if 0
|
||||
uint32_t base;
|
||||
|
||||
base = _tr[4] & 0xfffff800;
|
||||
#endif
|
||||
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
#if 0
|
||||
pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
#endif
|
||||
_tr[3] = *(uint32_t *) &(_cache[cache_index]);
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
}
|
||||
cpu_state.regs[cpu_rm].l = _tr[cpu_reg];
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int
|
||||
opMOV_r_TRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_r_TRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_r_TRx();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
opMOV_TRx_r(void)
|
||||
{
|
||||
uint32_t base;
|
||||
int i;
|
||||
int ctl;
|
||||
|
||||
_tr[cpu_reg] = cpu_state.regs[cpu_rm].l;
|
||||
base = _tr[4] & 0xfffff800;
|
||||
ctl = _tr[5] & 3;
|
||||
switch (cpu_reg) {
|
||||
case 3:
|
||||
#if 0
|
||||
pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]);
|
||||
#endif
|
||||
*(uint32_t *) &(_cache[cache_index]) = _tr[3];
|
||||
cache_index = (cache_index + 4) & 0xf;
|
||||
break;
|
||||
case 4:
|
||||
#if 0
|
||||
if (!(cr0 & 1) && !(_tr[5] & (1 << 19)))
|
||||
pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16);
|
||||
#endif
|
||||
break;
|
||||
case 5:
|
||||
#if 0
|
||||
pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0);
|
||||
#endif
|
||||
if (!(_tr[5] & (1 << 19))) {
|
||||
switch (ctl) {
|
||||
case 0:
|
||||
#if 0
|
||||
pclog(" Cache fill or read...\n", base);
|
||||
#endif
|
||||
break;
|
||||
case 1:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
#if 0
|
||||
pclog(" Writing 16 bytes to %08X...\n", base);
|
||||
#endif
|
||||
for (i = 0; i < 16; i += 4)
|
||||
mem_writel_phys(base + i, *(uint32_t *) &(_cache[i]));
|
||||
break;
|
||||
case 2:
|
||||
base += (_tr[5] & 0x7f0);
|
||||
#if 0
|
||||
pclog(" Reading 16 bytes from %08X...\n", base);
|
||||
#endif
|
||||
for (i = 0; i < 16; i += 4)
|
||||
*(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i);
|
||||
break;
|
||||
case 3:
|
||||
#if 0
|
||||
pclog(" Cache invalidate/flush...\n", base);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES(6);
|
||||
}
|
||||
static int
|
||||
opMOV_TRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opMOV_TRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
opMOV_TRx_r();
|
||||
PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -195,7 +195,11 @@ opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#ifdef OPS_286_386
|
||||
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#else
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#endif
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
op_loadseg(new_seg, &cpu_state.seg_fs);
|
||||
@@ -240,7 +244,11 @@ opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#ifdef OPS_286_386
|
||||
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#else
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#endif
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
op_loadseg(new_seg, &cpu_state.seg_fs);
|
||||
|
||||
@@ -367,6 +367,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
|
||||
switch (rmdat & 0x38) {
|
||||
case 0x00: /*SGDT*/
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(gdt.limit);
|
||||
@@ -389,6 +390,7 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32);
|
||||
break;
|
||||
case 0x10: /*LGDT*/
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) {
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
|
||||
292
src/cpu/x86_ops_prefix_2386.h
Normal file
292
src/cpu/x86_ops_prefix_2386.h
Normal file
@@ -0,0 +1,292 @@
|
||||
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
|
||||
static int op##name##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int legal; \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
if (in_lock) { \
|
||||
legal = is_lock_legal(fetchdat); \
|
||||
\
|
||||
ILLEGAL_ON(legal == 0); \
|
||||
} \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[fetchdat & 0xff]) \
|
||||
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
int legal; \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
if (in_lock) { \
|
||||
legal = is_lock_legal(fetchdat); \
|
||||
\
|
||||
ILLEGAL_ON(legal == 0); \
|
||||
} \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int legal; \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
if (in_lock) { \
|
||||
legal = is_lock_legal(fetchdat); \
|
||||
\
|
||||
ILLEGAL_ON(legal == 0); \
|
||||
} \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
int legal; \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
if (in_lock) { \
|
||||
legal = is_lock_legal(fetchdat); \
|
||||
\
|
||||
ILLEGAL_ON(legal == 0); \
|
||||
} \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
op_seg(CS, cpu_state.seg_cs, x86_2386_opcodes, x86_2386_opcodes)
|
||||
op_seg(DS, cpu_state.seg_ds, x86_2386_opcodes, x86_2386_opcodes)
|
||||
op_seg(ES, cpu_state.seg_es, x86_2386_opcodes, x86_2386_opcodes)
|
||||
op_seg(FS, cpu_state.seg_fs, x86_2386_opcodes, x86_2386_opcodes)
|
||||
op_seg(GS, cpu_state.seg_gs, x86_2386_opcodes, x86_2386_opcodes)
|
||||
op_seg(SS, cpu_state.seg_ss, x86_2386_opcodes, x86_2386_opcodes)
|
||||
// clang-format on
|
||||
|
||||
#define op_srp(name, seg, opcode_table, normal_opcode_table) \
|
||||
static int op##name##_w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[fetchdat & 0xff]) \
|
||||
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_l_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_w_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op##name##_l_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
cpu_state.pc++; \
|
||||
\
|
||||
cpu_state.ea_seg = &seg; \
|
||||
cpu_state.ssegs = 1; \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
op_srp(CS_REPE, cpu_state.seg_cs, x86_2386_opcodes_REPE, x86_2386_opcodes)
|
||||
op_srp(DS_REPE, cpu_state.seg_ds, x86_2386_opcodes_REPE, x86_2386_opcodes)
|
||||
op_srp(ES_REPE, cpu_state.seg_es, x86_2386_opcodes_REPE, x86_2386_opcodes)
|
||||
op_srp(FS_REPE, cpu_state.seg_fs, x86_2386_opcodes_REPE, x86_2386_opcodes)
|
||||
op_srp(GS_REPE, cpu_state.seg_gs, x86_2386_opcodes_REPE, x86_2386_opcodes)
|
||||
op_srp(SS_REPE, cpu_state.seg_ss, x86_2386_opcodes_REPE, x86_2386_opcodes)
|
||||
|
||||
op_srp(CS_REPNE, cpu_state.seg_cs, x86_2386_opcodes_REPNE, x86_2386_opcodes)
|
||||
op_srp(DS_REPNE, cpu_state.seg_ds, x86_2386_opcodes_REPNE, x86_2386_opcodes)
|
||||
op_srp(ES_REPNE, cpu_state.seg_es, x86_2386_opcodes_REPNE, x86_2386_opcodes)
|
||||
op_srp(FS_REPNE, cpu_state.seg_fs, x86_2386_opcodes_REPNE, x86_2386_opcodes)
|
||||
op_srp(GS_REPNE, cpu_state.seg_gs, x86_2386_opcodes_REPNE, x86_2386_opcodes)
|
||||
op_srp(SS_REPNE, cpu_state.seg_ss, x86_2386_opcodes_REPNE, x86_2386_opcodes)
|
||||
// clang-format on
|
||||
|
||||
static int
|
||||
op_66(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
int legal;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
if (in_lock) {
|
||||
legal = is_lock_legal(fetchdat);
|
||||
|
||||
ILLEGAL_ON(legal == 0);
|
||||
}
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op_67(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
int legal;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
if (in_lock) {
|
||||
legal = is_lock_legal(fetchdat);
|
||||
|
||||
ILLEGAL_ON(legal == 0);
|
||||
}
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
|
||||
static int
|
||||
op_66_REPE(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op_67_REPE(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op_66_REPNE(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int
|
||||
op_67_REPNE(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_2386_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
@@ -836,7 +836,7 @@ REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1)
|
||||
static int
|
||||
opREPNE(uint32_t fetchdat)
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
@@ -850,7 +850,7 @@ opREPNE(uint32_t fetchdat)
|
||||
static int
|
||||
opREPE(uint32_t fetchdat)
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
297
src/cpu/x86_ops_ret_2386.h
Normal file
297
src/cpu/x86_ops_ret_2386.h
Normal file
@@ -0,0 +1,297 @@
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define CPU_SET_OXPC
|
||||
#else
|
||||
# define CPU_SET_OXPC oxpc = cpu_state.pc;
|
||||
#endif
|
||||
|
||||
#define RETF_a16(stack_offset) \
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
|
||||
op_pmoderetf(0, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) { \
|
||||
cpu_state.pc = readmemw(ss, ESP); \
|
||||
op_loadcs(readmemw(ss, ESP + 2)); \
|
||||
} else { \
|
||||
cpu_state.pc = readmemw(ss, SP); \
|
||||
op_loadcs(readmemw(ss, SP + 2)); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (stack32) \
|
||||
ESP += 4 + stack_offset; \
|
||||
else \
|
||||
SP += 4 + stack_offset; \
|
||||
cycles -= timing_retf_rm;
|
||||
|
||||
#define RETF_a32(stack_offset) \
|
||||
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \
|
||||
op_pmoderetf(1, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
CPU_SET_OXPC \
|
||||
if (stack32) { \
|
||||
cpu_state.pc = readmeml(ss, ESP); \
|
||||
op_loadcs(readmeml(ss, ESP + 4) & 0xffff); \
|
||||
} else { \
|
||||
cpu_state.pc = readmeml(ss, SP); \
|
||||
op_loadcs(readmeml(ss, SP + 4) & 0xffff); \
|
||||
} \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (stack32) \
|
||||
ESP += 8 + stack_offset; \
|
||||
else \
|
||||
SP += 8 + stack_offset; \
|
||||
cycles -= timing_retf_rm;
|
||||
|
||||
static int
|
||||
opRETF_a16(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a16(0);
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opRETF_a32(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a32(0);
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opRETF_a16_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset = getwordf();
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a16(offset);
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
opRETF_a32_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t offset = getwordf();
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
CPU_BLOCK_END();
|
||||
RETF_a32(offset);
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
opIRET_186(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
op_pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
} else {
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opIRET_286(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
op_pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
} else {
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opIRET(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
if (cr4 & CR4_VME) {
|
||||
uint16_t new_pc;
|
||||
uint16_t new_cs;
|
||||
uint16_t new_flags;
|
||||
|
||||
new_pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
new_flags = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) {
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
SP += 6;
|
||||
if (new_flags & I_FLAG)
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||
op_loadcs(new_cs);
|
||||
cpu_state.pc = new_pc;
|
||||
|
||||
cycles -= timing_iret_rm;
|
||||
} else {
|
||||
x86gpf_expected(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
op_pmodeiret(0);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
} else {
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
static int
|
||||
opIRETD(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles;
|
||||
UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) {
|
||||
x86gpf_expected(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (msw & 1) {
|
||||
optype = IRET;
|
||||
op_pmodeiret(1);
|
||||
optype = 0;
|
||||
} else {
|
||||
uint16_t new_cs;
|
||||
CPU_SET_OXPC
|
||||
if (stack32) {
|
||||
cpu_state.pc = readmeml(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 4);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, ESP + 10);
|
||||
ESP += 12;
|
||||
} else {
|
||||
cpu_state.pc = readmeml(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
|
||||
SP += 12;
|
||||
}
|
||||
op_loadcs(new_cs);
|
||||
cycles -= timing_iret_rm;
|
||||
}
|
||||
flags_extract();
|
||||
nmi_enable = 1;
|
||||
rf_flag_no_clear = 1;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1);
|
||||
PREFETCH_FLUSH();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
@@ -667,7 +667,11 @@ opPOP_SS_w(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#ifdef OPS_286_386
|
||||
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#else
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -695,7 +699,11 @@ opPOP_SS_l(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
#ifdef OPS_286_386
|
||||
x86_2386_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#else
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,10 @@ x86seg_log(const char *fmt, ...)
|
||||
# define x86seg_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
extern int cpu_block_end;
|
||||
#endif
|
||||
|
||||
void
|
||||
#ifdef OPS_286_386
|
||||
x86_doabrt_2386(int x86_abrt)
|
||||
@@ -2088,6 +2092,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
uint32_t new_edi;
|
||||
uint32_t new_pc;
|
||||
uint32_t new_flags;
|
||||
uint32_t t_bit;
|
||||
uint32_t addr;
|
||||
uint32_t *segdat232 = (uint32_t *) segdat2;
|
||||
const x86seg *dt;
|
||||
@@ -2189,6 +2194,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
new_fs = readmemw(base, 0x58);
|
||||
new_gs = readmemw(base, 0x5C);
|
||||
new_ldt = readmemw(base, 0x60);
|
||||
t_bit = readmemb(base, 0x64) & 1;
|
||||
|
||||
cr0 |= 8;
|
||||
|
||||
@@ -2279,6 +2285,19 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
op_loadseg(new_ds, &cpu_state.seg_ds);
|
||||
op_loadseg(new_fs, &cpu_state.seg_fs);
|
||||
op_loadseg(new_gs, &cpu_state.seg_gs);
|
||||
|
||||
if (!cpu_use_exec)
|
||||
rf_flag_no_clear = 1;
|
||||
|
||||
if (t_bit) {
|
||||
if (cpu_use_exec)
|
||||
trap = 2;
|
||||
else
|
||||
trap |= 2;
|
||||
#ifdef USE_DYNAREC
|
||||
cpu_block_end = 1;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (limit < 43) {
|
||||
x86ts(NULL, seg);
|
||||
@@ -2382,7 +2401,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ldt.base |= (readmemb(0, templ + 7) << 24);
|
||||
}
|
||||
|
||||
if (!(new_cs & 0xfff8)) {
|
||||
if (!(new_cs & 0xfff8) && !(new_cs & 0x0004)) {
|
||||
x86ts(NULL, 0);
|
||||
return;
|
||||
}
|
||||
@@ -2454,6 +2473,8 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
tr.limit = limit;
|
||||
tr.access = segdat[2] >> 8;
|
||||
tr.ar_high = segdat[3] & 0xff;
|
||||
if (!cpu_use_exec)
|
||||
dr[7] &= 0xFFFFFFAA;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -87,6 +87,12 @@ x86de(UNUSED(char *s), UNUSED(uint16_t error))
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
x86gen(void)
|
||||
{
|
||||
x86_int(1);
|
||||
}
|
||||
|
||||
void
|
||||
x86gpf(UNUSED(char *s), uint16_t error)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@ extern int cgate32;
|
||||
extern int intgatesize;
|
||||
|
||||
extern void x86seg_reset(void);
|
||||
extern void x86gen(void);
|
||||
extern void x86de(char *s, uint16_t error);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
extern void x86gpf_expected(char *s, uint16_t error);
|
||||
|
||||
@@ -797,7 +797,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -806,7 +806,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -815,7 +815,7 @@ const OpFn OP_TABLE(sf_fpu_8087_df)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -1055,7 +1055,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -1064,7 +1064,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -1073,7 +1073,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -2114,7 +2114,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2123,7 +2123,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2132,7 +2132,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2154,7 +2154,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2163,7 +2163,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2172,7 +2172,7 @@ const OpFn OP_TABLE(sf_fpu_287_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2194,7 +2194,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2203,7 +2203,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2212,7 +2212,7 @@ const OpFn OP_TABLE(sf_fpu_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2234,7 +2234,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2243,7 +2243,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2252,7 +2252,7 @@ const OpFn OP_TABLE(sf_fpu_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2275,7 +2275,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2284,7 +2284,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2293,7 +2293,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16, sf_FISTiw_a16,
|
||||
sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16, sf_FISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16, sf_FBLD_PACKED_BCD_a16,
|
||||
sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16, sf_FILDiq_a16,
|
||||
sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16, sf_FBSTP_PACKED_BCD_a16,
|
||||
sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16, sf_FISTPiq_a16,
|
||||
@@ -2315,7 +2315,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2324,7 +2324,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -2333,7 +2333,7 @@ const OpFn OP_TABLE(sf_fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32, sf_FISTiw_a32,
|
||||
sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32, sf_FISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32, sf_FBLD_PACKED_BCD_a32,
|
||||
sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32, sf_FILDiq_a32,
|
||||
sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32, sf_FBSTP_PACKED_BCD_a32,
|
||||
sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32, sf_FISTPiq_a32,
|
||||
@@ -3373,7 +3373,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3382,7 +3382,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3391,7 +3391,7 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3413,7 +3413,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3422,7 +3422,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3431,7 +3431,7 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3453,7 +3453,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3462,7 +3462,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3471,7 +3471,7 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3493,7 +3493,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3502,7 +3502,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3511,7 +3511,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3534,7 +3534,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3543,7 +3543,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3552,7 +3552,7 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = {
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16, FBLD_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
@@ -3574,7 +3574,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3583,7 +3583,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
@@ -3592,7 +3592,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = {
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32,
|
||||
opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32, FBLD_a32,
|
||||
opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32,
|
||||
FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32,
|
||||
FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32,
|
||||
|
||||
@@ -144,6 +144,89 @@ opFILDiq_a32(uint32_t fetchdat)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
FBLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t load_reg_hi = 0xffff;
|
||||
uint64_t load_reg_lo = BX_CONST64(0xC000000000000000);
|
||||
int64_t load_val = 0ULL;
|
||||
uint64_t power;
|
||||
int sign;
|
||||
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
load_reg_lo = readmemq(easeg, cpu_state.eaaddr);
|
||||
load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
clear_C1();
|
||||
sign = (load_reg_hi & 0x8000) != 0;
|
||||
load_val = 0ULL;
|
||||
power = 1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
load_val += ((uint64_t) (load_reg_lo & 0xf)) * power;
|
||||
load_reg_lo >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
load_val += ((uint64_t) (load_reg_hi & 0xf)) * power;
|
||||
load_reg_hi >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
if (sign)
|
||||
load_val = -load_val;
|
||||
x87_push((double) load_val);
|
||||
cpu_state.MM[cpu_state.TOP & 7].q = load_val;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int
|
||||
FBLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t load_reg_hi = 0xffff;
|
||||
uint64_t load_reg_lo = BX_CONST64(0xC000000000000000);
|
||||
int64_t load_val = 0ULL;
|
||||
uint64_t power;
|
||||
int sign;
|
||||
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
load_reg_lo = readmemq(easeg, cpu_state.eaaddr);
|
||||
load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
clear_C1();
|
||||
sign = (load_reg_hi & 0x8000) != 0;
|
||||
load_val = 0ULL;
|
||||
power = 1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
load_val += ((uint64_t) (load_reg_lo & 0xf)) * power;
|
||||
load_reg_lo >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
load_val += ((uint64_t) (load_reg_hi & 0xf)) * power;
|
||||
load_reg_hi >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
if (sign)
|
||||
load_val = -load_val;
|
||||
x87_push((double) load_val);
|
||||
cpu_state.MM[cpu_state.TOP & 7].q = load_val;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
FBSTP_a16(uint32_t fetchdat)
|
||||
{
|
||||
|
||||
@@ -183,6 +183,99 @@ sf_FILDiq_a32(uint32_t fetchdat)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
sf_FBLD_PACKED_BCD_a16(uint32_t fetchdat)
|
||||
{
|
||||
floatx80 result;
|
||||
uint16_t load_reg_hi = 0xffff;
|
||||
uint64_t load_reg_lo = BX_CONST64(0xC000000000000000);
|
||||
int64_t load_val = 0ULL;
|
||||
uint64_t power;
|
||||
int sign;
|
||||
|
||||
FP_ENTER();
|
||||
FPU_check_pending_exceptions();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
load_reg_lo = readmemq(easeg, cpu_state.eaaddr);
|
||||
load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
clear_C1();
|
||||
if (!IS_TAG_EMPTY(-1)) {
|
||||
FPU_stack_overflow(fetchdat);
|
||||
} else {
|
||||
sign = (load_reg_hi & 0x8000) != 0;
|
||||
load_val = 0ULL;
|
||||
power = 1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
load_val += ((uint64_t) (load_reg_lo & 0xf)) * power;
|
||||
load_reg_lo >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
load_val += ((uint64_t) (load_reg_hi & 0xf)) * power;
|
||||
load_reg_hi >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
if (sign)
|
||||
load_val = -load_val;
|
||||
result = int64_to_floatx80(load_val);
|
||||
FPU_push();
|
||||
FPU_save_regi(result, 0);
|
||||
}
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int
|
||||
sf_FBLD_PACKED_BCD_a32(uint32_t fetchdat)
|
||||
{
|
||||
floatx80 result;
|
||||
uint16_t load_reg_hi = 0xffff;
|
||||
uint64_t load_reg_lo = BX_CONST64(0xC000000000000000);
|
||||
int64_t load_val = 0ULL;
|
||||
uint64_t power;
|
||||
int sign;
|
||||
|
||||
FP_ENTER();
|
||||
FPU_check_pending_exceptions();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
load_reg_lo = readmemq(easeg, cpu_state.eaaddr);
|
||||
load_reg_hi = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
clear_C1();
|
||||
if (!IS_TAG_EMPTY(-1)) {
|
||||
FPU_stack_overflow(fetchdat);
|
||||
} else {
|
||||
sign = (load_reg_hi & 0x8000) != 0;
|
||||
load_val = 0ULL;
|
||||
power = 1;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
load_val += ((uint64_t) (load_reg_lo & 0xf)) * power;
|
||||
load_reg_lo >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
load_val += ((uint64_t) (load_reg_hi & 0xf)) * power;
|
||||
load_reg_hi >>= 4;
|
||||
power *= 10;
|
||||
}
|
||||
if (sign)
|
||||
load_val = -load_val;
|
||||
result = int64_to_floatx80(load_val);
|
||||
FPU_push();
|
||||
FPU_save_regi(result, 0);
|
||||
}
|
||||
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi));
|
||||
CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
sf_FLDs_a16(uint32_t fetchdat)
|
||||
{
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x86 CPU segment emulation for the 286/386 interpreter.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#ifndef OPS_286_386
|
||||
# define OPS_286_386
|
||||
#endif
|
||||
#include "x86seg.c"
|
||||
34
src/device.c
34
src/device.c
@@ -51,6 +51,8 @@
|
||||
#include <86box/ini.h>
|
||||
#include <86box/config.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
@@ -62,6 +64,7 @@ static device_t *devices[DEVICE_MAX];
|
||||
static void *device_priv[DEVICE_MAX];
|
||||
static device_context_t device_current;
|
||||
static device_context_t device_prev;
|
||||
static void *device_common_priv;
|
||||
|
||||
#ifdef ENABLE_DEVICE_LOG
|
||||
int device_do_log = ENABLE_DEVICE_LOG;
|
||||
@@ -209,6 +212,16 @@ device_add(const device_t *dev)
|
||||
return device_add_common(dev, dev, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
device_add_linked(const device_t *dev, void *priv)
|
||||
{
|
||||
void *ret;
|
||||
device_common_priv = priv;
|
||||
ret = device_add_common(dev, dev, NULL, NULL, 0);
|
||||
device_common_priv = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
device_add_parameters(const device_t *dev, void *params)
|
||||
{
|
||||
@@ -305,6 +318,12 @@ device_cadd_inst_ex_parameters(const device_t *dev, const device_t *cd, void *pr
|
||||
device_add_common(dev, cd, priv, params, inst);
|
||||
}
|
||||
|
||||
void *
|
||||
device_get_common_priv(void)
|
||||
{
|
||||
return device_common_priv;
|
||||
}
|
||||
|
||||
void
|
||||
device_close_all(void)
|
||||
{
|
||||
@@ -328,6 +347,12 @@ device_reset_all(uint32_t match_flags)
|
||||
devices[c]->reset(device_priv[c]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNCOMMENT_LATER
|
||||
/* TODO: Actually convert the LPT devices to device_t's. */
|
||||
if ((match_flags == DEVICE_ALL) || (match_flags == DEVICE_PCI))
|
||||
lpt_reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -450,8 +475,7 @@ device_has_config(const device_t *dev)
|
||||
config = dev->config;
|
||||
|
||||
while (config->type != -1) {
|
||||
if (config->type != CONFIG_MAC)
|
||||
c++;
|
||||
c++;
|
||||
config++;
|
||||
}
|
||||
|
||||
@@ -849,3 +873,9 @@ machine_get_config_string(char *s)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const device_t*
|
||||
device_context_get_device(void)
|
||||
{
|
||||
return device_current.dev;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
|
||||
add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
|
||||
hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c
|
||||
postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
|
||||
smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c
|
||||
postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
|
||||
smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c
|
||||
kbc_at.c kbc_at_dev.c
|
||||
keyboard_at.c
|
||||
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c
|
||||
serial_passthrough.c)
|
||||
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c
|
||||
serial_passthrough.c
|
||||
novell_cardkey.c)
|
||||
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
target_link_libraries(86Box atomic)
|
||||
|
||||
@@ -73,8 +73,8 @@ ibm_5161_in(uint16_t port, void *priv)
|
||||
02-03 = not used
|
||||
04-07 = switch position
|
||||
1 = Off
|
||||
0 =On */
|
||||
ret = dev->regs[3] & 0x01;
|
||||
0 = On */
|
||||
ret = (dev->regs[3] & 0x01) | (((~(0xf - ((mem_size + isa_mem_size) >> 6))) & 0xf) << 4);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -95,8 +95,7 @@ ibm_5161_close(void *priv)
|
||||
static void *
|
||||
ibm_5161_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ibm_5161_t *dev = (ibm_5161_t *) malloc(sizeof(ibm_5161_t));
|
||||
memset(dev, 0, sizeof(ibm_5161_t));
|
||||
ibm_5161_t *dev = (ibm_5161_t *) calloc(1, sizeof(ibm_5161_t));
|
||||
|
||||
/* Extender Card Registers */
|
||||
io_sethandler(0x0210, 0x0004,
|
||||
|
||||
@@ -97,6 +97,7 @@
|
||||
#define ISAMEM_RAMPAGEXT_CARD 11
|
||||
#define ISAMEM_ABOVEBOARD_CARD 12
|
||||
#define ISAMEM_BRAT_CARD 13
|
||||
#define ISAMEM_EV165A_CARD 14
|
||||
|
||||
#define ISAMEM_DEBUG 0
|
||||
|
||||
@@ -452,6 +453,16 @@ isamem_init(const device_t *info)
|
||||
dev->frame_addr = 0xE0000;
|
||||
break;
|
||||
|
||||
case ISAMEM_EV165A_CARD: /* Everex Maxi Magic EV-165A */
|
||||
dev->base_addr = device_get_config_hex16("base");
|
||||
dev->total_size = device_get_config_int("size");
|
||||
dev->start_addr = device_get_config_int("start");
|
||||
tot = device_get_config_int("length");
|
||||
if (!!device_get_config_int("ems"))
|
||||
dev->flags |= FLAG_EMS;
|
||||
dev->frame_addr = 0xE0000;
|
||||
break;
|
||||
|
||||
case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */
|
||||
case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */
|
||||
case ISAMEM_BRAT_CARD: /* BocaRAM/AT */
|
||||
@@ -1238,6 +1249,101 @@ static const device_t ev159_device = {
|
||||
.config = ev159_config
|
||||
};
|
||||
|
||||
static const device_config_t ev165a_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "size",
|
||||
.description = "Memory Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.default_string = "",
|
||||
.default_int = 512,
|
||||
.file_filter = "",
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 2048,
|
||||
.step = 512
|
||||
},
|
||||
.selection = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "start",
|
||||
.description = "Start Address",
|
||||
.type = CONFIG_SPINNER,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 896,
|
||||
.step = 128
|
||||
},
|
||||
.selection = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "length",
|
||||
.description = "Contiguous Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 16384,
|
||||
.step = 128
|
||||
},
|
||||
.selection = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems",
|
||||
.description = "EMS mode",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = "",
|
||||
.default_int = 0,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "Enabled", .value = 1 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = "",
|
||||
.default_int = 0x0258,
|
||||
.file_filter = "",
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "208H", .value = 0x0208 },
|
||||
{ .description = "218H", .value = 0x0218 },
|
||||
{ .description = "258H", .value = 0x0258 },
|
||||
{ .description = "268H", .value = 0x0268 },
|
||||
{ .description = "2A8H", .value = 0x02A8 },
|
||||
{ .description = "2B8H", .value = 0x02B8 },
|
||||
{ .description = "2E8H", .value = 0x02E8 },
|
||||
{ .description = "" }
|
||||
},
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static const device_t ev165a_device = {
|
||||
.name = "Everex Magi Magic EV-165A",
|
||||
.internal_name = "ev165a",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ISAMEM_EV165A_CARD,
|
||||
.init = isamem_init,
|
||||
.close = isamem_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = ev165a_config
|
||||
};
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT)
|
||||
static const device_config_t brat_config[] = {
|
||||
// clang-format off
|
||||
@@ -1560,6 +1666,7 @@ static const struct {
|
||||
{ &a6pak_device },
|
||||
{ &ems5150_device },
|
||||
{ &ev159_device },
|
||||
{ &ev165a_device },
|
||||
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT)
|
||||
{ &brat_device },
|
||||
#endif
|
||||
|
||||
@@ -124,7 +124,7 @@ static void
|
||||
isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld)
|
||||
{
|
||||
/* Ignore card if it hasn't signed up for configuration changes. */
|
||||
if (!card->config_changed)
|
||||
if ((card == NULL) || !card->config_changed)
|
||||
return;
|
||||
|
||||
/* Populate config structure, performing endianness conversion as needed. */
|
||||
@@ -737,7 +737,7 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
|
||||
isapnp_log("ISAPnP: Parsing ROM resources for card %c%c%c%02X%02X (serial %08X)\n", '@' + ((vendor >> 10) & 0x1f), '@' + ((vendor >> 5) & 0x1f), '@' + (vendor & 0x1f), card->rom[2], card->rom[3], (card->rom[7] << 24) | (card->rom[6] << 16) | (card->rom[5] << 8) | card->rom[4]);
|
||||
const char *df_priority[] = { "good", "acceptable", "sub-optimal", "unknown priority" };
|
||||
const char *mem_control[] = { "8-bit", "16-bit", "8/16-bit", "32-bit" };
|
||||
const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "unknown" };
|
||||
const char *dma_transfer[] = { "8-bit", "8/16-bit", "16-bit", "Reserved" };
|
||||
const char *dma_speed[] = { "compatibility", "Type A", "Type B", "Type F" };
|
||||
#endif
|
||||
uint16_t i = 9;
|
||||
@@ -937,9 +937,9 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
|
||||
case 0x05: /* DMA */
|
||||
isapnp_log("ISAPnP: >>%s DMA index %d with mask %02X, %s, %sbus master, %scount by byte, %scount by word, %s speed\n", in_df ? ">" : "", dma++, card->rom[i + 1],
|
||||
dma_transfer[card->rom[i + 2] & 3],
|
||||
(card->rom[i + 2] & 0x04) ? "not " : "",
|
||||
(card->rom[i + 2] & 0x08) ? "not " : "",
|
||||
(card->rom[i + 2] & 0x10) ? "not " : "",
|
||||
(card->rom[i + 2] & 0x04) ? "" : "not ",
|
||||
(card->rom[i + 2] & 0x08) ? "" : "not ",
|
||||
(card->rom[i + 2] & 0x10) ? "" : "not ",
|
||||
dma_speed[(card->rom[i + 2] >> 5) & 3]);
|
||||
break;
|
||||
#endif
|
||||
@@ -1004,6 +1004,29 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size)
|
||||
|
||||
break;
|
||||
|
||||
case 0x09: /* Fixed I/O port */
|
||||
if (!ld) {
|
||||
isapnp_log("ISAPnP: >>%s Fixed I/O descriptor with no logical device\n", in_df ? ">" : "");
|
||||
break;
|
||||
}
|
||||
|
||||
if (io > 7) {
|
||||
isapnp_log("ISAPnP: >>%s Fixed I/O descriptor overflow (%d)\n", in_df ? ">" : "", io++);
|
||||
break;
|
||||
}
|
||||
|
||||
isapnp_log("ISAPnP: >>%s Fixed I/O range %d with %d ports at %04X\n", in_df ? ">" : "", io, card->rom[i + 3], *((uint16_t *) &card->rom[i + 1]));
|
||||
|
||||
/* Fixed I/O port ranges of this kind are always 10-bit. */
|
||||
ld->io_16bit &= ~(1 << io);
|
||||
|
||||
if (card->rom[i + 3] > ld->io_len[io])
|
||||
ld->io_len[io] = card->rom[i + 3];
|
||||
|
||||
io++;
|
||||
|
||||
break;
|
||||
|
||||
case 0x0f: /* end tag */
|
||||
/* Calculate checksum. */
|
||||
res = 0x00;
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/keyboard.h>
|
||||
|
||||
#include <86box/dma.h>
|
||||
#include <86box/pci.h>
|
||||
|
||||
#define STAT_PARITY 0x80
|
||||
#define STAT_RTIMEOUT 0x40
|
||||
#define STAT_TTIMEOUT 0x20
|
||||
@@ -85,8 +88,11 @@
|
||||
#define KBC_VEN_ALI 0x28
|
||||
#define KBC_VEN_SIEMENS 0x2c
|
||||
#define KBC_VEN_COMPAQ 0x30
|
||||
#define KBC_VEN_IBM 0x34
|
||||
#define KBC_VEN_MASK 0x7c
|
||||
|
||||
#define KBC_FLAG_IS_ASIC 0x80000000
|
||||
|
||||
#define FLAG_CLOCK 0x01
|
||||
#define FLAG_CACHE 0x02
|
||||
#define FLAG_PS2 0x04
|
||||
@@ -130,9 +136,9 @@ typedef struct atkbc_t {
|
||||
uint8_t stat_hi;
|
||||
uint8_t pending;
|
||||
uint8_t irq_state;
|
||||
uint8_t do_irq;
|
||||
uint8_t is_asic;
|
||||
uint8_t pad;
|
||||
uint8_t pad0;
|
||||
uint8_t pad1;
|
||||
|
||||
uint8_t mem[0x100];
|
||||
|
||||
@@ -141,8 +147,9 @@ typedef struct atkbc_t {
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
/* Main timer. */
|
||||
pc_timer_t send_delay_timer;
|
||||
/* Main timers. */
|
||||
pc_timer_t kbc_poll_timer;
|
||||
pc_timer_t kbc_dev_poll_timer;
|
||||
|
||||
/* P2 pulse callback timer. */
|
||||
pc_timer_t pulse_cb;
|
||||
@@ -160,6 +167,8 @@ kbc_at_port_t *kbc_at_ports[2] = { NULL, NULL };
|
||||
static uint8_t kbc_ami_revision = '8';
|
||||
static uint8_t kbc_award_revision = 0x42;
|
||||
|
||||
static uint8_t kbc_handler_set = 0;
|
||||
|
||||
static void (*kbc_at_do_poll)(atkbc_t *dev);
|
||||
|
||||
/* Non-translated to translated scan codes. */
|
||||
@@ -198,6 +207,19 @@ static const uint8_t nont_to_t[256] = {
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
static const uint8_t multikey_vars[0x0b] = {
|
||||
0x0a,
|
||||
0x03, 0x1e, 0x27, 0x28, 0x29, 0x38, 0x39, 0x18, 0x19, 0x35
|
||||
};
|
||||
|
||||
static uint8_t fast_reset = 0x00;
|
||||
|
||||
void
|
||||
kbc_at_set_fast_reset(const uint8_t new_fast_reset)
|
||||
{
|
||||
fast_reset = new_fast_reset;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_KBC_AT_LOG
|
||||
int kbc_at_do_log = ENABLE_KBC_AT_LOG;
|
||||
|
||||
@@ -327,6 +349,30 @@ kbc_translate(atkbc_t *dev, uint8_t val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
kbc_set_do_irq(atkbc_t *dev, uint8_t channel)
|
||||
{
|
||||
dev->channel = channel;
|
||||
dev->do_irq = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
kbc_do_irq(atkbc_t *dev)
|
||||
{
|
||||
if (dev->do_irq) {
|
||||
/* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly
|
||||
written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */
|
||||
picint_common(1 << 1, 0, 0, NULL);
|
||||
picint_common(1 << 12, 0, 0, NULL);
|
||||
if (dev->channel >= 2)
|
||||
picint_common(1 << 12, 0, 1, NULL);
|
||||
else
|
||||
picint_common(1 << 1, 0, 1, NULL);
|
||||
|
||||
dev->do_irq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
|
||||
{
|
||||
@@ -345,6 +391,8 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
|
||||
kbc_at_log("ATkbc: Sending %02X to the output buffer on channel %i...\n", temp, channel);
|
||||
dev->status = (dev->status & ~0xf0) | STAT_OFULL | stat_hi;
|
||||
|
||||
dev->do_irq = 0;
|
||||
|
||||
/* WARNING: On PS/2, all IRQ's are level-triggered, but the IBM PS/2 KBC firmware is explicitly
|
||||
written to pulse its P2 IRQ bits, so they should be kept as as edge-triggered here. */
|
||||
if (dev->misc_flags & FLAG_PS2) {
|
||||
@@ -352,16 +400,15 @@ kbc_send_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
|
||||
dev->status |= STAT_MFULL;
|
||||
|
||||
if (dev->mem[0x20] & 0x02)
|
||||
picint_common(1 << 12, 0, 1, NULL);
|
||||
picint_common(1 << 1, 0, 0, NULL);
|
||||
} else {
|
||||
if (dev->mem[0x20] & 0x01)
|
||||
picint_common(1 << 1, 0, 1, NULL);
|
||||
picint_common(1 << 12, 0, 0, NULL);
|
||||
}
|
||||
kbc_set_do_irq(dev, channel);
|
||||
} else if (dev->mem[0x20] & 0x01)
|
||||
kbc_set_do_irq(dev, channel);
|
||||
} else if (dev->mem[0x20] & 0x01)
|
||||
picintlevel(1 << 1, &dev->irq_state); /* AT KBC: IRQ 1 is level-triggered because it is tied to OBF. */
|
||||
|
||||
if (dev->is_asic || (kbc_ven == KBC_VEN_IBM_PS1) || (kbc_ven == KBC_VEN_IBM))
|
||||
kbc_do_irq(dev);
|
||||
|
||||
dev->ob = temp;
|
||||
}
|
||||
|
||||
@@ -580,6 +627,8 @@ kbc_scan_aux_ps2(atkbc_t *dev)
|
||||
static void
|
||||
kbc_at_poll_ps2(atkbc_t *dev)
|
||||
{
|
||||
kbc_do_irq(dev);
|
||||
|
||||
switch (dev->state) {
|
||||
case STATE_RESET:
|
||||
if (dev->status & STAT_IFULL) {
|
||||
@@ -594,7 +643,6 @@ kbc_at_poll_ps2(atkbc_t *dev)
|
||||
fallthrough;
|
||||
case STATE_MAIN_IBF:
|
||||
default:
|
||||
ps2_main_ibf:
|
||||
if (dev->status & STAT_IFULL)
|
||||
kbc_ibf_process(dev);
|
||||
else if (!(dev->status & STAT_OFULL)) {
|
||||
@@ -645,7 +693,8 @@ ps2_main_ibf:
|
||||
#endif
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
dev->pending = 0;
|
||||
goto ps2_main_ibf;
|
||||
// goto ps2_main_ibf;
|
||||
break;
|
||||
case STATE_KBC_OUT:
|
||||
/* Keyboard controller command want to output multiple bytes. */
|
||||
if (dev->status & STAT_IFULL) {
|
||||
@@ -695,10 +744,18 @@ kbc_at_poll(void *priv)
|
||||
{
|
||||
atkbc_t *dev = (atkbc_t *) priv;
|
||||
|
||||
timer_advance_u64(&dev->send_delay_timer, (100ULL * TIMER_USEC));
|
||||
timer_advance_u64(&dev->kbc_poll_timer, (100ULL * TIMER_USEC));
|
||||
|
||||
/* TODO: Implement the password security state. */
|
||||
kbc_at_do_poll(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
kbc_at_dev_poll(void *priv)
|
||||
{
|
||||
atkbc_t *dev = (atkbc_t *) priv;
|
||||
|
||||
timer_advance_u64(&dev->kbc_dev_poll_timer, (100ULL * TIMER_USEC));
|
||||
|
||||
if ((kbc_at_ports[0] != NULL) && (kbc_at_ports[0]->priv != NULL))
|
||||
kbc_at_ports[0]->poll(kbc_at_ports[0]->priv);
|
||||
@@ -736,7 +793,10 @@ write_p2(atkbc_t *dev, uint8_t val)
|
||||
/* AT, PS/2: Handle reset. */
|
||||
/* 0 holds the CPU in the RESET state, 1 releases it. To simplify this,
|
||||
we just do everything on release. */
|
||||
if ((old ^ val) & 0x01) { /*Reset*/
|
||||
/* TODO: The fast reset flag's condition should be reversed - the BCM SQ-588
|
||||
enables the flag and the CPURST on soft reset flag but expects this
|
||||
to still soft reset instead. */
|
||||
if ((fast_reset || !cpu_cpurst_on_sr) && ((old ^ val) & 0x01)) { /*Reset*/
|
||||
if (!(val & 0x01)) { /* Pin 0 selected. */
|
||||
/* Pin 0 selected. */
|
||||
kbc_at_log("write_p2(): Pulse reset!\n");
|
||||
@@ -753,11 +813,12 @@ write_p2(atkbc_t *dev, uint8_t val)
|
||||
flushmmucache();
|
||||
if (kbc_ven == KBC_VEN_ALI)
|
||||
smbase = 0x00030000;
|
||||
|
||||
/* Yes, this is a hack, but until someone gets ahold of the real PCD-2L
|
||||
and can find out what they actually did to make it boot from FFFFF0
|
||||
correctly despite A20 being gated when the CPU is reset, this will
|
||||
have to do. */
|
||||
else if (kbc_ven == KBC_VEN_SIEMENS)
|
||||
if (kbc_ven == KBC_VEN_SIEMENS)
|
||||
is486 ? loadcs(0xf000) : loadcs_2386(0xf000);
|
||||
}
|
||||
}
|
||||
@@ -765,6 +826,28 @@ write_p2(atkbc_t *dev, uint8_t val)
|
||||
|
||||
/* Do this here to avoid an infinite reset loop. */
|
||||
dev->p2 = val;
|
||||
|
||||
if (!fast_reset && cpu_cpurst_on_sr && ((old ^ val) & 0x01)) { /*Reset*/
|
||||
if (!(val & 0x01)) { /* Pin 0 selected. */
|
||||
/* Pin 0 selected. */
|
||||
kbc_at_log("write_p2(): Pulse reset!\n");
|
||||
dma_reset();
|
||||
dma_set_at(1);
|
||||
|
||||
device_reset_all(DEVICE_ALL);
|
||||
|
||||
cpu_alt_reset = 0;
|
||||
|
||||
pci_reset();
|
||||
|
||||
mem_a20_alt = 0;
|
||||
mem_a20_recalc();
|
||||
|
||||
flushmmucache();
|
||||
|
||||
resetx86();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1302,6 +1385,204 @@ write64_ami(void *priv, uint8_t val)
|
||||
return write64_generic(dev, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
write60_phoenix(void *priv, uint8_t val)
|
||||
{
|
||||
atkbc_t *dev = (atkbc_t *) priv;
|
||||
|
||||
switch (dev->command) {
|
||||
/* TODO: Make this actually load the password. */
|
||||
case 0xa3: /* Load Extended Password */
|
||||
kbc_at_log("ATkbc: Phoenix - Load Extended Password\n");
|
||||
if (val == 0x00)
|
||||
dev->command_phase = 0;
|
||||
else {
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case 0xaf: /* Set Inactivity Timer */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n");
|
||||
dev->mem[0x3a] = val;
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xb8: /* Set Extended Memory Access Index */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n");
|
||||
dev->mem_addr = val;
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xbb: /* Set Extended Memory */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n");
|
||||
dev->mem[dev->mem_addr] = val;
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xbd: /* Set MultiKey Variable */
|
||||
kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n");
|
||||
if ((dev->mem_addr > 0) && (dev->mem_addr <= multikey_vars[0x00]))
|
||||
dev->mem[multikey_vars[dev->mem_addr]] = val;
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xc7: /* Set Port1 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n");
|
||||
dev->p1 |= val;
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xc8: /* Clear Port1 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n");
|
||||
dev->p1 &= ~val;
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xc9: /* Set Port2 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n");
|
||||
write_p2(dev, dev->p2 | val);
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
case 0xca: /* Clear Port2 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n");
|
||||
write_p2(dev, dev->p2 & ~val);
|
||||
dev->command_phase = 0;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
write64_phoenix(void *priv, uint8_t val)
|
||||
{
|
||||
atkbc_t *dev = (atkbc_t *) priv;
|
||||
|
||||
switch (val) {
|
||||
case 0x00 ... 0x1f:
|
||||
kbc_at_log("ATkbc: Phoenix - alias read from %08X\n", val);
|
||||
kbc_delay_to_ob(dev, dev->mem[val + 0x20], 0, 0x00);
|
||||
return 0;
|
||||
|
||||
case 0x40 ... 0x5f:
|
||||
kbc_at_log("ATkbc: Phoenix - alias write to %08X\n", dev->command);
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xa2: /* Test Extended Password */
|
||||
kbc_at_log("ATkbc: Phoenix - Test Extended Password\n");
|
||||
kbc_at_queue_add(dev, 0xf1); /* Extended Password not loaded */
|
||||
return 0;
|
||||
|
||||
/* TODO: Make this actually load the password. */
|
||||
case 0xa3: /* Load Extended Password */
|
||||
kbc_at_log("ATkbc: Phoenix - Load Extended Password\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xaf: /* Set Inactivity Timer */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Inactivity Timer\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xb8: /* Set Extended Memory Access Index */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Extended Memory Access Index\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xb9: /* Get Extended Memory Access Index */
|
||||
kbc_at_log("ATkbc: Phoenix - Get Extended Memory Access Index\n");
|
||||
kbc_at_queue_add(dev, dev->mem_addr);
|
||||
return 0;
|
||||
|
||||
case 0xba: /* Get Extended Memory */
|
||||
kbc_at_log("ATkbc: Phoenix - Get Extended Memory\n");
|
||||
kbc_at_queue_add(dev, dev->mem[dev->mem_addr]);
|
||||
return 0;
|
||||
|
||||
case 0xbb: /* Set Extended Memory */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Extended Memory\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xbc: /* Get MultiKey Variable */
|
||||
kbc_at_log("ATkbc: Phoenix - Get MultiKey Variable\n");
|
||||
if (dev->mem_addr == 0)
|
||||
kbc_at_queue_add(dev, multikey_vars[dev->mem_addr]);
|
||||
else if (dev->mem_addr <= multikey_vars[dev->mem_addr])
|
||||
kbc_at_queue_add(dev, dev->mem[multikey_vars[dev->mem_addr]]);
|
||||
else
|
||||
kbc_at_queue_add(dev, 0xff);
|
||||
return 0;
|
||||
|
||||
case 0xbd: /* Set MultiKey Variable */
|
||||
kbc_at_log("ATkbc: Phoenix - Set MultiKey Variable\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xc7: /* Set Port1 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Port1 bits\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xc8: /* Clear Port1 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Clear Port1 bits\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xc9: /* Set Port2 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Set Port2 bits\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
case 0xca: /* Clear Port2 bits */
|
||||
kbc_at_log("ATkbc: Phoenix - Clear Port2 bits\n");
|
||||
dev->wantdata = 1;
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
return 0;
|
||||
|
||||
/* TODO: Handle these three commands properly - configurable
|
||||
revision level and proper CPU bits. */
|
||||
case 0xd5: /* Read MultiKey code revision level */
|
||||
kbc_at_log("ATkbc: Phoenix - Read MultiKey code revision level\n");
|
||||
kbc_at_queue_add(dev, 0x04);
|
||||
kbc_at_queue_add(dev, 0x16);
|
||||
return 0;
|
||||
|
||||
case 0xd6: /* Read Version Information */
|
||||
kbc_at_log("ATkbc: Phoenix - Read Version Information\n");
|
||||
kbc_at_queue_add(dev, 0x81);
|
||||
kbc_at_queue_add(dev, 0xac);
|
||||
return 0;
|
||||
|
||||
case 0xd7: /* Read MultiKey model numbers */
|
||||
kbc_at_log("ATkbc: Phoenix - Read MultiKey model numbers\n");
|
||||
kbc_at_queue_add(dev, 0x02);
|
||||
kbc_at_queue_add(dev, 0x87);
|
||||
kbc_at_queue_add(dev, 0x02);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return write64_generic(dev, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
write64_siemens(void *priv, uint8_t val)
|
||||
{
|
||||
@@ -1753,6 +2034,9 @@ kbc_at_process_cmd(void *priv)
|
||||
if (dev->ib == 0xbb)
|
||||
break;
|
||||
|
||||
if (strstr(machine_get_internal_name(), "pb41") != NULL)
|
||||
cpu_override_dynarec = 1;
|
||||
|
||||
if (dev->misc_flags & FLAG_PS2) {
|
||||
set_enable_aux(dev, 1);
|
||||
if ((dev->ports[1] != NULL) && (dev->ports[1]->priv != NULL)) {
|
||||
@@ -1796,26 +2080,10 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
if (fast_a20 && dev->wantdata && (dev->command == 0xd1)) {
|
||||
kbc_at_log("ATkbc: write P2\n");
|
||||
|
||||
#if 0
|
||||
/* Fast A20 - ignore all other bits. */
|
||||
val = (val & 0x02) | (dev->p2 & 0xfd);
|
||||
|
||||
/* Bit 2 of AMI flags is P22-P23 blocked (1 = yes, 0 = no),
|
||||
discovered by reverse-engineering the AOpeN Vi15G BIOS. */
|
||||
if (dev->ami_flags & 0x04) {
|
||||
/* If keyboard controller lines P22-P23 are blocked,
|
||||
we force them to remain unchanged. */
|
||||
val &= ~0x0c;
|
||||
val |= (dev->p2 & 0x0c);
|
||||
}
|
||||
|
||||
write_p2_fast_a20(dev, val | 0x01);
|
||||
#else
|
||||
/* Fast A20 - ignore all other bits. */
|
||||
write_p2_fast_a20(dev, (dev->p2 & 0xfd) | (val & 0x02));
|
||||
#endif
|
||||
|
||||
dev->wantdata = 0;
|
||||
dev->wantdata = 0;
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
return;
|
||||
}
|
||||
@@ -1829,6 +2097,11 @@ kbc_at_write(uint16_t port, uint8_t val, void *priv)
|
||||
dev->state = STATE_KBC_PARAM;
|
||||
dev->command = 0xd1;
|
||||
return;
|
||||
} else if (fast_reset && ((val & 0xf0) == 0xf0)) {
|
||||
pulse_output(dev, val & 0x0f);
|
||||
|
||||
dev->state = STATE_MAIN_IBF;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1857,6 +2130,8 @@ kbc_at_read(uint16_t port, void *priv)
|
||||
This also means that in AT mode, the IRQ is level-triggered. */
|
||||
if (!(dev->misc_flags & FLAG_PS2))
|
||||
picintclevel(1 << 1, &dev->irq_state);
|
||||
if ((strstr(machine_get_internal_name(), "pb41") != NULL) && (cpu_override_dynarec == 1))
|
||||
cpu_override_dynarec = 0;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
@@ -1934,7 +2209,8 @@ kbc_at_close(void *priv)
|
||||
int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1;
|
||||
|
||||
/* Stop timers. */
|
||||
timer_disable(&dev->send_delay_timer);
|
||||
timer_disable(&dev->kbc_dev_poll_timer);
|
||||
timer_disable(&dev->kbc_poll_timer);
|
||||
|
||||
for (int i = 0; i < max_ports; i++) {
|
||||
if (kbc_at_ports[i] != NULL) {
|
||||
@@ -1946,6 +2222,22 @@ kbc_at_close(void *priv)
|
||||
free(dev);
|
||||
}
|
||||
|
||||
void
|
||||
kbc_at_handler(int set, void *priv)
|
||||
{
|
||||
if (kbc_handler_set) {
|
||||
io_removehandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
|
||||
io_removehandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
|
||||
}
|
||||
|
||||
kbc_handler_set = set;
|
||||
|
||||
if (kbc_handler_set) {
|
||||
io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
|
||||
io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, priv);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
kbc_at_init(const device_t *info)
|
||||
{
|
||||
@@ -1957,18 +2249,22 @@ kbc_at_init(const device_t *info)
|
||||
|
||||
dev->flags = info->local;
|
||||
|
||||
dev->is_asic = !!(info->local & KBC_FLAG_IS_ASIC);
|
||||
|
||||
video_reset(gfxcard[0]);
|
||||
kbc_at_reset(dev);
|
||||
|
||||
if (info->flags & DEVICE_PCI)
|
||||
dev->misc_flags |= FLAG_PCI;
|
||||
|
||||
io_sethandler(0x0060, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0064, 1, kbc_at_read, NULL, NULL, kbc_at_write, NULL, NULL, dev);
|
||||
kbc_handler_set = 0;
|
||||
kbc_at_handler(1, dev);
|
||||
|
||||
timer_add(&dev->send_delay_timer, kbc_at_poll, dev, 1);
|
||||
timer_add(&dev->kbc_poll_timer, kbc_at_poll, dev, 1);
|
||||
timer_add(&dev->pulse_cb, pulse_poll, dev, 0);
|
||||
|
||||
timer_add(&dev->kbc_dev_poll_timer, kbc_at_dev_poll, dev, 1);
|
||||
|
||||
dev->write60_ven = NULL;
|
||||
dev->write64_ven = NULL;
|
||||
|
||||
@@ -1987,6 +2283,7 @@ kbc_at_init(const device_t *info)
|
||||
case KBC_VEN_GENERIC:
|
||||
case KBC_VEN_NCR:
|
||||
case KBC_VEN_IBM_PS1:
|
||||
case KBC_VEN_IBM:
|
||||
case KBC_VEN_COMPAQ:
|
||||
dev->write64_ven = write64_generic;
|
||||
break;
|
||||
@@ -2032,6 +2329,11 @@ kbc_at_init(const device_t *info)
|
||||
dev->write64_ven = write64_ami;
|
||||
break;
|
||||
|
||||
case KBC_VEN_PHOENIX:
|
||||
dev->write60_ven = write60_phoenix;
|
||||
dev->write64_ven = write64_phoenix;
|
||||
break;
|
||||
|
||||
case KBC_VEN_QUADTEL:
|
||||
dev->write60_ven = write60_quadtel;
|
||||
dev->write64_ven = write64_quadtel;
|
||||
@@ -2060,6 +2362,8 @@ kbc_at_init(const device_t *info)
|
||||
/* The actual keyboard. */
|
||||
device_add(&keyboard_at_generic_device);
|
||||
|
||||
fast_reset = 0x00;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -2245,6 +2549,34 @@ const device_t keyboard_ps2_ami_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_ps2_holtek_device = {
|
||||
.name = "PS/2 Keyboard (Holtek)",
|
||||
.internal_name = "keyboard_ps2_holtek",
|
||||
.flags = DEVICE_KBC,
|
||||
.local = KBC_TYPE_PS2_1 | KBC_VEN_AMI | KBC_FLAG_IS_ASIC,
|
||||
.init = kbc_at_init,
|
||||
.close = kbc_at_close,
|
||||
.reset = kbc_at_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_ps2_phoenix_device = {
|
||||
.name = "PS/2 Keyboard (Phoenix)",
|
||||
.internal_name = "keyboard_ps2_phoenix",
|
||||
.flags = DEVICE_KBC,
|
||||
.local = KBC_TYPE_PS2_1 | KBC_VEN_PHOENIX,
|
||||
.init = kbc_at_init,
|
||||
.close = kbc_at_close,
|
||||
.reset = kbc_at_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_ps2_tg_ami_device = {
|
||||
.name = "PS/2 Keyboard (TriGem AMI)",
|
||||
.internal_name = "keyboard_ps2_tg_ami",
|
||||
@@ -2259,11 +2591,25 @@ const device_t keyboard_ps2_tg_ami_device = {
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_ps2_mca_1_device = {
|
||||
.name = "PS/2 Keyboard (IBM PS/2 MCA Type 1)",
|
||||
.internal_name = "keyboard_ps2_mca_1",
|
||||
.flags = DEVICE_KBC,
|
||||
.local = KBC_TYPE_PS2_1 | KBC_VEN_IBM,
|
||||
.init = kbc_at_init,
|
||||
.close = kbc_at_close,
|
||||
.reset = kbc_at_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t keyboard_ps2_mca_2_device = {
|
||||
.name = "PS/2 Keyboard",
|
||||
.name = "PS/2 Keyboard (IBM PS/2 MCA Type 2)",
|
||||
.internal_name = "keyboard_ps2_mca_2",
|
||||
.flags = DEVICE_KBC,
|
||||
.local = KBC_TYPE_PS2_2 | KBC_VEN_GENERIC,
|
||||
.local = KBC_TYPE_PS2_2 | KBC_VEN_IBM,
|
||||
.init = kbc_at_init,
|
||||
.close = kbc_at_close,
|
||||
.reset = kbc_at_reset,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user