Conflict resolution.

This commit is contained in:
OBattler
2024-01-10 08:59:46 +01:00
716 changed files with 71690 additions and 41327 deletions

View File

@@ -51,6 +51,7 @@ AppDir:
- libgles2 # if QT:BOOL=ON
- libglvnd0 # if QT:BOOL=ON
- libglx0 # if QT:BOOL=ON
- libgomp1
- libgs9
- libpng16-16
- libqt5core5a # if QT:BOOL=ON

View File

@@ -540,12 +540,25 @@ then
# Attempt to install dependencies.
sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) 2>&1 | tee macports.log
# Stop if no port version activation errors were found.
# Check for port activation errors.
stuck_dep=$(grep " cannot be built while another version of " macports.log | cut -d" " -f10)
[ -z $stuck_dep ] && break
if [ -n "$stuck_dep" ]
then
# Deactivate the stuck dependency and try again.
sudo "$macports/bin/port" -f deactivate "$stuck_dep"
continue
fi
# Deactivate the stuck dependency and try again.
sudo "$macports/bin/port" -f deactivate $stuck_dep
stuck_dep=$(grep " Please deactivate this port first, or " macports.log | cut -d" " -f5 | tr -d :)
if [ -n "$stuck_dep" ]
then
# Activate the stuck dependency and try again.
sudo "$macports/bin/port" -f activate "$stuck_dep"
continue
fi
# Stop if no errors were found.
break
done
# Remove MacPorts error detection log.
@@ -566,6 +579,7 @@ else
arm32) arch_deb="armhf";;
*) arch_deb="$arch";;
esac
grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version
# Establish general dependencies.
pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream"

View File

@@ -9,5 +9,6 @@ zlib
libpng
rtmidi
libslirp
fluidsynth
qt5-static
qt5-translations

21
.gitattributes vendored Normal file
View File

@@ -0,0 +1,21 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.cc text
*.cpp text
*.h text
*.hpp text
*.rc text
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.ico binary
*.png binary
*.jpg binary
*.dat

View File

@@ -1,32 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. Windows 10]
- 86Box version: [e.g. v3.7.1 build 4032; saying "Latest from Jenkins" isn't helpful]
- Build information: [i.e. new/old dynarec, architecture and build type]
**Additional context**
Add any other context about the problem here. If you are using an Optimized build, make sure to try the regular build too before filing a bug report!

80
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,80 @@
name: Bug Report
description: File a bug report
title: "Title"
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
attributes:
label: What happened?
description: Also tell us, what did you expect to happen?
placeholder: Tell us what you see!
validations:
required: true
- type: textarea
attributes:
label: Configuration file
description: Please copy and paste your machine configuration file (`86box.cfg`). This will be automatically formatted into code, so no need for backticks.
render: ini
validations:
required: true
- type: input
attributes:
label: Operating system
description: What is your host operating system?
placeholder: e.g. Windows 10
validations:
required: true
- type: input
attributes:
label: CPU
description: What is your host CPU?
placeholder: e.g. AMD Ryzen 5 5600G
validations:
required: true
- type: input
attributes:
label: 86Box version
description: What version of 86Box are you running? (Saying "Latest from Jenkins" is not helpful.)
placeholder: e.g. v4.0 build 5000
validations:
required: true
- type: dropdown
attributes:
label: Build architecture
description: 86Box for what architecture are you using?
options:
- Linux - ARM (32-bit)
- Linux - ARM (64-bit)
- Linux - x64 (64-bit)
- Linux - x86 (32-bit)
- macOS - Universal (Intel and Apple Silicon)
- Windows - x64 (64-bit)
- Windows - x86 (32-bit)
validations:
required: true
- type: checkboxes
attributes:
label: Build type
description: What type of build are you using?
options:
- label: New recompiler
- label: Debug build
- type: dropdown
attributes:
label: Download source
description: Where did you download 86Box from?
options:
- Official website (Jenkins, GitHub)
- Manager auto-update
- I built 86Box myself (please tell us more about your build configuration)
- I got 86Box from a third party repository (please tell us where)
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Is there anything else you want to tell us?

View File

@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Question
- name: Machine Request
url: https://github.com/86Box/86Box/issues/3577#issue-comment-box
about: Please submit machine addition requests under this tracking issue.
- name: Feature Request or Question
url: https://github.com/86Box/86Box/discussions
about: Please ask and answer questions here.
about: Please submit feature requests and ask questions here.

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,4 +1,4 @@
name: MSYS2 Makefile
name: MSYS2 Makefile (Windows, Legacy)
on:
@@ -16,7 +16,7 @@ on:
jobs:
msys2:
name: "Windows MSYS2 Makefile (Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
runs-on: windows-2022
@@ -95,7 +95,7 @@ jobs:
libvncserver:p
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: make
run: >-

View File

@@ -1,463 +0,0 @@
name: CMake
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
msys2:
name: "Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
runs-on: windows-2022
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Win32 GUI
qt: off
static: on
- name: Qt GUI
qt: on
static: off
slug: -Qt
packages: >-
qt5-base:p
qt5-tools:p
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
- msystem: MINGW32
prefix: mingw-w64-i686
toolchain: ./cmake/flags-gcc-i686.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG32
# prefix: mingw-w64-clang-i686
# toolchain: ./cmake/llvm-win32-i686.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake
- msystem: UCRT64
prefix: mingw-w64-ucrt-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
steps:
- name: Prepare MSYS2 environment
uses: msys2/setup-msys2@v2
with:
release: false
update: true
msystem: ${{ matrix.environment.msystem }}
pacboy: >-
ninja:p
cmake:p
gcc:p
pkgconf:p
freetype:p
SDL2:p
zlib:p
libpng:p
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ${{ matrix.environment.toolchain }}
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D STATIC_BUILD=${{ matrix.ui.static }}
- name: Build
run: |
cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
path: build/artifacts/**
llvm-windows:
name: "Windows vcpkg/LLVM (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }})"
if: 0
runs-on: windows-2022
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite'
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Win32 GUI
qt: off
- name: Qt GUI
qt: on
slug: -Qt
target:
- name: x86
triplet: x86-windows-static
toolchain: ./cmake/llvm-win32-i686.cmake
vcvars: x64_x86
- name: x64
triplet: x64-windows-static
toolchain: ./cmake/llvm-win32-x86_64.cmake
vcvars: x64
- name: ARM64
triplet: arm64-windows-static
toolchain: ./cmake/llvm-win32-aarch64.cmake
vcvars: x64_arm64
exclude:
- dynarec:
new: off
target:
name: ARM64
steps:
- name: Prepare VS environment
uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{ matrix.target.vcvars }}
- name: Add LLVM to path
run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH
- name: Download Ninja
run: >
Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip &&
Expand-Archive ninja-win.zip -DestinationPath .
- name: Setup NuGet Credentials
run: >
& (C:/vcpkg/vcpkg fetch nuget | tail -n 2)
sources add
-source "https://nuget.pkg.github.com/86Box/index.json"
-storepasswordincleartext
-name "GitHub"
-username "86Box"
-password "${{ secrets.GITHUB_TOKEN }}"
- name: Fix MSVC atomic headers
run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
- name: Configure CMake
run: >
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }}
-D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }}
-D VCPKG_HOST_TRIPLET=x64-windows
-D VCPKG_USE_HOST_TOOLS=ON
- name: Fix Qt
if: matrix.ui.qt == 'on'
run: |
$qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake"
(Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath
- name: Reconfigure CMake
if: matrix.ui.qt == 'on'
run: |
cmake clean build
- name: Build
run: |
build-wrapper-win-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: |
cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}'
path: build/artifacts/**
linux:
name: "Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: ubuntu-22.04
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qtbase5-dev
qtbase5-private-dev
qttools5-dev
libevdev-dev
libxkbcommon-x11-dev
steps:
- name: Install dependencies
run: >-
sudo apt update && sudo apt install
build-essential
ninja-build
libfreetype-dev
libsdl2-dev
libpng-dev
libc6-dev
librtmidi-dev
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvncserver-dev
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
- name: Build
run: |
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
# if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: |
cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}'
path: build/artifacts/**
macos11:
name: "macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: macos-11
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qt@5
steps:
- name: Install dependencies
run: >-
brew install
ninja
freetype
sdl2
libpng
rtmidi
openal-soft
fluidsynth
libvncserver
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v1
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D Qt5_ROOT=$(brew --prefix qt@5)
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
-D OpenAL_ROOT=$(brew --prefix openal-soft)
- name: Build
run: |
build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: |
cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}'
path: build/artifacts/**

122
.github/workflows/cmake_linux.yml vendored Normal file
View File

@@ -0,0 +1,122 @@
name: CMake (Linux)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
linux:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
runs-on: ubuntu-22.04
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: SDL GUI
qt: off
static: on
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qtbase5-dev
qtbase5-private-dev
qttools5-dev
libevdev-dev
libxkbcommon-x11-dev
steps:
- name: Install dependencies
run: >-
sudo apt update && sudo apt install
build-essential
ninja-build
libfreetype-dev
libsdl2-dev
libpng-dev
libc6-dev
librtmidi-dev
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvncserver-dev
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
- name: Build
run: |
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
# if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: |
cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}'
path: build/artifacts/**

127
.github/workflows/cmake_macos.yml vendored Normal file
View File

@@ -0,0 +1,127 @@
name: CMake (macos)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
macos12:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
runs-on: macos-12
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: SDL GUI
qt: off
static: on
src-packages: >-
libsndfile
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qt@5
src-packages: >-
libsndfile
steps:
- name: Install source dependencies
run: >-
brew reinstall -s
${{ matrix.ui.src-packages }}
- name: Install dependencies
run: >-
brew install
ninja
freetype
sdl2
libpng
rtmidi
openal-soft
fluidsynth
libvncserver
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D Qt5_ROOT=$(brew --prefix qt@5)
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
-D OpenAL_ROOT=$(brew --prefix openal-soft)
- name: Build
run: |
build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: |
cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}'
path: build/artifacts/**

163
.github/workflows/cmake_windows_llvm.yml vendored Normal file
View File

@@ -0,0 +1,163 @@
name: CMake (Windows, vcpkg/LLVM)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
llvm-windows:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.target.name }}"
if: 0
runs-on: windows-2022
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite'
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Win32 GUI
qt: off
- name: Qt GUI
qt: on
slug: -Qt
target:
- name: x86
triplet: x86-windows-static
toolchain: ./cmake/llvm-win32-i686.cmake
vcvars: x64_x86
- name: x64
triplet: x64-windows-static
toolchain: ./cmake/llvm-win32-x86_64.cmake
vcvars: x64
# - name: ARM
# triplet: arm-windows-static
# toolchain: ./cmake/llvm-win32-arm.cmake
# vcvars: x64_arm
- name: ARM64
triplet: arm64-windows-static
toolchain: ./cmake/llvm-win32-aarch64.cmake
vcvars: x64_arm64
exclude:
- dynarec:
new: off
target:
name: ARM64
steps:
- name: Prepare VS environment
uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{ matrix.target.vcvars }}
- name: Add LLVM to path
run: echo "C:/Program Files/LLVM/bin" >> $env:GITHUB_PATH
- name: Download Ninja
run: >
Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip -OutFile ninja-win.zip &&
Expand-Archive ninja-win.zip -DestinationPath .
- name: Setup NuGet Credentials
run: >
& (C:/vcpkg/vcpkg --vcpkg-root "${{ env.VCPKG_ROOT }}" fetch nuget | tail -n 2)
sources add
-source "https://nuget.pkg.github.com/86Box/index.json"
-storepasswordincleartext
-name "GitHub"
-username "86Box"
-password "${{ secrets.GITHUB_TOKEN }}"
- name: Fix MSVC atomic headers
run: dir "C:/Program Files/Microsoft Visual Studio/2022/*/VC/Tools/MSVC/*/include" -include stdatomic.h -recurse | del
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }} -D QT=${{ matrix.ui.qt }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }}
-D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }}
-D VCPKG_HOST_TRIPLET=x64-windows
-D VCPKG_USE_HOST_TOOLS=ON
- name: Fix Qt
if: matrix.ui.qt == 'on'
run: |
$qtTargetsPath = "${{ github.workspace }}/build/vcpkg_installed/${{ matrix.target.triplet }}/share/Qt6/Qt6Targets.cmake"
(Get-Content $qtTargetsPath) -replace "^.*-Zc:__cplusplus;-permissive-.*$","#$&" | Set-Content $qtTargetsPath
- name: Reconfigure CMake
if: matrix.ui.qt == 'on'
run: |
cmake clean build
- name: Build
run: |
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: |
cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}'
path: build/artifacts/**

View File

@@ -0,0 +1,149 @@
name: CMake (Windows, msys2)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/cmake.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
msys2:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
runs-on: windows-2022
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: true
matrix:
build:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Win32 GUI
qt: off
static: on
- name: Qt GUI
qt: on
static: on
slug: -Qt
packages: >-
qt5-static:p
# qt5-base:p
# qt5-tools:p
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
- msystem: MINGW32
prefix: mingw-w64-i686
toolchain: ./cmake/flags-gcc-i686.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG32
# prefix: mingw-w64-clang-i686
# toolchain: ./cmake/llvm-win32-i686.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake
- msystem: UCRT64
prefix: mingw-w64-ucrt-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
steps:
- name: Prepare MSYS2 environment
uses: msys2/setup-msys2@v2
with:
release: false
update: true
msystem: ${{ matrix.environment.msystem }}
pacboy: >-
ninja:p
cmake:p
gcc:p
pkgconf:p
freetype:p
SDL2:p
zlib:p
libpng:p
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Install sonar-scanner and build-wrapper
uses: SonarSource/sonarcloud-github-c-cpp@v2
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ${{ matrix.environment.toolchain }}
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D STATIC_BUILD=${{ matrix.ui.static }}
- name: Build
run: |
.sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
- name: Run sonar-scanner
if: 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
.sonar/sonar-scanner-5.0.1.3006-windows/bin/sonar-scanner.bat --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
- name: Generate package
run: cmake --install build
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
path: build/artifacts/**

View File

@@ -1,303 +0,0 @@
name: CodeQL
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
analyze-msys2:
name: "Analyze Windows MSYS2 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
runs-on: windows-2022
permissions:
actions: read
contents: read
security-events: write
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: true
matrix:
language: [ 'cpp' ]
build:
# - name: Regular
# preset: regular
# - name: Debug
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Win32 GUI
qt: off
static: on
- name: Qt GUI
qt: on
static: off
slug: -Qt
packages: >-
qt5-base:p
qt5-tools:p
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
- msystem: MINGW32
prefix: mingw-w64-i686
toolchain: ./cmake/flags-gcc-i686.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG32
# prefix: mingw-w64-clang-i686
# toolchain: ./cmake/llvm-win32-i686.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake
- msystem: UCRT64
prefix: mingw-w64-ucrt-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
steps:
- name: Prepare MSYS2 environment
uses: msys2/setup-msys2@v2
with:
release: false
update: true
msystem: ${{ matrix.environment.msystem }}
pacboy: >-
ninja:p
cmake:p
gcc:p
pkgconf:p
freetype:p
SDL2:p
zlib:p
libpng:p
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ${{ matrix.environment.toolchain }}
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D STATIC_BUILD=${{ matrix.ui.static }}
- name: Build
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
analyze-linux:
name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: ubuntu-22.04
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: true
matrix:
language: [ 'cpp' ]
build:
# - name: Regular
# preset: regular
# - name: Debug
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qtbase5-dev
qtbase5-private-dev
qttools5-dev
libevdev-dev
libxkbcommon-x11-dev
steps:
- name: Install dependencies
run: >-
sudo apt update && sudo apt install
build-essential
ninja-build
libfreetype-dev
libsdl2-dev
libpng-dev
libc6-dev
librtmidi-dev
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvncserver-dev
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
- name: Build
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
analyze-macos11:
name: "Analyze macOS 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: macos-11
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: true
matrix:
language: [ 'cpp' ]
build:
# - name: Regular
# preset: regular
# - name: Debug
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qt@5
steps:
- name: Install dependencies
run: >-
brew install
ninja
freetype
sdl2
libpng
rtmidi
openal-soft
fluidsynth
libvncserver
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D Qt5_ROOT=$(brew --prefix qt@5)
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
-D OpenAL_ROOT=$(brew --prefix openal-soft)
- name: Build
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

112
.github/workflows/codeql_linux.yml vendored Normal file
View File

@@ -0,0 +1,112 @@
name: CodeQL Analysis (Linux)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
analyze-linux:
name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
runs-on: ubuntu-22.04
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: true
matrix:
language: [ 'cpp' ]
build:
# - name: Regular
# preset: regular
# - name: Debug
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: SDL GUI
qt: off
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qtbase5-dev
qtbase5-private-dev
qttools5-dev
libevdev-dev
libxkbcommon-x11-dev
steps:
- name: Install dependencies
run: >-
sudo apt update && sudo apt install
build-essential
ninja-build
libfreetype-dev
libsdl2-dev
libpng-dev
libc6-dev
librtmidi-dev
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvncserver-dev
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
- name: Build
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

108
.github/workflows/codeql_macos.yml vendored Normal file
View File

@@ -0,0 +1,108 @@
name: CodeQL Analysis (macos)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
analyze-macos12:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
runs-on: macos-12
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: true
matrix:
language: [ 'cpp' ]
build:
# - name: Regular
# preset: regular
# - name: Debug
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: SDL GUI
qt: off
- name: Qt GUI
qt: on
slug: -Qt
packages: >-
qt@5
steps:
- name: Install dependencies
run: >-
brew install
ninja
freetype
sdl2
libpng
rtmidi
openal-soft
fluidsynth
libvncserver
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ./cmake/flags-gcc-x86_64.cmake
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D Qt5_ROOT=$(brew --prefix qt@5)
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
-D OpenAL_ROOT=$(brew --prefix openal-soft)
- name: Build
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@@ -0,0 +1,141 @@
name: CodeQL Analysis (Windows, msys2)
on:
push:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
pull_request:
paths:
- src/**
- cmake/**
- "**/CMakeLists.txt"
- "CMakePresets.json"
- .github/workflows/**
- .github/workflows/codeql.yml
- vcpkg.json
- "!**/Makefile*"
jobs:
analyze-msys2:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
runs-on: windows-2022
permissions:
actions: read
contents: read
security-events: write
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: true
matrix:
language: [ 'cpp' ]
build:
# - name: Regular
# preset: regular
# - name: Debug
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
slug: -Dev
dynarec:
- name: ODR
new: off
slug: -ODR
- name: NDR
new: on
slug: -NDR
ui:
- name: Win32 GUI
qt: off
static: on
- name: Qt GUI
qt: on
static: off
slug: -Qt
packages: >-
qt5-base:p
qt5-tools:p
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
- msystem: MINGW32
prefix: mingw-w64-i686
toolchain: ./cmake/flags-gcc-i686.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG32
# prefix: mingw-w64-clang-i686
# toolchain: ./cmake/llvm-win32-i686.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake
- msystem: UCRT64
prefix: mingw-w64-ucrt-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
steps:
- name: Prepare MSYS2 environment
uses: msys2/setup-msys2@v2
with:
release: false
update: true
msystem: ${{ matrix.environment.msystem }}
pacboy: >-
ninja:p
cmake:p
gcc:p
pkgconf:p
freetype:p
SDL2:p
zlib:p
libpng:p
openal:p
rtmidi:p
libslirp:p
fluidsynth:p
libvncserver:p
${{ matrix.ui.packages }}
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml
- name: Configure CMake
run: >-
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
--toolchain ${{ matrix.environment.toolchain }}
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
-D CMAKE_INSTALL_PREFIX=./build/artifacts
-D QT=${{ matrix.ui.qt }}
-D STATIC_BUILD=${{ matrix.ui.static }}
- name: Build
run: cmake --build build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@@ -35,7 +35,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
VERSION 4.0
VERSION 4.1
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)
@@ -153,7 +153,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage"
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF)
@@ -197,7 +196,7 @@ if(NOT EMU_BUILD_NUM)
set(EMU_BUILD_NUM 0)
endif()
if(NOT EMU_COPYRIGHT_YEAR)
set(EMU_COPYRIGHT_YEAR 2022)
set(EMU_COPYRIGHT_YEAR 2024)
endif()
add_subdirectory(src)

View File

@@ -2,6 +2,7 @@
=====
[![Build Status](https://ci.86box.net/job/86Box/badge/icon)](https://ci.86box.net/job/86Box/)
[![License](https://img.shields.io/github/license/86Box/86Box)](COPYING) [![Latest release](https://img.shields.io/github/release/86Box/86Box.svg)](https://github.com/86Box/86Box/releases) [![Downloads](https://img.shields.io/github/downloads/86Box/86Box/total.svg)](https://github.com/86Box/86Box/releases)
**86Box** is a low level x86 emulator that runs older operating systems and software designed for IBM PC systems and compatibles from 1981 through fairly recent system designs based on the PCI bus.
@@ -30,8 +31,6 @@ Performance may vary depending on both host and guest configuration. Most emulat
It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines.
* [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only)
* [86Box Manager Lite](https://github.com/insanemal/86box_manager_py) by [Insanemal](https://github.com/insanemal)
* [WinBox for 86Box](https://github.com/86Box/WinBox-for-86Box) by Laci bá' (Windows only)
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested)
* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only)
@@ -67,7 +66,7 @@ Donations
---------
We do not charge you for the emulator but donations are still welcome:
https://paypal.me/86Box.
<https://paypal.me/86Box>.
You can also support the project on Patreon:
https://www.patreon.com/86box.
<https://www.patreon.com/86box>.

View File

@@ -14,7 +14,7 @@
# Copyright 2021 David Hrdlička.
#
string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard")
string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard")
string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard")
string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard")
include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake)

4
debian/changelog vendored
View File

@@ -1,5 +1,5 @@
86box (4.0) UNRELEASED; urgency=medium
86box (4.1) UNRELEASED; urgency=medium
* Bump release.
-- Jasmine Iwanek <jriwanek@gmail.com> Tue, 28 Feb 2023 00:02:16 -0500
-- Jasmine Iwanek <jriwanek@gmail.com> Mon, 16 Oct 2023 20:24:46 +0200

11
debian/control vendored
View File

@@ -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
View File

@@ -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
View File

@@ -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:

View File

@@ -1 +1 @@
3.0 (quilt)
3.0 (native)

View 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.

View File

@@ -65,6 +65,7 @@
#include <86box/machine.h>
#include <86box/bugger.h>
#include <86box/postcard.h>
#include <86box/unittester.h>
#include <86box/isamem.h>
#include <86box/isartc.h>
#include <86box/lpt.h>
@@ -111,7 +112,7 @@
/* Stuff that used to be globally declared in plat.h but is now extern there
and declared here instead. */
int dopause; /* system is paused */
int dopause = 1; /* system is paused */
atomic_flag doresize; /* screen resize requested */
volatile int is_quit; /* system exit requested */
uint64_t timer_freq;
@@ -123,7 +124,6 @@ int tracing_on = 0;
/* Commandline options. */
int dump_on_exit = 0; /* (O) dump regs on exit */
int do_dump_config = 0; /* (O) dump config on load */
int start_in_fullscreen = 0; /* (O) start in fullscreen */
#ifdef _WIN32
int force_debug = 0; /* (O) force debug output */
@@ -141,10 +141,15 @@ char rom_path[1024] = { '\0' }; /* (O) full path to ROMs */
rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */
char log_path[1024] = { '\0' }; /* (O) full path of logfile */
char vm_name[1024] = { '\0' }; /* (O) display name of the VM */
int do_nothing = 0;
int dump_missing = 0;
int clear_cmos = 0;
#ifdef USE_INSTRUMENT
uint8_t instru_enabled = 0;
uint64_t instru_run_ms = 0;
uint8_t instru_enabled = 0;
uint64_t instru_run_ms = 0;
#endif
int clear_flash = 0;
int auto_paused = 0;
/* Configuration values. */
int window_remember;
@@ -152,7 +157,8 @@ int vid_resize; /* (C) allow r
int invert_display = 0; /* (C) invert the display */
int suppress_overscan = 0; /* (C) suppress overscans */
int scale = 0; /* (C) screen scale factor */
int dpi_scale = 0; /* (C) DPI scaling of the emulated screen */
int dpi_scale = 0; /* (C) DPI scaling of the emulated
screen */
int vid_api = 0; /* (C) video renderer */
int vid_cga_contrast = 0; /* (C) video */
int video_fullscreen = 0; /* (C) video */
@@ -164,18 +170,21 @@ int video_filter_method = 1; /* (C) video *
int video_vsync = 0; /* (C) video */
int video_framerate = -1; /* (C) video */
char video_shader[512] = { '\0' }; /* (C) video */
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of pass-through for serial ports */
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of
pass-through for serial ports */
int bugger_enabled = 0; /* (C) enable ISAbugger */
int postcard_enabled = 0; /* (C) enable POST card */
int unittester_enabled = 0; /* (C) enable unit tester device */
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
int isartc_type = 0; /* (C) enable ISA RTC card */
int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
int voodoo_enabled = 0; /* (C) video option */
int ibm8514_enabled = 0; /* (C) video option */
int xga_enabled = 0; /* (C) video option */
uint32_t mem_size = 0; /* (C) memory size (Installed on system board)*/
int ibm8514_standalone_enabled = 0; /* (C) video option */
int xga_standalone_enabled = 0; /* (C) video option */
uint32_t mem_size = 0; /* (C) memory size (Installed on
system board)*/
uint32_t isa_mem_size = 0; /* (C) memory size (ISA Memory Cards) */
int cpu_use_dynarec = 0; /* (C) cpu uses/needs Dyna */
int cpu = 0; /* (C) cpu type */
@@ -188,8 +197,12 @@ int confirm_save = 1; /* (C) enable
int enable_discord = 0; /* (C) enable Discord integration */
int pit_mode = -1; /* (C) force setting PIT mode */
int fm_driver = 0; /* (C) select FM sound driver */
int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */
int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */
int open_dir_usr_path = 0; /* (C) default file open dialog directory
of usr_path */
int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings
also apply when maximized. */
int do_auto_pause = 0; /* (C) Auto-pause the emulator on focus
loss */
/* Statistics. */
extern int mmuflush;
@@ -225,6 +238,9 @@ int efscrnsz_y = SCREEN_RES_Y;
static wchar_t mouse_msg[3][200];
static volatile atomic_int do_pause_ack = 0;
static volatile atomic_int pause_ack = 0;
#ifndef RELEASE_BUILD
static char buff[1024];
static int seen = 0;
@@ -398,6 +414,31 @@ pc_log(const char *fmt, ...)
# define pc_log(fmt, ...)
#endif
static void
delete_nvr_file(uint8_t flash)
{
char *fn = NULL;
int c;
/* Set up the NVR file's name. */
c = strlen(machine_get_internal_name()) + 5;
fn = (char *) malloc(c + 1);
if (fn == NULL)
fatal("Error allocating memory for the removal of the %s file\n",
flash ? "BIOS flash" : "CMOS");
if (flash)
sprintf(fn, "%s.bin", machine_get_internal_name());
else
sprintf(fn, "%s.nvr", machine_get_internal_name());
remove(nvr_path(fn));
free(fn);
fn = NULL;
}
/*
* Perform initial startup of the PC.
*
@@ -416,6 +457,7 @@ pc_init(int argc, char *argv[])
char *fn[FDD_NUM] = { NULL };
char drive = 0;
char *temp2 = NULL;
char *what;
const struct tm *info;
time_t now;
int c;
@@ -479,34 +521,40 @@ usage:
printf("\nUsage: 86box [options] [cfg-file]\n\n");
printf("Valid options are:\n\n");
printf("-? or --help - show this information\n");
printf("-C or --config path - set 'path' to be config file\n");
printf("-? or --help - show this information\n");
printf("-C or --config path - set 'path' to be config file\n");
#ifdef _WIN32
printf("-D or --debug - force debug output logging\n");
printf("-D or --debug - force debug output logging\n");
#endif
#if 0
printf("-E or --nographic - forces the old behavior\n");
printf("-E or --nographic - forces the old behavior\n");
#endif
printf("-F or --fullscreen - start in fullscreen mode\n");
printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n");
printf("-F or --fullscreen - start in fullscreen mode\n");
printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n");
#ifdef _WIN32
printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n");
printf("-H or --hwnd id,hwnd - sends back the main dialog's hwnd\n");
#endif
printf("-I or --image d:path - load 'path' as floppy image on drive d\n");
printf("-L or --logfile path - set 'path' to be the logfile\n");
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
printf("-O or --dumpcfg - dump config file after loading\n");
printf("-P or --vmpath path - set 'path' to be root for vm\n");
printf("-R or --rompath path - set 'path' to be ROM path\n");
printf("-S or --settings - show only the settings dialog\n");
printf("-V or --vmname name - overrides the name of the running VM\n");
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
printf("-I or --image d:path - load 'path' as floppy image on drive d\n");
#ifdef USE_INSTRUMENT
printf("-J or --instrument name - set 'name' to be the profiling instrument\n");
#endif
printf("-K or --keycodes codes - set 'codes' to be the uncapture combination\n");
printf("-L or --logfile path - set 'path' to be the logfile\n");
printf("-M or --missing - dump missing machines and video cards\n");
printf("-N or --noconfirm - do not ask for confirmation on quit\n");
printf("-P or --vmpath path - set 'path' to be root for vm\n");
printf("-R or --rompath path - set 'path' to be ROM path\n");
#ifndef USE_SDL_UI
printf("-S or --settings - show only the settings dialog\n");
#endif
printf("-V or --vmname name - overrides the name of the running VM\n");
printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n");
printf("-Y or --donothing - do not show any UI or run the emulation\n");
printf("-Z or --lastvmpath - the last parameter is VM path rather than config\n");
printf("\nA config file can be specified. If none is, the default file will be used.\n");
return 0;
} else if (!strcasecmp(argv[c], "--lastvmpath") || !strcasecmp(argv[c], "-Z")) {
lvmp = 1;
} else if (!strcasecmp(argv[c], "--dumpcfg") || !strcasecmp(argv[c], "-O")) {
do_dump_config = 1;
#ifdef _WIN32
} else if (!strcasecmp(argv[c], "--debug") || !strcasecmp(argv[c], "-D")) {
force_debug = 1;
@@ -565,10 +613,38 @@ usage:
goto usage;
strcpy(vm_name, argv[++c]);
#ifndef USE_SDL_UI
} else if (!strcasecmp(argv[c], "--settings") || !strcasecmp(argv[c], "-S")) {
settings_only = 1;
#endif
} else if (!strcasecmp(argv[c], "--noconfirm") || !strcasecmp(argv[c], "-N")) {
confirm_exit_cmdl = 0;
} else if (!strcasecmp(argv[c], "--missing") || !strcasecmp(argv[c], "-M")) {
dump_missing = 1;
} else if (!strcasecmp(argv[c], "--donothing") || !strcasecmp(argv[c], "-Y")) {
do_nothing = 1;
} else if (!strcasecmp(argv[c], "--keycodes") || !strcasecmp(argv[c], "-K")) {
if ((c + 1) == argc)
goto usage;
sscanf(argv[++c], "%03hX,%03hX,%03hX,%03hX,%03hX,%03hX",
&key_prefix_1_1, &key_prefix_1_2, &key_prefix_2_1, &key_prefix_2_2,
&key_uncapture_1, &key_uncapture_2);
} else if (!strcasecmp(argv[c], "--clearboth") || !strcasecmp(argv[c], "-X")) {
if ((c + 1) == argc)
goto usage;
what = argv[++c];
if (!strcasecmp(what, "cmos"))
clear_cmos = 1;
else if (!strcasecmp(what, "flash"))
clear_flash = 1;
else if (!strcasecmp(what, "both")) {
clear_cmos = 1;
clear_flash = 1;
} else
goto usage;
#ifdef _WIN32
} else if (!strcasecmp(argv[c], "--hwnd") || !strcasecmp(argv[c], "-H")) {
@@ -578,9 +654,8 @@ usage:
uid = (uint32_t *) &unique_id;
shwnd = (uint32_t *) &source_hwnd;
sscanf(argv[++c], "%08X%08X,%08X%08X", uid + 1, uid, shwnd + 1, shwnd);
} else if (!strcasecmp(argv[c], "--lang") || !strcasecmp(argv[c], "-G")) {
#endif
} else if (!strcasecmp(argv[c], "--lang") || !strcasecmp(argv[c], "-G")) {
// This function is currently unimplemented for *nix but has placeholders.
lang_init = plat_language_code(argv[++c]);
@@ -590,13 +665,13 @@ usage:
// The return value of 0 only means that the code is invalid,
// not related to that translation is exists or not for the
// selected language.
} else if (!strcasecmp(argv[c], "--test")) {
} else if (!strcasecmp(argv[c], "--test") || !strcasecmp(argv[c], "-T")) {
/* some (undocumented) test function here.. */
/* .. and then exit. */
return 0;
#ifdef USE_INSTRUMENT
} else if (!strcasecmp(argv[c], "--instrument")) {
} else if (!strcasecmp(argv[c], "--instrument") || !strcasecmp(argv[c], "-J")) {
if ((c + 1) == argc)
goto usage;
instru_enabled = 1;
@@ -779,6 +854,18 @@ usage:
/* Load the configuration file. */
config_load();
/* Clear the CMOS and/or BIOS flash file, if we were started with
the relevant parameter(s). */
if (clear_cmos) {
delete_nvr_file(0);
clear_cmos = 0;
}
if (clear_flash) {
delete_nvr_file(1);
clear_flash = 0;
}
for (uint8_t i = 0; i < FDD_NUM; i++) {
if (fn[i] != NULL) {
if (strlen(fn[i]) <= 511)
@@ -804,7 +891,7 @@ pc_speed_changed(void)
if (cpu_s->cpu_type >= CPU_286)
pit_set_clock(cpu_s->rspeed);
else
pit_set_clock(14318184.0);
pit_set_clock((uint32_t) 14318184.0);
}
void
@@ -826,27 +913,29 @@ pc_init_modules(void)
wchar_t temp[512];
char tempc[512];
#ifdef PRINT_MISSING_MACHINES_AND_VIDEO_CARDS
c = m = 0;
while (machine_get_internal_name_ex(c) != NULL) {
m = machine_available(c);
if (!m)
pclog("Missing machine: %s\n", machine_getname_ex(c));
c++;
}
if (dump_missing) {
dump_missing = 0;
c = m = 0;
while (video_get_internal_name(c) != NULL) {
memset(tempc, 0, sizeof(tempc));
device_get_name(video_card_getdevice(c), 0, tempc);
if ((c > 1) && !(tempc[0]))
break;
m = video_card_available(c);
if (!m)
pclog("Missing video card: %s\n", tempc);
c++;
c = m = 0;
while (machine_get_internal_name_ex(c) != NULL) {
m = machine_available(c);
if (!m)
pclog("Missing machine: %s\n", machine_getname_ex(c));
c++;
}
c = m = 0;
while (video_get_internal_name(c) != NULL) {
memset(tempc, 0, sizeof(tempc));
device_get_name(video_card_getdevice(c), 0, tempc);
if ((c > 1) && !(tempc[0]))
break;
m = video_card_available(c);
if (!m)
pclog("Missing video card: %s\n", tempc);
c++;
}
}
#endif
pc_log("Scanning for ROM images:\n");
c = m = 0;
@@ -918,11 +1007,15 @@ pc_init_modules(void)
#ifdef USE_DYNAREC
# if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(0);
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(0);
}
# endif
codegen_init();
# if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(1);
if (__builtin_available(macOS 11.0, *)) {
pthread_jit_write_protect_np(1);
}
# endif
#endif
@@ -941,6 +1034,11 @@ pc_init_modules(void)
machine_status_init();
if (do_nothing) {
do_nothing = 0;
exit(-1);
}
return 1;
}
@@ -1048,19 +1146,9 @@ pc_reset_hard_init(void)
/* Initialize the actual machine and its basic modules. */
machine_init();
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
/* Reset any ISA RTC cards. */
isartc_reset();
fdc_card_init();
fdd_reset();
/* Reset some basic devices. */
speaker_init();
shadowbios = 0;
/*
* Once the machine has been initialized, all that remains
@@ -1071,10 +1159,19 @@ pc_reset_hard_init(void)
* that will be a call to device_reset_all() later !
*/
/* Reset some basic devices. */
speaker_init();
/* Reset and reconfigure the Sound Card layer. */
sound_card_reset();
/* Initialize parallel devices. */
/* note: PLIP LPT side has to be initialized before the network side */
lpt_devices_init();
shadowbios = 0;
/* Reset and reconfigure the Network Card layer. */
network_reset();
/* Reset and reconfigure the serial ports. */
serial_standalone_init();
serial_passthrough_init();
/*
* Reset the mouse, this will attach it to any port needed.
@@ -1084,25 +1181,33 @@ pc_reset_hard_init(void)
/* Reset the Hard Disk Controller module. */
hdc_reset();
fdc_card_init();
fdd_reset();
/* Reset the CD-ROM Controller module. */
cdrom_interface_reset();
/* Reset and reconfigure the SCSI layer. */
scsi_card_init();
cdrom_hard_reset();
scsi_disk_hard_reset();
zip_hard_reset();
cdrom_hard_reset();
mo_hard_reset();
scsi_disk_hard_reset();
zip_hard_reset();
/* Reset and reconfigure the Network Card layer. */
network_reset();
/* Reset any ISA RTC cards. */
isartc_reset();
/* Initialize the Voodoo cards here inorder to minimize
the chances of the SCSI controller ending up on the bridge. */
video_voodoo_init();
if (joystick_type)
gameport_update_joystick_type();
gameport_update_joystick_type(); /* installs game port if no device provides one, must be late */
ui_sb_update_panes();
@@ -1118,6 +1223,17 @@ pc_reset_hard_init(void)
device_add(&bugger_device);
if (postcard_enabled)
device_add(&postcard_device);
if (unittester_enabled)
device_add(&unittester_device);
if (IS_ARCH(machine, MACHINE_BUS_PCI)) {
pci_register_cards();
device_reset_all(DEVICE_PCI);
}
/* Mark IDE shadow drives (slaves with a present master) as such in case
the IDE controllers present are not some form of PCI. */
ide_drives_set_shadow();
/* Reset the CPU module. */
resetx86();
@@ -1196,10 +1312,6 @@ pc_close(UNUSED(thread_t *ptr))
/* Terminate the UI thread. */
is_quit = 1;
#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC))
codegen_close();
#endif
nvr_save();
config_save();
@@ -1256,6 +1368,15 @@ _ui_window_title(void *s)
}
#endif
void
ack_pause(void)
{
if (atomic_load(&do_pause_ack)) {
atomic_store(&do_pause_ack, 0);
atomic_store(&pause_ack, 1);
}
}
void
pc_run(void)
{
@@ -1271,12 +1392,15 @@ pc_run(void)
/* Run a block of code. */
startblit();
cpu_exec(cpu_s->rspeed / 100);
cpu_exec((int32_t) cpu_s->rspeed / 100);
ack_pause();
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
// if (gdbstub_step == GDBSTUB_EXEC)
if (gdbstub_step == GDBSTUB_EXEC) {
#endif
#if 0
mouse_process();
if (!mouse_timed)
mouse_process();
#ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */
}
#endif
joystick_process();
endblit();
@@ -1289,7 +1413,7 @@ pc_run(void)
}
if (title_update) {
mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_mode >= 1)) ? 2 : !!mouse_capture;
mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture;
swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps);
#ifdef __APPLE__
/* Needed due to modifying the UI on the non-main thread is a big no-no. */
@@ -1463,3 +1587,18 @@ get_actual_size_y(void)
{
return (efscrnsz_y);
}
void
do_pause(int p)
{
int old_p = dopause;
if ((p == 1) && !old_p)
do_pause_ack = p;
dopause = !!p;
if ((p == 1) && !old_p) {
while (!atomic_load(&pause_ack))
;
}
atomic_store(&pause_ack, 0);
}

View File

@@ -20,7 +20,8 @@ endif()
add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c machine_status.c ini.c)
mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
machine_status.c ini.c)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
@@ -228,5 +229,6 @@ if (QT)
elseif(WIN32)
add_subdirectory(win)
else()
add_compile_definitions(USE_SDL_UI)
add_subdirectory(unix)
endif()

View File

@@ -46,6 +46,8 @@ int acpi_enabled = 0;
static double cpu_to_acpi;
static int acpi_power_on = 0;
#ifdef ENABLE_ACPI_LOG
int acpi_do_log = ENABLE_ACPI_LOG;
@@ -122,20 +124,20 @@ acpi_update_irq(acpi_t *dev)
if (dev->vendor == VEN_SMC)
sci_level |= (dev->regs.pmsts & BM_STS);
if (sci_level) {
if ((dev->regs.pmcntrl & 0x01) && sci_level) {
if (dev->irq_mode == 1)
pci_set_irq(dev->slot, dev->irq_pin);
pci_set_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else if (dev->irq_mode == 2)
pci_set_mirq(5, dev->mirq_is_level);
pci_set_mirq(5, dev->mirq_is_level, &dev->irq_state);
else
pci_set_mirq(0xf0 | dev->irq_line, 1);
picintlevel(1 << dev->irq_line, &dev->irq_state);
} else {
if (dev->irq_mode == 1)
pci_clear_irq(dev->slot, dev->irq_pin);
pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state);
else if (dev->irq_mode == 2)
pci_clear_mirq(5, dev->mirq_is_level);
pci_clear_mirq(5, dev->mirq_is_level, &dev->irq_state);
else
pci_clear_mirq(0xf0 | dev->irq_line, 1);
picintclevel(1 << dev->irq_line, &dev->irq_state);
}
acpi_timer_update(dev, (dev->regs.pmen & TMROF_EN) && !(dev->regs.pmsts & TMROF_STS));
@@ -656,6 +658,7 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p
acpi_t *dev = (acpi_t *) priv;
int shift16;
int sus_typ;
uint8_t old;
addr &= 0x3f;
#ifdef ENABLE_ACPI_LOG
@@ -682,6 +685,7 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p
case 0x04:
case 0x05:
/* PMCNTRL - Power Management Control Register (IO) */
old = dev->regs.pmcntrl & 0xff;
if ((addr == 0x05) && (val & 0x20)) {
sus_typ = dev->suspend_types[(val >> 2) & 7];
acpi_log("ACPI suspend type %d flags %02X\n", (val >> 2) & 7, sus_typ);
@@ -719,11 +723,14 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p
/* Since the UI doesn't have a power button at the moment, pause emulation,
then trigger a resume event so that the system resumes after unpausing. */
plat_pause(1);
plat_pause(2); /* 2 means do not wait for pause as
we're already in the CPU thread. */
timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC);
}
}
dev->regs.pmcntrl = ((dev->regs.pmcntrl & ~(0xff << shift16)) | (val << shift16)) & 0x3f07 /* 0x3c07 */;
if ((addr == 0x04) && ((old ^ val) & 0x01))
acpi_update_irq(dev);
break;
default:
@@ -787,7 +794,7 @@ acpi_reg_write_ali(int size, uint16_t addr, uint8_t val, void *priv)
dev->regs.gpcntrl = ((dev->regs.gpcntrl & ~(0xff << shift32)) | (val << shift32)) & 0x00000001;
break;
case 0x30:
/* PM2_CNTRL - Power Management 2 Control Register( */
/* PM2_CNTRL - Power Management 2 Control Register */
dev->regs.pmcntrl = val & 1;
break;
default:
@@ -1619,7 +1626,10 @@ acpi_reset(void *priv)
acpi_t *dev = (acpi_t *) priv;
memset(&dev->regs, 0x00, sizeof(acpi_regs_t));
dev->regs.gpireg[0] = 0xff;
/* PC Chips M773:
- Bit 3: 80-conductor cable on unknown IDE channel (active low)
- Bit 1: 80-conductor cable on unknown IDE channel (active low) */
dev->regs.gpireg[0] = !strcmp(machine_get_internal_name(), "m773") ? 0xf5 : 0xff;
dev->regs.gpireg[1] = 0xff;
/* A-Trend ATC7020BXII:
- Bit 3: 80-conductor cable on secondary IDE channel (active low)
@@ -1653,10 +1663,16 @@ acpi_reset(void *priv)
dev->regs.gpi_val |= 0x00000004;
}
/* Power on always generates a resume event. */
dev->regs.pmsts |= 0x8000;
if (acpi_power_on) {
/* Power on always generates a resume event. */
dev->regs.pmsts |= 0x8100;
acpi_power_on = 0;
}
acpi_rtc_status = 0;
acpi_update_irq(dev);
dev->irq_state = 0;
}
static void
@@ -1759,7 +1775,9 @@ acpi_init(const device_t *info)
acpi_reset(dev);
acpi_enabled = 1;
acpi_enabled = 1;
acpi_power_on = 1;
return dev;
}

View File

@@ -145,13 +145,11 @@ cdrom_interface_reset(void)
cdrom_interface_current);
/* If we have a valid controller, add its device. */
if (!controllers[cdrom_interface_current].device)
return;
device_add(controllers[cdrom_interface_current].device);
if ((cdrom_interface_current > 0) && controllers[cdrom_interface_current].device)
device_add(controllers[cdrom_interface_current].device);
}
char *
const char *
cdrom_interface_get_internal_name(int cdinterface)
{
return device_get_internal_name(controllers[cdinterface].device);
@@ -531,7 +529,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
f = pos & 0xff;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) /*NEC*/
msf_from_bcd(&m, &s, &f);
if (pos == 0xffffff) {
@@ -545,7 +543,7 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
f = len & 0xff;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) /*NEC*/
msf_from_bcd(&m, &s, &f);
len = MSFtoLBA(m, s, f) - 150;
@@ -571,7 +569,6 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
dev->cd_end = len;
dev->cd_status = CD_STATUS_PLAYING;
dev->cd_buflen = 0;
return 1;
}
@@ -617,13 +614,73 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit)
break;
}
/* Unlike standard commands, if there's a data track on an Audio CD (mixed mode)
the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
cdrom_stop(dev);
return 0;
}
dev->cd_buflen = 0;
dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED;
return 1;
}
uint8_t
cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit)
{
int m = 0;
int s = 0;
int f = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
f = bcd2bin((pos >> 24) & 0xff);
s = bcd2bin((pos >> 16) & 0xff);
m = bcd2bin((pos >> 8) & 0xff);
if (pos == 0xffffffff) {
pos = dev->seek_pos;
} else
pos = MSFtoLBA(m, s, f) - 150;
dev->seek_pos = pos;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
cdrom_stop(dev);
return 0;
}
dev->cd_buflen = 0;
dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED;
return 1;
}
uint8_t
cdrom_audio_play_pioneer(cdrom_t *dev, uint32_t pos)
{
int m = 0;
int s = 0;
int f = 0;
if (dev->cd_status == CD_STATUS_DATA_ONLY)
return 0;
f = bcd2bin((pos >> 24) & 0xff);
s = bcd2bin((pos >> 16) & 0xff);
m = bcd2bin((pos >> 8) & 0xff);
pos = MSFtoLBA(m, s, f) - 150;
dev->cd_end = pos;
dev->cd_buflen = 0;
dev->cd_status = CD_STATUS_PLAYING;
return 1;
}
uint8_t
cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
{
@@ -662,8 +719,13 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type)
cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status);
/* Unlike standard commands, if there's a data track on an Audio CD (mixed mode)
the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from. */
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
cdrom_stop(dev);
return 0;
}
dev->cd_buflen = 0;
dev->cd_status = CD_STATUS_PLAYING;
@@ -751,7 +813,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
ret = 0x13;
}
cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, ret, dev->seek_pos, dev->cd_end);
cdrom_log("CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, relative at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, subc.rel_m, subc.rel_s, subc.rel_f, ret, dev->seek_pos, dev->cd_end);
if (b[pos] > 1) {
cdrom_log("B[%i] = %02x, ret = %02x.\n", pos, b[pos], ret);
@@ -766,7 +828,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
b[pos] = 0;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ {
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/
m = subc.abs_m;
s = subc.abs_s;
f = subc.abs_f;
@@ -785,7 +847,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
b[pos] = 0;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) /*NEC*/ {
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/
m = subc.rel_m;
s = subc.rel_s;
f = subc.rel_f;
@@ -820,36 +882,61 @@ void
cdrom_get_current_subchannel_sony(cdrom_t *dev, uint8_t *b, int msf)
{
subchannel_t subc;
int pos = 0;
uint32_t dat;
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end);
cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x, msf = %x.\n", dev->id, subc.abs_m, subc.abs_s, subc.abs_f, dev->seek_pos, dev->cd_end, msf);
b[pos++] = subc.attr;
b[pos++] = subc.track;
b[pos++] = subc.index;
b[0] = subc.attr;
b[1] = subc.track;
b[2] = subc.index;
if (msf) {
b[pos++] = subc.rel_m;
b[pos++] = subc.rel_s;
b[pos++] = subc.rel_f;
b[pos++] = subc.abs_m;
b[pos++] = subc.abs_s;
b[pos++] = subc.abs_f;
b[3] = subc.rel_m;
b[4] = subc.rel_s;
b[5] = subc.rel_f;
b[6] = subc.abs_m;
b[7] = subc.abs_s;
b[8] = subc.abs_f;
} else {
dat = MSFtoLBA(subc.rel_m, subc.rel_s, subc.rel_f);
b[pos++] = (dat >> 16) & 0xff;
b[pos++] = (dat >> 8) & 0xff;
b[pos++] = dat & 0xff;
b[3] = (dat >> 16) & 0xff;
b[4] = (dat >> 8) & 0xff;
b[5] = dat & 0xff;
dat = MSFtoLBA(subc.abs_m, subc.abs_s, subc.abs_f) - 150;
b[pos++] = (dat >> 16) & 0xff;
b[pos++] = (dat >> 8) & 0xff;
b[pos++] = dat & 0xff;
b[6] = (dat >> 16) & 0xff;
b[7] = (dat >> 8) & 0xff;
b[8] = dat & 0xff;
}
}
uint8_t
cdrom_get_audio_status_pioneer(cdrom_t *dev, uint8_t *b)
{
uint8_t ret;
subchannel_t subc;
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
if (dev->cd_status == CD_STATUS_DATA_ONLY)
ret = 0x05;
else {
if (dev->cd_status == CD_STATUS_PLAYING)
ret = dev->sound_on ? 0x00 : 0x02;
else if (dev->cd_status == CD_STATUS_PAUSED)
ret = 0x01;
else
ret = 0x03;
}
b[0] = 0;
b[1] = bin2bcd(subc.abs_m);
b[2] = bin2bcd(subc.abs_s);
b[3] = bin2bcd(subc.abs_f);
return ret;
}
uint8_t
cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf)
@@ -887,17 +974,35 @@ cdrom_get_audio_status_sony(cdrom_t *dev, uint8_t *b, int msf)
return ret;
}
uint8_t
cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
void
cdrom_get_current_subcodeq(cdrom_t *dev, uint8_t *b)
{
uint8_t ret;
subchannel_t subc;
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
cdrom_log("Get Current Subcode-q Play Status = %02x, op = %02x.\n", dev->cd_status, dev->audio_op);
b[0] = subc.attr;
b[1] = bin2bcd(subc.track);
b[2] = bin2bcd(subc.index);
b[3] = bin2bcd(subc.rel_m);
b[4] = bin2bcd(subc.rel_s);
b[5] = bin2bcd(subc.rel_f);
b[6] = bin2bcd(subc.abs_m);
b[7] = bin2bcd(subc.abs_s);
b[8] = bin2bcd(subc.abs_f);
}
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->cd_status == CD_STATUS_PLAYING_COMPLETED))
uint8_t
cdrom_get_current_subcodeq_playstatus(cdrom_t *dev, uint8_t *b)
{
uint8_t ret;
subchannel_t subc;
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
if ((dev->cd_status == CD_STATUS_DATA_ONLY) ||
(dev->cd_status == CD_STATUS_PLAYING_COMPLETED) ||
(dev->cd_status == CD_STATUS_STOPPED))
ret = 0x03;
else
ret = (dev->cd_status == CD_STATUS_PLAYING) ? 0x00 : dev->audio_op;
@@ -957,9 +1062,7 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m
/* No suitable starting track, return with error. */
if (first_track == -1) {
#ifdef ENABLE_CDROM_LOG
cdrom_log(" [ERROR] No suitable track found\n");
#endif
return -1;
}
@@ -976,7 +1079,7 @@ read_toc_normal(cdrom_t *dev, unsigned char *b, unsigned char start_track, int m
b[len++] = 0;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/
m = ti.m;
s = ti.s;
f = ti.f;
@@ -1029,7 +1132,7 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf)
b[len++] = 0;
/* NEC CDR-260 speaks BCD. */
if (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.01") || (!strcmp(cdrom_drive_types[dev->type].internal_name, "NEC_CD-ROM_DRIVE260_1.00"))) { /*NEC*/
if ((dev->type == CDROM_TYPE_NEC_260_100) || (dev->type == CDROM_TYPE_NEC_260_101)) { /*NEC*/
m = ti.m;
s = ti.s;
f = ti.f;
@@ -1128,9 +1231,7 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf
/* No suitable starting track, return with error. */
if (first_track == -1) {
#ifdef ENABLE_CDROM_LOG
cdrom_log(" [ERROR] No suitable track found\n");
#endif
return -1;
}
@@ -1138,8 +1239,8 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf
cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f);
dev->ops->get_track_info(dev, i + 1, 0, &ti);
b[len++] = ti.attr;
b[len++] = ti.number; /* track number */
b[len++] = ti.attr;
if (msf) {
b[len++] = 0;
@@ -1154,7 +1255,6 @@ read_toc_sony(cdrom_t *dev, unsigned char *b, unsigned char start_track, int msf
b[len++] = temp;
}
}
return len;
}
@@ -1294,6 +1394,7 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in
int m = 0;
int s = 0;
int f = 0;
uint32_t temp;
dev->ops->get_tracks(dev, &first_track, &last_track);
@@ -1333,11 +1434,32 @@ cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, in
b[3] = ti.attr;
cdrom_log("CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x.\n", dev->id, b[0], b[1], b[2], bcd2bin(track), m, s, f, ti.attr);
break;
case 3:
b[0] = 0x00; /*TODO: correct it further, mark it as CD-Audio/CD-ROM disc for now*/
b[1] = 0;
b[2] = 0;
b[3] = 0;
case 3: /* Undocumented on NEC CD-ROM's, from information based on sr_vendor.c from the Linux kernel */
switch (dev->type) {
case CDROM_TYPE_NEC_25_10a:
case CDROM_TYPE_NEC_38_103:
case CDROM_TYPE_NEC_75_103:
case CDROM_TYPE_NEC_77_106:
case CDROM_TYPE_NEC_211_100:
case CDROM_TYPE_NEC_464_105:
dev->ops->get_track_info(dev, 1, 0, &ti);
b[0x0e] = 0;
temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
b[0x0f] = temp >> 24;
b[0x10] = temp >> 16;
b[0x11] = temp >> 8;
b[0x12] = temp;
break;
default:
dev->ops->get_track_info(dev, 1, 0, &ti);
b[0] = 0;
temp = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
b[1] = temp >> 24;
b[2] = temp >> 16;
b[3] = temp >> 8;
break;
}
break;
default:
break;
@@ -1868,10 +1990,8 @@ cdrom_insert(uint8_t id)
{
cdrom_t *dev = &cdrom[id];
if (dev->bus_type) {
if (dev->insert)
dev->insert(dev->priv);
}
if (dev->bus_type && dev->insert)
dev->insert(dev->priv);
}
/* The mechanics of ejecting a CD-ROM from a drive. */

View File

@@ -68,24 +68,24 @@ cdrom_image_backend_log(const char *fmt, ...)
/* Binary file functions. */
static int
bin_read(void *p, uint8_t *buffer, uint64_t seek, size_t count)
bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
{
track_file_t *tf = (track_file_t *) p;
track_file_t *tf = (track_file_t *) priv;
cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n",
tf->file, seek, count);
tf->fp, seek, count);
if (tf->file == NULL)
if (tf->fp == NULL)
return 0;
if (fseeko64(tf->file, seek, SEEK_SET) == -1) {
if (fseeko64(tf->fp, seek, SEEK_SET) == -1) {
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during seek!\n");
#endif
return 0;
}
if (fread(buffer, count, 1, tf->file) != 1) {
if (fread(buffer, count, 1, tf->fp) != 1) {
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during read!\n");
#endif
@@ -96,39 +96,39 @@ bin_read(void *p, uint8_t *buffer, uint64_t seek, size_t count)
}
static uint64_t
bin_get_length(void *p)
bin_get_length(void *priv)
{
off64_t len;
track_file_t *tf = (track_file_t *) p;
track_file_t *tf = (track_file_t *) priv;
cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->file);
cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp);
if (tf->file == NULL)
if (tf->fp == NULL)
return 0;
fseeko64(tf->file, 0, SEEK_END);
len = ftello64(tf->file);
cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->file, len);
fseeko64(tf->fp, 0, SEEK_END);
len = ftello64(tf->fp);
cdrom_image_backend_log("CDROM: binary_length(%08lx) = %" PRIu64 "\n", tf->fp, len);
return len;
}
static void
bin_close(void *p)
bin_close(void *priv)
{
track_file_t *tf = (track_file_t *) p;
track_file_t *tf = (track_file_t *) priv;
if (tf == NULL)
return;
if (tf->file != NULL) {
fclose(tf->file);
tf->file = NULL;
if (tf->fp != NULL) {
fclose(tf->fp);
tf->fp = NULL;
}
memset(tf->fn, 0x00, sizeof(tf->fn));
free(p);
free(priv);
}
static track_file_t *
@@ -144,14 +144,14 @@ bin_init(const char *filename, int *error)
memset(tf->fn, 0x00, sizeof(tf->fn));
strncpy(tf->fn, filename, sizeof(tf->fn) - 1);
tf->file = plat_fopen64(tf->fn, "rb");
cdrom_image_backend_log("CDROM: binary_open(%s) = %08lx\n", tf->fn, tf->file);
tf->fp = plat_fopen64(tf->fn, "rb");
cdrom_image_backend_log("CDROM: binary_open(%s) = %08lx\n", tf->fn, tf->fp);
if (stat(tf->fn, &stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&stats, 0, sizeof(struct stat));
}
*error = ((tf->file == NULL) || ((stats.st_mode & S_IFMT) == S_IFDIR));
*error = ((tf->fp == NULL) || ((stats.st_mode & S_IFMT) == S_IFDIR));
/* Set the function pointers. */
if (!*error) {
@@ -162,7 +162,7 @@ bin_init(const char *filename, int *error)
/* From the check above, error may still be non-zero if opening a directory.
* The error is set for viso to try and open the directory following this function.
* However, we need to make sure the descriptor is closed. */
if ((tf->file != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) {
if ((tf->fp != NULL) && ((stats.st_mode & S_IFMT) == S_IFDIR)) {
/* tf is freed by bin_close */
bin_close(tf);
} else {
@@ -203,7 +203,7 @@ static void
cdi_clear_tracks(cd_img_t *cdi)
{
const track_file_t *last = NULL;
track_t *cur = NULL;
track_t *cur = NULL;
if ((cdi->tracks == NULL) || (cdi->tracks_num == 0))
return;
@@ -332,6 +332,11 @@ cdi_get_track(cd_img_t *cdi, uint32_t sector)
for (int i = 0; i < (cdi->tracks_num - 1); i++) {
cur = &cdi->tracks[i];
next = &cdi->tracks[i + 1];
/* Take into account cue sheets that do not start on sector 0. */
if ((i == 0) && (sector < cur->start))
return cur->number;
if ((cur->start <= sector) && (sector < next->start))
return cur->number;
}
@@ -425,8 +430,9 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
return 1;
} else if (!raw && track_is_raw)
return trk->file->read(trk->file, buffer, seek + offset, length);
else
else {
return trk->file->read(trk->file, buffer, seek, length);
}
}
int
@@ -652,9 +658,7 @@ cdi_cue_get_buffer(char *str, char **line, int up)
done = 1;
break;
}
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
default:
if (up && islower((int) *s))

View File

@@ -121,8 +121,10 @@ typedef struct {
size_t metadata_sectors, all_sectors, entry_map_size, sector_size, file_fifo_pos;
uint8_t *metadata;
track_file_t tf;
viso_entry_t *root_dir, **entry_map, *file_fifo[VISO_OPEN_FILES];
track_file_t tf;
viso_entry_t *root_dir;
viso_entry_t **entry_map;
viso_entry_t *file_fifo[VISO_OPEN_FILES];
} viso_t;
static const char rr_eid[] = "RRIP_1991A"; /* identifiers used in ER field for Rock Ridge */
@@ -148,24 +150,24 @@ cdrom_image_viso_log(const char *fmt, ...)
#endif
static size_t
viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *stream)
viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
{
uint64_t cur_pos = ftello64(stream);
uint64_t cur_pos = ftello64(fp);
size_t ret = 0;
if (fseeko64(stream, offset, SEEK_SET) != -1)
ret = fread(ptr, size, count, stream);
fseeko64(stream, cur_pos, SEEK_SET);
if (fseeko64(fp, offset, SEEK_SET) != -1)
ret = fread(ptr, size, count, fp);
fseeko64(fp, cur_pos, SEEK_SET);
return ret;
}
static size_t
viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *stream)
viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
{
uint64_t cur_pos = ftello64(stream);
uint64_t cur_pos = ftello64(fp);
size_t ret = 0;
if (fseeko64(stream, offset, SEEK_SET) != -1)
ret = fwrite(ptr, size, count, stream);
fseeko64(stream, cur_pos, SEEK_SET);
if (fseeko64(fp, offset, SEEK_SET) != -1)
ret = fwrite(ptr, size, count, fp);
fseeko64(fp, cur_pos, SEEK_SET);
return ret;
}
@@ -247,17 +249,28 @@ viso_convert_utf8(wchar_t *dest, const char *src, ssize_t buf_size)
c -= 'a' - 'A'; \
break; \
\
case ' ': \
case '!': \
case '"': \
case '#': \
case '$': \
case '%': \
case '&': \
case '\'': \
case '(': \
case ')': \
case '-': \
case '@': \
case '^': \
case '`': \
case '{': \
case '}': \
case '~': \
/* Valid on all sets (non-complying DOS characters). */ \
break; \
\
case ' ': \
case '"': \
case '+': \
case ',': \
case '-': \
case '.': \
case '<': \
case '=': \
@@ -331,7 +344,7 @@ viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries
}
/* Check if this filename is unique, and add a tail if required, while also adding the extension. */
char tail[8];
char tail[16];
for (int i = force_tail; i <= 999999; i++) {
/* Add tail to the filename if this is not the first run. */
int tail_len = -1;
@@ -429,7 +442,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
or way too far into 64-bit space (Linux). Fall back to epoch. */
time_t epoch = 0;
time_s = localtime(&epoch);
if (!time_s)
if (UNLIKELY(!time_s))
fatal("VISO: localtime(0) = NULL\n");
/* Force year clamping if the timestamp is known to be outside the supported ranges. */
@@ -636,12 +649,8 @@ pad_susp:
break;
}
if ((p - data) > 255)
#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)
fatal("VISO: Directory record overflow (%d) on entry %016" PRIX64 "\n", (uint32_t) (uintptr_t) (p - data), (uint64_t) (uintptr_t) entry);
#else
fatal("VISO: Directory record overflow (%d) on entry %08X\n", (uint32_t) (uintptr_t) (p - data), (uint32_t) (uintptr_t) entry);
#endif
if (UNLIKELY((p - data) > 255))
fatal("VISO: Directory record overflow (%" PRIuPTR ") on entry %08" PRIXPTR "\n", (uintptr_t) (p - data), (uintptr_t) entry);
data[0] = p - data; /* length */
return data[0];
@@ -654,9 +663,9 @@ viso_compare_entries(const void *a, const void *b)
}
int
viso_read(void *p, uint8_t *buffer, uint64_t seek, size_t count)
viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
{
track_file_t *tf = (track_file_t *) p;
track_file_t *tf = (track_file_t *) priv;
viso_t *viso = (viso_t *) tf->priv;
/* Handle reads in a sector by sector basis. */
@@ -723,18 +732,18 @@ viso_read(void *p, uint8_t *buffer, uint64_t seek, size_t count)
}
uint64_t
viso_get_length(void *p)
viso_get_length(void *priv)
{
track_file_t *tf = (track_file_t *) p;
track_file_t *tf = (track_file_t *) priv;
const viso_t *viso = (viso_t *) tf->priv;
return ((uint64_t) viso->all_sectors) * viso->sector_size;
}
void
viso_close(void *p)
viso_close(void *priv)
{
track_file_t *tf = (track_file_t *) p;
track_file_t *tf = (track_file_t *) priv;
viso_t *viso = (viso_t *) tf->priv;
if (viso == NULL)
@@ -743,8 +752,8 @@ viso_close(void *p)
cdrom_image_viso_log("VISO: close()\n");
/* De-allocate everything. */
if (tf->file)
fclose(tf->file);
if (tf->fp)
fclose(tf->fp);
#ifndef ENABLE_CDROM_IMAGE_VISO_LOG
remove(nvr_path(viso->tf.fn));
#endif
@@ -794,8 +803,8 @@ viso_init(const char *dirname, int *error)
#else
plat_tempfile(viso->tf.fn, "viso", ".tmp");
#endif
viso->tf.file = plat_fopen64(nvr_path(viso->tf.fn), "w+b");
if (!viso->tf.file)
viso->tf.fp = plat_fopen64(nvr_path(viso->tf.fn), "w+b");
if (!viso->tf.fp)
goto end;
/* Set up directory traversal. */
@@ -993,7 +1002,7 @@ next_dir:
/* Write 16 blank sectors. */
for (int i = 0; i < 16; i++)
fwrite(data, viso->sector_size, 1, viso->tf.file);
fwrite(data, viso->sector_size, 1, viso->tf.fp);
/* Get current time for the volume descriptors, and calculate
the timezone offset for descriptors and file times to use. */
@@ -1003,7 +1012,7 @@ next_dir:
tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4);
/* Get root directory basename for the volume ID. */
char *basename = path_get_filename(viso->root_dir->path);
const char *basename = path_get_filename(viso->root_dir->path);
if (!basename || (basename[0] == '\0'))
basename = EMU_NAME;
@@ -1016,7 +1025,7 @@ next_dir:
/* Fill volume descriptor. */
p = data;
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 1 + i; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
p += 5;
@@ -1039,7 +1048,7 @@ next_dir:
VISO_SKIP(p, 8); /* unused */
viso->vol_size_offsets[i] = ftello64(viso->tf.file) + (p - data);
viso->vol_size_offsets[i] = ftello64(viso->tf.fp) + (p - data);
VISO_LBE_32(p, 0); /* volume space size (filled in later) */
if (i) {
@@ -1056,10 +1065,10 @@ next_dir:
VISO_LBE_16(p, viso->sector_size); /* logical block size */
/* Path table metadata is filled in later. */
viso->pt_meta_offsets[i] = ftello64(viso->tf.file) + (p - data);
viso->pt_meta_offsets[i] = ftello64(viso->tf.fp) + (p - data);
VISO_SKIP(p, 24 + (16 * !(viso->format & VISO_FORMAT_ISO))); /* PT size, LE PT offset, optional LE PT offset (three on HSF), BE PT offset, optional BE PT offset (three on HSF) */
viso->root_dir->dr_offsets[i] = ftello64(viso->tf.file) + (p - data);
viso->root_dir->dr_offsets[i] = ftello64(viso->tf.fp) + (p - data);
p += viso_fill_dir_record(p, viso->root_dir, viso, VISO_DIR_CURRENT); /* root directory */
int copyright_abstract_len = (viso->format & VISO_FORMAT_ISO) ? 37 : 32;
@@ -1111,7 +1120,7 @@ next_dir:
memset(p, 0x00, viso->sector_size - (p - data));
/* Write volume descriptor. */
fwrite(data, viso->sector_size, 1, viso->tf.file);
fwrite(data, viso->sector_size, 1, viso->tf.fp);
/* Write El Torito boot descriptor. This is an awkward spot for
that, but the spec requires it to be the second descriptor. */
@@ -1120,7 +1129,7 @@ next_dir:
p = data;
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
p += 5;
@@ -1131,20 +1140,20 @@ next_dir:
VISO_SKIP(p, 40);
/* Save the boot catalog pointer's offset for later. */
eltorito_offset = ftello64(viso->tf.file) + (p - data);
eltorito_offset = ftello64(viso->tf.fp) + (p - data);
/* Blank the rest of the working sector. */
memset(p, 0x00, viso->sector_size - (p - data));
/* Write boot descriptor. */
fwrite(data, viso->sector_size, 1, viso->tf.file);
fwrite(data, viso->sector_size, 1, viso->tf.fp);
}
}
/* Fill terminator. */
p = data;
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0xff; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
p += 5;
@@ -1154,22 +1163,22 @@ next_dir:
memset(p, 0x00, viso->sector_size - (p - data));
/* Write terminator. */
fwrite(data, viso->sector_size, 1, viso->tf.file);
fwrite(data, viso->sector_size, 1, viso->tf.fp);
/* We start seeing a pattern of padding to even sectors here.
mkisofs does this, presumably for a very good reason... */
int write = ftello64(viso->tf.file) % (viso->sector_size * 2);
int write = ftello64(viso->tf.fp) % (viso->sector_size * 2);
if (write) {
write = (viso->sector_size * 2) - write;
memset(data, 0x00, write);
fwrite(data, write, 1, viso->tf.file);
fwrite(data, write, 1, viso->tf.fp);
}
/* Handle El Torito boot catalog. */
if (eltorito_entry) {
/* Write a pointer to this boot catalog to the boot descriptor. */
*((uint32_t *) data) = cpu_to_le32(ftello64(viso->tf.file) / viso->sector_size);
viso_pwrite(data, eltorito_offset, 4, 1, viso->tf.file);
*((uint32_t *) data) = cpu_to_le32(ftello64(viso->tf.fp) / viso->sector_size);
viso_pwrite(data, eltorito_offset, 4, 1, viso->tf.fp);
/* Fill boot catalog validation entry. */
p = data;
@@ -1199,21 +1208,21 @@ next_dir:
*p++ = 0x00; /* reserved */
/* Save offsets to the boot catalog entry's offset and size fields for later. */
eltorito_offset = ftello64(viso->tf.file) + (p - data);
eltorito_offset = ftello64(viso->tf.fp) + (p - data);
/* Blank the rest of the working sector. This includes the sector count,
ISO sector offset and 20-byte selection criteria fields at the end. */
memset(p, 0x00, viso->sector_size - (p - data));
/* Write boot catalog. */
fwrite(data, viso->sector_size, 1, viso->tf.file);
fwrite(data, viso->sector_size, 1, viso->tf.fp);
/* Pad to the next even sector. */
write = ftello64(viso->tf.file) % (viso->sector_size * 2);
write = ftello64(viso->tf.fp) % (viso->sector_size * 2);
if (write) {
write = (viso->sector_size * 2) - write;
memset(data, 0x00, write);
fwrite(data, write, 1, viso->tf.file);
fwrite(data, write, 1, viso->tf.fp);
}
/* Flag that we shouldn't hide the boot code directory if it contains other files. */
@@ -1226,12 +1235,12 @@ next_dir:
cdrom_image_viso_log("VISO: Generating path table #%d:\n", i);
/* Save this path table's start offset. */
uint64_t pt_start = ftello64(viso->tf.file);
uint64_t pt_start = ftello64(viso->tf.fp);
/* Write this table's sector offset to the corresponding volume descriptor. */
uint32_t pt_temp = pt_start / viso->sector_size;
*((uint32_t *) data) = (i & 1) ? cpu_to_be32(pt_temp) : cpu_to_le32(pt_temp);
viso_pwrite(data, viso->pt_meta_offsets[i >> 1] + 8 + (8 * (i & 1)), 4, 1, viso->tf.file);
viso_pwrite(data, viso->pt_meta_offsets[i >> 1] + 8 + (8 * (i & 1)), 4, 1, viso->tf.fp);
/* Go through directories. */
dir = viso->root_dir;
@@ -1248,7 +1257,7 @@ next_dir:
/* Save this directory's path table index and offset. */
dir->pt_idx = pt_idx;
dir->pt_offsets[i] = ftello64(viso->tf.file);
dir->pt_offsets[i] = ftello64(viso->tf.fp);
/* Fill path table entry. */
p = data;
@@ -1284,7 +1293,7 @@ next_dir:
*p++ = 0x00;
/* Write path table entry. */
fwrite(data, p - data, 1, viso->tf.file);
fwrite(data, p - data, 1, viso->tf.fp);
/* Increment path table index and stop if it overflows. */
if (++pt_idx == 0)
@@ -1295,17 +1304,17 @@ next_dir:
}
/* Write this table's size to the corresponding volume descriptor. */
pt_temp = ftello64(viso->tf.file) - pt_start;
pt_temp = ftello64(viso->tf.fp) - pt_start;
p = data;
VISO_LBE_32(p, pt_temp);
viso_pwrite(data, viso->pt_meta_offsets[i >> 1], 8, 1, viso->tf.file);
viso_pwrite(data, viso->pt_meta_offsets[i >> 1], 8, 1, viso->tf.fp);
/* Pad to the next even sector. */
write = ftello64(viso->tf.file) % (viso->sector_size * 2);
write = ftello64(viso->tf.fp) % (viso->sector_size * 2);
if (write) {
write = (viso->sector_size * 2) - write;
memset(data, 0x00, write);
fwrite(data, write, 1, viso->tf.file);
fwrite(data, write, 1, viso->tf.fp);
}
}
@@ -1324,25 +1333,25 @@ next_dir:
}
/* Pad to the next sector if required. */
write = ftello64(viso->tf.file) % viso->sector_size;
write = ftello64(viso->tf.fp) % viso->sector_size;
if (write) {
write = viso->sector_size - write;
memset(data, 0x00, write);
fwrite(data, write, 1, viso->tf.file);
fwrite(data, write, 1, viso->tf.fp);
}
/* Save this directory's child record array's start offset. */
uint64_t dir_start = ftello64(viso->tf.file);
uint64_t dir_start = ftello64(viso->tf.fp);
/* Write this directory's child record array's sector offset to its record... */
uint32_t dir_temp = dir_start / viso->sector_size;
p = data;
VISO_LBE_32(p, dir_temp);
viso_pwrite(data, dir->dr_offsets[i] + 2, 8, 1, viso->tf.file);
viso_pwrite(data, dir->dr_offsets[i] + 2, 8, 1, viso->tf.fp);
/* ...and to its path table entries. */
viso_pwrite(data, dir->pt_offsets[i << 1], 4, 1, viso->tf.file); /* little endian */
viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1], 4, 1, viso->tf.file); /* big endian */
viso_pwrite(data, dir->pt_offsets[i << 1], 4, 1, viso->tf.fp); /* little endian */
viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1], 4, 1, viso->tf.fp); /* big endian */
if (i == max_vd) /* overwrite pt_offsets in the union if we no longer need them */
dir->file = NULL;
@@ -1362,15 +1371,15 @@ next_dir:
viso_fill_dir_record(data, entry, viso, dir_type);
/* Entries cannot cross sector boundaries, so pad to the next sector if needed. */
write = viso->sector_size - (ftello64(viso->tf.file) % viso->sector_size);
write = viso->sector_size - (ftello64(viso->tf.fp) % viso->sector_size);
if (write < data[0]) {
p = data + (viso->sector_size * 2) - write;
memset(p, 0x00, write);
fwrite(p, write, 1, viso->tf.file);
fwrite(p, write, 1, viso->tf.fp);
}
/* Save this entry's record's offset. This overwrites name_short in the union. */
entry->dr_offsets[i] = ftello64(viso->tf.file);
entry->dr_offsets[i] = ftello64(viso->tf.fp);
/* Write data related to the . and .. pseudo-subdirectories,
while advancing the current directory type. */
@@ -1383,13 +1392,13 @@ next_dir:
} else if (dir_type == VISO_DIR_PARENT) {
/* Copy the parent directory's offset and size. The root directory's
parent size is a special, self-referential case handled later. */
viso_pread(data + 2, dir->parent->dr_offsets[i] + 2, 16, 1, viso->tf.file);
viso_pread(data + 2, dir->parent->dr_offsets[i] + 2, 16, 1, viso->tf.fp);
dir_type = i ? VISO_DIR_JOLIET : VISO_DIR_REGULAR;
}
/* Write entry. */
fwrite(data, data[0], 1, viso->tf.file);
fwrite(data, data[0], 1, viso->tf.fp);
next_entry:
/* Move on to the next entry, and stop if the end of this directory was reached. */
entry = entry->next;
@@ -1398,13 +1407,13 @@ next_entry:
}
/* Write this directory's child record array's size to its parent and . records. */
dir_temp = ftello64(viso->tf.file) - dir_start;
dir_temp = ftello64(viso->tf.fp) - dir_start;
p = data;
VISO_LBE_32(p, dir_temp);
viso_pwrite(data, dir->dr_offsets[i] + 10, 8, 1, viso->tf.file);
viso_pwrite(data, dir->first_child->dr_offsets[i] + 10, 8, 1, viso->tf.file);
viso_pwrite(data, dir->dr_offsets[i] + 10, 8, 1, viso->tf.fp);
viso_pwrite(data, dir->first_child->dr_offsets[i] + 10, 8, 1, viso->tf.fp);
if (dir->parent == dir) /* write size to .. on root directory as well */
viso_pwrite(data, dir->first_child->next->dr_offsets[i] + 10, 8, 1, viso->tf.file);
viso_pwrite(data, dir->first_child->next->dr_offsets[i] + 10, 8, 1, viso->tf.fp);
/* Move on to the next directory. */
dir_type = VISO_DIR_CURRENT;
@@ -1412,11 +1421,11 @@ next_entry:
}
/* Pad to the next even sector. */
write = ftello64(viso->tf.file) % (viso->sector_size * 2);
write = ftello64(viso->tf.fp) % (viso->sector_size * 2);
if (write) {
write = (viso->sector_size * 2) - write;
memset(data, 0x00, write);
fwrite(data, write, 1, viso->tf.file);
fwrite(data, write, 1, viso->tf.fp);
}
}
@@ -1454,13 +1463,13 @@ next_entry:
goto end;
/* Pad metadata to the new size's next sector. */
while (ftello64(viso->tf.file) % viso->sector_size)
fwrite(data, orig_sector_size, 1, viso->tf.file);
while (ftello64(viso->tf.fp) % viso->sector_size)
fwrite(data, orig_sector_size, 1, viso->tf.fp);
}
}
/* Start sector counts. */
viso->metadata_sectors = ftello64(viso->tf.file) / viso->sector_size;
viso->metadata_sectors = ftello64(viso->tf.fp) / viso->sector_size;
viso->all_sectors = viso->metadata_sectors;
/* Go through files, assigning sectors to them. */
@@ -1494,12 +1503,12 @@ next_entry:
*((uint16_t *) &data[0]) = cpu_to_le16(1);
}
*((uint32_t *) &data[2]) = cpu_to_le32(viso->all_sectors * base_factor);
viso_pwrite(data, eltorito_offset, 6, 1, viso->tf.file);
viso_pwrite(data, eltorito_offset, 6, 1, viso->tf.fp);
} else {
p = data;
VISO_LBE_32(p, viso->all_sectors * base_factor);
for (int i = 0; i <= max_vd; i++)
viso_pwrite(data, entry->dr_offsets[i] + 2, 8, 1, viso->tf.file);
viso_pwrite(data, entry->dr_offsets[i] + 2, 8, 1, viso->tf.fp);
}
/* Save this file's base offset. This overwrites dr_offsets in the union. */
@@ -1525,22 +1534,22 @@ next_entry:
p = data;
VISO_LBE_32(p, viso->all_sectors);
for (int i = 0; i < (sizeof(viso->vol_size_offsets) / sizeof(viso->vol_size_offsets[0])); i++)
viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.file);
viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp);
/* Metadata processing is finished, read it back to memory. */
cdrom_image_viso_log("VISO: Reading back %d %d-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size);
if (!viso->metadata)
goto end;
fseeko64(viso->tf.file, 0, SEEK_SET);
fseeko64(viso->tf.fp, 0, SEEK_SET);
uint64_t metadata_size = viso->metadata_sectors * viso->sector_size;
uint64_t metadata_remain = metadata_size;
while (metadata_remain > 0)
metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.file);
metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.fp);
/* We no longer need the temporary file; close and delete it. */
fclose(viso->tf.file);
viso->tf.file = NULL;
fclose(viso->tf.fp);
viso->tf.fp = NULL;
#ifndef ENABLE_CDROM_IMAGE_VISO_LOG
remove(nvr_path(viso->tf.fn));
#endif

View File

@@ -33,6 +33,10 @@
#include <86box/plat.h>
#include <86box/sound.h>
#define MCD_DEFAULT_IOPORT 0x310
#define MCD_DEFAULT_IRQ 5
#define MCD_DEFAULT_DMA 5
#define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048
@@ -86,8 +90,9 @@ enum {
IRQ_ERROR = 4
};
typedef struct {
int dma, irq;
typedef struct mcd_t {
int dma;
int irq;
int change;
int data;
uint8_t stat;
@@ -244,6 +249,8 @@ mitsumi_cdrom_in(uint16_t port, void *priv)
ret |= FLAG_NOSTAT;
pclog("Read port 1: ret = %02x\n", ret | FLAG_UNK);
return ret | FLAG_UNK;
case 2:
break;
default:
break;
}
@@ -324,9 +331,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
break;
case 5:
dev->readmsf = 0;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 4:
case 3:
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);
@@ -396,10 +401,10 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
}
break;
case CMD_GET_VER:
dev->cmdbuf[1] = 1;
dev->cmdbuf[2] = 'D';
dev->cmdbuf[3] = 0;
dev->cmdbuf_count = 4;
dev->cmdbuf[0] = 1;
dev->cmdbuf[1] = 'D';
dev->cmdbuf[2] = 0;
dev->cmdbuf_count = 3;
break;
case CMD_EJECT:
cdrom_stop(&cdrom);
@@ -421,6 +426,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
case 1:
mitsumi_cdrom_reset(dev);
break;
case 2:
break;
default:
break;
}
@@ -434,10 +441,10 @@ mitsumi_cdrom_init(UNUSED(const device_t *info))
dev = malloc(sizeof(mcd_t));
memset(dev, 0x00, sizeof(mcd_t));
dev->irq = 5;
dev->dma = 5;
dev->irq = MCD_DEFAULT_IRQ;
dev->dma = MCD_DEFAULT_DMA;
io_sethandler(0x310, 2,
io_sethandler(MCD_DEFAULT_IOPORT, 3,
mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev);
mitsumi_cdrom_reset(dev);

View File

@@ -13,13 +13,14 @@
# Copyright 2020-2021 David Hrdlička.
#
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c ali1531.c ali1541.c ali1543.c
ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c
intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c
opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c
sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c
via_pipc.c vl82c480.c wd76c10.c)
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c headland.c ims8848.c intel_82335.c
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c
sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c
umc_hb4.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
if(OLIVETTI)
target_sources(chipset PRIVATE olivetti_eva.c)

View File

@@ -46,11 +46,12 @@
typedef struct ali_1435_t {
uint8_t index;
uint8_t cfg_locked;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[16];
uint8_t pci_regs[256];
} ali1435_t;
#define ENABLE_ALI1435_LOG 1
#ifdef ENABLE_ALI1435_LOG
int ali1435_do_log = ENABLE_ALI1435_LOG;
@@ -190,24 +191,20 @@ ali1435_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x23:
#if 0
#ifdef ENABLE_ALI1435_LOG
if (dev->index != 0x03)
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
#endif
if (dev->index == 0x03)
dev->cfg_locked = (val != 0x69);
#ifdef ENABLE_ALI1435_LOG
else
ali1435_log("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
#endif
if (!dev->cfg_locked) {
pclog("M1435: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
/* PCI Mechanism select? */
case 0x00:
dev->regs[dev->index] = val;
pclog("PMC = %i\n", val != 0xc8);
pci_set_pmc(val != 0xc8);
ali1435_log("PMC = %i\n", val != 0xc8);
pci_key_write(((val & 0xc8) == 0xc8) ? 0xf0 : 0x00);
break;
/* ???? */
@@ -253,8 +250,6 @@ ali1435_reset(void *priv)
dev->regs[0x00] = 0xff;
pci_set_pmc(0);
dev->cfg_locked = 1;
memset(dev->pci_regs, 0, 256);
@@ -298,17 +293,10 @@ ali1435_init(UNUSED(const device_t *info))
*/
io_sethandler(0x0022, 0x0002, ali1435_read, NULL, NULL, ali1435_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1435_pci_read, ali1435_pci_write, dev, &dev->pci_slot);
ali1435_reset(dev);
#if 0
pci_set_irq_level(PCI_INTA, 0);
pci_set_irq_level(PCI_INTB, 0);
pci_set_irq_level(PCI_INTC, 0);
pci_set_irq_level(PCI_INTD, 0);
#endif
return dev;
}

View File

@@ -41,7 +41,8 @@
#include <86box/chipset.h>
#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | \
((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY))
#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY)
#ifdef ENABLE_ALI1489_LOG
@@ -64,19 +65,14 @@ ali1489_log(const char *fmt, ...)
typedef struct ali1489_t {
uint8_t index;
uint8_t ide_index;
uint8_t ide_chip_id;
uint8_t pci_slot;
uint8_t regs[256];
uint8_t pci_conf[256];
uint8_t ide_regs[256];
port_92_t *port_92;
smram_t *smram;
} ali1489_t;
static void ali1489_ide_handler(ali1489_t *dev);
static void
ali1489_shadow_recalc(ali1489_t *dev)
{
@@ -85,7 +81,8 @@ ali1489_shadow_recalc(ali1489_t *dev)
for (uint8_t i = 0; i < 8; i++) {
if (dev->regs[0x13] & (1 << i)) {
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
0xc0000 + (i << 14), 0xc3fff + (i << 14), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
0xc0000 + (i << 14), 0xc3fff + (i << 14),
!!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE);
} else {
ali1489_log("%06Xh-%06Xh region shadow disabled\n", 0xc0000 + (i << 14), 0xc3fff + (i << 14));
@@ -96,7 +93,8 @@ ali1489_shadow_recalc(ali1489_t *dev)
for (uint8_t i = 0; i < 4; i++) {
if (dev->regs[0x14] & (1 << i)) {
ali1489_log("%06Xh-%06Xh region shadow enabled: read = %i, write = %i\n",
0xe0000 + (i << 15), 0xe7fff + (i << 15), !!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
0xe0000 + (i << 15), 0xe7fff + (i << 15),
!!(dev->regs[0x14] & 0x10), !!(dev->regs[0x14] & 0x20));
mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE);
shadowbios |= !!(dev->regs[0x14] & 0x10);
shadowbios_write |= !!(dev->regs[0x14] & 0x20);
@@ -142,25 +140,9 @@ ali1489_smram_recalc(ali1489_t *dev)
static void
ali1489_defaults(ali1489_t *dev)
{
memset(dev->ide_regs, 0x00, 256);
memset(dev->pci_conf, 0x00, 256);
memset(dev->regs, 0x00, 256);
ide_pri_disable();
ide_sec_disable();
/* IDE registers */
dev->ide_regs[0x00] = 0x57;
dev->ide_regs[0x01] = 0x02;
dev->ide_regs[0x08] = 0xff;
dev->ide_regs[0x09] = 0x41;
dev->ide_regs[0x0c] = 0x02;
dev->ide_regs[0x0e] = 0x02;
dev->ide_regs[0x10] = 0x02;
dev->ide_regs[0x12] = 0x02;
dev->ide_regs[0x34] = 0xff;
dev->ide_regs[0x35] = 0x01;
/* PCI registers */
dev->pci_conf[0x00] = 0xb9;
dev->pci_conf[0x01] = 0x10;
@@ -203,8 +185,6 @@ ali1489_defaults(ali1489_t *dev)
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
ali1489_ide_handler(dev);
}
static void
@@ -385,7 +365,8 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x44: /* PCI INTx Sensitivity Register */
/* TODO: When doing the IRQ and PCI IRQ rewrite, bits 0 to 3 toggle edge/level output. */
/* TODO: When doing the IRQ and PCI IRQ rewrite,
bits 0 to 3 toggle edge/level output. */
dev->regs[dev->index] = val;
break;
default:
@@ -464,121 +445,6 @@ ali1489_pci_read(UNUSED(int func), int addr, void *priv)
return ret;
}
static void
ali1489_ide_handler(ali1489_t *dev)
{
ide_pri_disable();
ide_sec_disable();
if (dev->ide_regs[0x01] & 0x01) {
ide_pri_enable();
if (!(dev->ide_regs[0x35] & 0x40))
ide_sec_enable();
}
}
static void
ali1489_ide_write(uint16_t addr, uint8_t val, void *priv)
{
ali1489_t *dev = (ali1489_t *) priv;
switch (addr) {
case 0xf4: /* Usually it writes 30h here */
dev->ide_chip_id = val;
break;
case 0xf8:
dev->ide_index = val;
break;
case 0xfc:
if (dev->ide_chip_id != 0x30)
break;
switch (dev->ide_index) {
case 0x01: /* IDE Configuration Register */
dev->ide_regs[dev->ide_index] = val & 0x8f;
ali1489_ide_handler(dev);
break;
case 0x02: /* DBA Data Byte Cative Count for IDE-1 */
case 0x03: /* D0RA Disk 0 Read Active Count for IDE-1 */
case 0x04: /* D0WA Disk 0 Write Active Count for IDE-1 */
case 0x05: /* D1RA Disk 1 Read Active Count for IDE-1 */
case 0x06: /* D1WA Disk 1 Write Active Count for IDE-1 */
case 0x25: /* DBR Data Byte Recovery Count for IDE-1 */
case 0x26: /* D0RR Disk 0 Read Byte Recovery Count for IDE-1 */
case 0x27: /* D0WR Disk 0 Write Byte Recovery Count for IDE-1 */
case 0x28: /* D1RR Disk 1 Read Byte Recovery Count for IDE-1 */
case 0x29: /* D1WR Disk 1 Write Byte Recovery Count for IDE-1 */
case 0x2a: /* DBA Data Byte Cative Count for IDE-2 */
case 0x2b: /* D0RA Disk 0 Read Active Count for IDE-2 */
case 0x2c: /* D0WA Disk 0 Write Active Count for IDE-2 */
case 0x2d: /* D1RA Disk 1 Read Active Count for IDE-2 */
case 0x2e: /* D1WA Disk 1 Write Active Count for IDE-2 */
case 0x2f: /* DBR Data Byte Recovery Count for IDE-2 */
case 0x30: /* D0RR Disk 0 Read Byte Recovery Count for IDE-2 */
case 0x31: /* D0WR Disk 0 Write Byte Recovery Count for IDE-2 */
case 0x32: /* D1RR Disk 1 Read Byte Recovery Count for IDE-2 */
case 0x33: /* D1WR Disk 1 Write Byte Recovery Count for IDE-2 */
dev->ide_regs[dev->ide_index] = val & 0x1f;
break;
case 0x07: /* Buffer Mode Register 1 */
dev->ide_regs[dev->ide_index] = val;
break;
case 0x09: /* IDEPE1 IDE Port Enable Register 1 */
dev->ide_regs[dev->ide_index] = val & 0xc3;
break;
case 0x0a: /* Buffer Mode Register 2 */
dev->ide_regs[dev->ide_index] = val & 0x4f;
break;
case 0x0b: /* IDE Channel 1 Disk 0 Sector Byte Count Register 1 */
case 0x0d: /* IDE Channel 1 Disk 1 Sector Byte Count Register 1 */
case 0x0f: /* IDE Channel 2 Disk 0 Sector Byte Count Register 1 */
case 0x11: /* IDE Channel 2 Disk 1 Sector Byte Count Register 1 */
dev->ide_regs[dev->ide_index] = val & 0x03;
break;
case 0x0c: /* IDE Channel 1 Disk 0 Sector Byte Count Register 2 */
case 0x0e: /* IDE Channel 1 Disk 1 Sector Byte Count Register 2 */
case 0x10: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
case 0x12: /* IDE Channel 2 Disk 1 Sector Byte Count Register 2 */
dev->ide_regs[dev->ide_index] = val & 0x1f;
break;
case 0x35: /* IDEPE3 IDE Port Enable Register 3 */
dev->ide_regs[dev->ide_index] = val;
ali1489_ide_handler(dev);
break;
default:
break;
}
break;
default:
break;
}
}
static uint8_t
ali1489_ide_read(uint16_t addr, void *priv)
{
const ali1489_t *dev = (ali1489_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
case 0xf4:
ret = dev->ide_chip_id;
break;
case 0xfc:
ret = dev->ide_regs[dev->ide_index];
ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret);
break;
default:
break;
}
return ret;
}
static void
ali1489_reset(void *priv)
{
@@ -612,19 +478,10 @@ ali1489_init(UNUSED(const device_t *info))
23h Data Port */
io_sethandler(0x0022, 0x0002, ali1489_read, NULL, NULL, ali1489_write, NULL, NULL, dev);
/* M1489 IDE controller
F4h Chip ID we write always 30h onto it
F8h Index Port
FCh Data Port
*/
io_sethandler(0x0f4, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
io_sethandler(0x0f8, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev);
/* Dummy M1489 PCI device */
dev->pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev, &dev->pci_slot);
device_add(&ide_pci_2ch_device);
device_add(&ide_ali1489_device);
dev->port_92 = device_add(&port_92_pci_device);
dev->smram = smram_add();

View File

@@ -35,6 +35,11 @@
#include <86box/chipset.h>
typedef struct ali1531_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram;
@@ -374,7 +379,7 @@ ali1531_init(UNUSED(const device_t *info))
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
memset(dev, 0, sizeof(ali1531_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot);
dev->smram = smram_add();

View File

@@ -35,6 +35,11 @@
#include <86box/chipset.h>
typedef struct ali1541_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram;
@@ -641,7 +646,7 @@ ali1541_init(UNUSED(const device_t *info))
ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t));
memset(dev, 0, sizeof(ali1541_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot);
dev->smram = smram_add();

View File

@@ -47,6 +47,7 @@
#include <86box/chipset.h>
typedef struct ali1543_t {
uint8_t mirq_states[8];
uint8_t pci_conf[256];
uint8_t pmu_conf[256];
uint8_t usb_conf[256];
@@ -69,7 +70,6 @@ typedef struct ali1543_t {
sff8038i_t *ide_controller[2];
smbus_ali7101_t *smbus;
usb_t *usb;
usb_params_t usb_params;
} ali1543_t;
@@ -197,8 +197,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */
dev->pci_conf[addr] = val & 0xdf;
soft_reset_pci = !!(val & 0x80);
sff_set_irq_level(dev->ide_controller[0], 0, !(val & 0x10));
sff_set_irq_level(dev->ide_controller[1], 0, !(val & 0x10));
pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10));
ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]);
pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]);
pci_set_mirq_routing(PCI_MIRQ2, ali1533_irq_routing[val & 0x0f]);
@@ -418,8 +417,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */
dev->pci_conf[addr] = val & 0x1f;
sff_set_irq_level(dev->ide_controller[0], 1, !(val & 0x10));
sff_set_irq_level(dev->ide_controller[1], 1, !(val & 0x10));
pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10));
ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]);
pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]);
pci_set_mirq_routing(PCI_MIRQ3, ali1533_irq_routing[val & 0x0f]);
@@ -491,46 +489,39 @@ static void
ali5229_ide_irq_handler(ali1543_t *dev)
{
int ctl = 0;
int ch = 0;
int bit = 0;
if (dev->ide_conf[0x52] & 0x10) {
ctl ^= 1;
ch ^= 1;
bit ^= 5;
}
if (dev->ide_conf[0x09] & (1 ^ bit)) {
/* Primary IDE is native. */
ali1543_log("Primary IDE IRQ mode: Native, Native\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4);
sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN);
} else {
/* Primary IDE is legacy. */
switch (dev->pci_conf[0x58] & 0x03) {
case 0x00:
/* SIRQI, SIRQII */
ali1543_log("Primary IDE IRQ mode: SIRQI, SIRQII\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5);
sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0);
break;
case 0x01:
/* IRQ14, IRQ15 */
ali1543_log("Primary IDE IRQ mode: IRQ14, IRQ15\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY);
break;
case 0x02:
/* IRQ14, SIRQII */
ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQII\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5);
sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY);
break;
case 0x03:
/* IRQ14, SIRQI */
ali1543_log("Primary IDE IRQ mode: IRQ14, SIRQI\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2);
sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY);
break;
default:
@@ -543,34 +534,29 @@ ali5229_ide_irq_handler(ali1543_t *dev)
if (dev->ide_conf[0x09] & (4 ^ bit)) {
/* Secondary IDE is native. */
ali1543_log("Secondary IDE IRQ mode: Native, Native\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 4);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 4);
sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_ALI_ALADDIN);
} else {
/* Secondary IDE is legacy. */
switch (dev->pci_conf[0x58] & 0x03) {
case 0x00:
/* SIRQI, SIRQII */
ali1543_log("Secondary IDE IRQ mode: SIRQI, SIRQII\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 2);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5);
sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_MIRQ_0);
break;
case 0x01:
/* IRQ14, IRQ15 */
ali1543_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], IRQ_MODE_LEGACY);
break;
case 0x02:
/* IRQ14, SIRQII */
ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQII\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 5);
sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_1 : IRQ_MODE_LEGACY);
break;
case 0x03:
/* IRQ14, SIRQI */
ali1543_log("Secondary IDE IRQ mode: IRQ14, SIRQI\n");
sff_set_irq_mode(dev->ide_controller[ctl], 0 ^ ch, 0);
sff_set_irq_mode(dev->ide_controller[ctl], 1 ^ ch, 2);
sff_set_irq_mode(dev->ide_controller[ctl], ctl ? IRQ_MODE_MIRQ_0 : IRQ_MODE_LEGACY);
break;
default:
@@ -636,7 +622,6 @@ ali5229_ide_handler(ali1543_t *dev)
ali1543_log("ali5229_ide_handler(): Enabling primary IDE...\n");
ide_pri_enable();
sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch));
ali1543_log("M5229 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
}
@@ -650,13 +635,14 @@ ali5229_ide_handler(ali1543_t *dev)
ali1543_log("ali5229_ide_handler(): Enabling secondary IDE...\n");
ide_sec_enable();
sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch));
ali1543_log("M5229 SEC: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
}
} else {
sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01, (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8));
sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01, ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8);
}
sff_bus_master_handler(dev->ide_controller[0], dev->ide_conf[0x04] & 0x01,
((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (0 ^ ch));
sff_bus_master_handler(dev->ide_controller[1], dev->ide_conf[0x04] & 0x01,
((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + (8 ^ ch));
}
static void
@@ -722,8 +708,8 @@ ali5229_chip_reset(ali1543_t *dev)
sff_set_slot(dev->ide_controller[0], dev->ide_slot);
sff_set_slot(dev->ide_controller[1], dev->ide_slot);
sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8));
sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8);
sff_bus_master_reset(dev->ide_controller[0]);
sff_bus_master_reset(dev->ide_controller[1]);
ali5229_ide_handler(dev);
}
@@ -844,8 +830,8 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
if (val & 0x80)
ali5229_chip_reset(dev);
else if (val & 0x40) {
sff_bus_master_reset(dev->ide_controller[0], (dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8));
sff_bus_master_reset(dev->ide_controller[1], ((dev->ide_conf[0x20] & 0xf0) | (dev->ide_conf[0x21] << 8)) + 8);
sff_bus_master_reset(dev->ide_controller[0]);
sff_bus_master_reset(dev->ide_controller[1]);
}
break;
@@ -996,7 +982,7 @@ static void
ali7101_write(int func, int addr, uint8_t val, void *priv)
{
ali1543_t *dev = (ali1543_t *) priv;
ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val);
ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val);
if (func > 0)
return;
@@ -1068,7 +1054,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv)
case 0x40:
dev->pmu_conf[addr] = val & 0x1f;
pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03));
nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr);
break;
case 0x41:
dev->pmu_conf[addr] = val & 0x10;
@@ -1079,6 +1065,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv)
/* TODO: Is the status R/W or R/WC? */
case 0x42:
dev->pmu_conf[addr] &= ~(val & 0x1f);
if (val & 0x08)
nvr_smi_status_clear(dev->nvr);
break;
case 0x43:
dev->pmu_conf[addr] &= ~(val & 0x10);
@@ -1216,8 +1204,8 @@ ali7101_write(int func, int addr, uint8_t val, void *priv)
case 0x77:
/* TODO: If bit 1 is clear, then status bit is set even if SMI is disabled. */
dev->pmu_conf[addr] = val;
pic_set_smi_irq_mask(8, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x03));
ali1543_log("PMU77: %02X\n", val);
nvr_smi_enable((dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x40] & 0x08), dev->nvr);
apm_set_do_smi(dev->acpi->apm, (dev->pmu_conf[0x77] & 0x08) && (dev->pmu_conf[0x41] & 0x10));
break;
@@ -1418,70 +1406,81 @@ ali7101_read(int func, int addr, void *priv)
uint8_t ret = 0xff;
if (dev->pmu_dev_enable && (func == 0)) {
if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9))
return 0xff;
/* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */
if (addr == 0x43)
ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00;
else if (addr == 0x7f)
ret = 0x80;
else if (addr == 0xbc)
ret = inb(0x70);
else
ret = dev->pmu_conf[addr];
if (dev->pmu_conf[0x77] & 0x10) {
if (!(dev->pmu_conf[0xc9] & 0x01) || (addr < 0x40) || (addr == 0xc9)) {
/* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */
switch (addr) {
default:
ret = dev->pmu_conf[addr];
break;
case 0x10 ... 0x13:
if (dev->pmu_conf[0x5b] & 0x02)
ret = 0x00;
else
ret = dev->pmu_conf[addr];
break;
case 0x14 ... 0x17:
if (dev->pmu_conf[0x5b] & 0x04)
ret = 0x00;
else
ret = dev->pmu_conf[addr];
break;
case 0x42:
dev->pmu_conf[addr] &= 0xe0;
ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00);
break;
case 0x43:
dev->pmu_conf[addr] &= 0xef;
acpi_ali_soft_smi_status_write(dev->acpi, 0);
ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00;
break;
case 0x7f:
ret = 0x80;
break;
case 0xbc:
ret = inb(0x70);
break;
}
case 0x48:
dev->pmu_conf[addr] = 0x00;
break;
case 0x49:
dev->pmu_conf[addr] &= 0x60;
break;
case 0x4a:
dev->pmu_conf[addr] &= 0xc7;
break;
if (dev->pmu_conf[0x77] & 0x10) {
switch (addr) {
case 0x42:
dev->pmu_conf[addr] &= 0xe0;
break;
case 0x43:
dev->pmu_conf[addr] &= 0xef;
acpi_ali_soft_smi_status_write(dev->acpi, 0);
break;
case 0x4e:
dev->pmu_conf[addr] &= 0xfa;
break;
case 0x4f:
dev->pmu_conf[addr] &= 0xfe;
break;
case 0x48:
dev->pmu_conf[addr] = 0x00;
break;
case 0x49:
dev->pmu_conf[addr] &= 0x60;
break;
case 0x4a:
dev->pmu_conf[addr] &= 0xc7;
break;
case 0x74:
dev->pmu_conf[addr] &= 0xcc;
break;
case 0x4e:
dev->pmu_conf[addr] &= 0xfa;
break;
case 0x4f:
dev->pmu_conf[addr] &= 0xfe;
break;
default:
break;
case 0x74:
dev->pmu_conf[addr] &= 0xcc;
break;
default:
break;
}
}
}
}
ali1543_log("M7101: [R] dev->pmu_conf[%02x] = %02x\n", addr, ret);
return ret;
}
static void
ali5237_usb_update_interrupt(usb_t* usb, void *priv)
{
const ali1543_t *dev = (ali1543_t *) priv;
if (usb->irq_level)
pci_set_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
else
pci_clear_mirq(4, !!(dev->pci_conf[0x74] & 0x10));
}
static void
ali1543_reset(void *priv)
{
@@ -1595,16 +1594,16 @@ ali1543_init(const device_t *info)
memset(dev, 0, sizeof(ali1543_t));
/* Device 02: M1533 Southbridge */
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot);
/* Device 0B: M5229 IDE Controller*/
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev, &dev->ide_slot);
/* Device 0C: M7101 Power Managment Controller */
dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev, &dev->pmu_slot);
/* Device 0F: M5237 USB */
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev, &dev->usb_slot);
/* ACPI */
dev->acpi = device_add(&acpi_ali_device);
@@ -1632,10 +1631,7 @@ ali1543_init(const device_t *info)
dev->smbus = device_add(&ali7101_smbus_device);
/* USB */
dev->usb_params.parent_priv = dev;
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = ali5237_usb_update_interrupt;
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
dev->usb = device_add(&usb_device);
dev->type = info->local & 0xff;
dev->offset = (info->local >> 8) & 0x7f;

View File

@@ -36,6 +36,11 @@
#include <86box/chipset.h>
typedef struct ali1621_t {
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pad1;
uint8_t pci_conf[256];
smram_t *smram[2];
@@ -109,9 +114,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
switch (val & 0x30) {
case 0x10: /* Open. */
access_normal = ACCESS_SMRAM_RX;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x30: /* Protect. */
access_smm |= ACCESS_SMRAM_R;
break;
@@ -124,9 +127,7 @@ ali1621_smram_recalc(uint8_t val, ali1621_t *dev)
switch (val & 0x30) {
case 0x10: /* Open. */
access_normal |= ACCESS_SMRAM_W;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x30: /* Protect. */
access_smm |= ACCESS_SMRAM_W;
break;
@@ -671,7 +672,7 @@ ali1621_init(UNUSED(const device_t *info))
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
memset(dev, 0, sizeof(ali1621_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot);
dev->smram[0] = smram_add();
dev->smram[1] = smram_add();

View File

@@ -234,9 +234,7 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv)
case 0x12:
val &= 0xf7;
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x14:
case 0x15:

761
src/chipset/compaq_386.c Normal file
View File

@@ -0,0 +1,761 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the Compaq 386 memory controller.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 Miran Grca.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <math.h>
#include <86box/86box.h>
#include "cpu.h"
#include <86box/io.h>
#include <86box/timer.h>
#include <86box/pit.h>
#include <86box/mem.h>
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/keyboard.h>
#include <86box/fdd.h>
#include <86box/fdc.h>
#include <86box/fdc_ext.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/machine.h>
#include <86box/video.h>
#include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h>
#include <86box/plat_unused.h>
#define RAM_DIAG_L_BASE_MEM_640KB 0x00
#define RAM_DIAG_L_BASE_MEM_INV 0x10
#define RAM_DIAG_L_BASE_MEM_512KB 0x20
#define RAM_DIAG_L_BASE_MEM_256KB 0x30
#define RAM_DIAG_L_BASE_MEM_MASK 0x30
#define RAM_DIAG_L_PERMA_BITS 0x80
#define RAM_DIAG_H_SYS_RAM_4MB 0x01
#define RAM_DIAG_H_SYS_RAM_1MB 0x02
#define RAM_DIAG_H_SYS_RAM_NONE 0x03
#define RAM_DIAG_H_SYS_RAM_MASK 0x03
#define RAM_DIAG_H_MOD_A_RAM_4MB 0x04
#define RAM_DIAG_H_MOD_A_RAM_1MB 0x08
#define RAM_DIAG_H_MOD_A_RAM_NONE 0x0c
#define RAM_DIAG_H_MOD_A_RAM_MASK 0x0c
#define RAM_DIAG_H_MOD_B_RAM_4MB 0x10
#define RAM_DIAG_H_MOD_B_RAM_1MB 0x20
#define RAM_DIAG_H_MOD_B_RAM_NONE 0x30
#define RAM_DIAG_H_MOD_B_RAM_MASK 0x30
#define RAM_DIAG_H_MOD_C_RAM_4MB 0x40
#define RAM_DIAG_H_MOD_C_RAM_1MB 0x80
#define RAM_DIAG_H_MOD_C_RAM_NONE 0xc0
#define RAM_DIAG_H_MOD_C_RAM_MASK 0xc0
#define MEM_STATE_BUS 0x00
#define MEM_STATE_SYS 0x01
#define MEM_STATE_SYS_RELOC 0x02
#define MEM_STATE_MOD_A 0x04
#define MEM_STATE_MOD_B 0x08
#define MEM_STATE_MOD_C 0x10
#define MEM_STATE_MASK (MEM_STATE_SYS | MEM_STATE_MOD_A | MEM_STATE_MOD_B | MEM_STATE_MOD_C)
#define MEM_STATE_WP 0x20
typedef struct cpq_ram_t {
uint8_t wp;
uint32_t phys_base;
uint32_t virt_base;
mem_mapping_t mapping;
} cpq_ram_t;
typedef struct cpq_386_t {
uint8_t regs[8];
uint8_t old_state[256];
uint8_t mem_state[256];
uint32_t ram_bases[4];
uint32_t ram_sizes[4];
uint32_t ram_map_sizes[4];
cpq_ram_t ram[4][64];
cpq_ram_t high_ram[16];
mem_mapping_t regs_mapping;
} cpq_386_t;
static uint8_t
cpq_read_ram(uint32_t addr, void *priv)
{
const cpq_ram_t *dev = (cpq_ram_t *) priv;
uint8_t ret = 0xff;
addr = (addr - dev->virt_base) + dev->phys_base;
if (addr < (mem_size << 10))
ret = mem_read_ram(addr, priv);
return ret;
}
static uint16_t
cpq_read_ramw(uint32_t addr, void *priv)
{
const cpq_ram_t *dev = (cpq_ram_t *) priv;
uint16_t ret = 0xffff;
addr = (addr - dev->virt_base) + dev->phys_base;
if (addr < (mem_size << 10))
ret = mem_read_ramw(addr, priv);
return ret;
}
static uint32_t
cpq_read_raml(uint32_t addr, void *priv)
{
const cpq_ram_t *dev = (cpq_ram_t *) priv;
uint32_t ret = 0xffffffff;
addr = (addr - dev->virt_base) + dev->phys_base;
if (addr < (mem_size << 10))
ret = mem_read_raml(addr, priv);
return ret;
}
static void
cpq_write_ram(uint32_t addr, uint8_t val, void *priv)
{
const cpq_ram_t *dev = (cpq_ram_t *) priv;
addr = (addr - dev->virt_base) + dev->phys_base;
if (!dev->wp && (addr < (mem_size << 10)))
mem_write_ram(addr, val, priv);
}
static void
cpq_write_ramw(uint32_t addr, uint16_t val, void *priv)
{
const cpq_ram_t *dev = (cpq_ram_t *) priv;
addr = (addr - dev->virt_base) + dev->phys_base;
if (!dev->wp && (addr < (mem_size << 10)))
mem_write_ramw(addr, val, priv);
}
static void
cpq_write_raml(uint32_t addr, uint32_t val, void *priv)
{
const cpq_ram_t *dev = (cpq_ram_t *) priv;
addr = (addr - dev->virt_base) + dev->phys_base;
if (!dev->wp && (addr < (mem_size << 10)))
mem_write_raml(addr, val, priv);
}
static uint8_t
cpq_read_regs(uint32_t addr, void *priv)
{
const cpq_386_t *dev = (cpq_386_t *) priv;
uint8_t ret = 0xff;
addr &= 0x00000fff;
switch (addr) {
case 0x00000000:
case 0x00000001:
/* RAM Diagnostics (Read Only) */
case 0x00000002:
case 0x00000003:
/* RAM Setup Port (Read/Write) */
ret = dev->regs[addr];
break;
default:
break;
}
return ret;
}
static uint16_t
cpq_read_regsw(uint32_t addr, void *priv)
{
uint16_t ret = 0xffff;
ret = cpq_read_regs(addr, priv);
ret |= (((uint16_t) cpq_read_regs(addr + 1, priv)) << 8);
return ret;
}
static uint32_t
cpq_read_regsl(uint32_t addr, void *priv)
{
uint32_t ret = 0xffffffff;
ret = cpq_read_regsw(addr, priv);
ret |= (((uint32_t) cpq_read_regsw(addr + 2, priv)) << 16);
return ret;
}
static void
cpq_recalc_state(cpq_386_t *dev, uint8_t i)
{
uint32_t addr;
addr = ((uint32_t) i) << 16;
if (dev->mem_state[i] == 0x00)
mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
else if (dev->mem_state[i] == MEM_STATE_WP)
mem_set_mem_state(addr, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
else if (dev->mem_state[i] & MEM_STATE_WP)
mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
else
mem_set_mem_state(addr, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
dev->old_state[i] = dev->mem_state[i];
}
static void
cpq_recalc_states(cpq_386_t *dev)
{
/* Recalculate the entire 16 MB space. */
for (uint16_t i = 0; i < 256; i++) {
if (dev->mem_state[i] != dev->old_state[i])
cpq_recalc_state(dev, i);
}
flushmmucache_nopc();
}
static void
cpq_recalc_cache(cpq_386_t *dev)
{
cpu_cache_ext_enabled = (dev->regs[0x00000002] & 0x40);
cpu_update_waitstates();
}
static void
cpq_recalc_ram(cpq_386_t *dev)
{
uint8_t sys_ram = (dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK) & 0x01;
uint8_t setup_port = dev->regs[0x00000002] & 0x0f;
uint8_t sys_min_high = sys_ram ? 0xfa : 0xf4;
uint8_t ram_states[4] = { MEM_STATE_SYS, MEM_STATE_MOD_A,
MEM_STATE_MOD_B, MEM_STATE_MOD_C };
uint8_t ram_bases[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 } },
{ { 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } },
{ { 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x20, 0x20,
0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 },
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50,
0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } },
{ { 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x60,
0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00 },
{ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x90, 0x00, 0x00, 0xc0, 0xc0, 0xc0 } } };
uint8_t ram_sizes[4][2][16] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x30, 0x00, 0x10, 0x20, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 } },
{ { 0x00, 0x00, 0x10, 0x10, 0x10, 0x40, 0x10, 0x10,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10,
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 } },
{ { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x40,
0x30, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 },
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
0x00, 0x10, 0x10, 0x30, 0x40, 0x40, 0x40, 0x40 } },
{ { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
0x00, 0x00, 0x10, 0x20, 0x30, 0x40, 0x00, 0x00 },
{ 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x20, 0x30 } } };
uint8_t size;
uint8_t start;
uint8_t end;
uint8_t k;
uint32_t virt_base;
cpq_ram_t *cram;
for (uint16_t i = 0x10; i < sys_min_high; i++)
dev->mem_state[i] &= ~MEM_STATE_MASK;
for (uint8_t i = 0; i < 4; i++) {
for (uint8_t j = 0; j <= 64; j++) {
if ((i >= 1) || (j >= 0x10))
mem_mapping_disable(&dev->ram[i][j].mapping);
}
}
for (uint8_t i = 0; i < 4; i++) {
size = ram_sizes[i][sys_ram][setup_port];
if (size > 0x00) {
start = ram_bases[i][sys_ram][setup_port];
end = start + (size - 1);
virt_base = ((uint32_t) start) << 16;
for (uint16_t j = start; j <= end; j++) {
k = j - start;
if (i == 0)
k += 0x10;
cram = &(dev->ram[i][k]);
dev->mem_state[j] |= ram_states[i];
cram->virt_base = ((uint32_t) j) << 16;
cram->phys_base = cram->virt_base - virt_base + dev->ram_bases[i];
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
}
}
}
/* Recalculate the entire 16 MB space. */
cpq_recalc_states(dev);
}
static void
cpq_write_regs(uint32_t addr, uint8_t val, void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
addr &= 0x00000fff;
switch (addr) {
case 0x00000000:
case 0x00000001:
/* RAM Relocation (Write Only) */
dev->regs[addr + 4] = val;
if (addr == 0x00000000) {
dev->mem_state[0x0e] &= ~(MEM_STATE_SYS | MEM_STATE_WP);
dev->mem_state[0x0f] &= ~(MEM_STATE_SYS | MEM_STATE_WP);
dev->mem_state[0xfe] &= ~MEM_STATE_WP;
dev->mem_state[0xff] &= ~MEM_STATE_WP;
if (!(val & 0x01)) {
dev->mem_state[0x0e] |= MEM_STATE_SYS;
dev->mem_state[0x0f] |= MEM_STATE_SYS;
}
if (!(val & 0x02)) {
dev->mem_state[0x0e] |= MEM_STATE_WP;
dev->mem_state[0x0f] |= MEM_STATE_WP;
dev->mem_state[0xfe] |= MEM_STATE_WP;
dev->mem_state[0xff] |= MEM_STATE_WP;
}
cpq_recalc_state(dev, 0x0e);
cpq_recalc_state(dev, 0x0f);
cpq_recalc_state(dev, 0xfe);
cpq_recalc_state(dev, 0xff);
flushmmucache_nopc();
}
break;
case 0x00000002:
case 0x00000003:
/* RAM Setup Port (Read/Write) */
dev->regs[addr] = val;
if (addr == 0x00000002) {
cpq_recalc_ram(dev);
cpq_recalc_cache(dev);
}
break;
default:
break;
}
}
static void
cpq_write_regsw(uint32_t addr, uint16_t val, void *priv)
{
cpq_write_regs(addr, val & 0xff, priv);
cpq_write_regs(addr + 1, (val >> 8) & 0xff, priv);
}
static void
cpq_write_regsl(uint32_t addr, uint32_t val, void *priv)
{
cpq_write_regsw(addr, val & 0xff, priv);
cpq_write_regsw(addr + 2, (val >> 16) & 0xff, priv);
}
static void
compaq_ram_init(cpq_ram_t *dev)
{
mem_mapping_add(&dev->mapping,
0x00000000,
0x00010000,
cpq_read_ram,
cpq_read_ramw,
cpq_read_raml,
cpq_write_ram,
cpq_write_ramw,
cpq_write_raml,
NULL,
MEM_MAPPING_INTERNAL,
dev);
mem_mapping_disable(&dev->mapping);
}
static void
compaq_ram_diags_parse(cpq_386_t *dev)
{
uint8_t val = dev->regs[0x00000001];
uint32_t accum = 0x00100000;
for (uint8_t i = 0; i < 4; i++) {
dev->ram_bases[i] = accum;
switch (val & 0x03) {
case RAM_DIAG_H_SYS_RAM_1MB:
dev->ram_sizes[i] = 0x00100000;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
dev->ram_sizes[i] = 0x00400000;
break;
default:
break;
}
if (i == 0)
dev->ram_sizes[i] -= 0x00100000;
dev->ram_map_sizes[i] = dev->ram_sizes[i];
accum += dev->ram_sizes[i];
if (accum >= (mem_size << 10)) {
dev->ram_sizes[i] = (mem_size << 10) - dev->ram_bases[i];
break;
}
val >>= 2;
}
}
static void
compaq_recalc_base_ram(cpq_386_t *dev)
{
uint8_t base_mem = dev->regs[0x00000000] & RAM_DIAG_L_BASE_MEM_MASK;
uint8_t sys_ram = dev->regs[0x00000001] & RAM_DIAG_H_SYS_RAM_MASK;
uint8_t low_start = 0x00;
uint8_t low_end = 0x00;
uint8_t high_start = 0x00;
uint8_t high_end = 0x00;
cpq_ram_t *cram;
switch (base_mem) {
case RAM_DIAG_L_BASE_MEM_256KB:
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
low_start = 0x00;
low_end = 0x03;
high_start = 0xf4;
high_end = 0xff;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
low_start = 0x00;
low_end = 0x03;
high_start = 0xfa;
high_end = 0xff;
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
break;
case RAM_DIAG_L_BASE_MEM_512KB:
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
low_start = 0x00;
low_end = 0x07;
high_start = 0xf8;
high_end = 0xff;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
low_start = 0x00;
low_end = 0x07;
high_start = 0xfa;
high_end = 0xff;
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
break;
case RAM_DIAG_L_BASE_MEM_640KB:
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
low_start = 0x00;
low_end = 0x09;
high_start = 0xfa;
high_end = 0xff;
break;
case RAM_DIAG_H_SYS_RAM_4MB:
low_start = 0x00;
low_end = 0x09;
high_start = 0xfa;
high_end = 0xff;
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X %02X\n", base_mem, sys_ram);
return;
}
switch (sys_ram) {
case RAM_DIAG_H_SYS_RAM_1MB:
if (mem_size < 1024)
dev->regs[0x00000002] = 0x01;
else if (mem_size == 8192)
dev->regs[0x00000002] = 0x09;
else if (mem_size >= 11264)
dev->regs[0x00000002] = 0x0d;
else
dev->regs[0x00000002] = (mem_size >> 10);
break;
case RAM_DIAG_H_SYS_RAM_4MB:
if (mem_size < 4096)
dev->regs[0x00000002] = 0x04;
else if (mem_size == 11264)
dev->regs[0x00000002] = 0x0c;
else if (mem_size >= 16384)
dev->regs[0x00000002] = 0x00;
else if (mem_size > 13312)
dev->regs[0x00000002] = 0x0d;
else
dev->regs[0x00000002] = (mem_size >> 10);
break;
default:
fatal("Compaq 386 - Invalid configuation: %02X\n", sys_ram);
return;
}
/* The base 640 kB. */
for (uint8_t i = low_start; i <= low_end; i++) {
cram = &(dev->ram[0][i]);
cram->phys_base = cram->virt_base = ((uint32_t) i) << 16;
dev->mem_state[i] |= MEM_STATE_SYS;
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
cpq_recalc_state(dev, i);
}
/* The relocated 128 kB. */
for (uint8_t i = 0x0e; i <= 0x0f; i++) {
cram = &(dev->ram[0][i]);
cram->phys_base = cram->virt_base = ((uint32_t) i) << 16;
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
}
/* Blocks FA-FF. */
for (uint16_t i = high_start; i <= high_end; i++) {
cram = &(dev->high_ram[i & 0x0f]);
cram->phys_base = ((uint32_t) (i & 0x0f)) << 16;
cram->virt_base = ((uint32_t) i) << 16;
dev->mem_state[i] |= MEM_STATE_SYS;
mem_mapping_set_addr(&cram->mapping, cram->virt_base, 0x00010000);
mem_mapping_set_exec(&cram->mapping, &(ram[cram->phys_base]));
cpq_recalc_state(dev, i);
}
}
static void
compaq_386_close(void *priv)
{
cpq_386_t *dev = (cpq_386_t *) priv;
free(dev);
}
static void *
compaq_386_init(UNUSED(const device_t *info))
{
cpq_386_t *dev = (cpq_386_t *) calloc(1, sizeof(cpq_386_t));
mem_mapping_add(&dev->regs_mapping,
0x80c00000,
0x00001000,
cpq_read_regs,
cpq_read_regsw,
cpq_read_regsl,
cpq_write_regs,
cpq_write_regsw,
cpq_write_regsl,
NULL,
MEM_MAPPING_INTERNAL,
dev);
mem_set_mem_state(0x80c00000, 0x00001000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
dev->regs[0x00000000] = RAM_DIAG_L_PERMA_BITS;
if (mem_size >= 640)
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_640KB;
else if (mem_size >= 512)
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_512KB;
else if (mem_size >= 256)
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_256KB;
else
dev->regs[0x00000000] |= RAM_DIAG_L_BASE_MEM_INV;
/* Indicate no parity error. */
dev->regs[0x00000000] |= 0x0f;
if (mem_size >= 1024) {
switch (mem_size) {
case 1024:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 2048:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 3072:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 4096:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 5120:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 6144:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 7168:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_1MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB;
break;
case 8192:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 9216:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 10240:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_1MB | RAM_DIAG_H_MOD_C_RAM_1MB;
break;
case 11264:
case 12288:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_NONE;
break;
case 13312:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_1MB;
break;
case 14336:
case 15360:
case 16384:
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_4MB | RAM_DIAG_H_MOD_A_RAM_4MB |
RAM_DIAG_H_MOD_B_RAM_4MB | RAM_DIAG_H_MOD_C_RAM_4MB;
break;
default:
break;
}
} else
dev->regs[0x00000001] = RAM_DIAG_H_SYS_RAM_1MB | RAM_DIAG_H_MOD_A_RAM_NONE |
RAM_DIAG_H_MOD_B_RAM_NONE | RAM_DIAG_H_MOD_C_RAM_NONE;
dev->regs[0x00000003] = 0xfc;
dev->regs[0x00000004] = dev->regs[0x00000005] = 0xff;
compaq_ram_diags_parse(dev);
mem_mapping_disable(&ram_low_mapping);
mem_mapping_disable(&ram_mid_mapping);
mem_mapping_disable(&ram_high_mapping);
#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64))
/* Should never be the case, but you never know what a user may set. */
if (mem_size > 1048576)
mem_mapping_disable(&ram_2gb_mapping);
#endif
/* Initialize in reverse order for memory mapping precedence
reasons. */
for (int8_t i = 3; i >= 0; i--) {
for (uint8_t j = 0; j < 64; j++)
compaq_ram_init(&(dev->ram[i][j]));
}
for (uint8_t i = 0; i < 16; i++)
compaq_ram_init(&(dev->high_ram[i]));
/* First, set the entire 256 MB of space to invalid states. */
for (uint16_t i = 0; i < 256; i++)
dev->old_state[i] = 0xff;
/* Then, recalculate the base RAM mappings. */
compaq_recalc_base_ram(dev);
/* Enable the external cache. */
dev->regs[0x00000002] |= 0x40;
cpq_recalc_cache(dev);
/* Recalculate the rest of the RAM mapping. */
cpq_recalc_ram(dev);
return dev;
}
const device_t compaq_386_device = {
.name = "Compaq 386 Memory Control",
.internal_name = "compaq_386",
.flags = 0,
.local = 0,
.init = compaq_386_init,
.close = compaq_386_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -122,6 +122,9 @@
typedef struct ims8848_t {
uint8_t idx;
uint8_t access_data;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[256];
uint8_t pci_conf[256];
@@ -392,7 +395,7 @@ ims8848_init(UNUSED(const device_t *info))
PCI Device 0: IMS 8849 Dummy for compatibility reasons
*/
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, ims8849_pci_read, ims8849_pci_write, dev, &dev->pci_slot);
dev->smram = smram_add();
smram_set_separate_smram(1);

View File

@@ -15,6 +15,7 @@
*
* Copyright 2020 Miran Grca.
*/
#define USE_DRB_HACK
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
@@ -52,6 +53,9 @@
typedef struct i420ex_t {
uint8_t has_ide;
uint8_t smram_locked;
uint8_t pci_slot;
uint8_t pad;
uint8_t regs[256];
uint16_t timer_base;
@@ -519,7 +523,7 @@ i420ex_speed_changed(void *priv)
if (te)
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
te = timer_is_enabled(&dev->fast_off_timer);
te = timer_is_on(&dev->fast_off_timer);
timer_stop(&dev->fast_off_timer);
if (te)
@@ -534,7 +538,7 @@ i420ex_init(const device_t *info)
dev->smram = smram_add();
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, i420ex_read, i420ex_write, dev, &dev->pci_slot);
dev->has_ide = info->local;

View File

@@ -57,6 +57,9 @@ typedef struct i4x0_t {
uint8_t max_drb;
uint8_t drb_unit;
uint8_t drb_default;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t regs[256];
uint8_t regs_locked[256];
uint8_t mem_state[256];
@@ -1241,12 +1244,12 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
switch (dev->type) {
case INTEL_440FX:
regs[0x93] = (val & 0x0f);
trc_write(0x0093, val & 0x06, NULL);
pci_write(0x0cf9, val & 0x06, NULL);
break;
case INTEL_440LX:
case INTEL_440EX:
regs[0x93] = (val & 0x0e);
trc_write(0x0093, val & 0x06, NULL);
pci_write(0x0cf9, val & 0x06, NULL);
break;
default:
break;
@@ -1518,7 +1521,7 @@ i4x0_read(int func, int addr, void *priv)
/* Special behavior for 440FX register 0x93 which is basically TRC in PCI space
with the addition of bits 3 and 0. */
if ((func == 0) && (addr == 0x93) && ((dev->type == INTEL_440FX) || (dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)))
ret = (ret & 0xf9) | (trc_read(0x0093, NULL) & 0x06);
ret = (ret & 0xf9) | (pci_read(0x0cf9, NULL) & 0x06);
}
return ret;
@@ -1669,11 +1672,12 @@ i4x0_init(const device_t *info)
regs[0x52] = 0xea; /* 512 kB burst cache, set to 0xaa for 256 kB */
regs[0x57] = 0x31;
regs[0x59] = 0x0f;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 1;
dev->drb_default = 0x02;
dev->write_drbs = spd_write_drbs_with_ext;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 1;
dev->drb_default = 0x02;
dev->write_drbs = spd_write_drbs_with_ext;
break;
case INTEL_430FX:
regs[0x02] = 0x2d;
@@ -1702,11 +1706,12 @@ i4x0_init(const device_t *info)
regs[0x57] |= 0x02;
else if ((cpu_busspeed > 60000000) && (cpu_busspeed <= 66666667))
regs[0x57] |= 0x03;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 4;
dev->drb_default = 0x02;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 4;
dev->drb_default = 0x02;
break;
case INTEL_430VX:
regs[0x02] = 0x30;
@@ -1761,12 +1766,13 @@ i4x0_init(const device_t *info)
regs[0x53] = 0x80;
regs[0x57] = 0x01;
regs[0x58] = 0x10;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x71] = 0x10;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x02;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x02;
regs[0x71] = 0x10;
regs[0x72] = 0x02;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x02;
break;
case INTEL_440LX:
regs[0x02] = 0x80;
@@ -1781,7 +1787,8 @@ i4x0_init(const device_t *info)
regs[0x51] |= 0x00;
regs[0x53] = 0x83;
regs[0x57] = 0x01;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55;
regs[0x72] = 0x02;
regs[0xa0] = 0x02;
@@ -1803,7 +1810,8 @@ i4x0_init(const device_t *info)
regs[0x51] = 0x80;
regs[0x53] = 0x83;
regs[0x57] = 0x01;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x6c] = regs[0x6d] = regs[0x6e] = regs[0x6f] = 0x55;
regs[0x72] = 0x02;
regs[0xa0] = 0x02;
@@ -1831,19 +1839,20 @@ i4x0_init(const device_t *info)
regs[0x51] |= 0x00;
regs[0x57] = 0x28; /* 4 DIMMs, SDRAM */
regs[0x58] = 0x03;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x72] = 0x02;
regs[0x73] = 0x38;
regs[0x7b] = 0x38;
regs[0x90] = 0x80;
regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02;
regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10;
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x72] = 0x02;
regs[0x73] = 0x38;
regs[0x7b] = 0x38;
regs[0x90] = 0x80;
regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02;
regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10;
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
case INTEL_440GX:
regs[0x7a] = (info->local >> 8) & 0xff;
@@ -1854,19 +1863,20 @@ i4x0_init(const device_t *info)
regs[0x10] = 0x08;
regs[0x34] = (regs[0x7a] & 0x02) ? 0x00 : 0xa0;
regs[0x57] = 0x28;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x72] = 0x02;
regs[0x73] = 0x38;
regs[0x7b] = 0x38;
regs[0x90] = 0x80;
regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02;
regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10;
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] =
regs[0x64] = regs[0x65] = regs[0x66] = regs[0x67] = 0x01;
regs[0x72] = 0x02;
regs[0x73] = 0x38;
regs[0x7b] = 0x38;
regs[0x90] = 0x80;
regs[0xa0] = (regs[0x7a] & 0x02) ? 0x00 : 0x02;
regs[0xa2] = (regs[0x7a] & 0x02) ? 0x00 : 0x10;
regs[0xa4] = 0x03;
regs[0xa5] = 0x02;
regs[0xa7] = 0x1f;
dev->max_drb = 7;
dev->drb_unit = 8;
dev->drb_default = 0x01;
break;
default:
break;
@@ -1910,12 +1920,12 @@ i4x0_init(const device_t *info)
(dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev);
}
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot);
if ((dev->type >= INTEL_440BX) && !(regs[0x7a] & 0x02)) {
device_add((dev->type == INTEL_440GX) ? &i440gx_agp_device : &i440bx_agp_device);
dev->agpgart = device_add(&agpgart_device);
} else if (dev->type >= INTEL_440LX) {
} else if ((dev->type == INTEL_440LX) || (dev->type == INTEL_440EX)) {
device_add(&i440lx_agp_device);
dev->agpgart = device_add(&agpgart_device);
}
@@ -2106,7 +2116,7 @@ const device_t i440bx_device = {
};
const device_t i440bx_no_agp_device = {
.name = "Intel 82443BX",
.name = "Intel 82443BX (No AGP)",
.internal_name = "i440bx_no_agp",
.flags = DEVICE_PCI,
.local = 0x8200 | INTEL_440BX,

View File

@@ -62,11 +62,15 @@ i450kx_log(const char *fmt, ...)
typedef struct i450kx_t {
smram_t *smram[2];
uint8_t bus_index;
uint8_t pb_slot;
uint8_t mc_slot;
uint8_t pad;
uint8_t pb_pci_conf[256];
uint8_t mc_pci_conf[256];
uint8_t mem_state[2][256];
uint8_t bus_index;
uint8_t mem_state[2][256];
} i450kx_t;
static void
@@ -801,8 +805,8 @@ i450kx_init(UNUSED(const device_t *info))
{
i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t));
memset(dev, 0, sizeof(i450kx_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev); /* Device 19h: Intel 450KX PCI Bridge PB */
pci_add_card(PCI_ADD_AGPBRIDGE, mc_read, mc_write, dev); /* Device 14h: Intel 450KX Memory Controller MC */
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */
pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */
dev->smram[0] = smram_add();
dev->smram[1] = smram_add();

View File

@@ -66,10 +66,8 @@ typedef struct _piix_ {
uint8_t max_func;
uint8_t pci_slot;
uint8_t no_mirq0;
uint8_t pad;
uint8_t regs[4][256];
uint8_t readout_regs[256];
uint8_t board_config[2];
uint16_t func0_id;
uint16_t nvr_io_base;
uint16_t acpi_io_base;
@@ -84,7 +82,6 @@ typedef struct _piix_ {
piix_io_trap_t io_traps[26];
port_92_t *port_92;
pc_timer_t fast_off_timer;
usb_params_t usb_params;
} piix_t;
#ifdef ENABLE_PIIX_LOG
@@ -109,13 +106,13 @@ static void
smsc_ide_irqs(piix_t *dev)
{
int irq_line = 3;
uint8_t irq_mode[2] = { 0, 0 };
uint8_t irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY };
if (dev->regs[1][0x09] & 0x01)
irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1;
irq_mode[0] = (dev->regs[0][0xe1] & 0x01) ? IRQ_MODE_PCI_IRQ_LINE : IRQ_MODE_PCI_IRQ_PIN;
if (dev->regs[1][0x09] & 0x04)
irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? 3 : 1;
irq_mode[1] = (dev->regs[0][0xe1] & 0x01) ? IRQ_MODE_PCI_IRQ_LINE : IRQ_MODE_PCI_IRQ_PIN;
switch ((dev->regs[0][0xe1] >> 1) & 0x07) {
case 0x00:
@@ -147,12 +144,10 @@ smsc_ide_irqs(piix_t *dev)
}
sff_set_irq_line(dev->bm[0], irq_line);
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
sff_set_irq_mode(dev->bm[0], irq_mode[0]);
sff_set_irq_line(dev->bm[1], irq_line);
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
sff_set_irq_mode(dev->bm[1], irq_mode[1]);
}
static void
@@ -602,6 +597,12 @@ piix_write(int func, int addr, uint8_t val, void *priv)
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED);
else
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
if (dev->type == 3) {
if (val & 0x20)
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
else
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
}
piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled");
}
break;
@@ -1011,11 +1012,11 @@ piix_write(int func, int addr, uint8_t val, void *priv)
break;
case 0xc0:
if (dev->type <= 4)
fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20);
fregs[0xc0] = (fregs[0xc0] & 0x40) | (val & 0xbf);
break;
case 0xc1:
if (dev->type <= 4)
fregs[0xc1] &= ~val;
fregs[0xc1] = (fregs[0xc0] & ~(val & 0x8f)) | (val & 0x20);
break;
case 0xff:
if (dev->type == 4) {
@@ -1177,8 +1178,6 @@ piix_read(int func, int addr, void *priv)
if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) {
fregs = (uint8_t *) dev->regs[func];
ret = fregs[addr];
if ((func == 2) && (addr == 0xff))
ret |= 0xef;
piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr);
}
@@ -1191,9 +1190,7 @@ board_write(uint16_t port, uint8_t val, void *priv)
{
piix_t *dev = (piix_t *) priv;
if (port == 0x0078)
dev->board_config[0] = val;
else if (port == 0x00e0)
if (port == 0x00e0)
dev->cur_readout_reg = val;
else if (port == 0x00e1)
dev->readout_regs[dev->cur_readout_reg] = val;
@@ -1205,11 +1202,7 @@ board_read(uint16_t port, void *priv)
const piix_t *dev = (piix_t *) priv;
uint8_t ret = 0x64;
if (port == 0x0078)
ret = dev->board_config[0];
else if (port == 0x0079)
ret = dev->board_config[1];
else if (port == 0x00e0)
if (port == 0x00e0)
ret = dev->cur_readout_reg;
else if (port == 0x00e1)
ret = dev->readout_regs[dev->cur_readout_reg];
@@ -1222,23 +1215,19 @@ piix_reset_hard(piix_t *dev)
{
uint8_t *fregs;
uint16_t old_base = (dev->regs[1][0x20] & 0xf0) | (dev->regs[1][0x21] << 8);
sff_bus_master_reset(dev->bm[0], old_base);
sff_bus_master_reset(dev->bm[1], old_base + 8);
sff_bus_master_reset(dev->bm[0]);
sff_bus_master_reset(dev->bm[1]);
if (dev->type >= 4) {
sff_set_slot(dev->bm[0], dev->pci_slot);
sff_set_irq_pin(dev->bm[0], PCI_INTA);
sff_set_irq_line(dev->bm[0], 14);
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
sff_set_slot(dev->bm[1], dev->pci_slot);
sff_set_irq_pin(dev->bm[1], PCI_INTA);
sff_set_irq_line(dev->bm[1], 14);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
}
#ifdef ENABLE_PIIX_LOG
@@ -1443,17 +1432,6 @@ piix_fast_off_count(void *priv)
dev->regs[0][0xaa] |= 0x20;
}
static void
piix_usb_update_interrupt(usb_t* usb, void *priv)
{
const piix_t *dev = (piix_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->pci_slot, PCI_INTD);
else
pci_clear_irq(dev->pci_slot, PCI_INTD);
}
static void
piix_reset(void *priv)
{
@@ -1524,16 +1502,12 @@ piix_reset(void *priv)
piix_write(3, 0xd2, 0x00, priv);
}
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
if (dev->no_mirq0 || (dev->type >= 4)) {
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
} else {
sff_set_irq_mode(dev->bm[0], 1, 2);
sff_set_irq_mode(dev->bm[1], 1, 2);
}
if (dev->no_mirq0 || (dev->type >= 4))
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
else
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
}
static void
@@ -1554,10 +1528,10 @@ piix_speed_changed(void *priv)
if (!dev)
return;
int te = timer_is_enabled(&dev->fast_off_timer);
int to = timer_is_on(&dev->fast_off_timer);
timer_stop(&dev->fast_off_timer);
if (te)
if (to)
timer_on_auto(&dev->fast_off_timer, ((double) cpu_fast_off_val + 1) * dev->fast_off_period);
}
@@ -1574,7 +1548,7 @@ piix_init(const device_t *info)
dev->no_mirq0 = (info->local >> 12) & 0x0f;
dev->func0_id = info->local >> 16;
dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev, &dev->pci_slot);
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot);
@@ -1587,23 +1561,15 @@ piix_init(const device_t *info)
ide_board_set_force_ata3(1, 1);
}
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
if (dev->no_mirq0 || (dev->type >= 4)) {
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
} else {
sff_set_irq_mode(dev->bm[0], 1, 2);
sff_set_irq_mode(dev->bm[1], 1, 2);
}
if (dev->no_mirq0 || (dev->type >= 4))
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
else
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
if (dev->type >= 3) {
dev->usb_params.parent_priv = dev;
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = piix_usb_update_interrupt;
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
}
if (dev->type >= 3)
dev->usb = device_add(&usb_device);
if (dev->type > 3) {
dev->nvr = device_add(&piix4_nvr_device);
@@ -1638,7 +1604,10 @@ piix_init(const device_t *info)
dev->port_92 = device_add(&port_92_pci_device);
cpu_set_isa_pci_div(4);
if (cpu_busspeed > 50000000)
cpu_set_isa_pci_div(4);
else
cpu_set_isa_pci_div(3);
dma_alias_set();
@@ -1679,37 +1648,8 @@ piix_init(const device_t *info)
else if (cpu_dmulti > 2.5)
dev->readout_regs[1] |= 0x80;
io_sethandler(0x0078, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
dev->board_config[0] = 0xff;
/* Register 0x0079: */
/* Bit 7: 0 = Clear password, 1 = Keep password. */
/* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */
/* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */
/* Bit 4: External CPU clock (Switch 8). */
/* Bit 3: External CPU clock (Switch 7). */
/* 50 MHz: Switch 7 = Off, Switch 8 = Off. */
/* 60 MHz: Switch 7 = On, Switch 8 = Off. */
/* 66 MHz: Switch 7 = Off, Switch 8 = On. */
/* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */
/* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */
/* Bit 0: 0 = 1.5x multiplier, 1 = 2x multiplier (Switch 6). */
/* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */
dev->board_config[1] = 0xe0;
if (cpu_busspeed <= 50000000)
dev->board_config[1] |= 0x10;
else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000))
dev->board_config[1] |= 0x18;
else if (cpu_busspeed > 60000000)
dev->board_config[1] |= 0x00;
if (cpu_dmulti <= 1.5)
dev->board_config[1] |= 0x01;
else
dev->board_config[1] |= 0x00;
#if 0
device_add(&i8254_sec_device);
#endif

View File

@@ -37,6 +37,10 @@
typedef struct sio_t {
uint8_t id;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t regs[256];
uint16_t timer_base;
@@ -493,7 +497,7 @@ sio_speed_changed(void *priv)
timer_set_delay_u64(&dev->timer, ((uint64_t) dev->timer_latch) * TIMER_USEC);
if (dev->id == 0x03) {
te = timer_is_enabled(&dev->fast_off_timer);
te = timer_is_on(&dev->fast_off_timer);
timer_stop(&dev->fast_off_timer);
if (te)
@@ -507,7 +511,7 @@ sio_init(const device_t *info)
sio_t *dev = (sio_t *) malloc(sizeof(sio_t));
memset(dev, 0, sizeof(sio_t));
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot);
dev->id = info->local;

View File

@@ -673,13 +673,14 @@ neat_init(UNUSED(const device_t *info))
{
neat_t *dev;
uint8_t dram_mode = 0;
uint8_t i;
/* Create an instance. */
dev = (neat_t *) malloc(sizeof(neat_t));
memset(dev, 0x00, sizeof(neat_t));
/* Initialize some of the registers to specific defaults. */
for (uint8_t i = REG_RA0; i <= REG_RB11; i++) {
for (i = REG_RA0; i <= REG_RB11; i++) {
dev->indx = i;
neat_write(0x0023, 0x00, dev);
}

View File

@@ -102,8 +102,9 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv)
static uint8_t
olivetti_eva_read(uint16_t addr, void *priv)
{
olivetti_eva_t *dev = (olivetti_eva_t *) priv;
const olivetti_eva_t *dev = (olivetti_eva_t *) priv;
uint8_t ret = 0xff;
switch (addr) {
case 0x065:
ret = dev->reg_065;

View File

@@ -229,9 +229,7 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
case 0x14:
reset_on_hlt = !!(val & 0x40);
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x11:
case 0x12:
case 0x13:

View File

@@ -33,7 +33,7 @@
#include <86box/chipset.h>
typedef struct opti499_t {
uint8_t idx,
uint8_t idx;
uint8_t regs[256];
uint8_t scratch[2];
} opti499_t;

239
src/chipset/opti602.c Normal file
View File

@@ -0,0 +1,239 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Implementation of the OPTi 82C601/82C602 Buffer Devices.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2023 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/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/timer.h>
#include <86box/nvr.h>
#include <86box/smram.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
#include <86box/plat_unused.h>
typedef struct opti602_t {
uint8_t idx;
uint8_t regs[256];
uint8_t gpio[32];
uint16_t gpio_base;
uint16_t gpio_mask;
uint16_t gpio_size;
nvr_t *nvr;
} opti602_t;
#ifdef ENABLE_OPTI602_LOG
int opti602_do_log = ENABLE_OPTI602_LOG;
static void
opti602_log(const char *fmt, ...)
{
va_list ap;
if (opti602_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define opti602_log(fmt, ...)
#endif
static void
opti602_gpio_write(uint16_t addr, uint8_t val, void *priv)
{
opti602_t *dev = (opti602_t *) priv;
dev->gpio[addr - dev->gpio_base] = val;
}
static uint8_t
opti602_gpio_read(uint16_t addr, void *priv)
{
const opti602_t *dev = (opti602_t *) priv;
uint8_t ret = 0xff;
ret = dev->gpio[addr - dev->gpio_base];
return ret;
}
static void
opti602_gpio_recalc(opti602_t *dev)
{
if (dev->gpio_base != 0x0000)
io_removehandler(dev->gpio_base, dev->gpio_size, opti602_gpio_read, NULL, NULL, opti602_gpio_write, NULL, NULL, dev);
dev->gpio_base = dev->regs[0xf8];
dev->gpio_base |= (((uint16_t) dev->regs[0xf7]) << 8);
dev->gpio_size = 1 << ((dev->regs[0xf9] >> 2) & 0x07);
dev->gpio_mask = ~(dev->gpio_size - 1);
dev->gpio_base &= dev->gpio_mask;
dev->gpio_mask = ~dev->gpio_mask;
if (dev->gpio_base != 0x0000)
io_sethandler(dev->gpio_base, dev->gpio_size, opti602_gpio_read, NULL, NULL, opti602_gpio_write, NULL, NULL, dev);
}
static void
opti602_write(uint16_t addr, uint8_t val, void *priv)
{
opti602_t *dev = (opti602_t *) priv;
switch (addr) {
case 0x22:
dev->idx = val;
break;
case 0x24:
if ((dev->idx == 0xea) || ((dev->idx >= 0xf7) && (dev->idx <= 0xfa))) {
dev->regs[dev->idx] = val;
opti602_log("dev->regs[%04x] = %08x\n", dev->idx, val);
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
switch (dev->idx) {
case 0xea:
/* GREEN Power Port */
break;
case 0xf7:
case 0xf8:
/* General Purpose Chip Select Registers */
opti602_gpio_recalc(dev);
break;
case 0xf9:
/* General Purpose Chip Select Register */
nvr_bank_set(0, !!(val & 0x20), dev->nvr);
opti602_gpio_recalc(dev);
break;
case 0xfa:
/* GPM Port */
break;
default:
break;
}
}
break;
default:
break;
}
}
static uint8_t
opti602_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
const opti602_t *dev = (opti602_t *) priv;
switch (addr) {
case 0x24:
if ((dev->idx == 0xea) || ((dev->idx >= 0xf7) && (dev->idx <= 0xfa))) {
ret = dev->regs[dev->idx];
if ((dev->idx == 0xfa) && (dev->regs[0xf9] & 0x40))
ret |= dev->regs[0xea];
}
break;
default:
break;
}
return ret;
}
static void
opti602_reset(void *priv)
{
opti602_t *dev = (opti602_t *) priv;
memset(dev->regs, 0x00, 256 * sizeof(uint8_t));
memset(dev->gpio, 0x00, 32 * sizeof(uint8_t));
dev->regs[0xfa] = 0x07;
dev->gpio[0x01] |= 0xfe;
nvr_bank_set(0, 0, dev->nvr);
opti602_gpio_recalc(dev);
}
static void
opti602_close(void *priv)
{
opti602_t *dev = (opti602_t *) priv;
free(dev);
}
static void *
opti602_init(UNUSED(const device_t *info))
{
opti602_t *dev = (opti602_t *) calloc(1, sizeof(opti602_t));
io_sethandler(0x0022, 0x0001, opti602_read, NULL, NULL, opti602_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti602_read, NULL, NULL, opti602_write, NULL, NULL, dev);
dev->nvr = device_add(&at_mb_nvr_device);
opti602_reset(dev);
return dev;
}
const device_t opti601_device = {
.name = "OPTi 82C601",
.internal_name = "opti601",
.flags = 0,
.local = 0,
.init = opti602_init,
.close = opti602_close,
.reset = opti602_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t opti602_device = {
.name = "OPTi 82C602",
.internal_name = "opti602",
.flags = 0,
.local = 0,
.init = opti602_init,
.close = opti602_close,
.reset = opti602_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -43,6 +43,10 @@
typedef struct opti822_t {
uint8_t irq_convert;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_regs[256];
} opti822_t;
@@ -380,9 +384,9 @@ opti822_reset(void *priv)
}
static void
opti822_close(void *p)
opti822_close(void *priv)
{
opti822_t *dev = (opti822_t *) p;
opti822_t *dev = (opti822_t *) priv;
free(dev);
}
@@ -393,7 +397,7 @@ opti822_init(UNUSED(const device_t *info))
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
memset(dev, 0, sizeof(opti822_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot);
opti822_reset(dev);

View File

@@ -140,6 +140,8 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
{
opti895_t *dev = (opti895_t *) priv;
opti895_log("opti895_write(%04X, %08X)\n", addr, val);
switch (addr) {
case 0x22:
dev->idx = val;
@@ -155,6 +157,7 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->idx] = val;
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
switch (dev->idx) {
case 0x21:
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
@@ -213,12 +216,14 @@ opti895_read(uint16_t addr, void *priv)
ret = dev->regs[dev->idx];
break;
case 0x24:
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
ret = dev->regs[dev->idx];
if (dev->idx == 0xe0)
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;
}
break;
case 0xe1:
case 0xe2:
ret = dev->scratch[addr - 0xe1];
@@ -228,6 +233,8 @@ opti895_read(uint16_t addr, void *priv)
break;
}
opti895_log("opti895_read(%04X) = %02X\n", addr, ret);
return ret;
}

View File

@@ -8,11 +8,11 @@
*
* Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Tiseno100,
*
*
* Authors: Tiseno100,
*
* Copyright 2021 Tiseno100.
* Copyright 2021-2023 Miran Grca.
* Copyright 2021-2023 Tiseno100.
*/
#include <stdarg.h>
#include <stdio.h>
@@ -27,26 +27,23 @@
#include <86box/timer.h>
#include <86box/mem.h>
#include <86box/nvr.h>
#include <86box/hdd.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/hdc_ide_sff8038i.h>
#include <86box/pci.h>
#include <86box/pic.h>
#include <86box/pit.h>
#include <86box/pit_fast.h>
#include <86box/plat.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/smram.h>
#include <86box/spd.h>
#include <86box/chipset.h>
/* IDE Flags (1 Native / 0 Compatibility)*/
#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1)
#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4)
#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8)
#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2)
#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8)
#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2)
#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8))
#ifdef ENABLE_SIS_5511_LOG
int sis_5511_do_log = ENABLE_SIS_5511_LOG;
@@ -66,18 +63,28 @@ sis_5511_log(const char *fmt, ...)
#endif
typedef struct sis_5511_t {
uint8_t index;
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t regs[16];
uint8_t states[7];
uint8_t slic_regs[4096];
uint8_t pci_conf[256];
uint8_t pci_conf_sb[2][256];
uint8_t index;
uint8_t regs[16];
int nb_pci_slot;
int sb_pci_slot;
mem_mapping_t slic_mapping;
sff8038i_t *ide_drive[2];
sff8038i_t *bm[2];
smram_t *smram;
port_92_t *port_92;
void *pit;
nvr_t *nvr;
uint8_t (*pit_read_reg)(void *priv, uint8_t reg);
} sis_5511_t;
static void
@@ -88,23 +95,31 @@ sis_5511_shadow_recalc(sis_5511_t *dev)
for (uint8_t i = 0x80; i <= 0x86; i++) {
if (i == 0x86) {
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(0xf0000, 0x10000, state);
pclog("000F0000-000FFFFF\n");
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(0xf0000, 0x10000, state);
sis_5511_log("000F0000-000FFFFF\n");
}
} else {
base = ((i & 0x07) << 15) + 0xc0000;
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(base, 0x4000, state);
pclog("%08X-%08X\n", base, base + 0x3fff);
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(base, 0x4000, state);
sis_5511_log("%08X-%08X\n", base, base + 0x3fff);
}
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
pclog("%08X-%08X\n", base + 0x4000, base + 0x7fff);
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
}
}
dev->states[i & 0x0f] = dev->pci_conf[i];
}
flushmmucache_nopc();
@@ -133,38 +148,14 @@ sis_5511_smram_recalc(sis_5511_t *dev)
flushmmucache();
}
void
sis_5513_ide_handler(sis_5511_t *dev)
{
ide_pri_disable();
ide_sec_disable();
if (dev->pci_conf_sb[1][4] & 1) {
if (dev->pci_conf_sb[1][0x4a] & 4) {
ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0);
ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6);
ide_pri_enable();
}
if (dev->pci_conf_sb[1][0x4a] & 2) {
ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170);
ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376);
ide_sec_enable();
}
}
}
void
sis_5513_bm_handler(sis_5511_t *dev)
{
sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE);
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8);
}
static void
sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv)
{
sis_5511_t *dev = (sis_5511_t *) priv;
switch (addr) {
sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
if (func == 0x00) switch (addr) {
case 0x07: /* Status - High Byte */
dev->pci_conf[addr] &= 0xb0;
break;
@@ -264,106 +255,120 @@ sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv)
break;
case 0x70: /* DRAM Bank Register 0-0 */
case 0x71: /* DRAM Bank Register 0-0 */
case 0x72: /* DRAM Bank Register 0-1 */
dev->pci_conf[addr] = val;
break;
case 0x73: /* DRAM Bank Register 0-1 */
dev->pci_conf[addr] = val & 0x83;
break;
case 0x74: /* DRAM Bank Register 1-0 */
case 0x76: /* DRAM Bank Register 1-1 */
case 0x78: /* DRAM Bank Register 2-0 */
case 0x7a: /* DRAM Bank Register 2-1 */
case 0x7c: /* DRAM Bank Register 3-0 */
case 0x7e: /* DRAM Bank Register 3-1 */
spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82);
break;
case 0x71: /* DRAM Bank Register 0-0 */
dev->pci_conf[addr] = val;
break;
case 0x75: /* DRAM Bank Register 1-0 */
dev->pci_conf[addr] = val & 0x7f;
break;
case 0x76: /* DRAM Bank Register 1-1 */
dev->pci_conf[addr] = val;
break;
case 0x77: /* DRAM Bank Register 1-1 */
dev->pci_conf[addr] = val & 0x83;
break;
case 0x78: /* DRAM Bank Register 2-0 */
dev->pci_conf[addr] = val;
break;
case 0x79: /* DRAM Bank Register 2-0 */
dev->pci_conf[addr] = val & 0x7f;
break;
case 0x7a: /* DRAM Bank Register 2-1 */
dev->pci_conf[addr] = val;
break;
case 0x7b: /* DRAM Bank Register 2-1 */
dev->pci_conf[addr] = val & 0x83;
break;
case 0x7c: /* DRAM Bank Register 3-0 */
dev->pci_conf[addr] = val;
break;
case 0x7d: /* DRAM Bank Register 3-0 */
dev->pci_conf[addr] = val & 0x7f;
break;
case 0x7e: /* DRAM Bank Register 3-1 */
dev->pci_conf[addr] = val;
break;
case 0x73: /* DRAM Bank Register 0-1 */
case 0x77: /* DRAM Bank Register 1-1 */
case 0x7b: /* DRAM Bank Register 2-1 */
case 0x7f: /* DRAM Bank Register 3-1 */
dev->pci_conf[addr] = val & 0x83;
break;
case 0x80:
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x80 ... 0x85:
dev->pci_conf[addr] = val & 0xee;
sis_5511_shadow_recalc(dev);
break;
case 0x86:
dev->pci_conf[addr] = val & ((addr == 0x86) ? 0xe8 : 0xee);
dev->pci_conf[addr] = val & 0xe8;
sis_5511_shadow_recalc(dev);
break;
case 0x90: /* 5512 General Purpose Register Index */
case 0x91: /* 5512 General Purpose Register Index */
case 0x92: /* 5512 General Purpose Register Index */
case 0x93: /* 5512 General Purpose Register Index */
case 0x90 ... 0x93: /* 5512 General Purpose Register Index */
dev->pci_conf[addr] = val;
break;
default:
break;
}
sis_5511_log("SiS 5511: dev->pci_conf[%02x] = %02x POST: %02x\n", addr, dev->pci_conf[addr], inb(0x80));
}
static void
sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv)
{
sis_5511_t *dev = (sis_5511_t *) priv;
addr &= 0x00000fff;
switch (addr) {
case 0x00000000:
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
dev->slic_regs[addr] = val;
break;
case 0x00000010:
case 0x00000018:
case 0x00000028:
case 0x00000038:
dev->slic_regs[addr] = val & 0x01;
break;
case 0x00000030:
dev->slic_regs[addr] = val & 0x0f;
mem_mapping_set_addr(&dev->slic_mapping,
(((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000);
break;
}
}
static uint8_t
sis_5511_read(UNUSED(int func), int addr, void *priv)
{
const sis_5511_t *dev = (sis_5511_t *) priv;
uint8_t ret = 0xff;
sis_5511_log("SiS 5511: dev->pci_conf[%02x] (%02x) POST %02x\n", addr, dev->pci_conf[addr], inb(0x80));
return dev->pci_conf[addr];
if (func == 0x00)
ret = dev->pci_conf[addr];
sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
return ret;
}
static uint8_t
sis_5511_slic_read(uint32_t addr, void *priv)
{
sis_5511_t *dev = (sis_5511_t *) priv;
uint8_t ret = 0xff;
addr &= 0x00000fff;
switch (addr) {
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
ret = dev->slic_regs[addr];
break;
}
return ret;
}
void
sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
{
sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val);
switch (addr) {
case 0x04: /* Command */
dev->pci_conf_sb[0][addr] = val & 7;
dev->pci_conf_sb[0][addr] = val & 0x0f;
break;
case 0x07: /* Status */
dev->pci_conf_sb[0][addr] &= val & 0x36;
dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30);
break;
case 0x40: /* BIOS Control Register */
@@ -375,40 +380,24 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
case 0x43: /* INTC# Remapping Control Register */
case 0x44: /* INTD# Remapping Control Register */
dev->pci_conf_sb[0][addr] = val & 0x8f;
pci_set_irq_routing(addr & 7, (val & 0x80) ? (val & 0x80) : PCI_IRQ_DISABLED);
pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f));
break;
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
case 0x4c:
case 0x4d:
case 0x4e:
case 0x4f:
case 0x50:
case 0x51:
case 0x52:
case 0x53:
case 0x54:
case 0x55:
case 0x56:
case 0x57:
case 0x58:
case 0x59:
case 0x5a:
case 0x5b:
case 0x5c:
case 0x5d:
case 0x5e:
case 0x5f:
dev->pci_conf_sb[0][addr] = val;
break;
case 0x60: /* MIRQ0 Remapping Control Register */
case 0x61: /* MIRQ1 Remapping Control Register */
sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val);
dev->pci_conf_sb[0][addr] = val & 0xcf;
pci_set_mirq_routing(addr & 1, (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
if (val & 0x80)
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED);
else
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
break;
case 0x62: /* On-board Device DMA Control Register */
@@ -416,11 +405,12 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
break;
case 0x63: /* IDEIRQ Remapping Control Register */
sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val);
dev->pci_conf_sb[0][addr] = val & 0x8f;
if (val & 0x80) {
sff_set_irq_line(dev->ide_drive[0], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
sff_set_irq_line(dev->ide_drive[1], (val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
}
if (val & 0x80)
pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED);
else
pci_set_mirq_routing(PCI_MIRQ2, val & 0xf);
break;
case 0x64: /* GPIO0 Control Register */
@@ -437,7 +427,8 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
break;
case 0x6a: /* GPIO Status Register */
dev->pci_conf_sb[0][addr] &= val & 0x15;
dev->pci_conf_sb[0][addr] |= (val & 0x10);
dev->pci_conf_sb[0][addr] &= ~(val & 0x01);
break;
default:
@@ -445,52 +436,139 @@ sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
}
}
static void
sis_5513_ide_irq_handler(sis_5511_t *dev)
{
if (dev->pci_conf_sb[1][0x09] & 0x01) {
/* Primary IDE is native. */
sis_5511_log("Primary IDE IRQ mode: Native, Native\n");
sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X);
} else {
/* Primary IDE is legacy. */
sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n");
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
}
if (dev->pci_conf_sb[1][0x09] & 0x04) {
/* Secondary IDE is native. */
sis_5511_log("Secondary IDE IRQ mode: Native, Native\n");
sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X);
} else {
/* Secondary IDE is legacy. */
sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n");
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
}
}
static void
sis_5513_ide_handler(sis_5511_t *dev)
{
uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01;
uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe;
uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe;
uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe;
uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe;
uint16_t current_pri_base;
uint16_t current_pri_side;
uint16_t current_sec_base;
uint16_t current_sec_side;
/* Primary Channel Programming */
current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr;
current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr;
/* Secondary Channel Programming */
current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr;
current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr;
sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n");
ide_pri_disable();
sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n");
ide_sec_disable();
if (ide_io_on) {
/* Primary Channel Setup */
if (dev->pci_conf_sb[1][0x4a] & 0x02) {
sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base);
ide_set_base(0, current_pri_base);
sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side);
ide_set_side(0, current_pri_side);
sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n");
ide_pri_enable();
sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
}
/* Secondary Channel Setup */
if (dev->pci_conf_sb[1][0x4a] & 0x04) {
sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base);
ide_set_base(1, current_sec_base);
sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side);
ide_set_side(1, current_sec_side);
sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n");
ide_sec_enable();
sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
}
}
sff_bus_master_handler(dev->bm[0], ide_io_on,
((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0);
sff_bus_master_handler(dev->bm[1], ide_io_on,
((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8);
}
void
sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev)
{
sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val);
switch (addr) {
case 0x04: /* Command low byte */
dev->pci_conf_sb[1][addr] = val & 5;
dev->pci_conf_sb[1][addr] = val & 0x05;
sis_5513_ide_handler(dev);
sis_5513_bm_handler(dev);
break;
case 0x06: /* Status low byte */
dev->pci_conf_sb[1][addr] = val & 0x20;
break;
case 0x07: /* Status high byte */
dev->pci_conf_sb[1][addr] &= val & 0x3f;
dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38);
break;
case 0x09: /* Programming Interface Byte */
dev->pci_conf_sb[1][addr] = val;
dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05);
sis_5513_ide_irq_handler(dev);
sis_5513_ide_handler(dev);
break;
case 0x0d: /* Latency Timer */
dev->pci_conf_sb[1][addr] = val;
break;
case 0x10: /* Primary Channel Base Address Register */
case 0x11: /* Primary Channel Base Address Register */
case 0x12: /* Primary Channel Base Address Register */
case 0x13: /* Primary Channel Base Address Register */
case 0x14: /* Primary Channel Base Address Register */
case 0x15: /* Primary Channel Base Address Register */
case 0x16: /* Primary Channel Base Address Register */
case 0x17: /* Primary Channel Base Address Register */
case 0x18: /* Secondary Channel Base Address Register */
case 0x19: /* Secondary Channel Base Address Register */
case 0x1a: /* Secondary Channel Base Address Register */
case 0x1b: /* Secondary Channel Base Address Register */
case 0x1c: /* Secondary Channel Base Address Register */
case 0x1d: /* Secondary Channel Base Address Register */
case 0x1e: /* Secondary Channel Base Address Register */
case 0x1f: /* Secondary Channel Base Address Register */
dev->pci_conf_sb[1][addr] = val;
sis_5513_ide_handler(dev);
break;
/* Primary Base Address */
case 0x10:
case 0x11:
case 0x14:
case 0x15:
fallthrough;
case 0x20: /* Bus Master IDE Control Register Base Address */
case 0x21: /* Bus Master IDE Control Register Base Address */
case 0x22: /* Bus Master IDE Control Register Base Address */
case 0x23: /* Bus Master IDE Control Register Base Address */
dev->pci_conf_sb[1][addr] = val;
sis_5513_bm_handler(dev);
/* Secondary Base Address */
case 0x18:
case 0x19:
case 0x1c:
case 0x1d:
fallthrough;
/* Bus Mastering Base Address */
case 0x20:
case 0x21:
if (addr == 0x20)
dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01;
else
dev->pci_conf_sb[1][addr] = val;
sis_5513_ide_handler(dev);
break;
case 0x30: /* Expansion ROM Base Address */
@@ -501,20 +579,23 @@ sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev)
break;
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
case 0x48: /* IDE Command Recovery Time Control */
dev->pci_conf_sb[1][addr] = val & 0x0f;
break;
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
case 0x49: /* IDE Command Active Time Control */
dev->pci_conf_sb[1][addr] = val;
dev->pci_conf_sb[1][addr] = val & 0x07;
break;
case 0x4a: /* IDE General Control Register 0 */
dev->pci_conf_sb[1][addr] = val & 0x9f;
dev->pci_conf_sb[1][addr] = val & 0x9e;
sis_5513_ide_handler(dev);
break;
@@ -538,30 +619,59 @@ static void
sis_5513_write(int func, int addr, uint8_t val, void *priv)
{
sis_5511_t *dev = (sis_5511_t *) priv;
switch (func) {
default:
break;
case 0:
sis_5513_pci_to_isa_write(addr, val, dev);
break;
case 1:
sis_5513_ide_write(addr, val, dev);
break;
default:
break;
}
sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST: %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80));
}
static uint8_t
sis_5513_read(int func, int addr, void *priv)
{
const sis_5511_t *dev = (sis_5511_t *) priv;
uint8_t ret = 0xff;
sis_5511_log("SiS 5513: dev->pci_conf[%02x][%02x] = %02x POST %02x\n", func, addr, dev->pci_conf_sb[func][addr], inb(0x80));
if ((func >= 0) && (func <= 1))
return dev->pci_conf_sb[func][addr];
else
return 0xff;
if (func == 0x00) {
switch (addr) {
default:
ret = dev->pci_conf_sb[func][addr];
break;
case 0x4c ... 0x4f:
ret = pic_read_icw(0, addr & 0x03);
break;
case 0x50 ... 0x53:
ret = pic_read_icw(1, addr & 0x03);
break;
case 0x54 ... 0x55:
ret = pic_read_ocw(0, addr & 0x01);
break;
case 0x56 ... 0x57:
ret = pic_read_ocw(1, addr & 0x01);
break;
case 0x58 ... 0x5f:
ret = dev->pit_read_reg(dev->pit, addr & 0x07);
break;
}
sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret);
} else if (func == 0x01) {
if (addr == 0x3d)
ret = (((dev->pci_conf_sb[0x01][0x4b] & 0xc0) == 0xc0) ||
(dev->pci_conf_sb[0x01][0x09] & 0x05)) ? PCI_INTA : 0x00;
else
ret = dev->pci_conf_sb[func][addr];
sis_5511_log("SiS 5513 IDE: [R] dev->pci_conf_sb[1][%02X] = %02X\n", addr, ret);
}
return ret;
}
static void
@@ -574,6 +684,8 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
dev->index = val - 0x50;
break;
case 0x23:
sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val);
switch (dev->index) {
case 0x00:
dev->regs[dev->index] = val & 0xed;
@@ -591,6 +703,7 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
default:
break;
}
nvr_bank_set(0, !!(val & 0x08), dev->nvr);
break;
case 0x01:
dev->regs[dev->index] = val & 0xf4;
@@ -602,7 +715,8 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val;
break;
case 0x05:
dev->regs[dev->index] = inb(0x70);
dev->regs[dev->index] = val;
outb(0x70, val);
break;
case 0x08:
case 0x09:
@@ -614,7 +728,6 @@ sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
default:
break;
}
sis_5511_log("SiS 5513-ISA: dev->regs[%02x] = %02x POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80));
break;
default:
@@ -626,12 +739,18 @@ static uint8_t
sis_5513_isa_read(uint16_t addr, void *priv)
{
const sis_5511_t *dev = (sis_5511_t *) priv;
uint8_t ret = 0xff;
if (addr == 0x23) {
sis_5511_log("SiS 5513-ISA: dev->regs[%02x] (%02x) POST: %02x\n", dev->index + 0x50, dev->regs[dev->index], inb(0x80));
return dev->regs[dev->index];
} else
return 0xff;
if (dev->index == 0x05)
ret = inb(0x70);
else
ret = dev->regs[dev->index];
sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret);
}
return ret;
}
static void
@@ -665,58 +784,127 @@ sis_5511_reset(void *priv)
dev->pci_conf[0x66] = 0x00;
dev->pci_conf[0x67] = 0xff;
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
dev->pci_conf[0x6c] = dev->pci_conf[0x6d] = 0x00;
dev->pci_conf[0x6e] = dev->pci_conf[0x6f] = 0x00;
dev->pci_conf[0x6a] = 0x00;
dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff;
dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff;
dev->pci_conf[0x6f] = 0x00;
dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04;
dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04;
dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04;
dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04;
dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00;
dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80;
dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00;
dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80;
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
dev->pci_conf[0x86] = 0x00;
cpu_cache_ext_enabled = 0;
cpu_update_waitstates();
dev->pci_conf[0x6b] = 0xff;
dev->pci_conf[0x6c] = 0xff;
dev->pci_conf[0x70] = 4;
dev->pci_conf[0x72] = 4;
dev->pci_conf[0x73] = 0x80;
dev->pci_conf[0x74] = 4;
dev->pci_conf[0x76] = 4;
dev->pci_conf[0x77] = 0x80;
dev->pci_conf[0x78] = 4;
dev->pci_conf[0x7a] = 4;
dev->pci_conf[0x7b] = 0x80;
dev->pci_conf[0x7c] = 4;
dev->pci_conf[0x7e] = 4;
dev->pci_conf[0x7f] = 0x80;
dev->pci_conf[0x80] = 0x00;
dev->pci_conf[0x81] = 0x00;
dev->pci_conf[0x82] = 0x00;
dev->pci_conf[0x83] = 0x00;
dev->pci_conf[0x84] = 0x00;
dev->pci_conf[0x85] = 0x00;
dev->pci_conf[0x86] = 0x00;
sis_5511_smram_recalc(dev);
sis_5511_shadow_recalc(dev);
flushmmucache();
memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t));
dev->slic_regs[0x18] = 0x0f;
mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000);
/* SiS 5513 */
dev->pci_conf_sb[0][0x00] = 0x39;
dev->pci_conf_sb[0][0x01] = 0x10;
dev->pci_conf_sb[0][0x02] = 8;
dev->pci_conf_sb[0][0x04] = 7;
dev->pci_conf_sb[0][0x0a] = 1;
dev->pci_conf_sb[0][0x0b] = 6;
dev->pci_conf_sb[0][0x02] = 0x08;
dev->pci_conf_sb[0][0x03] = 0x00;
dev->pci_conf_sb[0][0x04] = 0x07;
dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00;
dev->pci_conf_sb[0][0x07] = 0x02;
dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00;
dev->pci_conf_sb[0][0x0a] = 0x01;
dev->pci_conf_sb[0][0x0b] = 0x06;
dev->pci_conf_sb[0][0x0e] = 0x80;
dev->pci_conf_sb[0][0x40] = 0x00;
dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80;
dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80;
dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 0x00;
dev->pci_conf_sb[0][0x4a] = dev->pci_conf_sb[0][0x4b] = 0x00;
dev->pci_conf_sb[0][0x60] = dev->pci_conf_sb[0][0x61] = 0x80;
dev->pci_conf_sb[0][0x62] = 0x00;
dev->pci_conf_sb[0][0x63] = 0x80;
dev->pci_conf_sb[0][0x64] = 0x00;
dev->pci_conf_sb[0][0x65] = 0x00;
dev->pci_conf_sb[0][0x66] = dev->pci_conf_sb[0][0x67] = 0x00;
dev->pci_conf_sb[0][0x68] = dev->pci_conf_sb[0][0x69] = 0x00;
dev->pci_conf_sb[0][0x6a] = 0x04;
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
pci_set_mirq_routing(PCI_MIRQ0, PCI_IRQ_DISABLED);
pci_set_mirq_routing(PCI_MIRQ1, PCI_IRQ_DISABLED);
pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED);
dev->regs[0x00] = dev->regs[0x01] = 0x00;
dev->regs[0x03] = dev->regs[0x04] = 0x00;
dev->regs[0x05] = 0x00;
dev->regs[0x08] = dev->regs[0x09] = 0x00;
dev->regs[0x0a] = dev->regs[0x0b] = 0x00;
cpu_set_isa_speed(7159091);
nvr_bank_set(0, 0, dev->nvr);
/* SiS 5513 IDE Controller */
dev->pci_conf_sb[1][0x00] = 0x39;
dev->pci_conf_sb[1][0x01] = 0x10;
dev->pci_conf_sb[1][0x02] = 0x13;
dev->pci_conf_sb[1][0x03] = 0x55;
dev->pci_conf_sb[1][0x0a] = 1;
dev->pci_conf_sb[1][0x0b] = 1;
dev->pci_conf_sb[1][0x04] = dev->pci_conf_sb[1][0x05] = 0x00;
dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00;
dev->pci_conf_sb[1][0x08] = 0x00;
dev->pci_conf_sb[1][0x09] = 0x8a;
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01;
dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00;
dev->pci_conf_sb[1][0x0e] = 0x80;
sff_set_slot(dev->ide_drive[0], dev->sb_pci_slot);
sff_set_slot(dev->ide_drive[1], dev->sb_pci_slot);
sff_bus_master_reset(dev->ide_drive[0], BUS_MASTER_BASE);
sff_bus_master_reset(dev->ide_drive[1], BUS_MASTER_BASE + 8);
dev->pci_conf_sb[1][0x0f] = 0x00;
dev->pci_conf_sb[1][0x10] = 0xf1;
dev->pci_conf_sb[1][0x11] = 0x01;
dev->pci_conf_sb[1][0x14] = 0xf5;
dev->pci_conf_sb[1][0x15] = 0x03;
dev->pci_conf_sb[1][0x18] = 0x71;
dev->pci_conf_sb[1][0x19] = 0x01;
dev->pci_conf_sb[1][0x1c] = 0x75;
dev->pci_conf_sb[1][0x1d] = 0x03;
dev->pci_conf_sb[1][0x20] = 0x01;
dev->pci_conf_sb[1][0x21] = 0xf0;
dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00;
dev->pci_conf_sb[1][0x24] = dev->pci_conf_sb[1][0x25] = 0x00;
dev->pci_conf_sb[1][0x26] = dev->pci_conf_sb[1][0x27] = 0x00;
dev->pci_conf_sb[1][0x28] = dev->pci_conf_sb[1][0x29] = 0x00;
dev->pci_conf_sb[1][0x2a] = dev->pci_conf_sb[1][0x2b] = 0x00;
dev->pci_conf_sb[1][0x2c] = dev->pci_conf_sb[1][0x2d] = 0x00;
dev->pci_conf_sb[1][0x2e] = dev->pci_conf_sb[1][0x2f] = 0x00;
dev->pci_conf_sb[1][0x30] = dev->pci_conf_sb[1][0x31] = 0x00;
dev->pci_conf_sb[1][0x32] = dev->pci_conf_sb[1][0x33] = 0x00;
dev->pci_conf_sb[1][0x40] = dev->pci_conf_sb[1][0x41] = 0x00;
dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00;
dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00;
dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00;
dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00;
dev->pci_conf_sb[1][0x4a] = 0x06;
dev->pci_conf_sb[1][0x4b] = 0x00;
dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x00;
dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0x00;
sis_5513_ide_irq_handler(dev);
sis_5513_ide_handler(dev);
sff_bus_master_reset(dev->bm[0]);
sff_bus_master_reset(dev->bm[1]);
}
static void
@@ -731,27 +919,53 @@ sis_5511_close(void *priv)
static void *
sis_5511_init(UNUSED(const device_t *info))
{
sis_5511_t *dev = (sis_5511_t *) malloc(sizeof(sis_5511_t));
memset(dev, 0, sizeof(sis_5511_t));
sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t));
uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1));
dev->nb_pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev); /* Device 0: SiS 5511 */
dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev); /* Device 1: SiS 5513 */
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev); /* Ports 22h-23h: SiS 5513 ISA */
/* Device 0: SiS 5511 */
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot);
/* Device 1: SiS 5513 */
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot);
/* SLiC Memory Mapped Registers */
mem_mapping_add(&dev->slic_mapping,
0xffc00000, 0x00001000,
sis_5511_slic_read,
NULL,
NULL,
sis_5511_slic_write,
NULL,
NULL,
NULL, MEM_MAPPING_EXTERNAL,
dev);
/* Ports 22h-23h: SiS 5513 ISA */
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev);
/* MIRQ */
pci_enable_mirq(0);
pci_enable_mirq(1);
/* IDEIRQ */
pci_enable_mirq(2);
/* Port 92h */
dev->port_92 = device_add(&port_92_device);
/* SFF IDE */
dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1);
dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2);
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
/* SMRAM */
dev->smram = smram_add();
/* PIT */
dev->pit = device_find_first_priv(DEVICE_PIT);
dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg;
/* NVR */
dev->nvr = device_add(&at_mb_nvr_device);
sis_5511_reset(dev);
return dev;

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@
*
* Copyright 2019-2020 Miran Grca.
*/
#define USE_DRB_HACK
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
@@ -45,9 +46,13 @@
typedef struct sis_85c496_t {
uint8_t cur_reg;
uint8_t rmsmiblk_count;
uint8_t pci_slot;
uint8_t pad;
#ifndef USE_DRB_HACK
uint8_t drb_default;
uint8_t drb_bits;
uint8_t pad0;
uint8_t pad1;
#endif
uint8_t regs[127];
uint8_t pci_conf[256];
@@ -612,9 +617,9 @@ sis_85c496_reset(void *priv)
}
static void
sis_85c496_close(void *p)
sis_85c496_close(void *priv)
{
sis_85c496_t *dev = (sis_85c496_t *) p;
sis_85c496_t *dev = (sis_85c496_t *) priv;
smram_del(dev->smram);
@@ -648,7 +653,7 @@ static void
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
dev->pci_conf[0xd1] = 0xff;
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c49x_pci_read, sis_85c49x_pci_write, dev, &dev->pci_slot);
#if 0
sis_85c497_isa_reset(dev);

View File

@@ -176,6 +176,8 @@ sis_85c4xx_out(uint16_t port, uint8_t val, void *priv)
valxor = val ^ dev->regs[rel_reg];
if (rel_reg == 0x19)
dev->regs[rel_reg] &= ~val;
else if (rel_reg == 0x00)
dev->regs[rel_reg] = (dev->regs[rel_reg] & 0x1f) | (val & 0xe0);
else
dev->regs[rel_reg] = val;

View File

@@ -59,6 +59,10 @@ sis_85c50x_log(const char *fmt, ...)
typedef struct sis_85c50x_t {
uint8_t index;
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t pad;
uint8_t pci_conf[256];
uint8_t pci_conf_sb[256];
uint8_t regs[256];
@@ -426,10 +430,10 @@ sis_85c50x_init(UNUSED(const device_t *info))
memset(dev, 0x00, sizeof(sis_85c50x_t));
/* 501/502 (Northbridge) */
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_85c50x_read, sis_85c50x_write, dev, &dev->nb_slot);
/* 503 (Southbridge) */
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_85c50x_sb_read, sis_85c50x_sb_write, dev, &dev->sb_slot);
io_sethandler(0x0022, 0x0002, sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
dev->smram[0] = smram_add();

View File

@@ -45,6 +45,11 @@
#define STPC_CLIENT 0x100e55cc
typedef struct stpc_t {
uint8_t nb_slot;
uint8_t sb_slot;
uint8_t ide_slot;
uint8_t usb_slot;
uint32_t local;
/* Main registers (port 22h/23h) */
@@ -54,23 +59,20 @@ typedef struct stpc_t {
/* Host bus interface */
uint16_t host_base;
uint8_t host_offset;
uint8_t usb_irq_state;
uint8_t host_regs[256];
/* Local bus */
uint16_t localbus_base;
uint8_t localbus_offset;
uint8_t pad0;
uint8_t localbus_regs[256];
/* PCI devices */
uint8_t pci_conf[4][256];
smram_t *smram;
usb_t *usb;
int ide_slot;
int usb_slot;
sff8038i_t *bm[2];
/* Miscellaneous */
usb_params_t usb_params;
} stpc_t;
typedef struct stpc_serial_t {
@@ -893,17 +895,6 @@ stpc_setup(stpc_t *dev)
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
}
static void
stpc_usb_update_interrupt(usb_t* usb, void* priv)
{
const stpc_t *dev = (stpc_t *) priv;
if (usb->irq_level)
pci_set_irq(dev->usb_slot, PCI_INTA);
else
pci_clear_irq(dev->usb_slot, PCI_INTA);
}
static void
stpc_close(void *priv)
{
@@ -926,26 +917,21 @@ stpc_init(const device_t *info)
dev->local = info->local;
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev);
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, stpc_nb_read, stpc_nb_write, dev, &dev->nb_slot);
pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_isab_read, stpc_isab_write, dev, &dev->sb_slot);
if (dev->local == STPC_ATLAS) {
dev->usb_params.smi_handle = NULL;
dev->usb_params.update_interrupt = stpc_usb_update_interrupt;
dev->usb_params.parent_priv = dev;
pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, stpc_ide_read, stpc_ide_write, dev, &dev->ide_slot);
dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_ide_read, stpc_ide_write, dev);
dev->usb = device_add_parameters(&usb_device, &dev->usb_params);
dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, stpc_usb_read, stpc_usb_write, dev);
dev->usb = device_add(&usb_device);
pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, stpc_usb_read, stpc_usb_write, dev, &dev->usb_slot);
}
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
stpc_setup(dev);
stpc_reset(dev);

View File

@@ -121,8 +121,13 @@ umc_8886_log(const char *fmt, ...)
#define SB_ID dev->sb_id
typedef struct umc_8886_t {
uint8_t max_func; /* Last function number */
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint8_t max_func; /* Last function number */
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf_sb[2][256]; /* PCI Registers */
uint16_t sb_id; /* Southbridge Revision */
int has_ide; /* Check if Southbridge Revision is AF or F */
} umc_8886_t;
@@ -371,7 +376,7 @@ umc_8886_init(const device_t *info)
memset(dev, 0, sizeof(umc_8886_t));
dev->has_ide = !!(info->local == 0x886a);
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev); /* Device 12: UMC 8886xx */
pci_add_card(PCI_ADD_SOUTHBRIDGE, umc_8886_read, umc_8886_write, dev, &dev->pci_slot); /* Device 12: UMC 8886xx */
/* Add IDE if UM8886AF variant */
if (HAS_IDE)

View File

@@ -103,25 +103,11 @@
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/mem.h>
#include <86box/pci.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/smram.h>
#ifdef USE_DYNAREC
# include "codegen_public.h"
#else
# ifdef USE_NEW_DYNAREC
# define PAGE_MASK_SHIFT 6
# else
# define PAGE_MASK_INDEX_MASK 3
# define PAGE_MASK_INDEX_SHIFT 10
# define PAGE_MASK_SHIFT 4
# endif
# define PAGE_MASK_MASK 63
#endif
#include <86box/chipset.h>
#ifdef ENABLE_HB4_LOG
@@ -146,6 +132,8 @@ typedef struct hb4_t {
uint8_t shadow;
uint8_t shadow_read;
uint8_t shadow_write;
uint8_t pci_slot;
uint8_t pci_conf[256]; /* PCI Registers */
int mem_state[9];
smram_t *smram[3]; /* SMRAM Handlers */
@@ -393,7 +381,7 @@ hb4_init(UNUSED(const device_t *info))
hb4_t *dev = (hb4_t *) malloc(sizeof(hb4_t));
memset(dev, 0, sizeof(hb4_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev); /* Device 10: UMC 8881x */
pci_add_card(PCI_ADD_NORTHBRIDGE, hb4_read, hb4_write, dev, &dev->pci_slot); /* Device 10: UMC 8881x */
/* Port 92 */
device_add(&port_92_pci_device);

View File

@@ -10,13 +10,12 @@
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Melissa Goad, <mszoopers@protonmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
* RichardG, <richardg867@gmail.com>
* Tiseno100,
*
* Copyright 2020 Miran Grca.
* Copyright 2020 Melissa Goad.
* Copyright 2020 RichardG.
* Copyright 2020 Tiseno100.
*/
#include <stdio.h>
@@ -45,10 +44,15 @@
#define VIA_8601 0x86010500
typedef struct via_apollo_t {
uint32_t id;
uint8_t drb_unit;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf[256];
uint32_t id;
smram_t *smram;
agpgart_t *agpgart;
} via_apollo_t;
@@ -715,7 +719,7 @@ via_apollo_init(const device_t *info)
if (dev->id != VIA_8601)
apollo_smram_map(dev, 1, 0x000a0000, 0x00020000, 1); /* SMM: Code DRAM, Data DRAM */
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, via_apollo_read, via_apollo_write, dev, &dev->pci_slot);
dev->id = info->local;

View File

@@ -10,14 +10,10 @@
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Melissa Goad, <mszoopers@protonmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
* RichardG, <richardg867@gmail.com>
*
* Copyright 2008-2020 Sarah Walker.
* Copyright 2016-2020 Miran Grca.
* Copyright 2020 Melissa Goad.
* Copyright 2020-2021 RichardG.
*/
#include <stdarg.h>
@@ -117,9 +113,10 @@ typedef struct {
} pipc_io_trap_t;
typedef struct _pipc_ {
uint32_t local;
uint8_t max_func;
uint8_t max_pcs;
uint8_t pci_slot;
uint8_t pad;
uint8_t pci_isa_regs[256];
uint8_t ide_regs[256];
@@ -129,10 +126,11 @@ typedef struct _pipc_ {
uint8_t fmnmi_regs[4];
uint8_t fmnmi_status;
uint32_t local;
sff8038i_t *bm[2];
nvr_t *nvr;
int nvr_enabled;
int slot;
ddma_t *ddma;
smbus_piix4_t *smbus;
usb_t *usb[2];
@@ -212,10 +210,9 @@ pipc_reset_hard(void *priv)
pipc_log("PIPC: reset_hard()\n");
pipc_t *dev = (pipc_t *) priv;
uint16_t old_base = (dev->ide_regs[0x20] & 0xf0) | (dev->ide_regs[0x21] << 8);
sff_bus_master_reset(dev->bm[0], old_base);
sff_bus_master_reset(dev->bm[1], old_base + 8);
sff_bus_master_reset(dev->bm[0]);
sff_bus_master_reset(dev->bm[1]);
memset(dev->pci_isa_regs, 0, 256);
memset(dev->ide_regs, 0, 256);
@@ -239,7 +236,8 @@ pipc_reset_hard(void *priv)
dev->pci_isa_regs[0x4a] = 0x04;
dev->pci_isa_regs[0x4f] = 0x03;
dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24; /* 686A/B default value does not line up with default bits */
/* 686A/B default value does not line up with default bits */
dev->pci_isa_regs[0x50] = (dev->local >= VIA_PIPC_686A) ? 0x0e : 0x24;
dev->pci_isa_regs[0x59] = 0x04;
if (dev->local >= VIA_PIPC_686A)
dev->pci_isa_regs[0x5a] = dev->pci_isa_regs[0x5f] = 0x04;
@@ -568,19 +566,17 @@ pipc_ide_handlers(pipc_t *dev)
static void
pipc_ide_irqs(pipc_t *dev)
{
int irq_mode[2] = { 0, 0 };
int irq_mode[2] = { IRQ_MODE_LEGACY, IRQ_MODE_LEGACY };
if (dev->ide_regs[0x09] & 0x01)
irq_mode[0] = (dev->ide_regs[0x3d] & 0x01);
irq_mode[0] = (dev->ide_regs[0x3d] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY;
if (dev->ide_regs[0x09] & 0x04)
irq_mode[1] = (dev->ide_regs[0x3d] & 0x01);
irq_mode[1] = (dev->ide_regs[0x3d] & 0x01) ? IRQ_MODE_PCI_IRQ_PIN : IRQ_MODE_LEGACY;
sff_set_irq_mode(dev->bm[0], 0, irq_mode[0]);
sff_set_irq_mode(dev->bm[0], 1, irq_mode[1]);
sff_set_irq_mode(dev->bm[0], irq_mode[0]);
sff_set_irq_mode(dev->bm[1], 0, irq_mode[0]);
sff_set_irq_mode(dev->bm[1], 1, irq_mode[1]);
sff_set_irq_mode(dev->bm[1], irq_mode[1]);
}
static void
@@ -1094,7 +1090,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0x47:
if (val & 0x01)
trc_write(0x0047, (val & 0x80) ? 0x06 : 0x04, NULL);
pci_write(0x0cf9, (val & 0x80) ? 0x06 : 0x04, NULL);
pic_set_shadow(!!(val & 0x10));
pic_elcr_io_handler(!!(val & 0x20));
dev->pci_isa_regs[0x47] = val & 0xfe;
@@ -1475,9 +1471,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv)
case 0xd2:
if (dev->local == VIA_PIPC_686B)
smbus_piix4_setclock(dev->smbus, (val & 0x04) ? 65536 : 16384);
#ifdef FALLTHROUGH_ANNOTATION
[[fallthrough]];
#endif
fallthrough;
case 0x90:
case 0x91:
@@ -1620,6 +1614,14 @@ pipc_reset(void *priv)
pipc_write(0, 0x44, 0x00, priv);
pipc_write(0, 0x77, 0x00, priv);
sff_set_slot(dev->bm[0], dev->pci_slot);
sff_set_slot(dev->bm[1], dev->pci_slot);
if (dev->local >= VIA_PIPC_686A)
ac97_via_set_slot(dev->ac97, dev->pci_slot, PCI_INTC);
if (dev->acpi)
acpi_set_slot(dev->acpi, dev->pci_slot);
}
static void *
@@ -1631,27 +1633,23 @@ pipc_init(const device_t *info)
pipc_log("PIPC: init()\n");
dev->local = info->local;
dev->slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev);
pci_add_card(PCI_ADD_SOUTHBRIDGE, pipc_read, pipc_write, dev, &dev->pci_slot);
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
sff_set_slot(dev->bm[0], dev->slot);
sff_set_irq_mode(dev->bm[0], 0, 0);
sff_set_irq_mode(dev->bm[0], 1, 0);
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
sff_set_irq_pin(dev->bm[0], PCI_INTA);
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
sff_set_slot(dev->bm[1], dev->slot);
sff_set_irq_mode(dev->bm[1], 0, 0);
sff_set_irq_mode(dev->bm[1], 1, 0);
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
sff_set_irq_pin(dev->bm[1], PCI_INTA);
dev->nvr = device_add(&via_nvr_device);
if (dev->local == VIA_PIPC_686B)
dev->smbus = device_add(&via_smbus_device);
else if (dev->local >= VIA_PIPC_596A)
dev->smbus = device_add(&piix4_smbus_device);
dev->nvr = device_add(&via_nvr_device);
if (dev->local >= VIA_PIPC_596A) {
dev->acpi = device_add(&acpi_via_596b_device);
acpi_set_trap_update(dev->acpi, pipc_trap_update_596, dev);
@@ -1665,7 +1663,6 @@ pipc_init(const device_t *info)
dev->usb[1] = device_add_inst(&usb_device, 2);
dev->ac97 = device_add(&ac97_via_device);
ac97_via_set_slot(dev->ac97, dev->slot, PCI_INTC);
dev->sb = device_add_inst(&sb_pro_compat_device, 2);
sound_add_handler(pipc_sb_get_buffer, dev);
@@ -1695,7 +1692,6 @@ pipc_init(const device_t *info)
dev->ddma = device_add(&ddma_device);
if (dev->acpi) {
acpi_set_slot(dev->acpi, dev->slot);
acpi_set_nvr(dev->acpi, dev->nvr);
acpi_init_gporeg(dev->acpi, 0xff, 0xbf, 0xff, 0x7f);

View File

@@ -30,6 +30,7 @@
#include <86box/mem.h>
#include <86box/smram.h>
#include <86box/pic.h>
#include <86box/timer.h>
#include <86box/hdc.h>
#include <86box/hdc_ide.h>
#include <86box/port_92.h>

View File

@@ -32,6 +32,10 @@
typedef struct vt82c505_t {
uint8_t index;
uint8_t pci_slot;
uint8_t pad;
uint8_t pad0;
uint8_t pci_conf[256];
} vt82c505_t;
@@ -203,7 +207,7 @@ vt82c505_init(UNUSED(const device_t *info))
vt82c505_t *dev = (vt82c505_t *) malloc(sizeof(vt82c505_t));
memset(dev, 0, sizeof(vt82c505_t));
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev);
pci_add_card(PCI_ADD_NORTHBRIDGE, vt82c505_read, vt82c505_write, dev, &dev->pci_slot);
dev->pci_conf[0x00] = 0x06;
dev->pci_conf[0x01] = 0x11;

View File

@@ -33,6 +33,8 @@ int codegen_in_recompile;
void
codegen_set_rounding_mode(int mode)
{
/* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */
#if 0
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00);
#endif
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10);
}

View File

@@ -74,19 +74,25 @@
*/
typedef struct codeblock_t {
uint64_t page_mask, page_mask2;
uint64_t *dirty_mask, *dirty_mask2;
uint64_t page_mask;
uint64_t page_mask2;
uint64_t *dirty_mask;
uint64_t *dirty_mask2;
uint64_t cmp;
/*Previous and next pointers, for the codeblock list associated with
each physical page. Two sets of pointers, as a codeblock can be
present in two pages.*/
struct codeblock_t *prev, *next;
struct codeblock_t *prev_2, *next_2;
struct codeblock_t *prev;
struct codeblock_t *next;
struct codeblock_t *prev_2;
struct codeblock_t *next_2;
/*Pointers for codeblock tree, used to search for blocks when hash lookup
fails.*/
struct codeblock_t *parent, *left, *right;
struct codeblock_t *parent;
struct codeblock_t *left;
struct codeblock_t *right;
int pnt;
int ins;

View File

@@ -5,10 +5,13 @@
#include <86box/86box.h>
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x86_flags.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "x87.h"
#include "386_common.h"
#include "cpu.h"

View File

@@ -8,7 +8,9 @@ ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg);
// ADD_HOST_REG_IMM_W(host_reg, 1);
#if 0
ADD_HOST_REG_IMM_W(host_reg, 1);
#endif
INC_HOST_REG_W(host_reg);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16);
@@ -29,7 +31,9 @@ ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg);
// ADD_HOST_REG_IMM(host_reg, 1);
#if 0
ADD_HOST_REG_IMM(host_reg, 1);
#endif
INC_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32);
@@ -50,7 +54,9 @@ ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg);
// SUB_HOST_REG_IMM_W(host_reg, 1);
#if 0
SUB_HOST_REG_IMM_W(host_reg, 1);
#endif
DEC_HOST_REG_W(host_reg);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16);
@@ -71,7 +77,9 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg);
// SUB_HOST_REG_IMM(host_reg, 1);
#if 0
SUB_HOST_REG_IMM(host_reg, 1);
#endif
DEC_HOST_REG(host_reg);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32);
@@ -83,194 +91,206 @@ ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, cod
return op_pc;
}
#define ROP_ARITH_RMW(name, op, writeback) \
static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_B_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_W(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_W_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_L(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_L_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
#define ROP_ARITH_RMW(name, op, writeback) \
static uint32_t \
rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_B_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t \
rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_W(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_W_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t \
rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_L(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_L_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
}
#define ROP_ARITH_RM(name, op, writeback) \
static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_B(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_B_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_W(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_W_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_L(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_L_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
#define ROP_ARITH_RM(name, op, writeback) \
static uint32_t \
rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_B(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_B_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t \
rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_W(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_W_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
} \
static uint32_t \
rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_L(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_L_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
codegen_flags_changed = 1; \
return op_pc + 1; \
}
ROP_ARITH_RMW(ADD, ADD, 1)

View File

@@ -194,23 +194,24 @@ ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, code
return new_pc;
}
#define ropFarith(name, size, load, op) \
static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
x86seg *target_seg; \
\
FP_ENTER(); \
op_pc--; \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
load(target_seg); \
\
op(FPU_##name); \
\
return op_pc + 1; \
#define ropFarith(name, size, load, op) \
static uint32_t \
ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
x86seg *target_seg; \
\
FP_ENTER(); \
op_pc--; \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
load(target_seg); \
\
op(FPU_##name); \
\
return op_pc + 1; \
}
ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
@@ -239,7 +240,8 @@ ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
#define ropFcompare(name, size, load, op) \
static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
static uint32_t \
ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
x86seg *target_seg; \
\
@@ -270,74 +272,80 @@ ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D);
ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW);
ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL);
/*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
#if 0
static uint32_t
ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_ADD);
FP_OP_S(FPU_ADD);
return op_pc + 1;
return op_pc + 1;
}
static uint32_t ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
static uint32_t
ropFDIVs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_DIV);
FP_OP_S(FPU_DIV);
return op_pc + 1;
return op_pc + 1;
}
static uint32_t ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
static uint32_t
ropFMULs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_MUL);
FP_OP_S(FPU_MUL);
return op_pc + 1;
return op_pc + 1;
}
static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
static uint32_t
ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg;
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
FP_ENTER();
op_pc--;
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
FP_OP_S(FPU_SUB);
FP_OP_S(FPU_SUB);
return op_pc + 1;
}*/
return op_pc + 1;
}
#endif
static uint32_t
ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
@@ -658,15 +666,16 @@ ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeb
return op_pc;
}
#define opFLDimm(name, v) \
static uint32_t ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
static double fp_imm = v; \
\
FP_ENTER(); \
FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \
\
return op_pc; \
#define opFLDimm(name, v) \
static uint32_t \
ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
static double fp_imm = v; \
\
FP_ENTER(); \
FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \
\
return op_pc; \
}
// clang-format off
@@ -678,7 +687,8 @@ opFLDimm(EG2, 0.3010299956639812);
opFLDimm(Z, 0.0)
// clang-format on
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
static uint32_t
ropFLDLN2(UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc, UNUSED(codeblock_t *block))
{
FP_ENTER();
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ULL);

View File

@@ -214,42 +214,45 @@ BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not )
}
}
#define ropBRANCH(name, func, not ) \
static uint32_t rop##name(uint8_t opcode, uint32_t fetchdat, \
uint32_t op_32, uint32_t op_pc, \
codeblock_t *block) \
{ \
uint32_t offset = fetchdat & 0xff; \
\
if (offset & 0x80) \
offset |= 0xffffff00; \
\
func(1, op_pc, offset, not ); \
\
return op_pc + 1; \
} \
static uint32_t rop##name##_w(uint8_t opcode, \
uint32_t fetchdat, uint32_t op_32, \
uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t offset = fetchdat & 0xffff; \
\
if (offset & 0x8000) \
offset |= 0xffff0000; \
\
func(2, op_pc, offset, not ); \
\
return op_pc + 2; \
} \
static uint32_t rop##name##_l(uint8_t opcode, \
uint32_t fetchdat, uint32_t op_32, \
uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t offset = fastreadl(cs + op_pc); \
\
func(4, op_pc, offset, not ); \
\
return op_pc + 4; \
#define ropBRANCH(name, func, not ) \
static uint32_t \
rop##name(uint8_t opcode, uint32_t fetchdat, \
uint32_t op_32, uint32_t op_pc, \
codeblock_t *block) \
{ \
uint32_t offset = fetchdat & 0xff; \
\
if (offset & 0x80) \
offset |= 0xffffff00; \
\
func(1, op_pc, offset, not ); \
\
return op_pc + 1; \
} \
static uint32_t \
rop##name##_w(uint8_t opcode, \
uint32_t fetchdat, uint32_t op_32, \
uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t offset = fetchdat & 0xffff; \
\
if (offset & 0x8000) \
offset |= 0xffff0000; \
\
func(2, op_pc, offset, not ); \
\
return op_pc + 2; \
} \
static uint32_t \
rop##name##_l(uint8_t opcode, \
uint32_t fetchdat, uint32_t op_32, \
uint32_t op_pc, codeblock_t *block) \
{ \
uint32_t offset = fastreadl(cs + op_pc); \
\
func(4, op_pc, offset, not ); \
\
return op_pc + 4; \
}
// clang-format off

View File

@@ -1,171 +1,183 @@
#define ROP_LOGIC(name, op, writeback) \
static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_B_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_W(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_W_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_L(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_L_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_B(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_B_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_W(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_W_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_L(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_L_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
#define ROP_LOGIC(name, op, writeback) \
static uint32_t \
rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_B_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t \
rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_W(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_W_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t \
rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
x86seg *target_seg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
dst_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
SAVE_EA(); \
MEM_CHECK_WRITE_L(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) { \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_L_RELEASE(dst_reg); \
else { \
LOAD_EA(); \
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \
} \
} else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t \
rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_B(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_B(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \
op##_HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_B_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t \
rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_W(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_W(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \
op##_HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_W_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t \
rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg; \
int dst_reg; \
\
if ((fetchdat & 0xc0) == 0xc0) { \
src_reg = LOAD_REG_L(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
MEM_LOAD_ADDR_EA_L(target_seg); \
src_reg = 0; \
} \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \
op##_HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \
if (writeback) \
STORE_REG_L_RELEASE(dst_reg); \
else \
RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
}
ROP_LOGIC(AND, AND, 1)

View File

@@ -95,33 +95,36 @@ ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc,
return op_pc + 1;
}
#define MMX_OP(name, func) \
static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg1, src_reg2; \
int xmm_src, xmm_dst; \
\
MMX_ENTER(); \
\
if ((fetchdat & 0xc0) == 0xc0) { \
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
\
MEM_LOAD_ADDR_EA_Q(target_seg); \
src_reg1 = LOAD_Q_REG_1; \
src_reg2 = LOAD_Q_REG_2; \
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
} \
xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \
func(xmm_dst, xmm_src); \
STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \
\
return op_pc + 1; \
#define MMX_OP(name, func) \
static uint32_t \
name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg1; \
int src_reg2; \
int xmm_src; \
int xmm_dst; \
\
MMX_ENTER(); \
\
if ((fetchdat & 0xc0) == 0xc0) { \
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
} else { \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
\
CHECK_SEG_READ(target_seg); \
\
MEM_LOAD_ADDR_EA_Q(target_seg); \
src_reg1 = LOAD_Q_REG_1; \
src_reg2 = LOAD_Q_REG_2; \
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
} \
xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \
func(xmm_dst, xmm_src); \
STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \
\
return op_pc + 1; \
}
MMX_OP(ropPAND, MMX_AND)

View File

@@ -224,30 +224,32 @@ ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, c
return op_pc;
}
#define ROP_PUSH_SEG(seg) \
static uint32_t ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-2); \
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
SP_MODIFY(-2); \
\
return op_pc; \
} \
static uint32_t ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-4); \
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
SP_MODIFY(-4); \
\
return op_pc; \
#define ROP_PUSH_SEG(seg) \
static uint32_t \
ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-2); \
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
SP_MODIFY(-2); \
\
return op_pc; \
} \
static uint32_t \
ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(-4); \
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
SP_MODIFY(-4); \
\
return op_pc; \
}
ROP_PUSH_SEG(CS)
@@ -257,26 +259,28 @@ ROP_PUSH_SEG(FS)
ROP_PUSH_SEG(GS)
ROP_PUSH_SEG(SS)
#define ROP_POP_SEG(seg, rseg) \
static uint32_t ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(2); \
\
return op_pc; \
} \
static uint32_t ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(4); \
\
return op_pc; \
#define ROP_POP_SEG(seg, rseg) \
static uint32_t \
ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(2); \
\
return op_pc; \
} \
static uint32_t \
ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
LOAD_SEG(0, &rseg); \
SP_MODIFY(4); \
\
return op_pc; \
}
ROP_POP_SEG(DS, cpu_state.seg_ds)

View File

@@ -219,8 +219,9 @@ CALL_FUNC(uintptr_t func)
}
static __inline void
RELEASE_REG(int host_reg)
RELEASE_REG(UNUSED(int host_reg))
{
//
}
static __inline int
@@ -536,7 +537,7 @@ FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
addlong((fetchdat >> 8) & 0xffff);
(*op_pc) += 2;
} else {
int base_reg = 0;
int base_reg = 0;
int index_reg = 0;
switch (rm) {
@@ -3949,7 +3950,8 @@ FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2)
static __inline int64_t
x87_fround16_64(double b)
{
int16_t a, c;
int16_t a;
int16_t c;
switch ((cpu_state.npxc >> 10) & 3) {
case 0: /*Nearest*/
@@ -3974,7 +3976,8 @@ x87_fround16_64(double b)
static __inline int64_t
x87_fround32_64(double b)
{
int32_t a, c;
int32_t a;
int32_t c;
switch ((cpu_state.npxc >> 10) & 3) {
case 0: /*Nearest*/
@@ -3999,7 +4002,8 @@ x87_fround32_64(double b)
static __inline int64_t
x87_fround(double b)
{
int64_t a, c;
int64_t a;
int64_t c;
switch ((cpu_state.npxc >> 10) & 3) {
case 0: /*Nearest*/
@@ -4550,8 +4554,9 @@ FP_COMPARE_IL(void)
}
static __inline void
UPDATE_NPXC(int reg)
UPDATE_NPXC(UNUSED(int reg))
{
//
}
static __inline void
@@ -4775,13 +4780,14 @@ STORE_MMX_Q_MMX(int guest_reg, int host_reg)
addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q));
}
#define MMX_x86_OP(name, opcode) \
static __inline void MMX_##name(int dst_reg, int src_reg) \
{ \
addbyte(0x66); /*op dst_reg, src_reg*/ \
addbyte(0x0f); \
addbyte(opcode); \
addbyte(0xc0 | (dst_reg << 3) | src_reg); \
#define MMX_x86_OP(name, opcode) \
static __inline void \
MMX_##name(int dst_reg, int src_reg) \
{ \
addbyte(0x66); /*op dst_reg, src_reg*/ \
addbyte(0x0f); \
addbyte(opcode); \
addbyte(0xc0 | (dst_reg << 3) | src_reg); \
}
MMX_x86_OP(AND, 0xdb)
@@ -5014,7 +5020,9 @@ LOAD_EA(void)
static __inline void
MEM_CHECK_WRITE(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3 = NULL;
uint8_t *jump1 = NULL;
uint8_t *jump2 = NULL;
uint8_t *jump3 = NULL;
CHECK_SEG_WRITE(seg);
@@ -5115,7 +5123,10 @@ MEM_CHECK_WRITE(x86seg *seg)
static __inline void
MEM_CHECK_WRITE_W(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3, *jump4 = NULL;
uint8_t *jump1 = NULL;
uint8_t *jump2 = NULL;
uint8_t *jump3 = NULL;
uint8_t *jump4 = NULL;
int jump_pos;
CHECK_SEG_WRITE(seg);
@@ -5248,7 +5259,10 @@ MEM_CHECK_WRITE_W(x86seg *seg)
static __inline void
MEM_CHECK_WRITE_L(x86seg *seg)
{
uint8_t *jump1, *jump2, *jump3, *jump4 = NULL;
uint8_t *jump1 = NULL;
uint8_t *jump2 = NULL;
uint8_t *jump3 = NULL;
uint8_t *jump4 = NULL;
int jump_pos;
CHECK_SEG_WRITE(seg);

View File

@@ -3619,37 +3619,39 @@ STORE_MMX_Q_MMX(int guest_reg, int host_reg)
addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q));
}
#define MMX_x86_OP(name, opcode) \
static __inline void MMX_##name(int dst_reg, int src_reg) \
{ \
addbyte(0x66); /*op dst_reg, src_reg*/ \
addbyte(0x0f); \
addbyte(opcode); \
addbyte(0xc0 | (dst_reg << 3) | src_reg); \
#define MMX_x86_OP(name, opcode) \
static \
__inline void MMX_##name(int dst_reg, int src_reg) \
{ \
addbyte(0x66); /*op dst_reg, src_reg*/ \
addbyte(0x0f); \
addbyte(opcode); \
addbyte(0xc0 | (dst_reg << 3) | src_reg); \
}
// clang-format off
MMX_x86_OP(AND, 0xdb)
MMX_x86_OP(ANDN, 0xdf)
MMX_x86_OP(OR, 0xeb)
MMX_x86_OP(XOR, 0xef)
MMX_x86_OP(ANDN, 0xdf)
MMX_x86_OP(OR, 0xeb)
MMX_x86_OP(XOR, 0xef)
MMX_x86_OP(ADDB, 0xfc)
MMX_x86_OP(ADDW, 0xfd)
MMX_x86_OP(ADDD, 0xfe)
MMX_x86_OP(ADDSB, 0xec)
MMX_x86_OP(ADDSW, 0xed)
MMX_x86_OP(ADDUSB, 0xdc)
MMX_x86_OP(ADDUSW, 0xdd)
MMX_x86_OP(ADDB, 0xfc)
MMX_x86_OP(ADDW, 0xfd)
MMX_x86_OP(ADDD, 0xfe)
MMX_x86_OP(ADDSB, 0xec)
MMX_x86_OP(ADDSW, 0xed)
MMX_x86_OP(ADDUSB, 0xdc)
MMX_x86_OP(ADDUSW, 0xdd)
MMX_x86_OP(SUBB, 0xf8)
MMX_x86_OP(SUBW, 0xf9)
MMX_x86_OP(SUBD, 0xfa)
MMX_x86_OP(SUBSB, 0xe8)
MMX_x86_OP(SUBSW, 0xe9)
MMX_x86_OP(SUBUSB, 0xd8)
MMX_x86_OP(SUBUSW, 0xd9)
MMX_x86_OP(SUBB, 0xf8)
MMX_x86_OP(SUBW, 0xf9)
MMX_x86_OP(SUBD, 0xfa)
MMX_x86_OP(SUBSB, 0xe8)
MMX_x86_OP(SUBSW, 0xe9)
MMX_x86_OP(SUBUSB, 0xd8)
MMX_x86_OP(SUBUSW, 0xd9)
MMX_x86_OP(PUNPCKLBW, 0x60);
MMX_x86_OP(PUNPCKLBW, 0x60);
MMX_x86_OP(PUNPCKLWD, 0x61);
MMX_x86_OP(PUNPCKLDQ, 0x62);
MMX_x86_OP(PCMPGTB, 0x64);
@@ -3672,6 +3674,7 @@ MMX_x86_OP(PSLLQ, 0xf3);
MMX_x86_OP(PMULLW, 0xd5);
MMX_x86_OP(PMULHW, 0xe5);
MMX_x86_OP(PMADDWD, 0xf5);
// clang-format on
static __inline void
MMX_PACKSSWB(int dst_reg, int src_reg)

View File

@@ -1,15 +1,16 @@
#define OP_XCHG_AX_(reg) \
static uint32_t ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int ax_reg, host_reg, temp_reg; \
\
ax_reg = LOAD_REG_W(REG_AX); \
host_reg = LOAD_REG_W(REG_##reg); \
temp_reg = COPY_REG(host_reg); \
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
\
return op_pc; \
#define OP_XCHG_AX_(reg) \
static uint32_t \
ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int ax_reg, host_reg, temp_reg; \
\
ax_reg = LOAD_REG_W(REG_AX); \
host_reg = LOAD_REG_W(REG_##reg); \
temp_reg = COPY_REG(host_reg); \
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
\
return op_pc; \
}
OP_XCHG_AX_(BX)
@@ -20,18 +21,19 @@ OP_XCHG_AX_(DI)
OP_XCHG_AX_(SP)
OP_XCHG_AX_(BP)
#define OP_XCHG_EAX_(reg) \
static uint32_t ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int eax_reg, host_reg, temp_reg; \
\
eax_reg = LOAD_REG_L(REG_EAX); \
host_reg = LOAD_REG_L(REG_##reg); \
temp_reg = COPY_REG(host_reg); \
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
\
return op_pc; \
#define OP_XCHG_EAX_(reg) \
static uint32_t \
ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int eax_reg, host_reg, temp_reg; \
\
eax_reg = LOAD_REG_L(REG_EAX); \
host_reg = LOAD_REG_L(REG_##reg); \
temp_reg = COPY_REG(host_reg); \
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
\
return op_pc; \
}
OP_XCHG_EAX_(EBX)

View File

@@ -11,8 +11,11 @@
# include "x86.h"
# include "x86_flags.h"
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
# include "386_common.h"
@@ -29,7 +32,8 @@
# include <windows.h>
# endif
int codegen_flat_ds, codegen_flat_ss;
int codegen_flat_ds;
int codegen_flat_ss;
int codegen_flags_changed = 0;
int codegen_fpu_entered = 0;
int codegen_fpu_loaded_iq[8];
@@ -63,8 +67,6 @@ static int last_ssegs;
void
codegen_init(void)
{
int c;
# if _WIN64
codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
# elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
@@ -77,26 +79,25 @@ codegen_init(void)
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
for (int c = 0; c < BLOCK_SIZE; c++)
codeblock[c].valid = 0;
}
void
codegen_reset(void)
{
int c;
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
mem_reset_page_blocks();
for (c = 0; c < BLOCK_SIZE; c++)
for (int c = 0; c < BLOCK_SIZE; c++)
codeblock[c].valid = 0;
}
void
dump_block(void)
{
//
}
static void
@@ -534,6 +535,7 @@ int opcode_0f_modrm[256] = {
void
codegen_debug(void)
{
//
}
static x86seg *

View File

@@ -49,6 +49,8 @@
# include "x86.h"
# include "x86_flags.h"
# include "x86_ops.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
/*ex*/
# include <86box/nmi.h>
@@ -1256,7 +1258,7 @@ codegen_init(void)
# else
__asm
{
fstcw cpu_state.old_npxc
fstcw cpu_state.old_npxc
}
# endif
}
@@ -1677,6 +1679,7 @@ int opcode_0f_modrm[256] = {
void
codegen_debug(void)
{
//
}
static x86seg *

View File

@@ -2,10 +2,13 @@
#include <86box/86box.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "x86_ops.h"
#include "codegen.h"
#include "x86.h"
#include "x86seg_common.h"
#include "x86seg.h"
#include "386_common.h"
@@ -90,7 +93,7 @@ codegen_generate_reset(void)
}
void
codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg)
codegen_check_seg_read(UNUSED(codeblock_t *block), ir_data_t *ir, x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
@@ -108,7 +111,7 @@ codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg)
seg->checked = 1;
}
void
codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg)
codegen_check_seg_write(UNUSED(codeblock_t *block), ir_data_t *ir, x86seg *seg)
{
/*Segments always valid in real/V86 mode*/
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
@@ -140,10 +143,10 @@ codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat,
int offset;
switch (cpu_rm & 7) {
default:
case 0:
case 1:
case 7:
default:
base_reg = IREG_EBX;
break;
case 2:
@@ -180,6 +183,9 @@ codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat,
uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset);
(*op_pc) += 2;
break;
default:
break;
}
uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff);
@@ -241,12 +247,16 @@ codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat,
(*op_pc) += 4;
uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7);
break;
default:
break;
}
if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/
{
if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) { /*ESP*/
uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset);
// addbyte(0x05);
// addlong(stack_offset);
#if 0
addbyte(0x05);
addlong(stack_offset);
#endif
}
if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &cpu_state.seg_ss;
@@ -264,6 +274,9 @@ codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat,
case 3:
uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3);
break;
default:
break;
}
}
} else {
@@ -374,7 +387,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
codeblock_t *block = &codeblock[block_current];
ir_data_t *ir = codegen_get_ir_data();
uint32_t op_pc = new_pc;
const OpFn *op_table = (OpFn *) x86_dynarec_opcodes;
const OpFn *op_table = x86_dynarec_opcodes;
RecompOpFn *recomp_op_table = recomp_opcodes;
int opcode_shift = 0;
int opcode_mask = 0x3ff;
@@ -637,7 +650,7 @@ generate_call:
if (!fpu_softfloat && recomp_opcodes_3DNOW[opcode_3dnow]) {
next_pc = opcode_pc + 1;
op_table = (OpFn *) x86_dynarec_opcodes_3DNOW;
op_table = x86_dynarec_opcodes_3DNOW;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_3DNOW;
opcode = opcode_3dnow;
recomp_opcode_mask = 0xff;
@@ -646,8 +659,10 @@ generate_call:
}
codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off);
/* It is apparently a prefixed instruction. */
// if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48))
// goto codegen_skip;
#if 0
if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48))
goto codegen_skip;
#endif
if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) {
uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc);
@@ -668,7 +683,7 @@ generate_call:
// codegen_skip:
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) {
op_table = (OpFn *) x86_dynarec_opcodes;
op_table = x86_dynarec_opcodes;
recomp_op_table = recomp_opcodes;
}
@@ -719,7 +734,9 @@ generate_call:
last_op_32 = op_32;
last_op_ea_seg = op_ea_seg;
last_op_ssegs = op_ssegs;
// codegen_block_ins++;
#if 0
codegen_block_ins++;
#endif
block->ins++;
@@ -728,6 +745,8 @@ generate_call:
codegen_endpc = (cs + cpu_state.pc) + 8;
// if (has_ea)
// fatal("Has EA\n");
#if 0
if (has_ea)
fatal("Has EA\n");
#endif
}

View File

@@ -290,7 +290,6 @@ codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len)
}
extern void codegen_init(void);
extern void codegen_close(void);
extern void codegen_reset(void);
extern void codegen_block_init(uint32_t phys_addr);
extern void codegen_block_remove(void);

View File

@@ -2,6 +2,7 @@
#include <86box/86box.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "codegen.h"
#include "codegen_accumulate.h"
@@ -16,7 +17,7 @@ static struct
};
void
codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
codegen_accumulate(UNUSED(ir_data_t *ir), int acc_reg, int delta)
{
acc_regs[acc_reg].count += delta;

View File

@@ -13,6 +13,7 @@
#include <86box/86box.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat_unused.h>
#include "codegen.h"
#include "codegen_allocator.h"
@@ -112,7 +113,7 @@ codeblock_allocator_get_ptr(mem_block_t *block)
}
void
codegen_allocator_clean_blocks(struct mem_block_t *block)
codegen_allocator_clean_blocks(UNUSED(struct mem_block_t *block))
{
#if defined __ARM_EABI__ || defined _ARM_ || defined __aarch64__ || defined _M_ARM || defined _M_ARM64
while (1) {

View File

@@ -13,6 +13,8 @@
# include "codegen_backend_arm_ops.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# if defined(__linux__) || defined(__APPLE__)
@@ -44,7 +46,7 @@ void *codegen_gpf_rout;
void *codegen_exit_rout;
host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = {
{REG_R4, 0},
{ REG_R4, 0},
{ REG_R5, 0},
{ REG_R6, 0},
{ REG_R7, 0},
@@ -54,7 +56,7 @@ host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = {
};
host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = {
{REG_D8, 0},
{ REG_D8, 0},
{ REG_D9, 0},
{ REG_D10, 0},
{ REG_D11, 0},
@@ -288,7 +290,6 @@ void
codegen_backend_init(void)
{
codeblock_t *block;
int c;
codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t));
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
@@ -296,7 +297,7 @@ codegen_backend_init(void)
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++)
for (int c = 0; c < BLOCK_SIZE; c++)
codeblock[c].pc = BLOCK_PC_INVALID;
block_current = 0;
@@ -306,7 +307,9 @@ codegen_backend_init(void)
block->data = codeblock_allocator_get_ptr(block->head_mem_block);
block_write_data = block->data;
build_loadstore_routines(&codeblock[block_current]);
// pclog("block_pos=%i\n", block_pos);
# if 0
pclog("block_pos=%i\n", block_pos);
# endif
codegen_fp_round = &block_write_data[block_pos];
build_fp_round_routine(&codeblock[block_current]);
@@ -322,7 +325,9 @@ codegen_backend_init(void)
host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC);
block_write_data = NULL;
// fatal("block_pos=%i\n", block_pos);
# if 0
fatal("block_pos=%i\n", block_pos);
# endif
asm("vmrs %0, fpscr\n"
: "=r"(cpu_state.old_fp_control));
if ((cpu_state.old_fp_control >> 22) & 3)

View File

@@ -13,6 +13,8 @@
# include "codegen_backend_arm64_ops.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# include "x87.h"
# if defined(__linux__) || defined(__APPLE__)
@@ -45,7 +47,7 @@ void *codegen_gpf_rout;
void *codegen_exit_rout;
host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = {
{REG_X19, 0},
{ REG_X19, 0},
{ REG_X20, 0},
{ REG_X21, 0},
{ REG_X22, 0},
@@ -58,7 +60,7 @@ host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = {
};
host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = {
{REG_V8, 0},
{ REG_V8, 0},
{ REG_V9, 0},
{ REG_V10, 0},
{ REG_V11, 0},
@@ -281,7 +283,6 @@ void
codegen_backend_init(void)
{
codeblock_t *block;
int c;
codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t));
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
@@ -289,7 +290,7 @@ codegen_backend_init(void)
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));
memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *));
for (c = 0; c < BLOCK_SIZE; c++) {
for (int c = 0; c < BLOCK_SIZE; c++) {
codeblock[c].pc = BLOCK_PC_INVALID;
}

View File

@@ -6,7 +6,7 @@
search over*/
#define IMM_NR 1302
static uint32_t imm_table[][2] = {
{0x800, 0x00000001},
{ 0x800, 0x00000001},
{ 0xfc0, 0x00000002},
{ 0x801, 0x00000003},
{ 0xf80, 0x00000004},

View File

@@ -1,9 +1,11 @@
#if defined __aarch64__ || defined _M_ARM64
# include <inttypes.h>
# include <stdint.h>
# include <86box/86box.h>
# include "cpu.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
# include "codegen.h"
# include "codegen_allocator.h"
@@ -340,7 +342,7 @@ host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm
} else if (imm_data & 0xfff000)
codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1));
} else
fatal("ADD_IMM_X %016llx\n", imm_data);
fatal("ADD_IMM_X %016" PRIu64 "\n", imm_data);
}
void
host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
@@ -662,7 +664,7 @@ host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data)
} else if (!(imm_data & 0xfffffffffffff000ull)) {
codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0));
} else
fatal("CMNX_IMM %08x\n", imm_data);
fatal("CMNX_IMM %016" PRIx64 "\n", imm_data);
}
void
@@ -683,7 +685,7 @@ host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data)
} else if (!(imm_data & 0xfffffffffffff000ull)) {
codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0));
} else
fatal("CMPX_IMM %08x\n", imm_data);
fatal("CMPX_IMM %08" PRIu64 "\n", imm_data);
}
void

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
# include <86box/86box.h>
# include "cpu.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
# include "codegen.h"
# include "codegen_allocator.h"
@@ -297,7 +298,9 @@ in_range(void *addr, void *base)
void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
// void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
# if 0
void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
# endif
void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
void

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,8 @@
# include "codegen_backend_x86-64_ops_sse.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# if defined(__linux__) || defined(__APPLE__)
# include <sys/mman.h>
@@ -71,7 +73,7 @@ static void
build_load_routine(codeblock_t *block, int size, int is_float)
{
uint8_t *branch_offset;
uint8_t *misaligned_offset;
uint8_t *misaligned_offset = NULL;
/*In - ESI = address
Out - ECX = data, ESI = abrt*/
@@ -159,7 +161,7 @@ static void
build_store_routine(codeblock_t *block, int size, int is_float)
{
uint8_t *branch_offset;
uint8_t *misaligned_offset;
uint8_t *misaligned_offset = NULL;
/*In - ECX = data, ESI = address
Out - ESI = abrt

View File

@@ -1,9 +1,11 @@
#if defined __amd64__ || defined _M_X64
# include <stdint.h>
# include <inttypes.h>
# include <86box/86box.h>
# include "cpu.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
# include "codegen.h"
# include "codegen_allocator.h"
@@ -125,7 +127,7 @@ host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data)
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/
} else
fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data);
fatal("ADD64_REG_IMM !is_imm8 %016" PRIx64 "\n", imm_data);
}
void
host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
@@ -584,7 +586,7 @@ host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 7);
codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/
codegen_addlong(block, offset);
@@ -604,7 +606,7 @@ host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 6);
codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/
codegen_addlong(block, offset);
@@ -689,11 +691,11 @@ host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 6);
codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/
codegen_addlong(block, offset);
} else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
} else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
codegen_alloc_bytes(block, 8);
codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/
codegen_addlong(block, ram_offset);
@@ -713,11 +715,11 @@ host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 7);
codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/
codegen_addlong(block, offset);
} else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
} else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
codegen_alloc_bytes(block, 9);
codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/
codegen_addbyte(block, 0x24);
@@ -743,11 +745,11 @@ host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 3);
codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 6);
codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/
codegen_addlong(block, offset);
} else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
} else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
codegen_alloc_bytes(block, 8);
codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/
codegen_addlong(block, ram_offset);
@@ -770,7 +772,7 @@ host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 7);
codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/
codegen_addlong(block, offset);
@@ -1091,7 +1093,7 @@ host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p)
codegen_alloc_bytes(block, 5);
codegen_addbyte(block, 0x66);
codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/
} else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
} else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
codegen_alloc_bytes(block, 10);
codegen_addbyte2(block, 0x66, 0x41);
codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/
@@ -1111,8 +1113,10 @@ host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p)
int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128);
int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram;
// if (dst_reg & 8)
// fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n");
#if 0
if (dst_reg & 8)
fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n");
#endif
if (offset >= -128 && offset < 127) {
if (dst_reg & 8) {
@@ -1123,7 +1127,7 @@ host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p)
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/
}
} else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
} else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
if (dst_reg & 8)
fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n");
@@ -1154,7 +1158,7 @@ host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/
} else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
} else if ((ram_offset < (1ULL << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) {
codegen_alloc_bytes(block, 9);
codegen_addbyte(block, 0x41);
codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/
@@ -1614,7 +1618,7 @@ host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data)
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/
} else
fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data);
fatal("SUB64_REG_IMM !is_imm8 %016" PRIx64 "\n", imm_data);
}
void
host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)

View File

@@ -1,16 +1,18 @@
#define JMP_LEN_BYTES 5
static inline void
codegen_addbyte(codeblock_t *block, uint8_t val)
codegen_addbyte(UNUSED(codeblock_t *block), uint8_t val)
{
if (block_pos >= BLOCK_MAX) {
fatal("codegen_addbyte over! %i\n", block_pos);
// CPU_BLOCK_END();
#if 0
CPU_BLOCK_END();
#endif
}
block_write_data[block_pos++] = val;
}
static inline void
codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb)
codegen_addbyte2(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb)
{
if (block_pos > (BLOCK_MAX - 2)) {
fatal("codegen_addbyte2 over! %i\n", block_pos);
@@ -20,7 +22,7 @@ codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb)
block_write_data[block_pos++] = valb;
}
static inline void
codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc)
codegen_addbyte3(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb, uint8_t valc)
{
if (block_pos > (BLOCK_MAX - 3)) {
fatal("codegen_addbyte3 over! %i\n", block_pos);
@@ -31,7 +33,7 @@ codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc)
block_write_data[block_pos++] = valc;
}
static inline void
codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald)
codegen_addbyte4(UNUSED(codeblock_t *block), uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald)
{
if (block_pos > (BLOCK_MAX - 4)) {
fatal("codegen_addbyte4 over! %i\n", block_pos);
@@ -44,7 +46,7 @@ codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, u
}
static inline void
codegen_addword(codeblock_t *block, uint16_t val)
codegen_addword(UNUSED(codeblock_t *block), uint16_t val)
{
if (block_pos > (BLOCK_MAX - 2)) {
fatal("codegen_addword over! %i\n", block_pos);
@@ -55,7 +57,7 @@ codegen_addword(codeblock_t *block, uint16_t val)
}
static inline void
codegen_addlong(codeblock_t *block, uint32_t val)
codegen_addlong(UNUSED(codeblock_t *block), uint32_t val)
{
if (block_pos > (BLOCK_MAX - 4)) {
fatal("codegen_addlong over! %i\n", block_pos);
@@ -66,7 +68,7 @@ codegen_addlong(codeblock_t *block, uint32_t val)
}
static inline void
codegen_addquad(codeblock_t *block, uint64_t val)
codegen_addquad(UNUSED(codeblock_t *block), uint64_t val)
{
if (block_pos > (BLOCK_MAX - 8)) {
fatal("codegen_addquad over! %i\n", block_pos);

View File

@@ -4,6 +4,7 @@
# include <86box/86box.h>
# include "cpu.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
# include "codegen.h"
# include "codegen_allocator.h"
@@ -127,7 +128,7 @@ host_x86_LDMXCSR(codeblock_t *block, void *p)
if (offset >= -128 && offset < 127) {
codegen_alloc_bytes(block, 4);
codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/
} else if (offset < (1ull << 32)) {
} else if (offset < (1ULL << 32)) {
codegen_alloc_bytes(block, 7);
codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/
codegen_addlong(block, offset);

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,8 @@
# include "codegen_backend_x86_ops_sse.h"
# include "codegen_reg.h"
# include "x86.h"
# include "x86seg_common.h"
# include "x86seg.h"
# if defined(__linux__) || defined(__APPLE__)
# include <sys/mman.h>

View File

@@ -4,6 +4,7 @@
# include <86box/86box.h>
# include "cpu.h"
# include <86box/mem.h>
# include <86box/plat_unused.h>
# include "codegen.h"
# include "codegen_allocator.h"

Some files were not shown because too many files have changed in this diff Show More