mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 09:05:32 -07:00
Merge branch 'master' into tc1995_pc98x1
This commit is contained in:
@@ -59,6 +59,7 @@ AppDir:
|
||||
- libqt5widgets5 # if QT:BOOL=ON
|
||||
- libsixel1 # if CLI:BOOL=ON
|
||||
- libslirp0
|
||||
- libsndfile1
|
||||
- libsndio7.0 # if OPENAL:BOOL=ON
|
||||
- libvdeplug-dev # -dev also pulls in libvdeplug2. -dev is required to get the proper .so symlink to the library
|
||||
- libx11-6 # if QT:BOOL=ON
|
||||
@@ -71,6 +72,7 @@ AppDir:
|
||||
- libxkbcommon-x11-0 # if QT:BOOL=ON
|
||||
- qtwayland5 # if QT:BOOL=ON
|
||||
- zlib1g
|
||||
- libserialport0
|
||||
files:
|
||||
exclude:
|
||||
- etc
|
||||
@@ -94,3 +96,4 @@ AppDir:
|
||||
AppImage:
|
||||
arch: !ENV '${arch_appimage}'
|
||||
file_name: !ENV '${appimage_path}'
|
||||
comp: gzip
|
||||
|
||||
7
.ci/Jenkinsfile
vendored
7
.ci/Jenkinsfile
vendored
@@ -20,11 +20,12 @@ def repository = ['https://github.com/86Box/86Box.git', scm.userRemoteConfigs[0]
|
||||
def commitBrowser = ['https://github.com/86Box/86Box/commit/%s', null]
|
||||
def branch = ['master', scm.branches[0].name]
|
||||
def buildType = ['beta', 'alpha']
|
||||
def tarballFlags = ['', '-t']
|
||||
def buildBranch = env.JOB_BASE_NAME.contains('-') ? 1 : 0
|
||||
|
||||
def osArchs = [
|
||||
'Windows': ['32', '64'],
|
||||
'Linux': ['x86', 'x86_64', 'arm32', 'arm64'],
|
||||
'Windows': ['64'],
|
||||
'Linux': ['x86_64', 'arm64'],
|
||||
'macOS': ['x86_64+x86_64h+arm64']
|
||||
]
|
||||
|
||||
@@ -238,7 +239,7 @@ pipeline {
|
||||
dir("${env.WORKSPACE_TMP}/output") {
|
||||
/* Run source tarball creation process. */
|
||||
def packageName = "${env.JOB_BASE_NAME}-Source$buildSuffix"
|
||||
if (runBuild("-s \"$packageName\"") == 0) {
|
||||
if (runBuild("-s \"$packageName\" ${tarballFlags[buildBranch]}") == 0) {
|
||||
/* Archive resulting artifacts. */
|
||||
archiveArtifacts artifacts: "$packageName*"
|
||||
} else {
|
||||
|
||||
157
.ci/build.sh
157
.ci/build.sh
@@ -48,6 +48,13 @@
|
||||
# architecture when invoking build.sh (either standalone or as part of an universal build)
|
||||
# - port and sed are called through sudo to manage dependencies; make sure those are configured
|
||||
# as NOPASSWD in /etc/sudoers if you're doing unattended builds
|
||||
# - Binaries are ad-hoc signed by default; specify a keychain name in ~/86box-keychain-name.txt
|
||||
# and password in ~/86box-keychain-password.txt to sign binaries with the first developer
|
||||
# certificate found inside that keychain.
|
||||
# - Notarization uses credentials stored in the same keychain used for signing. To save these
|
||||
# credentials, you must find the keychain's file path, run notarytool store-credentials with
|
||||
# --keychain pointed at that path, and specify the profile name you passed to notarytool in
|
||||
# ~/86box-keychain-notarytool.txt
|
||||
#
|
||||
|
||||
# Define common functions.
|
||||
@@ -126,6 +133,70 @@ save_buildtag() {
|
||||
return $?
|
||||
}
|
||||
|
||||
mac_keychain() {
|
||||
keychain_name=$(cat ~/86box-keychain-name.txt)
|
||||
if [ -n "$keychain_name" ]
|
||||
then
|
||||
echo $keychain_name
|
||||
security list-keychains -d user -s $(security list-keychains -d user | grep -Fv "/$keychain_name" | sed -e s/\ \*\"//g) "$keychain_name"
|
||||
security unlock-keychain -p "$(cat ~/86box-keychain-password.txt)" "$keychain_name"
|
||||
return $?
|
||||
fi
|
||||
}
|
||||
mac_signidentity() {
|
||||
if keychain_name=$(mac_keychain)
|
||||
then
|
||||
if [ -n "$keychain_name" ]
|
||||
then
|
||||
cert_name=$(security find-identity -v -p codesigning "$keychain_name" | perl -nle 'print for /([0-9A-F]+) "Developer ID Application: /')
|
||||
if [ -n "$cert_name" ]
|
||||
then
|
||||
echo [-] Using signing certificate [$cert_name] in keychain [$keychain_name] >&2
|
||||
echo "--keychain $keychain_name -s $cert_name"
|
||||
return 0
|
||||
else
|
||||
err="Keychain [$keychain_name] has no developer certificate"
|
||||
fi
|
||||
else
|
||||
err="No keychain specified"
|
||||
fi
|
||||
else
|
||||
err="Keychain [$keychain_name] failed to unlock"
|
||||
fi
|
||||
echo [!] $err, falling back to ad-hoc signing >&2
|
||||
echo "-s -"
|
||||
}
|
||||
mac_notarize() {
|
||||
if keychain_name=$(mac_keychain)
|
||||
then
|
||||
if [ -n "$keychain_name" ]
|
||||
then
|
||||
keychain_profile=$(cat ~/86box-keychain-notarytool.txt)
|
||||
if [ -n "$keychain_profile" ]
|
||||
then
|
||||
keychain_path=$(security list-keychains -d user | grep -F "/$keychain_name" | sed -e s/\ \*\"//g)
|
||||
if [ -n "$keychain_path" ]
|
||||
then
|
||||
echo [-] Notarizing with profile [$keychain_profile] in keychain [$keychain_name]
|
||||
# FIXME: needs a stapling system
|
||||
xcrun notarytool submit "$1" --keychain-profile "$keychain_profile" --keychain "$keychain_path" --no-wait
|
||||
return $?
|
||||
else
|
||||
err="File path for keychain [$keychain_name] not found"
|
||||
fi
|
||||
else
|
||||
err="No keychain profile specified"
|
||||
fi
|
||||
else
|
||||
err="No keychain specified"
|
||||
fi
|
||||
else
|
||||
err="Keychain [$keychain_name] failed to unlock"
|
||||
fi
|
||||
echo [!] $err, skipping notarization
|
||||
return 1
|
||||
}
|
||||
|
||||
# Set common variables.
|
||||
project=86Box
|
||||
cwd=$(pwd)
|
||||
@@ -208,7 +279,7 @@ cmake_flags_extra=
|
||||
if [ -z "$package_name" -a -z "$tarball_name" ] || [ -n "$package_name" -a -z "$arch" ]
|
||||
then
|
||||
echo '[!] Usage: build.sh -b {package_name} {architecture} [-t] [cmake_flags...]'
|
||||
echo ' build.sh -s {source_tarball_name}'
|
||||
echo ' build.sh -s {source_tarball_name} [-t]'
|
||||
echo 'Dep. tree: build.sh -p [archive_tmp/path/to/binary]'
|
||||
exit 100
|
||||
fi
|
||||
@@ -228,7 +299,10 @@ then
|
||||
[ ! -d "$cwd" ] && mkdir -p "$cwd"
|
||||
|
||||
# Save current HEAD commit to VERSION.
|
||||
git log --stat -1 > VERSION || rm -f VERSION
|
||||
if [ $strip -eq 0 ]
|
||||
then
|
||||
git log --stat -1 > VERSION || rm -f VERSION
|
||||
fi
|
||||
|
||||
# Archive source.
|
||||
make_tar "$cwd/$tarball_name.tar"
|
||||
@@ -469,12 +543,13 @@ then
|
||||
mv "archive_tmp_universal/$merge_src.app" "$app_bundle_name"
|
||||
|
||||
# Sign final app bundle.
|
||||
arch -"$(uname -m)" codesign --force --deep -s - "$app_bundle_name"
|
||||
arch -"$(uname -m)" codesign --force --deep $(mac_signidentity) -o runtime --entitlements src/mac/entitlements.plist --timestamp "$app_bundle_name"
|
||||
|
||||
# Create zip.
|
||||
echo [-] Creating artifact archive
|
||||
cd archive_tmp
|
||||
zip --symlinks -r "$cwd/$package_name.zip" .
|
||||
zip_name="$cwd/$package_name.zip"
|
||||
zip --symlinks -r "$zip_name" .
|
||||
status=$?
|
||||
|
||||
# Check if the archival succeeded.
|
||||
@@ -484,6 +559,9 @@ then
|
||||
exit 7
|
||||
fi
|
||||
|
||||
# Notarize the compressed app bundle.
|
||||
mac_notarize "$zip_name"
|
||||
|
||||
# All good.
|
||||
echo [-] Universal build of [$package_name] for [$arch] with flags [$cmake_flags] successful
|
||||
exit 0
|
||||
@@ -522,6 +600,9 @@ then
|
||||
cmake_flags_extra="$cmake_flags_extra -D MOLTENVK=ON -D \"MOLTENVK_INCLUDE_DIR=$macports\""
|
||||
fi
|
||||
|
||||
# Enable Libserialport
|
||||
cmake_flags_extra="$cmake_flags_extra -D \"LIBSERIALPORT_ROOT=$macports\""
|
||||
|
||||
# Install dependencies only if we're in a new build and/or MacPorts prefix.
|
||||
if check_buildtag "$(basename "$macports")"
|
||||
then
|
||||
@@ -535,6 +616,21 @@ then
|
||||
sudo sed -i -e 's/-no-feature-vulkan/-feature-vulkan/g' "$qt5_portfile"
|
||||
sudo sed -i -e 's/configure.env-append MAKE=/configure.env-append VULKAN_SDK=${prefix} MAKE=/g' "$qt5_portfile"
|
||||
fi
|
||||
|
||||
# Patch openal-soft to use 1.23.1 on all targets instead of 1.24.2 on >=10.13 only,
|
||||
# to prevent a symlink mismatch from having different versions on x86_64 and arm64.
|
||||
# See: https://github.com/macports/macports-ports/commit/9b4903fc9c76769d476079e404c9a3b8a225f8aa
|
||||
# https://github.com/macports/macports-ports/commit/788deb64dc0695e8d04afb32ed904947f2a7591b
|
||||
openal_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/audio/openal-soft/Portfile"
|
||||
sudo sed -i -e 's/if {${os.platform} ne "darwin" ||/if {0 \&\&/g' "$openal_portfile"
|
||||
|
||||
# Patch wget to remove libproxy support, as it depends on shared-mime-info which
|
||||
# fails to build for a 10.13 target, which we have to do despite wget only being
|
||||
# a host dependency. MacPorts issue 69406 strongly implies this will not be fixed.
|
||||
wget_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/net/wget/Portfile"
|
||||
sudo sed -i -e 's/--enable-libproxy/--disable-libproxy/g' "$wget_portfile"
|
||||
sudo sed -i -e 's/port:libproxy//g' "$wget_portfile"
|
||||
|
||||
while :
|
||||
do
|
||||
# Attempt to install dependencies.
|
||||
@@ -582,7 +678,7 @@ else
|
||||
grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version
|
||||
|
||||
# Establish general dependencies.
|
||||
pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream"
|
||||
pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream qttranslations5-l10n python3-pip python3-venv squashfs-tools"
|
||||
if [ "$(dpkg --print-architecture)" = "$arch_deb" ]
|
||||
then
|
||||
pkgs="$pkgs build-essential"
|
||||
@@ -605,7 +701,7 @@ else
|
||||
# ...and the ones we do want listed. Non-dev packages fill missing spots on the list.
|
||||
libpkgs=""
|
||||
longest_libpkg=0
|
||||
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev
|
||||
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev libserialport-dev
|
||||
do
|
||||
libpkgs="$libpkgs $pkg:$arch_deb"
|
||||
length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c)
|
||||
@@ -884,7 +980,7 @@ then
|
||||
fi
|
||||
|
||||
# Sign app bundle, unless we're in an universal build.
|
||||
[ $skip_archive -eq 0 ] && codesign --force --deep -s - "archive_tmp/"*".app"
|
||||
[ $skip_archive -eq 0 ] && codesign --force --deep $(mac_signidentity) -o runtime --entitlements src/mac/entitlements.plist --timestamp "archive_tmp/"*".app"
|
||||
elif [ "$BUILD_TAG" = "precondition" ]
|
||||
then
|
||||
# Continue with no app bundle on a dry build.
|
||||
@@ -1083,7 +1179,8 @@ elif is_mac
|
||||
then
|
||||
# Create zip.
|
||||
cd archive_tmp
|
||||
zip --symlinks -r "$cwd/$package_name.zip" .
|
||||
zip_name="$cwd/$package_name.zip"
|
||||
zip --symlinks -r "$zip_name" .
|
||||
status=$?
|
||||
else
|
||||
# Determine AppImage runtime architecture.
|
||||
@@ -1120,55 +1217,32 @@ EOF
|
||||
|
||||
# Copy line.
|
||||
echo "$line" >> AppImageBuilder-generated.yml
|
||||
|
||||
# Workaround for appimage-builder issues 272 and 283 (i686 and armhf are also missing)
|
||||
if [ "$arch_appimage" != "x86_64" -a "$line" = " files:" ]
|
||||
then
|
||||
# Some mild arbitrary code execution with a dummy package...
|
||||
[ ! -d /runtime ] && sudo apt-get -y -o 'DPkg::Post-Invoke::=mkdir -p /runtime; chmod 777 /runtime' install libsixel1 > /dev/null 2>&1
|
||||
|
||||
echo " include:" >> AppImageBuilder-generated.yml
|
||||
for loader in "/lib/$libdir/ld-linux"*.so.*
|
||||
do
|
||||
for loader_copy in "$loader" "/lib/$(basename "$loader")"
|
||||
do
|
||||
if [ ! -e "/runtime/compat$loader_copy" ]
|
||||
then
|
||||
mkdir -p "/runtime/compat$(dirname "$loader_copy")"
|
||||
ln -s "$loader" "/runtime/compat$loader_copy"
|
||||
fi
|
||||
echo " - /runtime/compat$loader_copy" >> AppImageBuilder-generated.yml
|
||||
done
|
||||
done
|
||||
fi
|
||||
done < .ci/AppImageBuilder.yml
|
||||
|
||||
# Download appimage-builder if necessary.
|
||||
appimage_builder_url="https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-$(uname -m).AppImage"
|
||||
appimage_builder_binary="$cache_dir/$(basename "$appimage_builder_url")"
|
||||
if [ ! -e "$appimage_builder_binary" ]
|
||||
appimage_builder_commit=22fefa298f9cee922a651a6f65a46fe0ccbfa34e # from issue 376
|
||||
appimage_builder_dir="$cache_dir/appimage-builder-$appimage_builder_commit"
|
||||
if [ ! -x "$appimage_builder_dir/bin/appimage-builder" ]
|
||||
then
|
||||
rm -rf "$cache_dir/"*".AppImage" # remove old versions
|
||||
wget -qO "$appimage_builder_binary" "$appimage_builder_url"
|
||||
rm -rf "$cache_dir/appimage-builder-"* # remove old versions
|
||||
python3 -m venv "$appimage_builder_dir" # venv to solve some Debian setuptools headaches
|
||||
"$appimage_builder_dir/bin/pip" install -U "git+https://github.com/AppImageCrafters/appimage-builder.git@$appimage_builder_commit"
|
||||
fi
|
||||
|
||||
# Symlink appimage-builder binary and global cache directory.
|
||||
# Symlink appimage-builder global cache directory.
|
||||
rm -rf appimage-builder.AppImage appimage-builder-cache "$project-"*".AppImage" # also remove any dangling AppImages which may interfere with the renaming process
|
||||
ln -s "$appimage_builder_binary" appimage-builder.AppImage
|
||||
chmod u+x appimage-builder.AppImage
|
||||
mkdir -p "$cache_dir/appimage-builder-cache"
|
||||
ln -s "$cache_dir/appimage-builder-cache" appimage-builder-cache
|
||||
|
||||
# Run appimage-builder in extract-and-run mode for Docker compatibility.
|
||||
# Run appimage-builder from the virtual environment created above.
|
||||
# --appdir is a workaround for appimage-builder issue 270 reported by us.
|
||||
for retry in 1 2 3 4 5
|
||||
do
|
||||
project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \
|
||||
arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \
|
||||
arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" "$appimage_builder_dir/bin/appimage-builder" \
|
||||
--recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)"
|
||||
status=$?
|
||||
[ $status -eq 0 ] && break
|
||||
[ $status -eq 127 ] && rm -rf /tmp/appimage_extracted_*
|
||||
done
|
||||
|
||||
# Remove appimage-builder binary on failure, just in case it's corrupted.
|
||||
@@ -1182,6 +1256,9 @@ then
|
||||
exit 7
|
||||
fi
|
||||
|
||||
# Notarize the compressed app bundle if we're on macOS.
|
||||
is_mac && mac_notarize "$zip_name"
|
||||
|
||||
# All good.
|
||||
echo [-] Build of [$package_name] for [$arch] with flags [$cmake_flags] successful
|
||||
exit 0
|
||||
|
||||
@@ -15,3 +15,5 @@ fluidsynth
|
||||
ghostscript
|
||||
libslirp
|
||||
vde2
|
||||
libsndfile
|
||||
libserialport
|
||||
|
||||
@@ -12,3 +12,6 @@ libslirp
|
||||
fluidsynth
|
||||
qt5-static
|
||||
qt5-translations
|
||||
vulkan-headers
|
||||
libsndfile
|
||||
libserialport
|
||||
|
||||
@@ -5,34 +5,11 @@ indent_style = space
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
|
||||
# Disabled for now since not all editors support setting a tab_width value different from indent_size
|
||||
# Relevant VSCode extension issue: https://github.com/editorconfig/editorconfig-vscode/issues/190
|
||||
# [*.rc]
|
||||
# indent_style = space
|
||||
# indent_size = 4
|
||||
# tab_width = 4
|
||||
|
||||
# [Makefile.*]
|
||||
# indent_style = space
|
||||
# indent_size = 4
|
||||
# tab_width = 4
|
||||
|
||||
[*.manifest]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[**/CMakeLists.txt]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.cmake]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
[*.ui]
|
||||
indent_size = 1
|
||||
|
||||
16
.gitattributes
vendored
16
.gitattributes
vendored
@@ -3,12 +3,28 @@
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
# Code
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cpp text
|
||||
*.h text
|
||||
*.hpp text
|
||||
|
||||
# CMake scripts
|
||||
CMakeLists.txt text
|
||||
*.cmake text
|
||||
|
||||
# Windows resource scripts and manifests
|
||||
*.rc text
|
||||
*.manifest text
|
||||
|
||||
# Translation files
|
||||
*.po text
|
||||
|
||||
# Qt XML files
|
||||
*.ui text
|
||||
*.ts text
|
||||
*.qrc text
|
||||
|
||||
|
||||
# Declare files that will always have CRLF line endings on checkout.
|
||||
|
||||
44
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
44
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -6,7 +6,15 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
## Thanks for taking the time to fill out this bug report!
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I **have searched** the issue tracker and **was unable** to find an [open](../issues?q=is%3Aissue+is%3Aopen) or [closed](../issues?q=is%3Aissue+is%3Aclosed) issue matching what I'm seeing.
|
||||
required: true
|
||||
- label: I **have verified** that the issue is happening in the **[latest nightly build](https://ci.86box.net/job/86Box/lastSuccessfulBuild/artifact/)**, or the latest commit, if building from source.
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What happened?
|
||||
@@ -25,20 +33,13 @@ body:
|
||||
attributes:
|
||||
label: Operating system
|
||||
description: What is your host operating system?
|
||||
placeholder: e.g. Windows 10
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: CPU
|
||||
description: What is your host CPU?
|
||||
placeholder: e.g. AMD Ryzen 5 5600G
|
||||
placeholder: e.g. Windows 11 24H2
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: 86Box version
|
||||
description: What version of 86Box are you running? (Saying "Latest from Jenkins" is not helpful.)
|
||||
description: What version of 86Box are you running? (Please ensure you have updated to the [latest build](https://ci.86box.net/job/86Box/lastSuccessfulBuild/artifact/) before reporting. Merely saying "Latest from Jenkins" is not helpful.)
|
||||
placeholder: e.g. v4.0 build 5000
|
||||
validations:
|
||||
required: true
|
||||
@@ -47,13 +48,13 @@ body:
|
||||
label: Build architecture
|
||||
description: 86Box for what architecture are you using?
|
||||
options:
|
||||
- Linux - ARM (32-bit)
|
||||
- Linux - ARM (64-bit)
|
||||
- Linux - x64 (64-bit)
|
||||
- Linux - x86 (32-bit)
|
||||
- macOS - Universal (Intel and Apple Silicon)
|
||||
- Windows - x64 (64-bit)
|
||||
- macOS - Universal (Intel and Apple Silicon)
|
||||
- Linux - x64 (64-bit)
|
||||
- Linux - ARM (64-bit)
|
||||
- Windows - x86 (32-bit)
|
||||
- Linux - ARM (32-bit)
|
||||
- Linux - x86 (32-bit)
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
@@ -63,18 +64,7 @@ body:
|
||||
options:
|
||||
- label: New recompiler
|
||||
- label: Debug build
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Download source
|
||||
description: Where did you download 86Box from?
|
||||
options:
|
||||
- Official website (Jenkins, GitHub)
|
||||
- Manager auto-update
|
||||
- I built 86Box myself (please tell us more about your build configuration)
|
||||
- I got 86Box from a third party repository (please tell us where)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Is there anything else you want to tell us?
|
||||
description: Is there anything else you want to tell us? If you build 86Box from source, please post your build configuration here.
|
||||
|
||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Machine Request
|
||||
url: https://github.com/86Box/86Box/issues/3577#issue-comment-box
|
||||
about: Please submit machine addition requests under this tracking issue.
|
||||
url: https://github.com/86Box/86Box/discussions/4823#issue-comment-box
|
||||
about: Please submit machine addition requests in this discussion thread.
|
||||
- name: Feature Request or Question
|
||||
url: https://github.com/86Box/86Box/discussions
|
||||
about: Please submit feature requests and ask questions here.
|
||||
|
||||
116
.github/workflows/c-cpp.yml
vendored
116
.github/workflows/c-cpp.yml
vendored
@@ -1,116 +0,0 @@
|
||||
name: MSYS2 Makefile (Windows, Legacy)
|
||||
|
||||
on:
|
||||
|
||||
push:
|
||||
paths:
|
||||
- src/**
|
||||
- .github/workflows/c-cpp.yml
|
||||
- "!**/CMakeLists.txt"
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- src/**
|
||||
- .github/workflows/c-cpp.yml
|
||||
- "!**/CMakeLists.txt"
|
||||
|
||||
jobs:
|
||||
msys2:
|
||||
# Negative condition disables the job
|
||||
if: false
|
||||
name: "Win32 GUI, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# debug: n
|
||||
# dev: n
|
||||
- name: Debug
|
||||
debug: y
|
||||
dev: n
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
debug: y
|
||||
dev: y
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: n
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: y
|
||||
slug: -NDR
|
||||
environment:
|
||||
# - msystem: MSYS
|
||||
# clang: n
|
||||
# x64: y
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
clang: n
|
||||
x64: n
|
||||
- msystem: MINGW64
|
||||
prefix: mingw-w64-x86_64
|
||||
clang: n
|
||||
x64: y
|
||||
# - msystem: CLANG32
|
||||
# prefix: mingw-w64-clang-i686
|
||||
# clang: y
|
||||
# x64: n
|
||||
# - msystem: CLANG64
|
||||
# prefix: mingw-w64-clang-x86_64
|
||||
# clang: y
|
||||
# x64: y
|
||||
- msystem: UCRT64
|
||||
prefix: mingw-w64-ucrt-x86_64
|
||||
clang: n
|
||||
x64: y
|
||||
|
||||
steps:
|
||||
- name: Prepare MSYS2 environment
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false
|
||||
update: true
|
||||
msystem: ${{ matrix.environment.msystem }}
|
||||
install: >-
|
||||
make
|
||||
pacboy: >-
|
||||
gcc:p
|
||||
clang:p
|
||||
pkg-config:p
|
||||
freetype:p
|
||||
SDL2:p
|
||||
zlib:p
|
||||
libpng:p
|
||||
openal:p
|
||||
rtmidi:p
|
||||
libslirp:p
|
||||
fluidsynth:p
|
||||
libvncserver:p
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: make
|
||||
run: >-
|
||||
make -fwin/Makefile.mingw -j
|
||||
DEV_BUILD=${{ matrix.build.dev }}
|
||||
DEBUG=${{ matrix.build.debug }}
|
||||
NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
CLANG=${{ matrix.environment.clang }}
|
||||
X64=${{ matrix.environment.x64 }}
|
||||
working-directory: ./src
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
|
||||
path: src/86Box.exe
|
||||
75
.github/workflows/cmake_linux.yml
vendored
75
.github/workflows/cmake_linux.yml
vendored
@@ -8,7 +8,8 @@ on:
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/cmake_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
@@ -18,20 +19,18 @@ on:
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/cmake_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.arch }}"
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
runs-on: ${{ matrix.environment.runner }}
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
@@ -40,10 +39,10 @@ jobs:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
preset: development
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
@@ -55,16 +54,47 @@ jobs:
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
qt6: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
- name: Qt 5 GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
qt6: off
|
||||
slug: -Qt5
|
||||
packages: >-
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
qttranslations5-l10n
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
- name: Qt 6 GUI
|
||||
qt: on
|
||||
qt6: on
|
||||
slug: -Qt6
|
||||
packages: >-
|
||||
qt6-base-dev
|
||||
qt6-base-private-dev
|
||||
qt6-tools-dev
|
||||
qt6-tools-dev-tools
|
||||
qt6-l10n-tools
|
||||
qt6-translations-l10n
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
libvulkan-dev
|
||||
environment:
|
||||
- arch: x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
slug: "-x86_64"
|
||||
runner: ubuntu-22.04
|
||||
- arch: arm64
|
||||
toolchain: ./cmake/flags-gcc-aarch64.cmake
|
||||
slug: -arm64
|
||||
runner: ubuntu-22.04-arm
|
||||
exclude:
|
||||
- dynarec:
|
||||
new: off
|
||||
environment:
|
||||
arch: arm64
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
@@ -80,7 +110,8 @@ jobs:
|
||||
libopenal-dev
|
||||
libslirp-dev
|
||||
libfluidsynth-dev
|
||||
libvncserver-dev
|
||||
libvdeplug-dev
|
||||
libserialport-dev
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
@@ -88,35 +119,25 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/flags-gcc-x86_64.cmake
|
||||
--toolchain ${{ matrix.environment.toolchain }}
|
||||
-D NEW_DYNAREC=${{ matrix.dynarec.new }}
|
||||
-D CMAKE_INSTALL_PREFIX=./build/artifacts
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D USE_QT6=${{ matrix.ui.qt6 }}
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
# if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
cmake --build build
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy-x86_64-gha${{ github.run_number }}'
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-UbuntuJammy${{ matrix.environment.slug }}-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
132
.github/workflows/cmake_macos.yml
vendored
132
.github/workflows/cmake_macos.yml
vendored
@@ -8,7 +8,8 @@ on:
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/cmake_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
@@ -18,20 +19,18 @@ on:
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/cmake_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
macos12:
|
||||
macos13-x86_64:
|
||||
|
||||
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
|
||||
runs-on: macos-13
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
@@ -40,10 +39,10 @@ jobs:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
preset: development
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
@@ -56,33 +55,23 @@ jobs:
|
||||
- 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
|
||||
libslirp
|
||||
vde
|
||||
libserialport
|
||||
${{ matrix.ui.packages }}
|
||||
|
||||
- name: Checkout repository
|
||||
@@ -90,9 +79,6 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
uses: SonarSource/sonarcloud-github-c-cpp@v2
|
||||
|
||||
- name: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
@@ -103,25 +89,93 @@ jobs:
|
||||
-D Qt5_ROOT=$(brew --prefix qt@5)
|
||||
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
|
||||
-D OpenAL_ROOT=$(brew --prefix openal-soft)
|
||||
-D LIBSERIALPORT_ROOT=$(brew --prefix libserialport)
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Run sonar-scanner
|
||||
if: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
|
||||
run: cmake --build build
|
||||
|
||||
- name: Generate package
|
||||
run: |
|
||||
cmake --install build
|
||||
run: cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
macos14-arm64:
|
||||
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, arm64"
|
||||
|
||||
runs-on: macos-14
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: development
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
# - name: ODR
|
||||
# new: off
|
||||
# slug: -ODR
|
||||
- name: NDR
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt@5
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
sdl2
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
libslirp
|
||||
vde
|
||||
libserialport
|
||||
${{ 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: Configure CMake
|
||||
run: >-
|
||||
cmake -G Ninja -S . -B build --preset ${{ matrix.build.preset }}
|
||||
--toolchain ./cmake/llvm-macos-aarch64.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)
|
||||
-D LIBSERIALPORT_ROOT=$(brew --prefix libserialport)
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Generate package
|
||||
run: cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-macOS-arm64-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
163
.github/workflows/cmake_windows_llvm.yml
vendored
163
.github/workflows/cmake_windows_llvm.yml
vendored
@@ -1,163 +0,0 @@
|
||||
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/**
|
||||
77
.github/workflows/cmake_windows_msys2.yml
vendored
77
.github/workflows/cmake_windows_msys2.yml
vendored
@@ -8,7 +8,8 @@ on:
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/cmake.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/cmake_windows_msys2.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
@@ -18,20 +19,18 @@ on:
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/cmake.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/cmake_windows_msys2.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
jobs:
|
||||
|
||||
msys2:
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
|
||||
|
||||
runs-on: windows-2022
|
||||
name: "${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
runs-on: ${{ matrix.environment.runner }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -44,10 +43,10 @@ jobs:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
- name: Debug
|
||||
preset: debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
preset: development
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
@@ -62,33 +61,41 @@ jobs:
|
||||
static: on
|
||||
slug: -Qt
|
||||
packages: >-
|
||||
qt5-static:p
|
||||
# qt5-base:p
|
||||
# qt5-tools:p
|
||||
qt5-base:p
|
||||
qt5-tools:p
|
||||
vulkan-headers:p
|
||||
environment:
|
||||
# - msystem: MSYS
|
||||
# toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
toolchain: ./cmake/flags-gcc-i686.cmake
|
||||
# slug: "-MSYS64"
|
||||
- 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
|
||||
slug: "-64"
|
||||
runner: windows-2022
|
||||
# - msystem: CLANG64
|
||||
# prefix: mingw-w64-clang-x86_64
|
||||
# toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
- msystem: UCRT64
|
||||
prefix: mingw-w64-ucrt-x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
# slug: "CLANG64"
|
||||
# - msystem: UCRT64
|
||||
# prefix: mingw-w64-ucrt-x86_64
|
||||
# toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
# slug: "UCRT64"
|
||||
- msystem: CLANGARM64
|
||||
toolchain: ./cmake/flags-gcc-aarch64.cmake
|
||||
slug: -arm64
|
||||
runner: windows-11-arm
|
||||
exclude:
|
||||
- dynarec:
|
||||
new: off
|
||||
environment:
|
||||
msystem: CLANGARM64
|
||||
|
||||
steps:
|
||||
- name: Prepare MSYS2 environment
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false
|
||||
release: true
|
||||
update: true
|
||||
msystem: ${{ matrix.environment.msystem }}
|
||||
pacboy: >-
|
||||
@@ -104,43 +111,31 @@ jobs:
|
||||
rtmidi:p
|
||||
libslirp:p
|
||||
fluidsynth:p
|
||||
libvncserver:p
|
||||
${{ matrix.ui.packages }}
|
||||
libserialport:p
|
||||
qt5-static:p
|
||||
vulkan-headers:p
|
||||
openmp:p
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
- name: Install 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 }}"
|
||||
run: cmake --build build
|
||||
|
||||
- name: Generate package
|
||||
run: cmake --install build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '86Box${{ matrix.ui.slug }}${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
|
||||
name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows${{ matrix.environment.slug }}-gha${{ github.run_number }}'
|
||||
path: build/artifacts/**
|
||||
|
||||
59
.github/workflows/codeql_linux.yml
vendored
59
.github/workflows/codeql_linux.yml
vendored
@@ -3,34 +3,43 @@ name: CodeQL Analysis (Linux)
|
||||
on:
|
||||
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/codeql_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/codeql_linux.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
schedule:
|
||||
- cron: '22 11 * * 0'
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-linux:
|
||||
|
||||
name: "Analyze Linux GCC 11 (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
name: "Analyze (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
@@ -43,12 +52,12 @@ jobs:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
- name: Debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
# - name: Dev
|
||||
# preset: development
|
||||
# slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
@@ -59,6 +68,7 @@ jobs:
|
||||
ui:
|
||||
- name: SDL GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
slug: -Qt
|
||||
@@ -66,6 +76,7 @@ jobs:
|
||||
qtbase5-dev
|
||||
qtbase5-private-dev
|
||||
qttools5-dev
|
||||
qttranslations5-l10n
|
||||
libevdev-dev
|
||||
libxkbcommon-x11-dev
|
||||
|
||||
@@ -83,14 +94,20 @@ jobs:
|
||||
libopenal-dev
|
||||
libslirp-dev
|
||||
libfluidsynth-dev
|
||||
libvncserver-dev
|
||||
libvdeplug-dev
|
||||
libserialport-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 Build Wrapper
|
||||
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v5
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
@@ -104,9 +121,23 @@ jobs:
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
run: |
|
||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
- name: SonarQube Scan
|
||||
if: matrix.build.preset == 'dev_debug' && matrix.dynarec.new == 'on' && matrix.ui.qt == 'on' && env.SONAR_TOKEN != ''
|
||||
# if: 0
|
||||
uses: SonarSource/sonarqube-scan-action@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
# SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
||||
with:
|
||||
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
|
||||
args: >
|
||||
--define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
||||
|
||||
66
.github/workflows/codeql_macos.yml
vendored
66
.github/workflows/codeql_macos.yml
vendored
@@ -3,33 +3,42 @@ name: CodeQL Analysis (macos)
|
||||
on:
|
||||
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/codeql_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/codeql_macos.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
schedule:
|
||||
- cron: '22 11 * * 0'
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-macos12:
|
||||
analyze-macos13-x86_64:
|
||||
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
|
||||
name: "Analyze (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64)"
|
||||
|
||||
runs-on: macos-12
|
||||
runs-on: macos-13
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
@@ -43,12 +52,12 @@ jobs:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
- name: Debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
# - name: Dev
|
||||
# preset: development
|
||||
# slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
@@ -69,21 +78,25 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: >-
|
||||
brew install
|
||||
ninja
|
||||
freetype
|
||||
sdl2
|
||||
libpng
|
||||
rtmidi
|
||||
openal-soft
|
||||
fluidsynth
|
||||
libvncserver
|
||||
libslirp
|
||||
vde
|
||||
libserialport
|
||||
${{ 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 Build Wrapper
|
||||
uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v5
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
@@ -98,11 +111,26 @@ jobs:
|
||||
-D Qt5_ROOT=$(brew --prefix qt@5)
|
||||
-D Qt5LinguistTools_ROOT=$(brew --prefix qt@5)
|
||||
-D OpenAL_ROOT=$(brew --prefix openal-soft)
|
||||
-D LIBSERIALPORT_ROOT=$(brew --prefix libserialport)
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
run: |
|
||||
build-wrapper-macosx-x86 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
- name: SonarQube Scan
|
||||
# if: matrix.build.preset == 'dev_debug' && matrix.dynarec.new == 'on' && matrix.ui.qt == 'on' && env.SONAR_TOKEN != ''
|
||||
if: 0
|
||||
uses: SonarSource/sonarqube-scan-action@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
# SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
||||
with:
|
||||
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
|
||||
args: >
|
||||
--define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
||||
|
||||
95
.github/workflows/codeql_windows_msys2.yml
vendored
95
.github/workflows/codeql_windows_msys2.yml
vendored
@@ -3,33 +3,42 @@ name: CodeQL Analysis (Windows, msys2)
|
||||
on:
|
||||
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/codeql.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/codeql_windows_msys2.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- src/**
|
||||
- cmake/**
|
||||
- "**/CMakeLists.txt"
|
||||
- "CMakePresets.json"
|
||||
- .github/workflows/**
|
||||
- .github/workflows/codeql.yml
|
||||
- "!.github/workflows/**"
|
||||
- .github/workflows/codeql_windows_msys2.yml
|
||||
- vcpkg.json
|
||||
- "!**/Makefile*"
|
||||
|
||||
schedule:
|
||||
- cron: '22 11 * * 0'
|
||||
|
||||
jobs:
|
||||
|
||||
analyze-msys2:
|
||||
|
||||
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }}"
|
||||
name: "Analyze (${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, ${{ matrix.environment.msystem }})"
|
||||
|
||||
runs-on: windows-2022
|
||||
runs-on: ${{ matrix.environment.runner }}
|
||||
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
@@ -47,12 +56,12 @@ jobs:
|
||||
build:
|
||||
# - name: Regular
|
||||
# preset: regular
|
||||
# - name: Debug
|
||||
# preset: debug
|
||||
# slug: -Debug
|
||||
- name: Dev
|
||||
preset: experimental
|
||||
slug: -Dev
|
||||
- name: Debug
|
||||
preset: dev_debug
|
||||
slug: -Debug
|
||||
# - name: Dev
|
||||
# preset: development
|
||||
# slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: off
|
||||
@@ -61,9 +70,6 @@ jobs:
|
||||
new: on
|
||||
slug: -NDR
|
||||
ui:
|
||||
- name: Win32 GUI
|
||||
qt: off
|
||||
static: on
|
||||
- name: Qt GUI
|
||||
qt: on
|
||||
static: off
|
||||
@@ -71,30 +77,41 @@ jobs:
|
||||
packages: >-
|
||||
qt5-base:p
|
||||
qt5-tools:p
|
||||
vulkan-headers:p
|
||||
environment:
|
||||
# - msystem: MSYS
|
||||
# toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
toolchain: ./cmake/flags-gcc-i686.cmake
|
||||
# slug: "-MSYS64"
|
||||
- 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
|
||||
slug: "-64"
|
||||
runner: windows-2022
|
||||
# - msystem: CLANG64
|
||||
# prefix: mingw-w64-clang-x86_64
|
||||
# toolchain: ./cmake/llvm-win32-x86_64.cmake
|
||||
- msystem: UCRT64
|
||||
prefix: mingw-w64-ucrt-x86_64
|
||||
toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
# slug: "CLANG64"
|
||||
# runner: windows-2022
|
||||
# - msystem: UCRT64
|
||||
# prefix: mingw-w64-ucrt-x86_64
|
||||
# toolchain: ./cmake/flags-gcc-x86_64.cmake
|
||||
# slug: "UCRT64"
|
||||
# runner: windows-2022
|
||||
# - msystem: CLANGARM64
|
||||
# toolchain: ./cmake/flags-gcc-aarch64.cmake
|
||||
# slug: -arm64
|
||||
# runner: windows-11-arm
|
||||
exclude:
|
||||
- dynarec:
|
||||
new: off
|
||||
environment:
|
||||
msystem: CLANGARM64
|
||||
|
||||
steps:
|
||||
- name: Prepare MSYS2 environment
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
release: false
|
||||
release: true
|
||||
update: true
|
||||
msystem: ${{ matrix.environment.msystem }}
|
||||
pacboy: >-
|
||||
@@ -110,14 +127,20 @@ jobs:
|
||||
rtmidi:p
|
||||
libslirp:p
|
||||
fluidsynth:p
|
||||
libvncserver:p
|
||||
libserialport:p
|
||||
${{ matrix.ui.packages }}
|
||||
openmp:p
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
|
||||
# - name: Install Build Wrapper
|
||||
# uses: SonarSource/sonarqube-scan-action/install-build-wrapper@v5
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
@@ -131,11 +154,27 @@ jobs:
|
||||
-D QT=${{ matrix.ui.qt }}
|
||||
-D STATIC_BUILD=${{ matrix.ui.static }}
|
||||
|
||||
# - name: Build
|
||||
# run: |
|
||||
# .sonar/build-wrapper-win-x86/build-wrapper-win-x86-64.exe --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
- name: SonarQube Scan
|
||||
# if: matrix.build.preset == 'dev_debug' && matrix.dynarec.new == 'on' && matrix.ui.qt == 'on' && env.SONAR_TOKEN != ''
|
||||
if: 0
|
||||
uses: SonarSource/sonarqube-scan-action@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
# SONAR_ROOT_CERT: ${{ secrets.SONAR_ROOT_CERT }}
|
||||
with:
|
||||
# Consult https://docs.sonarsource.com/sonarqube-server/latest/analyzing-source-code/scanners/sonarscanner/ for more information and options
|
||||
args: >
|
||||
--define sonar.cfamily.compile-commands="${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json"
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -59,3 +59,9 @@ CMakeLists.txt.user
|
||||
|
||||
# MacOS Finder stuff
|
||||
.DS_Store
|
||||
|
||||
# clangd
|
||||
.cache
|
||||
|
||||
# Jetbrains CLion
|
||||
.idea
|
||||
|
||||
122
CMakeLists.txt
122
CMakeLists.txt
@@ -1,16 +1,17 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2021-2025 Jasmine Iwanek.
|
||||
#
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
@@ -35,7 +36,7 @@ if(MUNT_EXTERNAL)
|
||||
endif()
|
||||
|
||||
project(86Box
|
||||
VERSION 4.1
|
||||
VERSION 5.1
|
||||
DESCRIPTION "Emulator of x86-based systems"
|
||||
HOMEPAGE_URL "https://86box.net"
|
||||
LANGUAGES C CXX)
|
||||
@@ -122,43 +123,68 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
||||
|
||||
# Optional features
|
||||
#
|
||||
# Option Description Def.
|
||||
# ------ ----------- ----
|
||||
option(RELEASE "Release build" OFF)
|
||||
option(DYNAREC "Dynamic recompiler" ON)
|
||||
option(OPENAL "OpenAL" ON)
|
||||
option(RTMIDI "RtMidi" ON)
|
||||
option(FLUIDSYNTH "FluidSynth" ON)
|
||||
option(MUNT "MUNT" ON)
|
||||
option(VNC "VNC renderer" OFF)
|
||||
option(DINPUT "DirectInput" OFF)
|
||||
option(CPPTHREADS "C++11 threads" ON)
|
||||
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
|
||||
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
|
||||
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
|
||||
option(DEV_BRANCH "Development branch" OFF)
|
||||
option(QT "Qt GUI" ON)
|
||||
option(DISCORD "Discord Rich Presence support" ON)
|
||||
# Option Description Def.
|
||||
# ------ ----------- ----
|
||||
option(RELEASE "Release build" OFF)
|
||||
option(DYNAREC "Dynamic recompiler" ON)
|
||||
option(OPENAL "OpenAL" ON)
|
||||
option(RTMIDI "RtMidi" ON)
|
||||
option(FLUIDSYNTH "FluidSynth" ON)
|
||||
option(MUNT "MUNT" ON)
|
||||
option(VNC "VNC renderer" OFF)
|
||||
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
|
||||
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
|
||||
option(DEV_BRANCH "Development branch" OFF)
|
||||
option(DISCORD "Discord Rich Presence support" ON)
|
||||
option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
|
||||
option(LIBASAN "Enable compilation with the addresss sanitizer" OFF)
|
||||
|
||||
if((ARCH STREQUAL "arm64") OR (ARCH STREQUAL "arm"))
|
||||
set(NEW_DYNAREC ON)
|
||||
else()
|
||||
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
|
||||
option(AUDIO4 "Use audio(4) as sound backend" ON)
|
||||
else()
|
||||
set(AUDIO4 OFF)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
option(SNDIO "Use sndio as sound backend" ON)
|
||||
else()
|
||||
set(SNDIO OFF)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(QT ON)
|
||||
option(CPPTHREADS "C++11 threads" OFF)
|
||||
else()
|
||||
option(QT "Qt GUI" ON)
|
||||
option(CPPTHREADS "C++11 threads" ON)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,wxneeded")
|
||||
endif()
|
||||
|
||||
# Development branch features
|
||||
#
|
||||
# Option Description Def. Condition Otherwise
|
||||
# ------ ----------- ---- --------- ---------
|
||||
cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(DESKPRO386 "Compaq Deskpro 386" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
|
||||
# Option Description Def. Condition Otherwise
|
||||
# ------ ----------- ---- ------------ ---------
|
||||
cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(WACOM "Wacom Input Devices" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
|
||||
cmake_dependent_option(NETSWITCH "Network Switch Support" ON "DEV_BRANCH" OFF)
|
||||
|
||||
# Ditto but for Qt
|
||||
if(QT)
|
||||
@@ -196,7 +222,15 @@ if(NOT EMU_BUILD_NUM)
|
||||
set(EMU_BUILD_NUM 0)
|
||||
endif()
|
||||
if(NOT EMU_COPYRIGHT_YEAR)
|
||||
set(EMU_COPYRIGHT_YEAR 2024)
|
||||
set(EMU_COPYRIGHT_YEAR 2025)
|
||||
endif()
|
||||
|
||||
# Libasan
|
||||
if(LIBASAN)
|
||||
add_compile_options(-fsanitize=address)
|
||||
add_link_options(-fsanitize=address)
|
||||
endif()
|
||||
|
||||
set(CMAKE_TOP_LEVEL_PROCESSED TRUE)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
@@ -43,17 +43,23 @@
|
||||
"name": "development",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"DEV_BRANCH": "ON",
|
||||
"NEW_DYNAREC": "OFF"
|
||||
"DEV_BRANCH": "ON"
|
||||
},
|
||||
"inherits": "base"
|
||||
},
|
||||
{
|
||||
"name": "experimental",
|
||||
"name": "dev_debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"DEV_BRANCH": "ON",
|
||||
"NEW_DYNAREC": "ON"
|
||||
"DEV_BRANCH": "ON"
|
||||
},
|
||||
"inherits": "base"
|
||||
},
|
||||
{
|
||||
"name": "ultra_debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "UltraDebug",
|
||||
"DEV_BRANCH": "ON"
|
||||
},
|
||||
"inherits": "base"
|
||||
},
|
||||
@@ -70,7 +76,8 @@
|
||||
"Qt5_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5",
|
||||
"MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk",
|
||||
"Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools",
|
||||
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft"
|
||||
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft",
|
||||
"LIBSERIALPORT_ROOT": "/opt/homebrew/opt/libserialport"
|
||||
},
|
||||
"inherits": "regular"
|
||||
},
|
||||
@@ -88,6 +95,7 @@
|
||||
"MOLTENVK_DIR": "/opt/homebrew/opt/molten-vk",
|
||||
"Qt5LinguistTools_DIR": "/opt/homebrew/opt/qt@5/lib/cmake/Qt5LinguistTools",
|
||||
"OpenAL_ROOT": "/opt/homebrew/opt/openal-soft",
|
||||
"LIBSERIALPORT_ROOT": "/opt/homebrew/opt/libserialport",
|
||||
"CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG",
|
||||
"CMAKE_C_FLAGS_DEBUG": "-g -O0 -DENABLE_VDE_LOG"
|
||||
},
|
||||
|
||||
19
README.md
19
README.md
@@ -26,15 +26,18 @@ Minimum system requirements and recommendations
|
||||
* macOS version: macOS High Sierra 10.13 or newer
|
||||
* 4 GB of RAM or higher
|
||||
|
||||
Performance may vary depending on both host and guest configuration. Most emulation logic is executed in a single thread; therefore, systems with better IPC (instructions per clock) generally should be able to emulate higher clock speeds.
|
||||
Performance may vary depending on host and guest configuration. Most emulation logic is executed in a single thread. Therefore, systems with greater IPC (instructions per clock) capacity should be able to emulate higher clock speeds.
|
||||
|
||||
It is also recommended to use a manager application with 86Box for easier handling of multiple virtual machines.
|
||||
For easier handling of multiple virtual machines, use a manager application:
|
||||
|
||||
* [Avalonia 86](https://github.com/notBald/Avalonia86) by [notBald](https://github.com/notBald) (Windows and Linux)
|
||||
* [86Box Manager](https://github.com/86Box/86BoxManager) by [Overdoze](https://github.com/daviunic) (Windows only)
|
||||
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by Dungeonseeker (Linux focused, should work on Windows though untested)
|
||||
* [86Box Manager X](https://github.com/RetBox/86BoxManagerX) by [xafero](https://github.com/xafero) (Cross platform Port of 86Box Manager using Avalonia)
|
||||
* [sl86](https://github.com/DDXofficial/sl86) by [DDX](https://github.com/DDXofficial) (Command-line 86Box machine manager written in Python)
|
||||
* [Linbox-qt5](https://github.com/Dungeonseeker/linbox-qt5) by [Dungeonseeker](https://github.com/Dungeonseeker/) (Linux focused, should work on Windows though untested)
|
||||
* [MacBox for 86Box](https://github.com/Moonif/MacBox) by [Moonif](https://github.com/Moonif) (MacOS only)
|
||||
|
||||
It is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option.
|
||||
To use 86Box on its own, use the `--vmpath`/`-P` command line option.
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
@@ -44,17 +47,21 @@ See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for a
|
||||
Community
|
||||
---------
|
||||
|
||||
We operate an IRC channel and a Discord server for discussing 86Box, its development and anything related to retro computing. We look forward to hearing from you!
|
||||
We operate an IRC channel and a Discord server for discussing 86Box, its development, and anything related to retro computing. We look forward to hearing from you!
|
||||
|
||||
[](https://kiwiirc.com/client/irc.ringoflightning.net/?nick=86box|?#86Box)
|
||||
|
||||
[](https://discord.gg/QXK9XTv)
|
||||
|
||||
Contributions
|
||||
---------
|
||||
-------------
|
||||
|
||||
We welcome all contributions to the project, as long as the [contribution guidelines](CONTRIBUTING.md) are followed.
|
||||
|
||||
Building
|
||||
---------
|
||||
For instructions on how to build 86Box from source, see the [build guide](https://86box.readthedocs.io/en/latest/dev/buildguide.html).
|
||||
|
||||
Licensing
|
||||
---------
|
||||
|
||||
|
||||
18
SECURITY.md
Normal file
18
SECURITY.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| >= master | :white_check_mark: |
|
||||
| < master | :x: |
|
||||
|
||||
Each version is supported in the form of patch releases until the next version is merged into master.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a vulnerability, either open an issue here on GitHub or join our Discord server. If it is
|
||||
accepted, that means we have begun working on it and it will be fixed if it is at all possible. If it
|
||||
is declined, then that means we have either determined it to not actually be a vulnerability or we
|
||||
have determined it is not feasible to fix it. On GitHub, we are going to notify you when a decision
|
||||
taken, and if accepted, when it is fixed. On Discord, you get live updates.
|
||||
@@ -26,12 +26,6 @@ then
|
||||
fi
|
||||
shift
|
||||
|
||||
# Extract version components.
|
||||
newversion_maj=$(echo "$newversion" | cut -d. -f1)
|
||||
newversion_min=$(echo "$newversion" | cut -d. -f2)
|
||||
newversion_patch=$(echo "$newversion" | cut -d. -f3)
|
||||
[ -z "$newversion_patch" ] && newversion_patch=0
|
||||
|
||||
if [ -z "${romversion}" ]; then
|
||||
# Get the latest ROM release from the GitHub API.
|
||||
romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" |
|
||||
@@ -62,12 +56,6 @@ patch_file() {
|
||||
}
|
||||
patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/'
|
||||
patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION 's/(#\s*define\s+EMU_VERSION\s+")[^"]+/\1'"$newversion"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION_MAJ 's/(#\s*define\s+EMU_VERSION_MAJ\s+)[0-9]+/\1'"$newversion_maj"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION_MIN 's/(#\s*define\s+EMU_VERSION_MIN\s+)[0-9]+/\1'"$newversion_min"'/'
|
||||
patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_VERSION_PATCH\s+)[0-9]+/\1'"$newversion_patch"'/'
|
||||
patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/'
|
||||
patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/'
|
||||
patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/'
|
||||
patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/'
|
||||
patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/'
|
||||
|
||||
@@ -20,6 +20,8 @@ string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3")
|
||||
string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og")
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -ggdb -Og")
|
||||
string(APPEND CMAKE_C_FLAGS_ULTRADEBUG_INIT " -O0 -ggdb -g3")
|
||||
string(APPEND CMAKE_CXX_FLAGS_ULTRADEBUG_INIT " -O0 -ggdb -g3")
|
||||
string(APPEND CMAKE_C_FLAGS_OPTIMIZED_INIT " -march=native -mtune=native -O3 -ffp-contract=fast -flto")
|
||||
string(APPEND CMAKE_CXX_FLAGS_OPTIMIZED_INIT " -march=native -mtune=native -O3 -ffp-contract=fast -flto")
|
||||
|
||||
@@ -28,7 +30,7 @@ foreach(LANG C;CXX)
|
||||
set(CMAKE_${LANG}_FLAGS "$ENV{${LANG}FLAGS} ${CMAKE_${LANG}_FLAGS_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during all build types.")
|
||||
mark_as_advanced(CMAKE_${LANG}_FLAGS)
|
||||
|
||||
foreach(CONFIG RELEASE;DEBUG;OPTIMIZED)
|
||||
foreach(CONFIG RELEASE;DEBUG;ULTRADEBUG;OPTIMIZED)
|
||||
set(CMAKE_${LANG}_FLAGS_${CONFIG} "${CMAKE_${LANG}_FLAGS_${CONFIG}_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during ${CONFIG} builds.")
|
||||
mark_as_advanced(CMAKE_${LANG}_FLAGS_${CONFIG})
|
||||
endforeach()
|
||||
|
||||
20
cmake/intel-linux-x86_64.cmake
Normal file
20
cmake/intel-linux-x86_64.cmake
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake toolchain file defining GCC compiler flags
|
||||
# for 64-bit x86 targets.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2021 David Hrdlička.
|
||||
#
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-x86_64.cmake)
|
||||
|
||||
set(CMAKE_C_COMPILER icx)
|
||||
set(CMAKE_CXX_COMPILER icpx)
|
||||
23
cmake/llvm-linux-x86_64.cmake
Normal file
23
cmake/llvm-linux-x86_64.cmake
Normal file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake toolchain file defining Clang compiler flags
|
||||
# for 64-bit x86 targets.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# dob205
|
||||
#
|
||||
# Copyright 2021 David Hrdlička.
|
||||
# Copyright 2022 dob205.
|
||||
#
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-x86_64.cmake)
|
||||
|
||||
# Use the GCC-compatible Clang executables in order to use our flags
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
4
debian/changelog
vendored
4
debian/changelog
vendored
@@ -1,5 +1,5 @@
|
||||
86box (4.1) UNRELEASED; urgency=medium
|
||||
86box (5.1) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump release.
|
||||
|
||||
-- Jasmine Iwanek <jriwanek@gmail.com> Mon, 16 Oct 2023 20:24:46 +0200
|
||||
-- Jasmine Iwanek <jriwanek@gmail.com> Wed, 27 Aug 2025 19:39:16 +0200
|
||||
|
||||
6
debian/control
vendored
6
debian/control
vendored
@@ -13,9 +13,11 @@ Build-Depends: cmake (>= 3.21),
|
||||
libsdl2-dev,
|
||||
libslirp-dev,
|
||||
libxkbcommon-x11-dev,
|
||||
libsndfile-dev,
|
||||
ninja-build,
|
||||
qttools5-dev,
|
||||
qtbase5-private-dev
|
||||
qtbase5-private-dev,
|
||||
libserialport-dev
|
||||
Standards-Version: 4.6.0
|
||||
Homepage: https://86box.net/
|
||||
#Vcs-Browser: https://salsa.debian.org/debian/86box
|
||||
@@ -31,4 +33,4 @@ Recommends: libpcap0.8-dev
|
||||
Description: An emulator for classic IBM PC clones
|
||||
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.
|
||||
fairly recent system designs based on the PCI bus.
|
||||
|
||||
814
src/86box.c
814
src/86box.c
File diff suppressed because it is too large
Load Diff
@@ -12,16 +12,43 @@
|
||||
# dob205
|
||||
#
|
||||
# Copyright 2020-2022 David Hrdlička.
|
||||
# Copyright 2021 dob205.
|
||||
# Copyright 2021 dob205.
|
||||
# Copyright 2024 Jasmine Iwanek.
|
||||
#
|
||||
|
||||
if(NOT CMAKE_TOP_LEVEL_PROCESSED)
|
||||
message(FATAL_ERROR "Incorrect source directory specified. Delete your build directory and retry with the top-level directory instead")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif()
|
||||
|
||||
add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
|
||||
dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
|
||||
mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
|
||||
machine_status.c ini.c)
|
||||
add_executable(86Box
|
||||
86box.c
|
||||
config.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
|
||||
device.c
|
||||
nvr.c
|
||||
nvr_at.c
|
||||
nvr_ps2.c
|
||||
machine_status.c
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
|
||||
@@ -48,21 +75,24 @@ if(DYNAREC)
|
||||
add_compile_definitions(USE_DYNAREC)
|
||||
endif()
|
||||
|
||||
if(DEV_BRANCH)
|
||||
add_compile_definitions(DEV_BRANCH)
|
||||
endif()
|
||||
|
||||
if(DISCORD)
|
||||
add_compile_definitions(DISCORD)
|
||||
target_sources(86Box PRIVATE discord.c)
|
||||
endif()
|
||||
|
||||
if(DEBUGREGS486)
|
||||
add_compile_definitions(USE_DEBUG_REGS_486)
|
||||
endif()
|
||||
|
||||
if(VNC)
|
||||
find_package(LibVNCServer)
|
||||
if(LibVNCServer_FOUND)
|
||||
add_compile_definitions(USE_VNC)
|
||||
add_library(vnc OBJECT vnc.c vnc_keymap.c)
|
||||
target_link_libraries(86Box vnc LibVNCServer::vncserver)
|
||||
add_library(vnc OBJECT
|
||||
vnc.c
|
||||
vnc_keymap.c
|
||||
)
|
||||
target_link_libraries(86Box vnc LibVNCServer::vncserver)
|
||||
if(WIN32)
|
||||
target_link_libraries(86Box ws2_32)
|
||||
endif()
|
||||
@@ -73,8 +103,12 @@ if(INSTRUMENT)
|
||||
add_compile_definitions(USE_INSTRUMENT)
|
||||
endif()
|
||||
|
||||
target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd
|
||||
net print scsi sio snd vid voodoo plat ui)
|
||||
target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom rdisk mo hdd
|
||||
net print scsi sio snd utils vid voodoo plat ui)
|
||||
|
||||
if(HAIKU)
|
||||
target_link_libraries(86Box be)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND ARCH STREQUAL "i386")
|
||||
if(MINGW)
|
||||
@@ -119,16 +153,6 @@ if(APPLE)
|
||||
target_link_libraries(86Box Freetype::Freetype)
|
||||
endif()
|
||||
|
||||
find_package(SDL2 REQUIRED)
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
if(STATIC_BUILD AND TARGET SDL2::SDL2-static)
|
||||
target_link_libraries(86Box SDL2::SDL2-static)
|
||||
elseif(TARGET SDL2::SDL2)
|
||||
target_link_libraries(86Box SDL2::SDL2)
|
||||
else()
|
||||
target_link_libraries(86Box ${SDL2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
include_directories(${PNG_INCLUDE_DIRS})
|
||||
target_link_libraries(86Box PNG::PNG)
|
||||
@@ -139,8 +163,10 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
include_directories(include)
|
||||
if(NEW_DYNAREC)
|
||||
include_directories(cpu codegen_new)
|
||||
else()
|
||||
elseif(DYNAREC)
|
||||
include_directories(cpu codegen)
|
||||
else()
|
||||
include_directories(cpu)
|
||||
endif()
|
||||
|
||||
add_subdirectory(cdrom)
|
||||
@@ -149,7 +175,7 @@ add_subdirectory(chipset)
|
||||
add_subdirectory(cpu)
|
||||
if(NEW_DYNAREC)
|
||||
add_subdirectory(codegen_new)
|
||||
else()
|
||||
elseif(DYNAREC)
|
||||
add_subdirectory(codegen)
|
||||
endif()
|
||||
|
||||
@@ -189,7 +215,6 @@ elseif(APPLE AND NOT QT)
|
||||
COMPONENT Runtime)
|
||||
endif()
|
||||
|
||||
|
||||
# Install the PDB file on Windows builds
|
||||
if(MSVC)
|
||||
# CMake fully supports PDB files on MSVC-compatible compilers
|
||||
@@ -219,16 +244,20 @@ add_subdirectory(printer)
|
||||
add_subdirectory(sio)
|
||||
add_subdirectory(scsi)
|
||||
add_subdirectory(sound)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(video)
|
||||
|
||||
if (APPLE)
|
||||
add_subdirectory(mac)
|
||||
endif()
|
||||
|
||||
if (QT)
|
||||
add_subdirectory(qt)
|
||||
elseif(WIN32)
|
||||
add_subdirectory(win)
|
||||
else()
|
||||
add_compile_definitions(USE_SDL_UI)
|
||||
add_subdirectory(unix)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
add_custom_command(TARGET 86Box POST_BUILD COMMAND paxctl ARGS +m $<TARGET_FILE:86Box> COMMENT "Disable PaX MPROTECT")
|
||||
endif()
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# Prefix for localizing the general Makefile.mingw for local
|
||||
# settings, so we can avoid changing the main one for all of
|
||||
# our local setups.
|
||||
#
|
||||
# Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
|
||||
#########################################################################
|
||||
# Anything here will override defaults in Makefile.MinGW. #
|
||||
#########################################################################
|
||||
|
||||
|
||||
# Name of the executable.
|
||||
#PROG := 86box.exe
|
||||
|
||||
|
||||
# Various compile-time options.
|
||||
# -DROM_TRACE=0xc800 traces ROM access from segment C800
|
||||
# -DIO_TRACE=0x66 traces I/O on port 0x66
|
||||
# -DIO_CATCH enables I/O range catch logs
|
||||
STUFF :=
|
||||
|
||||
# Add feature selections here.
|
||||
# -DANSI_CFG forces the config file to ANSI encoding.
|
||||
# Root logging:
|
||||
# -DENABLE_ACPI_LOG=N sets logging level at N.
|
||||
# -DENABLE_APM_LOG=N sets logging level at N.
|
||||
# -DENABLE_BUGGER_LOG=N sets logging level at N.
|
||||
# -DENABLE_CONFIG_LOG=N sets logging level at N.
|
||||
# -DENABLE_DDMA_LOG=N sets logging level at N.
|
||||
# -DENABLE_DEVICE_LOG=N sets logging level at N.
|
||||
# -DENABLE_DMA_LOG=N sets logging level at N.
|
||||
# -DENABLE_IO_LOG=N sets logging level at N.
|
||||
# -DENABLE_IOAPIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_ISAMEM_LOG=N sets logging level at N.
|
||||
# -DENABLE_ISARTC_LOG=N sets logging level at N.
|
||||
# -DENABLE_KEYBOARD_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_KEYBOARD_XT_LOG=N sets logging level at N.
|
||||
# -DENABLE_LM75_LOG=N sets logging level at N.
|
||||
# -DENABLE_LM78_LOG=N sets logging level at N.
|
||||
# -DENABLE_MEM_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_BUS_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_PS2_LOG=N sets logging level at N.
|
||||
# -DENABLE_MOUSE_SERIAL_LOG=N sets logging level at N.
|
||||
# -DENABLE_NVR_LOG=N sets logging level at N.
|
||||
# -DENABLE_PC_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCI_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIT_LOG=N sets logging level at N.
|
||||
# -DENABLE_POSTCARD_LOG=N sets logging level at N.
|
||||
# -DENABLE_ROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_SERIAL_LOG=N sets logging level at N.
|
||||
# -DENABLE_SMBUS_LOG=N sets logging level at N.
|
||||
# -DENABLE_SMBUS_PIIX4_LOG=N sets logging level at N.
|
||||
# -DENABLE_SPD_LOG=N sets logging level at N.
|
||||
# -DENABLE_USB_LOG=N sets logging level at N.
|
||||
# -DENABLE_VNC_LOG=N sets logging level at N.
|
||||
# -DENABLE_VNC_KEYMAP_LOG=N sets logging level at N.
|
||||
# cdrom/ logging:
|
||||
# -DENABLE_CDROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_CDROM_IMAGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_CDROM_IMAGE_BACKEND_LOG=N sets logging level at N.
|
||||
# chipset/ logging:
|
||||
# -DENABLE_I420EX_LOG=N sets logging level at N.
|
||||
# -DENABLE_NEAT_LOG=N sets logging level at N.
|
||||
# -DENABLE_OPTI495_LOG=N sets logging level at N.
|
||||
# -DENABLE_OPTI895_LOG=N sets logging level at N.
|
||||
# -DENABLE_PIIX_LOG=N sets logging level at N.
|
||||
# -DENABLE_SIO_LOG=N sets logging level at N.
|
||||
# -DENABLE_SIS_85C496_LOG=N sets logging level at N.
|
||||
# codegen/, codegen_new/, cpu/ logging:
|
||||
# -DENABLE_X86SEG_LOG=N sets logging level at N.
|
||||
# cpu/ logging:
|
||||
# -DENABLE_386_LOG=N sets logging level at N.
|
||||
# -DENABLE_386_COMMON_LOG=N sets logging level at N.
|
||||
# -DENABLE_386_DYNAREC_LOG=N sets logging level at N.
|
||||
# -DENABLE_808X_LOG=N sets logging level at N.
|
||||
# -DENABLE_CPU_LOG=N sets logging level at N.
|
||||
# -DENABLE_FPU_LOG=N sets logging level at N.
|
||||
# disk/ logging:
|
||||
# -DENABLE_ESDI_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_ESDI_MCA_LOG=N sets logging level at N.
|
||||
# -DENABLE_HDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_IDE_LOG=N sets logging level at N.
|
||||
# -DENABLE_MO_LOG=N sets logging level at N.
|
||||
# -DENABLE_SFF_LOG=N sets logging level at N.
|
||||
# -DENABLE_ST506_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_ST506_XT_LOG=N sets logging level at N.
|
||||
# -DENABLE_XTA_LOG=N sets logging level at N.
|
||||
# -DENABLE_ZIP_LOG=N sets logging level at N.
|
||||
# floppy/ logging:
|
||||
# -DENABLE_D86F_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDD_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDI_LOG=N sets logging level at N.
|
||||
# -DENABLE_FDI2RAW_LOG=N sets logging level at N.
|
||||
# -DENABLE_IMD_LOG=N sets logging level at N.
|
||||
# -DENABLE_IMG_LOG=N sets logging level at N.
|
||||
# -DENABLE_JSON_LOG=N sets logging level at N.
|
||||
# -DENABLE_MFM_LOG=N sets logging level at N.
|
||||
# -DENABLE_TD0_LOG=N sets logging level at N.
|
||||
# machine/ logging:
|
||||
# -DENABLE_AMSTRAD_LOG=N sets logging level at N.
|
||||
# -DENABLE_EUROPC_LOG=N sets logging level at N.
|
||||
# -DENABLE_M24VID_LOG=N sets logging level at N.
|
||||
# -DENABLE_MACHINE_LOG=N sets logging level at N.
|
||||
# -DENABLE_PS1_HDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_PS2_MCA_LOG=N sets logging level at N.
|
||||
# -DENABLE_TANDY_LOG=N sets logging level at N.
|
||||
# -DENABLE_T1000_LOG=N sets logging level at N.
|
||||
# -DENABLE_T3100E_LOG=N sets logging level at N.
|
||||
# network/ logging:
|
||||
# -DENABLE_3COM503_LOG=N sets logging level at N.
|
||||
# -DENABLE_DP8390_LOG=N sets logging level at N.
|
||||
# -DENABLE_NETWORK_LOG=N sets logging level at N.
|
||||
# -DENABLE_NE2K_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCAP_LOG=N sets logging level at N.
|
||||
# -DENABLE_PCNET_LOG=N sets logging level at N.
|
||||
# -DENABLE_SLIRP_LOG=N sets logging level at N.
|
||||
# -DENABLE_WD_LOG=N sets logging level at N.
|
||||
# printer/ logging:
|
||||
# -DENABLE_ESCP_LOG=N sets logging level at N.
|
||||
# scsi/ logging:
|
||||
# -DENABLE_AHA154X_LOG=N sets logging level at N.
|
||||
# -DENABLE_BUSLOGIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_NCR5380_LOG=N sets logging level at N.
|
||||
# -DENABLE_NCR53C8XX_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
|
||||
# -DENABLE_SPOCK_LOG=N sets logging level at N.
|
||||
# -DENABLE_X54X_LOG=N sets logging level at N.
|
||||
# sound/ logging:
|
||||
# -DENABLE_ADLIB_LOG=N sets logging level at N.
|
||||
# -DENABLE_AUDIOPCI_LOG=N sets logging level at N.
|
||||
# -DENABLE_EMU8K_LOG=N sets logging level at N.
|
||||
# -DENABLE_MPU401_LOG=N sets logging level at N.
|
||||
# -DENABLE_PAS16_LOG=N sets logging level at N.
|
||||
# -DENABLE_SB_LOG=N sets logging level at N.
|
||||
# -DENABLE_SB_DSP_LOG=N sets logging level at N.
|
||||
# -DENABLE_SOUND_LOG=N sets logging level at N.
|
||||
# video/ logging:
|
||||
# -DENABLE_ATI28800_LOG=N sets logging level at N.
|
||||
# -DENABLE_MACH64_LOG=N sets logging level at N.
|
||||
# -DENABLE_COMPAQ_CGA_LOG=N sets logging level at N.
|
||||
# -DENABLE_ET4000W32_LOG=N sets logging level at N.
|
||||
# -DENABLE_HT216_LOG=N sets logging level at N.
|
||||
# -DENABLE_ICD2061_LOG=N sets logging level at N.
|
||||
# -DENABLE_IM1024_LOG=N sets logging level at N.
|
||||
# -DENABLE_PGC_LOG=N sets logging level at N.
|
||||
# -DENABLE_S3_VIRGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_VID_TABLE_LOG=N sets logging level at N.
|
||||
# -DENABLE_VIDEO_LOG=N sets logging level at N.
|
||||
# -DENABLE_VOODOO_LOG=N sets logging level at N.
|
||||
# win/ logging:
|
||||
# -DENABLE_WIN_LOG=N sets logging level at N.
|
||||
# -DENABLE_DISCORD_LOG=N sets logging level at N.
|
||||
# -DENABLE_DYNLD_LOG=N sets logging level at N.
|
||||
# -DENABLE_JOYSTICK_LOG=N sets logging level at N.
|
||||
# -DENABLE_SDL_LOG=N sets logging level at N.
|
||||
# -DENABLE_SETTINGS_LOG=N sets logging level at N.
|
||||
EXTRAS :=
|
||||
|
||||
|
||||
AUTODEP := n
|
||||
DEBUG := n
|
||||
OPTIM := n
|
||||
X64 := n
|
||||
RELEASE := n
|
||||
USB := n
|
||||
VNC := n
|
||||
RDP := n
|
||||
DEV_BUILD := n
|
||||
DEV_BRANCH := n
|
||||
CIRRUS := n
|
||||
NE1000 := n
|
||||
NV_RIVA := n
|
||||
OPENAL := y
|
||||
FLUIDSYNTH := y
|
||||
MUNT := y
|
||||
PAS16 := n
|
||||
DYNAREC := y
|
||||
|
||||
|
||||
#########################################################################
|
||||
# Include the master Makefile.MinGW for the rest. #
|
||||
#########################################################################
|
||||
include win/Makefile.mingw
|
||||
|
||||
|
||||
# End of Makefile.local.
|
||||
988
src/acpi.c
988
src/acpi.c
File diff suppressed because it is too large
Load Diff
@@ -122,7 +122,7 @@ const device_t apm_device = {
|
||||
.init = apm_init,
|
||||
.close = apm_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -136,7 +136,7 @@ const device_t apm_pci_device = {
|
||||
.init = apm_init,
|
||||
.close = apm_close,
|
||||
.reset = apm_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -150,7 +150,7 @@ const device_t apm_pci_acpi_device = {
|
||||
.init = apm_init,
|
||||
.close = apm_close,
|
||||
.reset = apm_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -9,8 +9,36 @@
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2024 Jasmine Iwanek.
|
||||
#
|
||||
|
||||
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
pkg_check_modules(SNDFILE REQUIRED IMPORTED_TARGET sndfile)
|
||||
|
||||
add_library(cdrom OBJECT
|
||||
cdrom.c
|
||||
cdrom_image.c
|
||||
cdrom_image_viso.c
|
||||
cdrom_mke.c
|
||||
)
|
||||
if(NOT WIN32)
|
||||
target_include_directories(86Box PRIVATE PkgConfig::SNDFILE)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
target_include_directories(cdrom PRIVATE /usr/local/include)
|
||||
endif()
|
||||
target_link_libraries(86Box PkgConfig::SNDFILE)
|
||||
|
||||
if(CDROM_MITSUMI)
|
||||
target_compile_definitions(cdrom PRIVATE USE_CDROM_MITSUMI)
|
||||
target_sources(cdrom PRIVATE cdrom_mitsumi.c)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# MSYS2
|
||||
target_link_libraries(86Box -static ${SNDFILE_STATIC_LIBRARIES})
|
||||
endif()
|
||||
|
||||
4146
src/cdrom/cdrom.c
4146
src/cdrom/cdrom.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,7 @@
|
||||
*
|
||||
* Virtual ISO CD-ROM image back-end.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG <richardg867@gmail.com>
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2022 RichardG.
|
||||
*/
|
||||
@@ -23,7 +21,9 @@
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#ifdef IMAGE_VISO_LOG
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -31,43 +31,51 @@
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/bswap.h>
|
||||
#include <86box/cdrom_image_backend.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_image.h>
|
||||
#include <86box/cdrom_image_viso.h>
|
||||
#include <86box/log.h>
|
||||
#include <86box/path.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/bswap.h>
|
||||
#include <86box/plat_dir.h>
|
||||
#include <86box/version.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#define VISO_SKIP(p, n) \
|
||||
{ \
|
||||
memset(p, 0x00, n); \
|
||||
p += n; \
|
||||
#ifdef _WIN32
|
||||
# define stat _stat64
|
||||
typedef struct __stat64 stat_t;
|
||||
#else
|
||||
typedef struct stat stat_t;
|
||||
#endif
|
||||
|
||||
#define VISO_SKIP(p, n) \
|
||||
{ \
|
||||
memset((p), 0x00, (n)); \
|
||||
(p) += (n); \
|
||||
}
|
||||
#define VISO_TIME_VALID(t) ((t) > 0)
|
||||
|
||||
/* ISO 9660 defines "both endian" data formats, which
|
||||
are stored as little endian followed by big endian. */
|
||||
#define VISO_LBE_16(p, x) \
|
||||
{ \
|
||||
*((uint16_t *) p) = cpu_to_le16(x); \
|
||||
p += 2; \
|
||||
*((uint16_t *) p) = cpu_to_be16(x); \
|
||||
p += 2; \
|
||||
#define VISO_LBE_16(p, x) \
|
||||
{ \
|
||||
*((uint16_t *) (p)) = cpu_to_le16((x)); \
|
||||
(p) += 2; \
|
||||
*((uint16_t *) (p)) = cpu_to_be16((x)); \
|
||||
(p) += 2; \
|
||||
}
|
||||
#define VISO_LBE_32(p, x) \
|
||||
{ \
|
||||
*((uint32_t *) p) = cpu_to_le32(x); \
|
||||
p += 4; \
|
||||
*((uint32_t *) p) = cpu_to_be32(x); \
|
||||
p += 4; \
|
||||
#define VISO_LBE_32(p, x) \
|
||||
{ \
|
||||
*((uint32_t *) (p)) = cpu_to_le32((x)); \
|
||||
(p) += 4; \
|
||||
*((uint32_t *) (p)) = cpu_to_be32((x)); \
|
||||
(p) += 4; \
|
||||
}
|
||||
|
||||
#define VISO_SECTOR_SIZE COOKED_SECTOR_SIZE
|
||||
@@ -106,7 +114,7 @@ typedef struct _viso_entry_ {
|
||||
};
|
||||
uint16_t pt_idx;
|
||||
|
||||
struct stat stats;
|
||||
stat_t stats;
|
||||
|
||||
struct _viso_entry_ *parent, *next, *next_dir, *first_child;
|
||||
|
||||
@@ -131,29 +139,30 @@ static const char rr_eid[] = "RRIP_1991A"; /* identifiers used in ER field for
|
||||
static const char rr_edesc[] = "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS.";
|
||||
static int8_t tz_offset = 0;
|
||||
|
||||
#ifdef ENABLE_CDROM_IMAGE_VISO_LOG
|
||||
int cdrom_image_viso_do_log = ENABLE_CDROM_IMAGE_VISO_LOG;
|
||||
#ifdef IMAGE_VISO_LOG
|
||||
int image_viso_do_log = IMAGE_VISO_LOG;
|
||||
|
||||
void
|
||||
cdrom_image_viso_log(const char *fmt, ...)
|
||||
image_viso_log(void *priv, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (cdrom_image_viso_do_log) {
|
||||
if (image_viso_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
log_out(priv, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define cdrom_image_viso_log(fmt, ...)
|
||||
# define image_viso_log(priv, fmt, ...)
|
||||
#endif
|
||||
|
||||
static size_t
|
||||
viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
|
||||
viso_pread(void *ptr, const uint64_t offset, const size_t size,
|
||||
const size_t count, FILE *fp)
|
||||
{
|
||||
uint64_t cur_pos = ftello64(fp);
|
||||
size_t ret = 0;
|
||||
const uint64_t cur_pos = ftello64(fp);
|
||||
size_t ret = 0;
|
||||
if (fseeko64(fp, offset, SEEK_SET) != -1)
|
||||
ret = fread(ptr, size, count, fp);
|
||||
fseeko64(fp, cur_pos, SEEK_SET);
|
||||
@@ -161,10 +170,11 @@ viso_pread(void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
|
||||
}
|
||||
|
||||
static size_t
|
||||
viso_pwrite(const void *ptr, uint64_t offset, size_t size, size_t count, FILE *fp)
|
||||
viso_pwrite(const void *ptr, const uint64_t offset, const size_t size,
|
||||
const size_t count, FILE *fp)
|
||||
{
|
||||
uint64_t cur_pos = ftello64(fp);
|
||||
size_t ret = 0;
|
||||
const uint64_t cur_pos = ftello64(fp);
|
||||
size_t ret = 0;
|
||||
if (fseeko64(fp, offset, SEEK_SET) != -1)
|
||||
ret = fwrite(ptr, size, count, fp);
|
||||
fseeko64(fp, cur_pos, SEEK_SET);
|
||||
@@ -436,24 +446,36 @@ static int
|
||||
viso_fill_time(uint8_t *data, time_t time, int format, int longform)
|
||||
{
|
||||
uint8_t *p = data;
|
||||
struct tm *time_s = localtime(&time);
|
||||
if (!time_s) {
|
||||
/* localtime will return NULL if the time_t is negative (Windows)
|
||||
or way too far into 64-bit space (Linux). Fall back to epoch. */
|
||||
time_t epoch = 0;
|
||||
time_s = localtime(&epoch);
|
||||
if (UNLIKELY(!time_s))
|
||||
fatal("VISO: localtime(0) = NULL\n");
|
||||
struct tm time_s_buf;
|
||||
struct tm *time_s = NULL;
|
||||
time_t epoch = 0;
|
||||
|
||||
/* Force year clamping if the timestamp is known to be outside the supported ranges. */
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&time_s_buf, &time) == 0)
|
||||
time_s = &time_s_buf;
|
||||
#else
|
||||
time_s = localtime_r(&time, &time_s_buf);
|
||||
#endif
|
||||
|
||||
if (!time_s) {
|
||||
/* localtime may return NULL if time is negative or out of range */
|
||||
#ifdef _WIN32
|
||||
if (localtime_s(&time_s_buf, &epoch) == 0)
|
||||
time_s = &time_s_buf;
|
||||
#else
|
||||
time_s = localtime_r(&epoch, &time_s_buf);
|
||||
#endif
|
||||
if (!time_s)
|
||||
fatal("VISO: localtime fallback to epoch failed\n");
|
||||
|
||||
/* Force year clamping for out-of-range times */
|
||||
if (time < (longform ? -62135596800LL : -2208988800LL)) /* 0001-01-01 00:00:00 : 1900-01-01 00:00:00 */
|
||||
time_s->tm_year = -1901;
|
||||
else if (time > (longform ? 253402300799LL : 5869583999LL)) /* 9999-12-31 23:59:59 : 2155-12-31 23:59:59 */
|
||||
time_s->tm_year = 8100;
|
||||
}
|
||||
|
||||
/* Clamp year to the supported ranges, and assume the
|
||||
OS returns valid numbers in the other struct fields. */
|
||||
/* Clamp year within supported ranges */
|
||||
if (time_s->tm_year < (longform ? -1900 : 0)) {
|
||||
time_s->tm_year = longform ? -1900 : 0;
|
||||
time_s->tm_mon = time_s->tm_hour = time_s->tm_min = time_s->tm_sec = 0;
|
||||
@@ -466,18 +488,18 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
|
||||
time_s->tm_min = time_s->tm_sec = 59;
|
||||
}
|
||||
|
||||
/* Convert timestamp. */
|
||||
/* Convert timestamp */
|
||||
if (longform) {
|
||||
p += sprintf((char *) p, "%04u%02u%02u%02u%02u%02u00",
|
||||
1900 + time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday,
|
||||
p += sprintf((char *)p, "%04u%02u%02u%02u%02u%02u00",
|
||||
1900 + (unsigned)time_s->tm_year, 1 + time_s->tm_mon, time_s->tm_mday,
|
||||
time_s->tm_hour, time_s->tm_min, time_s->tm_sec);
|
||||
} else {
|
||||
*p++ = time_s->tm_year; /* year since 1900 */
|
||||
*p++ = 1 + time_s->tm_mon; /* month */
|
||||
*p++ = time_s->tm_mday; /* day */
|
||||
*p++ = time_s->tm_hour; /* hour */
|
||||
*p++ = time_s->tm_min; /* minute */
|
||||
*p++ = time_s->tm_sec; /* second */
|
||||
*p++ = (uint8_t)time_s->tm_year; /* year since 1900 */
|
||||
*p++ = (uint8_t)(1 + time_s->tm_mon); /* month */
|
||||
*p++ = (uint8_t)time_s->tm_mday; /* day */
|
||||
*p++ = (uint8_t)time_s->tm_hour; /* hour */
|
||||
*p++ = (uint8_t)time_s->tm_min; /* minute */
|
||||
*p++ = (uint8_t)time_s->tm_sec; /* second */
|
||||
}
|
||||
if (format & VISO_FORMAT_ISO)
|
||||
*p++ = tz_offset; /* timezone (ISO only) */
|
||||
@@ -496,10 +518,6 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type)
|
||||
*p++ = 0; /* extended attribute length */
|
||||
VISO_SKIP(p, 8); /* sector offset */
|
||||
VISO_LBE_32(p, entry->stats.st_size); /* size (filled in later if this is a directory) */
|
||||
#ifdef _WIN32
|
||||
if (entry->stats.st_mtime < 0)
|
||||
pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path);
|
||||
#endif
|
||||
p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* time */
|
||||
*p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */
|
||||
|
||||
@@ -671,9 +689,9 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
/* Handle reads in a sector by sector basis. */
|
||||
while (count > 0) {
|
||||
/* Determine the current sector, offset and remainder. */
|
||||
uint32_t sector = seek / viso->sector_size;
|
||||
uint32_t sector_offset = seek % viso->sector_size;
|
||||
uint32_t sector_remain = MIN(count, viso->sector_size - sector_offset);
|
||||
size_t sector = seek / viso->sector_size;
|
||||
size_t sector_offset = seek % viso->sector_size;
|
||||
size_t sector_remain = MIN(count, viso->sector_size - sector_offset);
|
||||
|
||||
/* Handle sector. */
|
||||
if (sector < viso->metadata_sectors) {
|
||||
@@ -690,22 +708,22 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
/* Close any existing FIFO entry's file. */
|
||||
viso_entry_t *other_entry = viso->file_fifo[viso->file_fifo_pos];
|
||||
if (other_entry && other_entry->file) {
|
||||
cdrom_image_viso_log("VISO: Closing [%s]", other_entry->path);
|
||||
image_viso_log(viso->tf.log, "Closing [%s]...\n", other_entry->path);
|
||||
fclose(other_entry->file);
|
||||
other_entry->file = NULL;
|
||||
cdrom_image_viso_log("\n");
|
||||
image_viso_log(viso->tf.log, "Done\n");
|
||||
}
|
||||
|
||||
/* Open file. */
|
||||
cdrom_image_viso_log("VISO: Opening [%s]", entry->path);
|
||||
image_viso_log(viso->tf.log, "Opening [%s]...\n", entry->path);
|
||||
if ((entry->file = fopen(entry->path, "rb"))) {
|
||||
cdrom_image_viso_log("\n");
|
||||
image_viso_log(viso->tf.log, "Done\n");
|
||||
|
||||
/* Add this entry to the FIFO. */
|
||||
viso->file_fifo[viso->file_fifo_pos++] = entry;
|
||||
viso->file_fifo_pos &= (sizeof(viso->file_fifo) / sizeof(viso->file_fifo[0])) - 1;
|
||||
} else {
|
||||
cdrom_image_viso_log(" => failed\n");
|
||||
image_viso_log(viso->tf.log, "Failed\n");
|
||||
|
||||
/* Clear any existing FIFO entry. */
|
||||
viso->file_fifo[viso->file_fifo_pos] = NULL;
|
||||
@@ -713,8 +731,11 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
|
||||
}
|
||||
|
||||
/* Read data. */
|
||||
if (entry->file && (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) != -1))
|
||||
read = fread(buffer, 1, sector_remain, entry->file);
|
||||
if (!entry->file || (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) == -1))
|
||||
return -1;
|
||||
read = fread(buffer, 1, sector_remain, entry->file);
|
||||
if (sector_remain && !read)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fill remainder with 00 bytes if needed. */
|
||||
@@ -749,12 +770,12 @@ viso_close(void *priv)
|
||||
if (viso == NULL)
|
||||
return;
|
||||
|
||||
cdrom_image_viso_log("VISO: close()\n");
|
||||
image_viso_log(viso->tf.log, "close()\n");
|
||||
|
||||
/* De-allocate everything. */
|
||||
if (tf->fp)
|
||||
fclose(tf->fp);
|
||||
#ifndef ENABLE_CDROM_IMAGE_VISO_LOG
|
||||
#ifndef ENABLE_IMAGE_VISO_LOG
|
||||
remove(nvr_path(viso->tf.fn));
|
||||
#endif
|
||||
|
||||
@@ -773,21 +794,31 @@ viso_close(void *priv)
|
||||
if (viso->entry_map)
|
||||
free(viso->entry_map);
|
||||
|
||||
if (tf->log != NULL)
|
||||
log_close(tf->log);
|
||||
|
||||
free(viso);
|
||||
}
|
||||
|
||||
track_file_t *
|
||||
viso_init(const char *dirname, int *error)
|
||||
viso_init(const uint8_t id, const char *dirname, int *error)
|
||||
{
|
||||
cdrom_image_viso_log("VISO: init()\n");
|
||||
|
||||
/* Initialize our data structure. */
|
||||
viso_t *viso = (viso_t *) calloc(1, sizeof(viso_t));
|
||||
uint8_t *data = NULL;
|
||||
uint8_t *p;
|
||||
*error = 1;
|
||||
|
||||
if (viso == NULL)
|
||||
goto end;
|
||||
|
||||
char n[1024] = { 0 };
|
||||
|
||||
sprintf(n, "CD-ROM %i VISO ", id + 1);
|
||||
viso->tf.log = log_open(n);
|
||||
|
||||
image_viso_log(viso->tf.log, "init()\n");
|
||||
|
||||
viso->sector_size = VISO_SECTOR_SIZE;
|
||||
viso->format = VISO_FORMAT_ISO | VISO_FORMAT_JOLIET | VISO_FORMAT_RR;
|
||||
viso->use_version_suffix = (viso->format & VISO_FORMAT_ISO); /* cleared later if required */
|
||||
@@ -798,7 +829,7 @@ viso_init(const char *dirname, int *error)
|
||||
goto end;
|
||||
|
||||
/* Open temporary file. */
|
||||
#ifdef ENABLE_CDROM_IMAGE_VISO_LOG
|
||||
#ifdef ENABLE_IMAGE_VISO_LOG
|
||||
strcpy(viso->tf.fn, "viso-debug.iso");
|
||||
#else
|
||||
plat_tempfile(viso->tf.fn, "viso", ".tmp");
|
||||
@@ -808,7 +839,7 @@ viso_init(const char *dirname, int *error)
|
||||
goto end;
|
||||
|
||||
/* Set up directory traversal. */
|
||||
cdrom_image_viso_log("VISO: Traversing directories:\n");
|
||||
image_viso_log(viso->tf.log, "Traversing directories:\n");
|
||||
viso_entry_t *entry;
|
||||
viso_entry_t *last_entry;
|
||||
viso_entry_t *dir;
|
||||
@@ -830,12 +861,12 @@ viso_init(const char *dirname, int *error)
|
||||
strcpy(dir->path, dirname);
|
||||
if (stat(dirname, &dir->stats) != 0) {
|
||||
/* Use a blank structure if stat failed. */
|
||||
memset(&dir->stats, 0x00, sizeof(struct stat));
|
||||
memset(&dir->stats, 0x00, sizeof(stat_t));
|
||||
}
|
||||
if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */
|
||||
goto end;
|
||||
dir->parent = dir; /* for the root's path table and .. entries */
|
||||
cdrom_image_viso_log("[%08X] %s => [root]\n", dir, dir->path);
|
||||
image_viso_log(viso->tf.log, "[%08X] %s => [root]\n", dir, dir->path);
|
||||
|
||||
/* Traverse directories, starting with the root. */
|
||||
viso_entry_t **dir_entries = NULL;
|
||||
@@ -879,13 +910,14 @@ viso_init(const char *dirname, int *error)
|
||||
/* Stat the current directory or parent directory. */
|
||||
if (stat(children_count ? dir->parent->path : dir->path, &entry->stats) != 0) {
|
||||
/* Use a blank structure if stat failed. */
|
||||
memset(&entry->stats, 0x00, sizeof(struct stat));
|
||||
memset(&entry->stats, 0x00, sizeof(stat_t));
|
||||
}
|
||||
|
||||
/* Set basename. */
|
||||
strcpy(entry->name_short, children_count ? ".." : ".");
|
||||
|
||||
cdrom_image_viso_log("[%08X] %s => %s\n", entry, dir->path, entry->name_short);
|
||||
image_viso_log(viso->tf.log, "[%08X] %s => %s\n", entry,
|
||||
dir->path, entry->name_short);
|
||||
}
|
||||
|
||||
/* Iterate through this directory's children again, making the entries. */
|
||||
@@ -893,12 +925,16 @@ viso_init(const char *dirname, int *error)
|
||||
rewinddir(dirp);
|
||||
while ((readdir_entry = readdir(dirp))) {
|
||||
/* Ignore . and .. pseudo-directories. */
|
||||
if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.')))
|
||||
if ((readdir_entry->d_name[0] == '.') &&
|
||||
((readdir_entry->d_name[1] == '\0') ||
|
||||
(*((uint16_t *) &readdir_entry->d_name[1]) == '.')))
|
||||
continue;
|
||||
|
||||
/* Add and fill entry. */
|
||||
entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2);
|
||||
if (!entry)
|
||||
entry = dir_entries[children_count++] =
|
||||
(viso_entry_t *) calloc(1, sizeof(viso_entry_t) +
|
||||
dir_path_len + strlen(readdir_entry->d_name) + 2);
|
||||
if (entry == NULL)
|
||||
break;
|
||||
entry->parent = dir;
|
||||
strcpy(entry->path, dir->path);
|
||||
@@ -909,7 +945,7 @@ viso_init(const char *dirname, int *error)
|
||||
/* Stat this child. */
|
||||
if (stat(entry->path, &entry->stats) != 0) {
|
||||
/* Use a blank structure if stat failed. */
|
||||
memset(&entry->stats, 0x00, sizeof(struct stat));
|
||||
memset(&entry->stats, 0x00, sizeof(stat_t));
|
||||
}
|
||||
|
||||
/* Handle file size and El Torito boot code. */
|
||||
@@ -968,10 +1004,12 @@ have_eltorito_entry:
|
||||
continue;
|
||||
}
|
||||
|
||||
cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename);
|
||||
image_viso_log(viso->tf.log, "[%08X] %s => [%-12s] %s\n", entry,
|
||||
dir->path, entry->name_short, entry->basename);
|
||||
}
|
||||
} else {
|
||||
cdrom_image_viso_log("VISO: Failed to enumerate [%s], will be empty\n", dir->path);
|
||||
image_viso_log(viso->tf.log, "Failed to enumerate [%s], will be empty\n",
|
||||
dir->path);
|
||||
}
|
||||
|
||||
/* Add terminator. */
|
||||
@@ -1008,8 +1046,15 @@ next_dir:
|
||||
the timezone offset for descriptors and file times to use. */
|
||||
tzset();
|
||||
time_t now = time(NULL);
|
||||
if (viso->format & VISO_FORMAT_ISO) /* timezones are ISO only */
|
||||
tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4);
|
||||
struct tm now_tm;
|
||||
if (viso->format & VISO_FORMAT_ISO) { /* timezones are ISO only */
|
||||
#ifdef _WIN32
|
||||
gmtime_s(&now_tm, &now); // Windows: output first param, input second
|
||||
#else
|
||||
gmtime_r(&now, &now_tm); // POSIX: input first param, output second
|
||||
#endif
|
||||
tz_offset = (now - mktime(&now_tm)) / (3600 / 4);
|
||||
}
|
||||
|
||||
/* Get root directory basename for the volume ID. */
|
||||
const char *basename = path_get_filename(viso->root_dir->path);
|
||||
@@ -1125,13 +1170,17 @@ next_dir:
|
||||
/* Write El Torito boot descriptor. This is an awkward spot for
|
||||
that, but the spec requires it to be the second descriptor. */
|
||||
if (!i && eltorito_entry) {
|
||||
cdrom_image_viso_log("VISO: Writing El Torito boot descriptor for entry [%08X]\n", eltorito_entry);
|
||||
image_viso_log(viso->tf.log, "Writing El Torito boot descriptor for "
|
||||
"entry [%08X]\n", eltorito_entry);
|
||||
|
||||
p = data;
|
||||
if (!(viso->format & VISO_FORMAT_ISO))
|
||||
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size); /* sector offset (HSF only) */
|
||||
*p++ = 0; /* type */
|
||||
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
|
||||
/* Sector offset (HSF only). */
|
||||
VISO_LBE_32(p, ftello64(viso->tf.fp) / viso->sector_size);
|
||||
/* Type. */
|
||||
*p++ = 0;
|
||||
/* Standard ID. */
|
||||
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5);
|
||||
p += 5;
|
||||
*p++ = 1; /* version */
|
||||
|
||||
@@ -1232,7 +1281,7 @@ next_dir:
|
||||
|
||||
/* Write each path table. */
|
||||
for (int i = 0; i <= ((max_vd << 1) | 1); i++) {
|
||||
cdrom_image_viso_log("VISO: Generating path table #%d:\n", i);
|
||||
image_viso_log(viso->tf.log, "Generating path table #%d:\n", i);
|
||||
|
||||
/* Save this path table's start offset. */
|
||||
uint64_t pt_start = ftello64(viso->tf.fp);
|
||||
@@ -1253,7 +1302,9 @@ next_dir:
|
||||
continue;
|
||||
}
|
||||
|
||||
cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename : dir->name_short);
|
||||
image_viso_log(viso->tf.log, "[%08X] %s => %s\n", dir,
|
||||
dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename :
|
||||
dir->name_short);
|
||||
|
||||
/* Save this directory's path table index and offset. */
|
||||
dir->pt_idx = pt_idx;
|
||||
@@ -1321,7 +1372,7 @@ next_dir:
|
||||
/* Write directory records for each type. */
|
||||
int dir_type = VISO_DIR_CURRENT_ROOT;
|
||||
for (int i = 0; i <= max_vd; i++) {
|
||||
cdrom_image_viso_log("VISO: Generating directory record set #%d:\n", i);
|
||||
image_viso_log(viso->tf.log, "Generating directory record set #%d:\n", i);
|
||||
|
||||
/* Go through directories. */
|
||||
dir = viso->root_dir;
|
||||
@@ -1364,8 +1415,10 @@ next_dir:
|
||||
if ((entry == eltorito_entry) || (entry == eltorito_dir))
|
||||
goto next_entry;
|
||||
|
||||
cdrom_image_viso_log("[%08X] %s => %s\n", entry, dir->path,
|
||||
((dir_type == VISO_DIR_PARENT) ? ".." : ((dir_type < VISO_DIR_PARENT) ? "." : (i ? entry->basename : entry->name_short))));
|
||||
image_viso_log(viso->tf.log, "[%08X] %s => %s\n", entry, dir->path,
|
||||
((dir_type == VISO_DIR_PARENT) ? ".." :
|
||||
((dir_type < VISO_DIR_PARENT) ? "." :
|
||||
(i ? entry->basename : entry->name_short))));
|
||||
|
||||
/* Fill directory record. */
|
||||
viso_fill_dir_record(data, entry, viso, dir_type);
|
||||
@@ -1432,7 +1485,8 @@ next_entry:
|
||||
/* Allocate entry map for sector->file lookups. */
|
||||
size_t orig_sector_size = viso->sector_size;
|
||||
while (1) {
|
||||
cdrom_image_viso_log("VISO: Allocating entry map for %d %d-byte sectors\n", viso->entry_map_size, viso->sector_size);
|
||||
image_viso_log(viso->tf.log, "Allocating entry map for %zu %zu-byte sectors\n",
|
||||
viso->entry_map_size, viso->sector_size);
|
||||
viso->entry_map = (viso_entry_t **) calloc(viso->entry_map_size, sizeof(viso_entry_t *));
|
||||
if (viso->entry_map) {
|
||||
/* Successfully allocated. */
|
||||
@@ -1444,7 +1498,7 @@ next_entry:
|
||||
|
||||
/* If we don't have enough memory, double the sector size. */
|
||||
viso->sector_size *= 2;
|
||||
if (viso->sector_size == 0) /* give up if sectors become too large */
|
||||
if ((viso->sector_size < VISO_SECTOR_SIZE) || (viso->sector_size > (1 << 30))) /* give up if sectors become too large */
|
||||
goto end;
|
||||
|
||||
/* Go through files, recalculating the entry map size. */
|
||||
@@ -1473,7 +1527,7 @@ next_entry:
|
||||
viso->all_sectors = viso->metadata_sectors;
|
||||
|
||||
/* Go through files, assigning sectors to them. */
|
||||
cdrom_image_viso_log("VISO: Assigning sectors to files:\n");
|
||||
image_viso_log(viso->tf.log, "Assigning sectors to files:\n");
|
||||
size_t base_factor = viso->sector_size / orig_sector_size;
|
||||
viso_entry_t *prev_entry = viso->root_dir;
|
||||
viso_entry_t **entry_map_p = viso->entry_map;
|
||||
@@ -1515,10 +1569,11 @@ next_entry:
|
||||
entry->data_offset = ((uint64_t) viso->all_sectors) * viso->sector_size;
|
||||
|
||||
/* Determine how many sectors this file will take. */
|
||||
uint32_t size = entry->stats.st_size / viso->sector_size;
|
||||
size_t size = entry->stats.st_size / viso->sector_size;
|
||||
if (entry->stats.st_size % viso->sector_size)
|
||||
size++; /* round up to the next sector */
|
||||
cdrom_image_viso_log("[%08X] %s => %" PRIu32 " + %" PRIu32 " sectors\n", entry, entry->path, viso->all_sectors, size);
|
||||
image_viso_log(viso->tf.log, "[%08X] %s => %zu + %zu sectors\n", entry,
|
||||
entry->path, viso->all_sectors, size);
|
||||
|
||||
/* Allocate sectors to this file. */
|
||||
viso->all_sectors += size;
|
||||
@@ -1537,20 +1592,21 @@ next_entry:
|
||||
viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp);
|
||||
|
||||
/* Metadata processing is finished, read it back to memory. */
|
||||
cdrom_image_viso_log("VISO: Reading back %d %d-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
|
||||
image_viso_log(viso->tf.log, "Reading back %zu %zu-byte sectors of metadata\n",
|
||||
viso->metadata_sectors, viso->sector_size);
|
||||
viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size);
|
||||
if (!viso->metadata)
|
||||
if (viso->metadata == NULL)
|
||||
goto end;
|
||||
fseeko64(viso->tf.fp, 0, SEEK_SET);
|
||||
uint64_t metadata_size = viso->metadata_sectors * viso->sector_size;
|
||||
uint64_t metadata_remain = metadata_size;
|
||||
size_t metadata_size = viso->metadata_sectors * viso->sector_size;
|
||||
size_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.fp);
|
||||
|
||||
/* We no longer need the temporary file; close and delete it. */
|
||||
fclose(viso->tf.fp);
|
||||
viso->tf.fp = NULL;
|
||||
#ifndef ENABLE_CDROM_IMAGE_VISO_LOG
|
||||
#ifndef ENABLE_IMAGE_VISO_LOG
|
||||
remove(nvr_path(viso->tf.fn));
|
||||
#endif
|
||||
|
||||
@@ -1561,16 +1617,20 @@ end:
|
||||
/* Set the function pointers. */
|
||||
viso->tf.priv = viso;
|
||||
if (!*error) {
|
||||
cdrom_image_viso_log("VISO: Initialized\n");
|
||||
image_viso_log(viso->tf.log, "Initialized\n");
|
||||
|
||||
viso->tf.read = viso_read;
|
||||
viso->tf.get_length = viso_get_length;
|
||||
viso->tf.close = viso_close;
|
||||
|
||||
return &viso->tf;
|
||||
} else {
|
||||
cdrom_image_viso_log("VISO: Initialization failed\n");
|
||||
if (data)
|
||||
free(data);
|
||||
viso_close(&viso->tf);
|
||||
if (viso != NULL) {
|
||||
image_viso_log(viso->tf.log, "Initialization failed\n");
|
||||
if (data)
|
||||
free(data);
|
||||
viso_close(&viso->tf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
*
|
||||
* Mitsumi CD-ROM emulation for the ISA bus.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2022 Miran Grca.
|
||||
* Copyright 2022 Miran Grca.
|
||||
* Copyright 2024-2025 Jasmine Iwanek.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
@@ -33,10 +33,6 @@
|
||||
#include <86box/plat.h>
|
||||
#include <86box/sound.h>
|
||||
|
||||
#define MCD_DEFAULT_IOPORT 0x310
|
||||
#define MCD_DEFAULT_IRQ 5
|
||||
#define MCD_DEFAULT_DMA 5
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
@@ -116,15 +112,9 @@ typedef struct mcd_t {
|
||||
int cur_toc_track;
|
||||
int pos;
|
||||
int newstat;
|
||||
} mcd_t;
|
||||
|
||||
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
|
||||
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
|
||||
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
|
||||
#ifdef MSFtoLBA
|
||||
#undef MSFtoLBA
|
||||
#endif
|
||||
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
|
||||
cdrom_t *cdrom_dev;
|
||||
} mcd_t;
|
||||
|
||||
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
||||
#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f))
|
||||
@@ -147,14 +137,16 @@ mitsumi_cdrom_log(const char *fmt, ...)
|
||||
# define mitsumi_cdrom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static int
|
||||
mitsumi_cdrom_is_ready(const mcd_t *dev)
|
||||
{
|
||||
return (dev->cdrom_dev->image_path[0] != 0x00);
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_reset(mcd_t *dev)
|
||||
{
|
||||
cdrom_t cdrom;
|
||||
|
||||
cdrom.host_drive = 0;
|
||||
|
||||
dev->stat = cdrom.host_drive ? (STAT_READY | STAT_CHANGE) : 0;
|
||||
dev->stat = mitsumi_cdrom_is_ready(dev) ? (STAT_READY | STAT_CHANGE) : 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 0;
|
||||
dev->buf_count = 0;
|
||||
@@ -172,12 +164,11 @@ mitsumi_cdrom_reset(mcd_t *dev)
|
||||
static int
|
||||
mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
{
|
||||
cdrom_t cdrom;
|
||||
uint8_t status;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->drvmode == DRV_MODE_CDDA) {
|
||||
status = cdrom_mitsumi_audio_play(&cdrom, dev->readmsf, dev->readcount);
|
||||
status = cdrom_mitsumi_audio_play(dev->cdrom_dev, dev->readmsf, dev->readcount);
|
||||
if (status == 1)
|
||||
return status;
|
||||
else
|
||||
@@ -191,15 +182,15 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
dev->data = 0;
|
||||
return 0;
|
||||
}
|
||||
cdrom_stop(&cdrom);
|
||||
ret = cdrom_readsector_raw(&cdrom, dev->buf, cdrom.seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
|
||||
if (!ret)
|
||||
cdrom_stop(dev->cdrom_dev);
|
||||
ret = cdrom_readsector_raw(dev->cdrom_dev, dev->buf, dev->cdrom_dev->seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
if (dev->mode & 0x40) {
|
||||
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
|
||||
dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff);
|
||||
}
|
||||
dev->readmsf = cdrom_lba_to_msf_accurate(cdrom.seek_pos + 1);
|
||||
dev->readmsf = cdrom_lba_to_msf_accurate(dev->cdrom_dev->seek_pos + 1);
|
||||
dev->buf_count = dev->dmalen + 1;
|
||||
dev->buf_idx = 0;
|
||||
dev->data = 1;
|
||||
@@ -220,7 +211,7 @@ static uint8_t
|
||||
mitsumi_cdrom_in(uint16_t port, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
uint8_t ret;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
pclog("Mitsumi CD-ROM IN=%03x\n", port);
|
||||
switch (port & 1) {
|
||||
@@ -255,14 +246,13 @@ mitsumi_cdrom_in(uint16_t port, void *priv)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
cdrom_t cdrom;
|
||||
|
||||
pclog("Mitsumi CD-ROM OUT=%03x, val=%02x\n", port, val);
|
||||
switch (port & 1) {
|
||||
@@ -344,19 +334,19 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
if (!dev->cmdrd_count)
|
||||
dev->stat = cdrom.host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->stat = mitsumi_cdrom_is_ready(dev) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
return;
|
||||
}
|
||||
dev->cmd = val;
|
||||
dev->cmdbuf_idx = 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = cdrom.host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->cmdbuf[0] = mitsumi_cdrom_is_ready(dev) ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->data = 0;
|
||||
switch (val) {
|
||||
case CMD_GET_INFO:
|
||||
if (cdrom.host_drive) {
|
||||
cdrom_get_track_buffer(&cdrom, &(dev->cmdbuf[1]));
|
||||
if (mitsumi_cdrom_is_ready(dev)) {
|
||||
cdrom_get_track_buffer(dev->cdrom_dev, &(dev->cmdbuf[1]));
|
||||
dev->cmdbuf_count = 10;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
@@ -365,8 +355,8 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
case CMD_GET_Q:
|
||||
if (cdrom.host_drive) {
|
||||
cdrom_get_q(&cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
|
||||
if (mitsumi_cdrom_is_ready(dev)) {
|
||||
cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
|
||||
dev->cmdbuf_count = 11;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
@@ -382,7 +372,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
case CMD_STOPCDDA:
|
||||
case CMD_STOP:
|
||||
cdrom_stop(&cdrom);
|
||||
cdrom_stop(dev->cdrom_dev);
|
||||
dev->drvmode = DRV_MODE_STOP;
|
||||
dev->cur_toc_track = 0;
|
||||
break;
|
||||
@@ -391,7 +381,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
case CMD_READ1X:
|
||||
case CMD_READ2X:
|
||||
if (cdrom.host_drive) {
|
||||
if (mitsumi_cdrom_is_ready(dev)) {
|
||||
dev->readcount = 0;
|
||||
dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ;
|
||||
dev->cmdrd_count = 6;
|
||||
@@ -407,7 +397,7 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
dev->cmdbuf_count = 3;
|
||||
break;
|
||||
case CMD_EJECT:
|
||||
cdrom_stop(&cdrom);
|
||||
cdrom_stop(dev->cdrom_dev);
|
||||
cdrom_eject(0);
|
||||
dev->readcount = 0;
|
||||
break;
|
||||
@@ -436,15 +426,25 @@ mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
static void *
|
||||
mitsumi_cdrom_init(UNUSED(const device_t *info))
|
||||
{
|
||||
mcd_t *dev;
|
||||
mcd_t *dev = calloc(1, sizeof(mcd_t));
|
||||
|
||||
dev = malloc(sizeof(mcd_t));
|
||||
memset(dev, 0x00, sizeof(mcd_t));
|
||||
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
||||
if (cdrom[i].bus_type == CDROM_BUS_MITSUMI) {
|
||||
dev->cdrom_dev = &cdrom[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->irq = MCD_DEFAULT_IRQ;
|
||||
dev->dma = MCD_DEFAULT_DMA;
|
||||
if (!dev->cdrom_dev)
|
||||
return NULL;
|
||||
|
||||
io_sethandler(MCD_DEFAULT_IOPORT, 3,
|
||||
dev->cdrom_dev->priv = &dev;
|
||||
|
||||
uint16_t base = device_get_config_hex16("base");
|
||||
dev->irq = device_get_config_int("irq");
|
||||
dev->dma = device_get_config_int("dma");
|
||||
|
||||
io_sethandler(base, 3,
|
||||
mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev);
|
||||
|
||||
mitsumi_cdrom_reset(dev);
|
||||
@@ -463,16 +463,74 @@ mitsumi_cdrom_close(void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
static const device_config_t mitsumi_config[] = {
|
||||
// clang-format off
|
||||
{
|
||||
.name = "base",
|
||||
.description = "Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0x310,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "300H", .value = 0x300 },
|
||||
{ .description = "310H", .value = 0x310 },
|
||||
{ .description = "320H", .value = 0x320 },
|
||||
{ .description = "340H", .value = 0x340 },
|
||||
{ .description = "350H", .value = 0x350 },
|
||||
{ NULL }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "irq",
|
||||
.description = "IRQ",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 5,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "IRQ 3", .value = 3 },
|
||||
{ .description = "IRQ 5", .value = 5 },
|
||||
{ .description = "IRQ 9", .value = 9 },
|
||||
{ .description = "IRQ 10", .value = 10 },
|
||||
{ .description = "IRQ 11", .value = 11 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "dma",
|
||||
.description = "DMA",
|
||||
.type = CONFIG_SELECTION,
|
||||
.default_string = NULL,
|
||||
.default_int = 5,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "DMA 5", .value = 5 },
|
||||
{ .description = "DMA 6", .value = 6 },
|
||||
{ .description = "DMA 7", .value = 7 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
// clang-format off
|
||||
};
|
||||
|
||||
const device_t mitsumi_cdrom_device = {
|
||||
.name = "Mitsumi CD-ROM interface",
|
||||
.internal_name = "mcd",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 1,
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 0,
|
||||
.init = mitsumi_cdrom_init,
|
||||
.close = mitsumi_cdrom_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.config = mitsumi_config
|
||||
};
|
||||
|
||||
1078
src/cdrom/cdrom_mke.c
Normal file
1078
src/cdrom/cdrom_mke.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -358,8 +358,7 @@ ct_82c100_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ct_82c100_t *dev;
|
||||
|
||||
dev = (ct_82c100_t *) malloc(sizeof(ct_82c100_t));
|
||||
memset(dev, 0x00, sizeof(ct_82c100_t));
|
||||
dev = (ct_82c100_t *) calloc(1, sizeof(ct_82c100_t));
|
||||
|
||||
ct_82c100_reset(dev);
|
||||
|
||||
@@ -393,7 +392,7 @@ const device_t ct_82c100_device = {
|
||||
.init = ct_82c100_init,
|
||||
.close = ct_82c100_close,
|
||||
.reset = ct_82c100_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -9,19 +9,88 @@
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
#
|
||||
# Copyright 2020-2021 David Hrdlička.
|
||||
# Copyright 2024 Jasmine Iwanek.
|
||||
#
|
||||
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
|
||||
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c 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)
|
||||
endif()
|
||||
add_library(chipset OBJECT
|
||||
82c100.c
|
||||
acc2036.c
|
||||
acc2168.c
|
||||
cs8220.c
|
||||
cs8230.c
|
||||
ali1429.c
|
||||
ali1435.c
|
||||
ali1489.c
|
||||
ali1531.c
|
||||
ali1541.c
|
||||
ali1543.c
|
||||
ali1621.c
|
||||
ali6117.c
|
||||
ali1409.c
|
||||
compaq.c
|
||||
compaq_386.c
|
||||
contaq_82c59x.c
|
||||
cs4031.c
|
||||
grid1520.c
|
||||
gc100.c
|
||||
headland.c
|
||||
ims8848.c
|
||||
intel_82335.c
|
||||
intel_420ex.c
|
||||
intel_4x0.c
|
||||
intel_i450kx.c
|
||||
intel_sio.c
|
||||
intel_piix.c
|
||||
isa486c.c
|
||||
../ioapic.c
|
||||
laserxt.c
|
||||
neat.c
|
||||
olivetti_eva.c
|
||||
opti283.c
|
||||
opti291.c
|
||||
opti391.c
|
||||
opti495.c
|
||||
opti498.c
|
||||
opti499.c
|
||||
opti602.c
|
||||
opti822.c
|
||||
opti895.c
|
||||
opti5x7.c
|
||||
philips.c
|
||||
sanyo.c
|
||||
scamp.c
|
||||
scat.c
|
||||
sis_85c310.c
|
||||
sis_85c4xx.c
|
||||
sis_85c496.c
|
||||
sis_85c50x.c
|
||||
sis_5511.c
|
||||
sis_5571.c
|
||||
sis_5581.c
|
||||
sis_5591.c
|
||||
sis_5600.c
|
||||
sis_5511_h2p.c
|
||||
sis_5571_h2p.c
|
||||
sis_5581_h2p.c
|
||||
sis_5591_h2p.c
|
||||
sis_5600_h2p.c
|
||||
sis_5513_p2i.c
|
||||
sis_5513_ide.c
|
||||
sis_5572_usb.c
|
||||
sis_5595_pmu.c
|
||||
sis_55xx.c
|
||||
sl82c461.c
|
||||
stpc.c
|
||||
via_vt82c49x.c
|
||||
via_vt82c505.c
|
||||
umc_8886.c
|
||||
umc_hb4.c
|
||||
umc_8890.c
|
||||
via_apollo.c
|
||||
via_pipc.c
|
||||
vl82c480.c
|
||||
wd76c10.c
|
||||
)
|
||||
|
||||
346
src/chipset/acc2036.c
Normal file
346
src/chipset/acc2036.c
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ACC 2036 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t virt;
|
||||
uint32_t phys;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
} ram_page_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t reg;
|
||||
uint8_t regs[32];
|
||||
|
||||
ram_page_t ram_mid_pages[24];
|
||||
ram_page_t ems_pages[4];
|
||||
} acc2036_t;
|
||||
|
||||
static uint8_t
|
||||
acc2036_mem_read(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
acc2036_mem_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint16_t *) &(ram[addr]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_mem_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_mem_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ram_page_t *dev = (ram_page_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_recalc(acc2036_t *dev)
|
||||
{
|
||||
uint32_t ems_bases[4] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000e0000 };
|
||||
|
||||
int start_i = (ems_bases[dev->regs[0x0c] & 0x03] - 0x000a0000) >> 14;
|
||||
int end_i = start_i + 3;
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
mem_mapping_disable(&rp->mapping);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ram_page_t *ep = &dev->ems_pages[i];
|
||||
mem_mapping_disable(&ep->mapping);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
|
||||
if ((dev->regs[0x03] & 0x08) && (i >= start_i) && (i <= end_i)) {
|
||||
/* EMS */
|
||||
ram_page_t *ep = &dev->ems_pages[i - start_i];
|
||||
|
||||
mem_mapping_disable(&rp->mapping);
|
||||
mem_mapping_set_addr(&ep->mapping, ep->virt, 0x000040000);
|
||||
mem_mapping_set_exec(&ep->mapping, ram + ep->phys);
|
||||
mem_set_mem_state_both(ep->virt, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
int master_write;
|
||||
int master_read;
|
||||
int bit;
|
||||
int ew_flag;
|
||||
int er_flag;
|
||||
int flags;
|
||||
uint8_t val;
|
||||
|
||||
mem_mapping_set_addr(&rp->mapping, rp->virt, 0x000040000);
|
||||
mem_mapping_set_exec(&rp->mapping, ram + rp->phys);
|
||||
|
||||
if ((i >= 8) && (i <= 15)) {
|
||||
/* 0C0000-0DFFFF */
|
||||
master_write = dev->regs[0x02] & 0x08;
|
||||
master_read = dev->regs[0x02] & 0x04;
|
||||
bit = ((i - 8) >> 1);
|
||||
val = dev->regs[0x0d] & (1 << bit);
|
||||
if (i >= 12) {
|
||||
ew_flag = (dev->regs[0x07] & 0x80) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x07] & 0x80) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
} else {
|
||||
ew_flag = (dev->regs[0x07] & 0x40) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x07] & 0x40) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
}
|
||||
flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag;
|
||||
flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag;
|
||||
mem_set_mem_state_both(rp->virt, 0x00004000, flags);
|
||||
} else if (i > 15) {
|
||||
/* 0E0000-0FFFFF */
|
||||
master_write = dev->regs[0x02] & 0x02;
|
||||
master_read = dev->regs[0x02] & 0x01;
|
||||
bit = ((i - 8) >> 2);
|
||||
val = dev->regs[0x0c] & (1 << bit);
|
||||
if (i >= 20) {
|
||||
ew_flag = MEM_WRITE_EXTANY;
|
||||
er_flag = MEM_READ_EXTANY;
|
||||
} else {
|
||||
ew_flag = (dev->regs[0x0c] & 0x10) ? MEM_WRITE_EXTANY : MEM_WRITE_EXTERNAL;
|
||||
er_flag = (dev->regs[0x0c] & 0x10) ? MEM_READ_EXTANY : MEM_READ_EXTERNAL;
|
||||
}
|
||||
flags = (val && master_write) ? MEM_WRITE_INTERNAL : ew_flag;
|
||||
flags |= (val && master_read) ? MEM_READ_INTERNAL : er_flag;
|
||||
mem_set_mem_state_both(rp->virt, 0x00004000, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->regs[0x00] & 0x40)
|
||||
mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(0x00fe0000, 0x00010000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
for (int i = 0x01; i <= 0x06; i++) {
|
||||
uint32_t base = 0x00fe0000 - (i * 0x00010000);
|
||||
|
||||
if (dev->regs[i] & 0x40)
|
||||
mem_set_mem_state_both(base, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
|
||||
if (dev->regs[i] & 0x80)
|
||||
mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
else
|
||||
mem_set_mem_state_both(base + 0x00008000, 0x00008000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
mem_remap_top(0);
|
||||
if (dev->regs[0x03] & 0x10) {
|
||||
if (dev->regs[0x02] & 0x0c)
|
||||
mem_remap_top(128);
|
||||
else if (dev->regs[0x02] & 0x03)
|
||||
mem_remap_top(256);
|
||||
else
|
||||
mem_remap_top(384);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
acc2036_in(uint16_t port, void *priv) {
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
uint8_t reg = dev->reg - 0x20;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port & 0x0001) switch (dev->reg) {
|
||||
default:
|
||||
break;
|
||||
case 0x20 ... 0x2e:
|
||||
case 0x31 ... 0x3f:
|
||||
ret = dev->regs[reg];
|
||||
break;
|
||||
} else
|
||||
ret = dev->reg;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_out(uint16_t port, uint8_t val, void *priv) {
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
uint8_t reg = dev->reg - 0x20;
|
||||
|
||||
if (port & 0x0001) switch (dev->reg) {
|
||||
default:
|
||||
break;
|
||||
case 0x20 ... 0x23:
|
||||
dev->regs[reg] = val;
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x24 ... 0x2b:
|
||||
dev->regs[reg] = val;
|
||||
dev->ems_pages[(reg - 0x04) >> 1].phys = ((dev->regs[reg & 0xfe] & 0x1f) << 19) |
|
||||
((dev->regs[reg | 0x01] & 0x1f) << 14);
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x2c: case 0x2d:
|
||||
dev->regs[reg] = val;
|
||||
acc2036_recalc(dev);
|
||||
break;
|
||||
case 0x2e:
|
||||
dev->regs[reg] = val | 0x10;
|
||||
break;
|
||||
case 0x31:
|
||||
dev->regs[reg] = val;
|
||||
mem_a20_alt = (val & 0x01);
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
if (val & 0x02) {
|
||||
softresetx86(); /* Pulse reset! */
|
||||
cpu_set_edx();
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
case 0x32 ... 0x3f:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
} else
|
||||
dev->reg = val;
|
||||
}
|
||||
|
||||
static void
|
||||
acc2036_close(void *priv)
|
||||
{
|
||||
acc2036_t *dev = (acc2036_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
acc2036_init(UNUSED(const device_t *info))
|
||||
{
|
||||
acc2036_t *dev = (acc2036_t *) calloc(1, sizeof(acc2036_t));
|
||||
|
||||
for (int i = 0; i < 24; i++) {
|
||||
ram_page_t *rp = &dev->ram_mid_pages[i];
|
||||
|
||||
rp->virt = 0x000a0000 + (i << 14);
|
||||
rp->phys = 0x000a0000 + (i << 14);
|
||||
mem_mapping_add(&rp->mapping, rp->virt, 0x00004000,
|
||||
acc2036_mem_read, acc2036_mem_readw, NULL,
|
||||
acc2036_mem_write, acc2036_mem_writew, NULL,
|
||||
ram + rp->phys, MEM_MAPPING_INTERNAL, rp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ram_page_t *ep = &dev->ems_pages[i];
|
||||
|
||||
ep->virt = 0x000d0000 + (i << 14);
|
||||
ep->phys = 0x00000000 + (i << 14);
|
||||
mem_mapping_add(&ep->mapping, ep->virt, 0x00004000,
|
||||
acc2036_mem_read, acc2036_mem_readw, NULL,
|
||||
acc2036_mem_write, acc2036_mem_writew, NULL,
|
||||
ram + ep->phys, MEM_MAPPING_INTERNAL, ep);
|
||||
mem_mapping_disable(&ep->mapping);
|
||||
}
|
||||
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
|
||||
dev->regs[0x00] = 0x02;
|
||||
dev->regs[0x0e] = 0x10;
|
||||
dev->regs[0x11] = 0x01;
|
||||
dev->regs[0x13] = 0x40;
|
||||
dev->regs[0x15] = 0x40;
|
||||
dev->regs[0x17] = 0x40;
|
||||
dev->regs[0x19] = 0x40;
|
||||
dev->regs[0x1b] = 0x40;
|
||||
dev->regs[0x1c] = 0x22;
|
||||
dev->regs[0x1d] = 0xc4;
|
||||
dev->regs[0x1f] = 0x30;
|
||||
acc2036_recalc(dev);
|
||||
|
||||
mem_a20_alt = 0x01;
|
||||
mem_a20_recalc();
|
||||
flushmmucache();
|
||||
|
||||
io_sethandler(0x00f2, 0x0002,
|
||||
acc2036_in, NULL, NULL, acc2036_out, NULL, NULL, dev);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t acc2036_device = {
|
||||
.name = "ACC 2036",
|
||||
.internal_name = "acc2036",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = acc2036_init,
|
||||
.close = acc2036_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -184,8 +184,7 @@ acc2168_close(void *priv)
|
||||
static void *
|
||||
acc2168_init(UNUSED(const device_t *info))
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *) malloc(sizeof(acc2168_t));
|
||||
memset(dev, 0, sizeof(acc2168_t));
|
||||
acc2168_t *dev = (acc2168_t *) calloc(1, sizeof(acc2168_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev);
|
||||
@@ -201,7 +200,7 @@ const device_t acc2168_device = {
|
||||
.init = acc2168_init,
|
||||
.close = acc2168_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
343
src/chipset/ali1409.c
Normal file
343
src/chipset/ali1409.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* 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 ALi M1409 chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Jose Phillips, <jose@latinol.com>
|
||||
* Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
*
|
||||
* Copyright 2024 Jose Phillips.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
#include <86box/apm.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#ifdef ENABLE_ALI1409_LOG
|
||||
int ali1409_do_log = ENABLE_ALI1409_LOG;
|
||||
|
||||
static void
|
||||
ali1409_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ali1409_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define ali1409_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct ali_1409_t {
|
||||
uint8_t index;
|
||||
uint8_t cfg_locked;
|
||||
uint8_t regs[256];
|
||||
uint8_t shadow[4];
|
||||
uint8_t last_reg;
|
||||
} ali1409_t;
|
||||
|
||||
/*
|
||||
This here is because from the two BIOS'es I used to reverse engineer this,
|
||||
it is unclear which of the two interpretations of the shadow RAM register
|
||||
operation is correct.
|
||||
The 16 kB interpretation appears to work fine right now but it may be wrong,
|
||||
so I left the 32 kB interpretation in as well.
|
||||
*/
|
||||
#ifdef INTERPRETATION_32KB
|
||||
#define SHADOW_SIZE 0x00008000
|
||||
#else
|
||||
#define SHADOW_SIZE 0x00004000
|
||||
#endif
|
||||
|
||||
static void
|
||||
ali1409_shadow_recalc(ali1409_t *dev)
|
||||
{
|
||||
uint32_t base = 0x000c0000;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
uint8_t reg = 0x08 + i;
|
||||
|
||||
#ifdef INTERPRETATION_32KB
|
||||
for (uint8_t j = 0; j < 4; j += 2) {
|
||||
uint8_t mask = (0x03 << j);
|
||||
#else
|
||||
for (uint8_t j = 0; j < 4; j++) {
|
||||
uint8_t mask = (0x01 << j);
|
||||
#endif
|
||||
uint8_t r_on = dev->regs[reg] & 0x10;
|
||||
uint8_t w_on = dev->regs[reg] & 0x20;
|
||||
uint8_t val = dev->regs[reg] & mask;
|
||||
uint8_t xor = (dev->shadow[i] ^ dev->regs[reg]) & (mask | 0x30);
|
||||
int read = r_on ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
int write = w_on ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
|
||||
if (xor) {
|
||||
#ifdef INTERPRETATION_32KB
|
||||
switch (val >> j) {
|
||||
case 0x00:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x01:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | write);
|
||||
break;
|
||||
case 0x02:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, read | write);
|
||||
break;
|
||||
case 0x03:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, read | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (val >> j) {
|
||||
case 0x00:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
break;
|
||||
case 0x01:
|
||||
mem_set_mem_state_both(base, SHADOW_SIZE, read | write);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
base += SHADOW_SIZE;
|
||||
}
|
||||
|
||||
dev->shadow[i] = dev->regs[reg];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
ali1409_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1409_t *dev = (ali1409_t *) priv;
|
||||
ali1409_log("[%04X:%08X] [W] %04X = %02X\n", CS, cpu_state.pc, addr, val);
|
||||
|
||||
if (addr & 0x0001) {
|
||||
if (dev->cfg_locked) {
|
||||
if ((dev->last_reg == 0x14) && (val == 0x09))
|
||||
dev->cfg_locked = 0;
|
||||
|
||||
dev->last_reg = val;
|
||||
return;
|
||||
}
|
||||
|
||||
/* It appears writing anything at all to register 0xFF locks it again. */
|
||||
if (dev->index == 0xff)
|
||||
dev->cfg_locked = 1;
|
||||
else if (dev->index < 0x44) {
|
||||
ali1409_log("[%04X:%08X] [W] Register %02X = %02X\n", CS, cpu_state.pc, dev->index, val);
|
||||
|
||||
if (dev->index < 0x10) {
|
||||
dev->regs[dev->index] = val;
|
||||
|
||||
/*
|
||||
There are still a lot of unknown here, but unfortunately, this is
|
||||
as far as I have been able to come with two BIOS'es that are
|
||||
available (the Acer 100T and an AMI Color dated 07/07/91).
|
||||
*/
|
||||
switch (dev->index) {
|
||||
case 0x02:
|
||||
/*
|
||||
- Bit 7: The RAS address hold time:
|
||||
- 0: 1/2 T;
|
||||
- 1: 1 T.
|
||||
- Bits 6-4: The RAS precharge time:
|
||||
- 0, 0, 0: 1.5 T;
|
||||
- 0, 0, 1: 2 T;
|
||||
- 0, 1, 0: 2.5 T;
|
||||
- 0, 1, 1: 3 T;
|
||||
- 1, 0, 0: 3.5 T;
|
||||
- 1, 0, 1: 4 T;
|
||||
- 1, 1, 0: Reserved;
|
||||
- 1, 1, 1: Reserved.
|
||||
- Bit 3: Early miss cycle:
|
||||
- 0: Disabled;
|
||||
- 1: Enabled.
|
||||
*/
|
||||
break;
|
||||
case 0x03:
|
||||
/*
|
||||
- Bit 6: CAS pulse for read cycle:
|
||||
- 0: 1 T;
|
||||
- 1: 1.5 T or 2 T.
|
||||
I can not get the 2.5 T or 3 T setting to apply so
|
||||
I have no idea what bit governs that.
|
||||
- Bits 5, 4: CAS pulse for write cycle:
|
||||
- 0, 0: 0.5 T or 1 T;
|
||||
- 0, 1: 1.5 T or 2 T;
|
||||
- 1, 0: 2.5 T or 3 T;
|
||||
- 1, 1: Reserved.
|
||||
- Bit 3: CAS active for read cycle:
|
||||
- 0: Disabled;
|
||||
- 1: Enabled.
|
||||
- Bit 2: CAS active for write cycle:
|
||||
- 0: Disabled;
|
||||
- 1: Enabled.
|
||||
*/
|
||||
break;
|
||||
case 0x06:
|
||||
/*
|
||||
- Bits 6-4: Clock divider:
|
||||
- 0, 0, 0: / 2;
|
||||
- 0, 0, 1: / 4;
|
||||
- 0, 1, 0: / 8;
|
||||
- 0, 1, 1: Reserved;
|
||||
- 1, 0, 0: / 3;
|
||||
- 1, 0, 1: / 6;
|
||||
- 1, 1, 0: / 5;
|
||||
- 1, 1, 1: / 10.
|
||||
*/
|
||||
switch ((val >> 4) & 7) {
|
||||
default:
|
||||
case 3: /* Reserved */
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
cpu_set_isa_speed(cpu_busspeed / 2);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
cpu_set_isa_speed(cpu_busspeed / 4);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
cpu_set_isa_speed(cpu_busspeed / 8);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
cpu_set_isa_speed(cpu_busspeed / 3);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
cpu_set_isa_speed(cpu_busspeed / 6);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
cpu_set_isa_speed(cpu_busspeed / 5);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
cpu_set_isa_speed(cpu_busspeed / 10);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x08 ... 0x0b:
|
||||
ali1409_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x0c:
|
||||
/*
|
||||
This appears to be turbo in bit 4 (1 = on, 0 = off),
|
||||
and bus speed in the rest of the bits.
|
||||
*/
|
||||
break;
|
||||
case 0x0d:
|
||||
cpu_cache_ext_enabled = !!(val & 0x08);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
dev->index = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1409_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const ali1409_t *dev = (ali1409_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->cfg_locked)
|
||||
ret = 0xff;
|
||||
else if (addr & 0x0001) {
|
||||
if (dev->index < 0x44)
|
||||
ret = dev->regs[dev->index];
|
||||
} else
|
||||
ret = dev->index;
|
||||
|
||||
ali1409_log("[%04X:%08X] [R] %04X = %02X\n", CS, cpu_state.pc, addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
ali1409_close(void *priv)
|
||||
{
|
||||
ali1409_t *dev = (ali1409_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
ali1409_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ali1409_t *dev = (ali1409_t *) calloc(1, sizeof(ali1409_t));
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
|
||||
ali1409_log("Bus speed: %i\n", cpu_busspeed);
|
||||
|
||||
io_sethandler(0x0022, 0x0002, ali1409_read, NULL, NULL, ali1409_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x0f] = 0x08;
|
||||
|
||||
cpu_set_isa_speed(7159091);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t ali1409_device = {
|
||||
.name = "ALi M1409",
|
||||
.internal_name = "ali1409",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ali1409_init,
|
||||
.close = ali1409_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -331,8 +331,7 @@ ali1429_defaults(ali1429_t *dev)
|
||||
static void *
|
||||
ali1429_init(const device_t *info)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *) malloc(sizeof(ali1429_t));
|
||||
memset(dev, 0, sizeof(ali1429_t));
|
||||
ali1429_t *dev = (ali1429_t *) calloc(1, sizeof(ali1429_t));
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
GREEN = info->local;
|
||||
@@ -358,7 +357,7 @@ const device_t ali1429_device = {
|
||||
.init = ali1429_init,
|
||||
.close = ali1429_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -372,7 +371,7 @@ const device_t ali1429g_device = {
|
||||
.init = ali1429_init,
|
||||
.close = ali1429_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -282,8 +282,7 @@ ali1435_close(void *priv)
|
||||
static void *
|
||||
ali1435_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ali1435_t *dev = (ali1435_t *) malloc(sizeof(ali1435_t));
|
||||
memset(dev, 0, sizeof(ali1435_t));
|
||||
ali1435_t *dev = (ali1435_t *) calloc(1, sizeof(ali1435_t));
|
||||
|
||||
dev->cfg_locked = 1;
|
||||
|
||||
@@ -308,7 +307,7 @@ const device_t ali1435_device = {
|
||||
.init = ali1435_init,
|
||||
.close = ali1435_close,
|
||||
.reset = ali1435_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -28,9 +28,10 @@
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/pic.h>
|
||||
@@ -470,8 +471,7 @@ ali1489_close(void *priv)
|
||||
static void *
|
||||
ali1489_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ali1489_t *dev = (ali1489_t *) malloc(sizeof(ali1489_t));
|
||||
memset(dev, 0, sizeof(ali1489_t));
|
||||
ali1489_t *dev = (ali1489_t *) calloc(1, sizeof(ali1489_t));
|
||||
|
||||
/* M1487/M1489
|
||||
22h Index Port
|
||||
@@ -486,6 +486,9 @@ ali1489_init(UNUSED(const device_t *info))
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
dev->smram = smram_add();
|
||||
|
||||
if (machine_get_kbc_device(machine) == NULL)
|
||||
device_add_params(&kbc_at_device, (void *) KBC_VEN_ALI);
|
||||
|
||||
ali1489_defaults(dev);
|
||||
|
||||
return dev;
|
||||
@@ -499,7 +502,7 @@ const device_t ali1489_device = {
|
||||
.init = ali1489_init,
|
||||
.close = ali1489_close,
|
||||
.reset = ali1489_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/device.h>
|
||||
@@ -225,12 +226,8 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
ali1531_shadow_recalc(val, dev);
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x50 ... 0x52:
|
||||
case 0x54 ... 0x56:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -247,8 +244,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0x86;
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x59 ... 0x5a:
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
@@ -270,8 +266,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
spd_write_drbs_interleaved(dev->pci_conf, 0x60, 0x6f, 1);
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x70 ... 0x71:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -283,8 +278,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
dev->pci_conf[addr] = val & 0x2b;
|
||||
break;
|
||||
|
||||
case 0x76:
|
||||
case 0x77:
|
||||
case 0x76 ... 0x77:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
@@ -376,8 +370,7 @@ ali1531_close(void *priv)
|
||||
static void *
|
||||
ali1531_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ali1531_t *dev = (ali1531_t *) malloc(sizeof(ali1531_t));
|
||||
memset(dev, 0, sizeof(ali1531_t));
|
||||
ali1531_t *dev = (ali1531_t *) calloc(1, sizeof(ali1531_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1531_read, ali1531_write, dev, &dev->pci_slot);
|
||||
|
||||
@@ -396,7 +389,7 @@ const device_t ali1531_device = {
|
||||
.init = ali1531_init,
|
||||
.close = ali1531_close,
|
||||
.reset = ali1531_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/device.h>
|
||||
@@ -643,8 +644,7 @@ ali1541_close(void *priv)
|
||||
static void *
|
||||
ali1541_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ali1541_t *dev = (ali1541_t *) malloc(sizeof(ali1541_t));
|
||||
memset(dev, 0, sizeof(ali1541_t));
|
||||
ali1541_t *dev = (ali1541_t *) calloc(1, sizeof(ali1541_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1541_read, ali1541_write, dev, &dev->pci_slot);
|
||||
|
||||
@@ -665,7 +665,7 @@ const device_t ali1541_device = {
|
||||
.init = ali1541_init,
|
||||
.close = ali1541_close,
|
||||
.reset = ali1541_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
@@ -197,6 +198,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x44: /* Set IRQ Line for Primary IDE if it's on native mode */
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
soft_reset_pci = !!(val & 0x80);
|
||||
pci_set_mirq_level(PCI_MIRQ0, !(val & 0x10));
|
||||
pci_set_mirq_level(PCI_MIRQ2, !(val & 0x10));
|
||||
ali1543_log("INTAJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]);
|
||||
pci_set_mirq_routing(PCI_MIRQ0, ali1533_irq_routing[val & 0x0f]);
|
||||
@@ -412,11 +414,13 @@ ali1533_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x74: /* USB IRQ Routing - we cheat and use MIRQ4 */
|
||||
dev->pci_conf[addr] = val & 0xdf;
|
||||
/* TODO: MIRQ level/edge control - if bit 4 = 1, it's level */
|
||||
pci_set_mirq_level(PCI_MIRQ4, !(val & 0x10));
|
||||
pci_set_mirq_routing(PCI_MIRQ4, ali1533_irq_routing[val & 0x0f]);
|
||||
break;
|
||||
|
||||
case 0x75: /* Set IRQ Line for Secondary IDE if it's on native mode */
|
||||
dev->pci_conf[addr] = val & 0x1f;
|
||||
pci_set_mirq_level(PCI_MIRQ1, !(val & 0x10));
|
||||
pci_set_mirq_level(PCI_MIRQ3, !(val & 0x10));
|
||||
ali1543_log("INTBJ = IRQ %i\n", ali1533_irq_routing[val & 0x0f]);
|
||||
pci_set_mirq_routing(PCI_MIRQ1, ali1533_irq_routing[val & 0x0f]);
|
||||
@@ -704,7 +708,7 @@ ali5229_chip_reset(ali1543_t *dev)
|
||||
ali5229_write(0, 0x09, 0xfa, dev);
|
||||
ali5229_write(0, 0x52, 0x00, dev);
|
||||
|
||||
ali5229_write(0, 0x50, 0x00, dev);
|
||||
ali5229_write(0, 0x50, 0x02, dev);
|
||||
|
||||
sff_set_slot(dev->ide_controller[0], dev->ide_slot);
|
||||
sff_set_slot(dev->ide_controller[1], dev->ide_slot);
|
||||
@@ -717,7 +721,7 @@ static void
|
||||
ali5229_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
ali1543_t *dev = (ali1543_t *) priv;
|
||||
ali1543_log("M5229: dev->ide_conf[%02x] = %02x\n", addr, val);
|
||||
ali1543_log("M5229: [W] dev->ide_conf[%02x] = %02x\n", addr, val);
|
||||
|
||||
if (func > 0)
|
||||
return;
|
||||
@@ -756,6 +760,10 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
|
||||
ali5229_ide_irq_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* LT - Latency Timer */
|
||||
dev->ide_conf[addr] = val;
|
||||
break;
|
||||
|
||||
/* Primary Base Address */
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
@@ -776,9 +784,9 @@ ali5229_write(int func, int addr, uint8_t val, void *priv)
|
||||
/* Datasheet erratum: the PCI BAR's actually have different sizes. */
|
||||
if (addr == 0x20)
|
||||
dev->ide_conf[addr] = (val & 0xe0) | 0x01;
|
||||
else if ((addr & 0x43) == 0x00)
|
||||
else if ((addr & 0x07) == 0x00)
|
||||
dev->ide_conf[addr] = (val & 0xf8) | 0x01;
|
||||
else if ((addr & 0x43) == 0x40)
|
||||
else if ((addr & 0x07) == 0x04)
|
||||
dev->ide_conf[addr] = (val & 0xfc) | 0x01;
|
||||
else
|
||||
dev->ide_conf[addr] = val;
|
||||
@@ -887,13 +895,15 @@ ali5229_read(int func, int addr, void *priv)
|
||||
if (dev->ide_dev_enable && (func == 0)) {
|
||||
ret = dev->ide_conf[addr];
|
||||
if ((addr == 0x09) && !(dev->ide_conf[0x50] & 0x02))
|
||||
ret &= 0x0f;
|
||||
ret = (ret & 0x0f) | 0x80;
|
||||
else if (addr == 0x50)
|
||||
ret = (ret & 0xfe) | (dev->ide_dev_enable ? 0x01 : 0x00);
|
||||
else if (addr == 0x75)
|
||||
ret = ide_read_ali_75();
|
||||
else if (addr == 0x76)
|
||||
ret = ide_read_ali_76();
|
||||
|
||||
ali1543_log("M5229: [R] dev->ide_conf[%02x] = %02x\n", addr, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1590,8 +1600,7 @@ ali1543_close(void *priv)
|
||||
static void *
|
||||
ali1543_init(const device_t *info)
|
||||
{
|
||||
ali1543_t *dev = (ali1543_t *) malloc(sizeof(ali1543_t));
|
||||
memset(dev, 0, sizeof(ali1543_t));
|
||||
ali1543_t *dev = (ali1543_t *) calloc(1, sizeof(ali1543_t));
|
||||
|
||||
/* Device 02: M1533 Southbridge */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev, &dev->pci_slot);
|
||||
@@ -1664,7 +1673,7 @@ const device_t ali1543_device = {
|
||||
.init = ali1543_init,
|
||||
.close = ali1543_close,
|
||||
.reset = ali1543_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1678,7 +1687,7 @@ const device_t ali1543c_device = {
|
||||
.init = ali1543_init,
|
||||
.close = ali1543_close,
|
||||
.reset = ali1543_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -669,8 +669,7 @@ ali1621_close(void *priv)
|
||||
static void *
|
||||
ali1621_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ali1621_t *dev = (ali1621_t *) malloc(sizeof(ali1621_t));
|
||||
memset(dev, 0, sizeof(ali1621_t));
|
||||
ali1621_t *dev = (ali1621_t *) calloc(1, sizeof(ali1621_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, ali1621_read, ali1621_write, dev, &dev->pci_slot);
|
||||
|
||||
@@ -692,7 +691,7 @@ const device_t ali1621_device = {
|
||||
.init = ali1621_init,
|
||||
.close = ali1621_close,
|
||||
.reset = ali1621_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <86box/io.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/device.h>
|
||||
@@ -466,12 +467,12 @@ ali6117_init(const device_t *info)
|
||||
|
||||
ali6117_log("ALI6117: init()\n");
|
||||
|
||||
ali6117_t *dev = (ali6117_t *) malloc(sizeof(ali6117_t));
|
||||
memset(dev, 0, sizeof(ali6117_t));
|
||||
ali6117_t *dev = (ali6117_t *) calloc(1, sizeof(ali6117_t));
|
||||
|
||||
dev->local = info->local;
|
||||
|
||||
device_add(&ide_isa_device);
|
||||
if (!(dev->local & 0x08))
|
||||
device_add(&ide_isa_device);
|
||||
|
||||
ali6117_setup(dev);
|
||||
|
||||
@@ -493,12 +494,12 @@ ali6117_init(const device_t *info)
|
||||
const device_t ali1217_device = {
|
||||
.name = "ALi M1217",
|
||||
.internal_name = "ali1217",
|
||||
.flags = DEVICE_AT,
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 0x8,
|
||||
.init = ali6117_init,
|
||||
.close = ali6117_close,
|
||||
.reset = ali6117_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -507,12 +508,12 @@ const device_t ali1217_device = {
|
||||
const device_t ali6117d_device = {
|
||||
.name = "ALi M6117D",
|
||||
.internal_name = "ali6117d",
|
||||
.flags = DEVICE_AT,
|
||||
.flags = DEVICE_ISA16,
|
||||
.local = 0x2,
|
||||
.init = ali6117_init,
|
||||
.close = ali6117_close,
|
||||
.reset = ali6117_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
135
src/chipset/compaq.c
Normal file
135
src/chipset/compaq.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* 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>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
/* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */
|
||||
typedef struct cpq_t {
|
||||
mem_mapping_t ram_mapping;
|
||||
} cpq_t;
|
||||
|
||||
static uint8_t
|
||||
read_ram(uint32_t addr, UNUSED(void *priv))
|
||||
{
|
||||
addr = (addr & 0x7ffff) + 0x80000;
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
|
||||
return (ram[addr]);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
read_ramw(uint32_t addr, UNUSED(void *priv))
|
||||
{
|
||||
addr = (addr & 0x7ffff) + 0x80000;
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
|
||||
return (*(uint16_t *) &ram[addr]);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
read_raml(uint32_t addr, UNUSED(void *priv))
|
||||
{
|
||||
addr = (addr & 0x7ffff) + 0x80000;
|
||||
addreadlookup(mem_logical_addr, addr);
|
||||
|
||||
return (*(uint32_t *) &ram[addr]);
|
||||
}
|
||||
|
||||
static void
|
||||
write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv))
|
||||
{
|
||||
addr = (addr & 0x7ffff) + 0x80000;
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
|
||||
mem_write_ramb_page(addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
static void
|
||||
write_ramw(uint32_t addr, uint16_t val, UNUSED(void *priv))
|
||||
{
|
||||
addr = (addr & 0x7ffff) + 0x80000;
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
|
||||
mem_write_ramw_page(addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
static void
|
||||
write_raml(uint32_t addr, uint32_t val, UNUSED(void *priv))
|
||||
{
|
||||
addr = (addr & 0x7ffff) + 0x80000;
|
||||
addwritelookup(mem_logical_addr, addr);
|
||||
|
||||
mem_write_raml_page(addr, val, &pages[addr >> 12]);
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_close(void *priv)
|
||||
{
|
||||
cpq_t *dev = (cpq_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_init(UNUSED(const device_t *info))
|
||||
{
|
||||
cpq_t *dev = (cpq_t *) calloc(1, sizeof(cpq_t));
|
||||
|
||||
mem_remap_top(384);
|
||||
mem_mapping_add(&dev->ram_mapping, 0xfa0000, 0x60000,
|
||||
read_ram, read_ramw, read_raml,
|
||||
write_ram, write_ramw, write_raml,
|
||||
0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t compaq_device = {
|
||||
.name = "Compaq Memory Control",
|
||||
.internal_name = "compaq",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = compaq_init,
|
||||
.close = compaq_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define RAM_DIAG_L_BASE_MEM_640KB 0x00
|
||||
#define RAM_DIAG_L_BASE_MEM_INV 0x10
|
||||
@@ -746,6 +747,23 @@ compaq_386_init(UNUSED(const device_t *info))
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
compaq_genoa_outw(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
if (port == 0x0c02)
|
||||
cpq_write_regs(0x80c00000, val, priv);
|
||||
}
|
||||
|
||||
static void *
|
||||
compaq_genoa_init(UNUSED(const device_t *info))
|
||||
{
|
||||
void *cpq = device_add(&compaq_386_device);
|
||||
|
||||
io_sethandler(0x0c02, 2, NULL, NULL, NULL, NULL, compaq_genoa_outw, NULL, cpq);
|
||||
|
||||
return ram;
|
||||
}
|
||||
|
||||
const device_t compaq_386_device = {
|
||||
.name = "Compaq 386 Memory Control",
|
||||
.internal_name = "compaq_386",
|
||||
@@ -754,7 +772,21 @@ const device_t compaq_386_device = {
|
||||
.init = compaq_386_init,
|
||||
.close = compaq_386_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t compaq_genoa_device = {
|
||||
.name = "Compaq Genoa Memory Control",
|
||||
.internal_name = "compaq_genoa",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = compaq_genoa_init,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -322,8 +322,7 @@ contaq_82c59x_close(void *priv)
|
||||
static void *
|
||||
contaq_82c59x_init(const device_t *info)
|
||||
{
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) malloc(sizeof(contaq_82c59x_t));
|
||||
memset(dev, 0x00, sizeof(contaq_82c59x_t));
|
||||
contaq_82c59x_t *dev = (contaq_82c59x_t *) calloc(1, sizeof(contaq_82c59x_t));
|
||||
|
||||
dev->green = info->local;
|
||||
|
||||
@@ -359,7 +358,7 @@ const device_t contaq_82c596a_device = {
|
||||
.init = contaq_82c59x_init,
|
||||
.close = contaq_82c59x_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -373,7 +372,7 @@ const device_t contaq_82c597_device = {
|
||||
.init = contaq_82c59x_init,
|
||||
.close = contaq_82c59x_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -164,8 +164,7 @@ cs4031_close(void *priv)
|
||||
static void *
|
||||
cs4031_init(UNUSED(const device_t *info))
|
||||
{
|
||||
cs4031_t *dev = (cs4031_t *) malloc(sizeof(cs4031_t));
|
||||
memset(dev, 0, sizeof(cs4031_t));
|
||||
cs4031_t *dev = (cs4031_t *) calloc(1, sizeof(cs4031_t));
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
|
||||
@@ -185,7 +184,7 @@ const device_t cs4031_device = {
|
||||
.init = cs4031_init,
|
||||
.close = cs4031_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
289
src/chipset/cs8220.c
Normal file
289
src/chipset/cs8220.c
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of C&T CS8220 ("PC/AT") chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t virt;
|
||||
uint32_t phys;
|
||||
|
||||
uint32_t size;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t regs[3];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
} cs8220_t;
|
||||
|
||||
static uint8_t
|
||||
cs8220_mem_read(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
cs8220_mem_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ret = *(uint16_t *) &(ram[addr]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_mem_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_mem_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
ram_bank_t *dev = (ram_bank_t *) priv;
|
||||
|
||||
addr = (addr - dev->virt) + dev->phys;
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *) &(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cs8220_in(uint16_t port, void *priv) {
|
||||
cs8220_t *dev = (cs8220_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (port) {
|
||||
case 0x00a4 ... 0x00a5:
|
||||
ret = dev->regs[port & 0x0001];
|
||||
break;
|
||||
case 0x00ab:
|
||||
ret = dev->regs[2];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_out(uint16_t port, uint8_t val, void *priv) {
|
||||
cs8220_t *dev = (cs8220_t *) priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x00a4:
|
||||
dev->regs[0] = val;
|
||||
mem_a20_alt = val & 0x40;
|
||||
mem_a20_recalc();
|
||||
break;
|
||||
case 0x00a5:
|
||||
dev->regs[1] = val;
|
||||
if (val & 0x01) {
|
||||
mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, 0x000040000);
|
||||
mem_mapping_disable(&dev->ram_banks[1].mapping);
|
||||
mem_mapping_disable(&dev->ram_banks[2].mapping);
|
||||
} else {
|
||||
mem_mapping_set_addr(&dev->ram_banks[0].mapping, 0, dev->ram_banks[0].size);
|
||||
mem_mapping_enable(&dev->ram_banks[1].mapping);
|
||||
mem_mapping_enable(&dev->ram_banks[2].mapping);
|
||||
}
|
||||
break;
|
||||
case 0x00ab:
|
||||
dev->regs[2] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cs8220_close(void *priv)
|
||||
{
|
||||
cs8220_t *dev = (cs8220_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
cs8220_init(UNUSED(const device_t *info))
|
||||
{
|
||||
cs8220_t *dev = (cs8220_t *) calloc(1, sizeof(cs8220_t));
|
||||
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
|
||||
/*
|
||||
Dell System 200: 640 kB soldered on-board, any other RAM is expansion.
|
||||
*/
|
||||
if (!strcmp(machine_get_internal_name(), "dells200")) switch (mem_size) {
|
||||
default:
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x000a0000;
|
||||
dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000;
|
||||
fallthrough;
|
||||
case 640:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
break;
|
||||
/*
|
||||
We are limited to steps of equal size, so we have to simulate some
|
||||
memory expansions to work around the chipset's limits.
|
||||
*/
|
||||
} else switch (mem_size) {
|
||||
case 256:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00020000;
|
||||
dev->ram_banks[1].virt = 0x00020000;
|
||||
dev->ram_banks[1].phys = 0x00020000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
break;
|
||||
case 384:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00020000;
|
||||
/* Pretend there's a 128k expansion. */
|
||||
dev->ram_banks[2].virt = 0x00020000;
|
||||
dev->ram_banks[2].phys = 0x00020000;
|
||||
dev->ram_banks[2].size = 0x00040000;
|
||||
break;
|
||||
case 512:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
break;
|
||||
default:
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x000a0000;
|
||||
dev->ram_banks[2].size = (mem_size << 10) - 0x000a0000;
|
||||
fallthrough;
|
||||
case 640:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
break;
|
||||
case 768:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
/* Pretend there's a 128k expansion. */
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x00080000;
|
||||
dev->ram_banks[2].size = 0x00020000;
|
||||
break;
|
||||
case 896:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00080000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00020000;
|
||||
/* Pretend there's a 256k expansion. */
|
||||
dev->ram_banks[2].virt = 0x00100000;
|
||||
dev->ram_banks[2].phys = 0x00080000;
|
||||
dev->ram_banks[2].size = 0x00040000;
|
||||
break;
|
||||
case 1024:
|
||||
dev->ram_banks[0].virt = 0x00000000;
|
||||
dev->ram_banks[0].phys = 0x00000000;
|
||||
dev->ram_banks[0].size = 0x00080000;
|
||||
dev->ram_banks[1].virt = 0x00100000;
|
||||
dev->ram_banks[1].phys = 0x00080000;
|
||||
dev->ram_banks[1].size = 0x00080000;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dev->ram_banks[0].size > 0x00000000)
|
||||
mem_mapping_add(&dev->ram_banks[0].mapping, dev->ram_banks[0].virt, dev->ram_banks[0].size,
|
||||
cs8220_mem_read, cs8220_mem_readw, NULL,
|
||||
cs8220_mem_write, cs8220_mem_writew, NULL,
|
||||
ram + dev->ram_banks[0].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[0]));
|
||||
|
||||
if (dev->ram_banks[1].size > 0x00000000)
|
||||
mem_mapping_add(&dev->ram_banks[1].mapping, dev->ram_banks[1].virt, dev->ram_banks[1].size,
|
||||
cs8220_mem_read, cs8220_mem_readw, NULL,
|
||||
cs8220_mem_write, cs8220_mem_writew, NULL,
|
||||
ram + dev->ram_banks[1].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[1]));
|
||||
|
||||
if (dev->ram_banks[2].size > 0x00000000)
|
||||
mem_mapping_add(&dev->ram_banks[2].mapping, dev->ram_banks[2].virt, dev->ram_banks[2].size,
|
||||
cs8220_mem_read, cs8220_mem_readw, NULL,
|
||||
cs8220_mem_write, cs8220_mem_writew, NULL,
|
||||
ram + dev->ram_banks[2].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[2]));
|
||||
|
||||
io_sethandler(0x00a4, 0x0002,
|
||||
cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev);
|
||||
io_sethandler(0x00ab, 0x0001,
|
||||
cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t cs8220_device = {
|
||||
.name = "C&T CS8220 (PC/AT)",
|
||||
.internal_name = "cs8220",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = cs8220_init,
|
||||
.close = cs8220_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -157,8 +157,7 @@ cs8230_close(void *priv)
|
||||
static void *
|
||||
cs8230_init(UNUSED(const device_t *info))
|
||||
{
|
||||
cs8230_t *cs8230 = (cs8230_t *) malloc(sizeof(cs8230_t));
|
||||
memset(cs8230, 0, sizeof(cs8230_t));
|
||||
cs8230_t *cs8230 = (cs8230_t *) calloc(1, sizeof(cs8230_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0002, cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, cs8230);
|
||||
|
||||
@@ -178,7 +177,7 @@ const device_t cs8230_device = {
|
||||
.init = cs8230_init,
|
||||
.close = cs8230_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -137,8 +137,7 @@ et6000_close(void *priv)
|
||||
static void *
|
||||
et6000_init(UNUSED(const device_t *info))
|
||||
{
|
||||
et6000_t *dev = (et6000_t *) malloc(sizeof(et6000_t));
|
||||
memset(dev, 0, sizeof(et6000_t));
|
||||
et6000_t *dev = (et6000_t *) calloc(1, sizeof(et6000_t));
|
||||
|
||||
/* Port 92h */
|
||||
device_add(&port_92_device);
|
||||
@@ -162,7 +161,7 @@ const device_t et6000_device = {
|
||||
.init = et6000_init,
|
||||
.close = et6000_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/nmi.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
@@ -208,8 +209,7 @@ gc100_close(void *priv)
|
||||
static void *
|
||||
gc100_init(const device_t *info)
|
||||
{
|
||||
gc100_t *dev = (gc100_t *) malloc(sizeof(gc100_t));
|
||||
memset(dev, 0, sizeof(gc100_t));
|
||||
gc100_t *dev = (gc100_t *) calloc(1, sizeof(gc100_t));
|
||||
|
||||
dev->reg[0x2] = 0xff;
|
||||
dev->reg[0x3] = 0x0;
|
||||
@@ -238,7 +238,7 @@ const device_t gc100_device = {
|
||||
.init = gc100_init,
|
||||
.close = gc100_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -252,7 +252,7 @@ const device_t gc100a_device = {
|
||||
.init = gc100_init,
|
||||
.close = gc100_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
333
src/chipset/grid1520.c
Normal file
333
src/chipset/grid1520.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the GRiD GRiDcase 1520
|
||||
*
|
||||
* The GRiDcase 1520 is a 286-based portable.
|
||||
* These are HDDs supported by GRiD1520 (and probably other 15XX) BIOS
|
||||
* "CP3022",5
|
||||
* "CP3024",5, 615,4,17 BIOS table type 2
|
||||
* "CP344",6,
|
||||
* "CP3044",9, 980,5,17 BIOS table type 17
|
||||
* "CP3042",9
|
||||
* "CP3104",7, 776,8,33 extended type 224 (separate entry outside BIOS table)
|
||||
* The only way to run unpatched BIOS is to run exactly that (or larger)
|
||||
* geometry and report model name correctly in response to IDENTYIFY command.
|
||||
* Alternatively you can use RomBuster to patch the BIOS.
|
||||
* https://classicbits.net/coding-and-software/my-software/rombuster/
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#define GRID_APPROM_SELECT 0x440
|
||||
#define GRID_APPROM_ENABLE 0x405
|
||||
|
||||
/*
|
||||
approm mapping regs?
|
||||
XXX_7FA equ 7FAh
|
||||
XXX_7F8 equ 7F8h
|
||||
XXX_7F9 equ 7F9h
|
||||
XXX_BD0 equ 0BD0h
|
||||
XXX_BD1 equ 0BD1h
|
||||
*/
|
||||
|
||||
#define GRID_EMS_PAGE_0 0x0258
|
||||
#define GRID_EMS_PAGE_1 0x4258
|
||||
#define GRID_EMS_PAGE_2 0x8258
|
||||
#define GRID_EMS_PAGE_3 0xC258
|
||||
#define GRID_TURBO 0x416
|
||||
#define GRID_UNUSED_424 0x424
|
||||
#define GRID_426 0x426
|
||||
#define GRID_HIGH_ENABLE 0xFFF
|
||||
#define GRID_ROM_SUBSYSTEM 0x6F8
|
||||
|
||||
// EMS window
|
||||
#define GRID_EMS_BASE 0xE0000
|
||||
#define GRID_EMS_PAGE_SIZE 0x4000
|
||||
#define GRID_EMS_PAGE_MASK 0x3FFF
|
||||
#define GRID_EMS_PAGE_SHIFT 14
|
||||
// physical base of extended memory
|
||||
#define GRID_EXTENDED_BASE 0xA0000
|
||||
#define GRID_1M 0x100000
|
||||
|
||||
typedef struct {
|
||||
uint8_t grid_unknown;
|
||||
uint8_t grid_unused_424;
|
||||
uint8_t grid_426;
|
||||
uint8_t grid_high_enable;
|
||||
uint8_t grid_ems_page[4];
|
||||
mem_mapping_t grid_ems_mapping[4];
|
||||
uint8_t grid_turbo;
|
||||
uint8_t grid_rom_enable;
|
||||
uint8_t grid_rom_select;
|
||||
} grid_t;
|
||||
|
||||
|
||||
static uint32_t get_grid_ems_paddr(grid_t *dev, uint32_t addr) {
|
||||
uint32_t slot = (addr >> GRID_EMS_PAGE_SHIFT) & 0x3;
|
||||
uint32_t paddr = addr;
|
||||
|
||||
if (dev->grid_ems_page[slot] & 0x80)
|
||||
paddr = GRID_EXTENDED_BASE + ((uint32_t)(dev->grid_ems_page[slot] & 0x7F) << GRID_EMS_PAGE_SHIFT) + (addr & GRID_EMS_PAGE_MASK);
|
||||
|
||||
return paddr;
|
||||
}
|
||||
|
||||
static void grid_ems_mem_write8(uint32_t addr, uint8_t val, void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
|
||||
addr = get_grid_ems_paddr(dev, addr);
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
static uint8_t grid_ems_mem_read8(uint32_t addr, void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
uint8_t val = 0xFF;
|
||||
|
||||
addr = get_grid_ems_paddr(dev, addr);
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
val = ram[addr];
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void grid_ems_mem_write16(uint32_t addr, uint16_t val, void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
|
||||
addr = get_grid_ems_paddr(dev, addr);
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
*(uint16_t *)&(ram[addr]) = val;
|
||||
}
|
||||
|
||||
static uint16_t grid_ems_mem_read16(uint32_t addr, void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
uint16_t val = 0xFFFF;
|
||||
|
||||
addr = get_grid_ems_paddr(dev, addr);
|
||||
|
||||
if (addr < (mem_size << 10))
|
||||
val = *(uint16_t *)&(ram[addr]);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void grid_ems_update_mapping(grid_t *dev, uint32_t slot) {
|
||||
uint32_t vaddr = GRID_EMS_BASE + (slot << GRID_EMS_PAGE_SHIFT);
|
||||
if (dev->grid_ems_page[slot] & 0x80) {
|
||||
uint32_t paddr;
|
||||
mem_mapping_enable(&dev->grid_ems_mapping[slot]);
|
||||
paddr = get_grid_ems_paddr(dev, vaddr);
|
||||
mem_mapping_set_exec(&dev->grid_ems_mapping[slot], ram + paddr);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->grid_ems_mapping[slot]);
|
||||
}
|
||||
}
|
||||
|
||||
static void grid_io_write(uint16_t port, uint8_t val, void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
|
||||
switch (port) {
|
||||
case GRID_426:
|
||||
dev->grid_426 = val;
|
||||
break;
|
||||
case GRID_UNUSED_424:
|
||||
dev->grid_unused_424 = val;
|
||||
break;
|
||||
case GRID_ROM_SUBSYSTEM:
|
||||
case GRID_ROM_SUBSYSTEM+1:
|
||||
case GRID_ROM_SUBSYSTEM+2:
|
||||
case GRID_ROM_SUBSYSTEM+3:
|
||||
case GRID_ROM_SUBSYSTEM+4:
|
||||
case GRID_ROM_SUBSYSTEM+5:
|
||||
case GRID_ROM_SUBSYSTEM+6:
|
||||
case GRID_ROM_SUBSYSTEM+7:
|
||||
break;
|
||||
case GRID_APPROM_SELECT:
|
||||
dev->grid_rom_select = val;
|
||||
break;
|
||||
case GRID_APPROM_ENABLE:
|
||||
dev->grid_rom_enable = val;
|
||||
break;
|
||||
case GRID_TURBO:
|
||||
if ((dev->grid_turbo ^ val) & 1) {
|
||||
dev->grid_turbo = val;
|
||||
if (dev->grid_turbo)
|
||||
cpu_dynamic_switch(cpu);
|
||||
else
|
||||
cpu_dynamic_switch(0); /* 286/6 */
|
||||
}
|
||||
break;
|
||||
case GRID_EMS_PAGE_0:
|
||||
case GRID_EMS_PAGE_1:
|
||||
case GRID_EMS_PAGE_2:
|
||||
case GRID_EMS_PAGE_3: {
|
||||
uint32_t slot = (port >> 14) & 0x3;
|
||||
if (dev->grid_ems_page[slot] == val)
|
||||
break; // no change
|
||||
|
||||
dev->grid_ems_page[slot] = val;
|
||||
if (dev->grid_high_enable & 0x1)
|
||||
break; // XMS is enabled
|
||||
grid_ems_update_mapping(dev, slot);
|
||||
|
||||
flushmmucache();
|
||||
break;
|
||||
}
|
||||
case GRID_HIGH_ENABLE: {
|
||||
if (((val ^ dev->grid_high_enable) & 0x1) == 0)
|
||||
break; // no change
|
||||
dev->grid_high_enable = val;
|
||||
if (dev->grid_high_enable & 0x1) {
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
mem_mapping_disable(&dev->grid_ems_mapping[i]);
|
||||
mem_mapping_enable(&ram_high_mapping);
|
||||
} else {
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
grid_ems_update_mapping(dev, i);
|
||||
}
|
||||
flushmmucache();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t grid_io_read(uint16_t port, void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
|
||||
switch (port) {
|
||||
case GRID_426:
|
||||
return dev->grid_426;
|
||||
break;
|
||||
case GRID_UNUSED_424:
|
||||
return dev->grid_unused_424;
|
||||
break;
|
||||
case GRID_ROM_SUBSYSTEM:
|
||||
return 0x99;
|
||||
break;
|
||||
case GRID_ROM_SUBSYSTEM+1:
|
||||
case GRID_ROM_SUBSYSTEM+2:
|
||||
case GRID_ROM_SUBSYSTEM+3:
|
||||
case GRID_ROM_SUBSYSTEM+4:
|
||||
case GRID_ROM_SUBSYSTEM+5:
|
||||
case GRID_ROM_SUBSYSTEM+6:
|
||||
case GRID_ROM_SUBSYSTEM+7:
|
||||
break;
|
||||
case GRID_APPROM_SELECT:
|
||||
return dev->grid_rom_select;
|
||||
case GRID_APPROM_ENABLE:
|
||||
return dev->grid_rom_enable;
|
||||
case GRID_TURBO:
|
||||
return dev->grid_turbo;
|
||||
case GRID_HIGH_ENABLE:
|
||||
return dev->grid_high_enable;
|
||||
case GRID_EMS_PAGE_0:
|
||||
case GRID_EMS_PAGE_1:
|
||||
case GRID_EMS_PAGE_2:
|
||||
case GRID_EMS_PAGE_3: {
|
||||
uint32_t slot = (port >> 14) & 0x3;
|
||||
|
||||
return dev->grid_ems_page[slot];
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static void *
|
||||
grid_init(UNUSED(const device_t *info))
|
||||
{
|
||||
grid_t *dev = calloc(1, sizeof(grid_t));
|
||||
|
||||
io_sethandler(GRID_ROM_SUBSYSTEM, 0x0008, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_UNUSED_424, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_426, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_APPROM_SELECT, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_APPROM_ENABLE, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_TURBO, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
dev->grid_turbo = 0x1;
|
||||
|
||||
io_sethandler(GRID_HIGH_ENABLE, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_EMS_PAGE_0, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_EMS_PAGE_1, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_EMS_PAGE_2, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
io_sethandler(GRID_EMS_PAGE_3, 0x0001, grid_io_read, NULL, NULL, grid_io_write, NULL, NULL, dev);
|
||||
|
||||
dev->grid_high_enable = 1;
|
||||
for (uint8_t slot = 0; slot < 4; slot++) {
|
||||
dev->grid_ems_page[slot] = 0;
|
||||
mem_mapping_add(&dev->grid_ems_mapping[slot], GRID_EMS_BASE + (slot << GRID_EMS_PAGE_SHIFT), GRID_EMS_PAGE_SIZE, grid_ems_mem_read8, grid_ems_mem_read16, NULL,
|
||||
grid_ems_mem_write8, grid_ems_mem_write16, NULL, ram + GRID_EXTENDED_BASE + (slot << GRID_EMS_PAGE_SHIFT), MEM_MAPPING_EXTERNAL, dev);
|
||||
mem_mapping_disable(&dev->grid_ems_mapping[slot]);
|
||||
}
|
||||
flushmmucache();
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void grid_close(void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void grid_reset(void *priv) {
|
||||
grid_t *dev = (grid_t *) priv;
|
||||
|
||||
dev->grid_high_enable = 1;
|
||||
mem_mapping_enable(&ram_high_mapping);
|
||||
dev->grid_turbo = 0x1;
|
||||
for (uint8_t slot = 0; slot < 4; slot++) {
|
||||
dev->grid_ems_page[slot] = 0;
|
||||
mem_mapping_disable(&dev->grid_ems_mapping[slot]);
|
||||
}
|
||||
flushmmucache();
|
||||
dev->grid_unknown = 0;
|
||||
dev->grid_unused_424 = 0;
|
||||
dev->grid_426 = 0;
|
||||
dev->grid_rom_enable = 0;
|
||||
dev->grid_rom_select = 0;
|
||||
}
|
||||
|
||||
const device_t grid1520_device = {
|
||||
.name = "GRiDcase 1520 chipset",
|
||||
.internal_name = "grid1520",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = grid_init,
|
||||
.close = grid_close,
|
||||
.reset = grid_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -594,8 +594,7 @@ headland_init(const device_t *info)
|
||||
headland_t *dev;
|
||||
int ht386 = 0;
|
||||
|
||||
dev = (headland_t *) malloc(sizeof(headland_t));
|
||||
memset(dev, 0x00, sizeof(headland_t));
|
||||
dev = (headland_t *) calloc(1, sizeof(headland_t));
|
||||
|
||||
dev->has_cri = (info->local & HEADLAND_HAS_CRI);
|
||||
dev->has_sleep = (info->local & HEADLAND_HAS_SLEEP);
|
||||
@@ -699,7 +698,7 @@ const device_t headland_gc10x_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -713,7 +712,7 @@ const device_t headland_gc113_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -727,7 +726,7 @@ const device_t headland_ht18a_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -741,7 +740,7 @@ const device_t headland_ht18b_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -755,7 +754,7 @@ const device_t headland_ht18c_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -769,7 +768,7 @@ const device_t headland_ht21c_d_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -783,7 +782,7 @@ const device_t headland_ht21e_device = {
|
||||
.init = headland_init,
|
||||
.close = headland_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -381,8 +381,7 @@ ims8848_close(void *priv)
|
||||
static void *
|
||||
ims8848_init(UNUSED(const device_t *info))
|
||||
{
|
||||
ims8848_t *dev = (ims8848_t *) malloc(sizeof(ims8848_t));
|
||||
memset(dev, 0, sizeof(ims8848_t));
|
||||
ims8848_t *dev = (ims8848_t *) calloc(1, sizeof(ims8848_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
@@ -416,7 +415,7 @@ const device_t ims8848_device = {
|
||||
.init = ims8848_init,
|
||||
.close = ims8848_close,
|
||||
.reset = ims8848_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -533,8 +533,7 @@ i420ex_speed_changed(void *priv)
|
||||
static void *
|
||||
i420ex_init(const device_t *info)
|
||||
{
|
||||
i420ex_t *dev = (i420ex_t *) malloc(sizeof(i420ex_t));
|
||||
memset(dev, 0, sizeof(i420ex_t));
|
||||
i420ex_t *dev = (i420ex_t *) calloc(1, sizeof(i420ex_t));
|
||||
|
||||
dev->smram = smram_add();
|
||||
|
||||
@@ -579,7 +578,7 @@ const device_t i420ex_device = {
|
||||
.init = i420ex_init,
|
||||
.close = i420ex_close,
|
||||
.reset = i420ex_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = i420ex_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -593,7 +592,7 @@ const device_t i420ex_ide_device = {
|
||||
.init = i420ex_init,
|
||||
.close = i420ex_close,
|
||||
.reset = i420ex_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = i420ex_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -493,16 +493,40 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x52: /* Cache Control Register */
|
||||
switch (dev->type) {
|
||||
default:
|
||||
/*
|
||||
420TX/ZX:
|
||||
Bit 7-6: 0, 0 = 64 kB,
|
||||
0, 1 = 128 kB,
|
||||
1, 0 = 256 kB,
|
||||
1, 1 = 512 kB.
|
||||
Bit 5: 1 = L2 cache present, 0 = L2 cache absent.
|
||||
Bit 1: 1 = Write back cache, 0 = write through cache.
|
||||
Bit 0: 1 = L2 cache enable, 0 = L2 cache disable.
|
||||
*/
|
||||
case INTEL_420TX:
|
||||
case INTEL_420ZX:
|
||||
case INTEL_430NX:
|
||||
regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1f);
|
||||
cpu_cache_ext_enabled = val & 0x01;
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_430LX:
|
||||
regs[0x52] = (regs[0x52] & 0xe0) | (val & 0x1b);
|
||||
cpu_cache_ext_enabled = val & 0x01;
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_430FX:
|
||||
case INTEL_430VX:
|
||||
case INTEL_430TX:
|
||||
regs[0x52] = (val & 0xfb);
|
||||
regs[0x52] = (regs[0x52] & 0x04) | (val & 0xfb);
|
||||
cpu_cache_ext_enabled = ((val & 0x03) == 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_430NX:
|
||||
case INTEL_430HX:
|
||||
regs[0x52] = val;
|
||||
cpu_cache_ext_enabled = ((val & 0x03) == 0x01);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
case INTEL_440FX:
|
||||
regs[0x52] = val;
|
||||
break;
|
||||
@@ -989,7 +1013,8 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
case INTEL_430TX:
|
||||
if (!dev->smram_locked) {
|
||||
i4x0_smram_handler_phase0(dev);
|
||||
regs[0x71] = (regs[0x71] & 0x20) | (val & 0xdf);
|
||||
regs[0x71] = (regs[0x71] & 0x60) | (val & 0x9f);
|
||||
regs[0x71] &= (val & 0x40);
|
||||
i4x0_smram_handler_phase1(dev);
|
||||
}
|
||||
break;
|
||||
@@ -1017,9 +1042,11 @@ i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
regs[0x72] = (val & 0x7f);
|
||||
else
|
||||
regs[0x72] = (regs[0x72] & 0x87) | (val & 0x78);
|
||||
dev->smram_locked = (val & 0x10);
|
||||
if (dev->smram_locked)
|
||||
regs[0x72] &= 0xbf;
|
||||
if (val & 0x08) {
|
||||
dev->smram_locked = (val & 0x10);
|
||||
if (dev->smram_locked)
|
||||
regs[0x72] &= 0xbf;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dev->smram_locked)
|
||||
@@ -1553,6 +1580,8 @@ i4x0_reset(void *priv)
|
||||
dev->regs[0x68 + i] = 0x00;
|
||||
}
|
||||
|
||||
dev->smram_locked = 0;
|
||||
|
||||
if (dev->type >= INTEL_430FX) {
|
||||
dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */
|
||||
i4x0_write(0, 0x72, 0x02, priv);
|
||||
@@ -1584,11 +1613,9 @@ i4x0_close(void *priv)
|
||||
static void *
|
||||
i4x0_init(const device_t *info)
|
||||
{
|
||||
i4x0_t *dev = (i4x0_t *) malloc(sizeof(i4x0_t));
|
||||
i4x0_t *dev = (i4x0_t *) calloc(1, sizeof(i4x0_t));
|
||||
uint8_t *regs;
|
||||
|
||||
memset(dev, 0, sizeof(i4x0_t));
|
||||
|
||||
dev->smram_low = smram_add();
|
||||
dev->smram_high = smram_add();
|
||||
|
||||
@@ -1630,11 +1657,16 @@ i4x0_init(const device_t *info)
|
||||
0x00 = None, 0x01 = 64 kB, 0x41 = 128 kB, 0x81 = 256 kB, 0xc1 = 512 kB,
|
||||
If bit 0 is set, then if bit 2 is also set, the cache is write back,
|
||||
otherwise it's write through. */
|
||||
regs[0x52] = 0xc3; /* 512 kB writeback cache */
|
||||
regs[0x52] = 0xe0; /* 512 kB writeback cache */
|
||||
regs[0x57] = 0x31;
|
||||
regs[0x59] = 0x0f;
|
||||
regs[0x60] = regs[0x61] = regs[0x62] = regs[0x63] = 0x02;
|
||||
dev->max_drb = 3;
|
||||
/* At the very least the 420ZX seems to read to 0x64, per the SB486PV. */
|
||||
if (dev->type == INTEL_420ZX) {
|
||||
regs[0x64] = 0x02;
|
||||
dev->max_drb = 4;
|
||||
} else
|
||||
dev->max_drb = 3;
|
||||
dev->drb_unit = 1;
|
||||
dev->drb_default = 0x02;
|
||||
break;
|
||||
@@ -1943,7 +1975,7 @@ const device_t i420tx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1957,7 +1989,7 @@ const device_t i420zx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1971,7 +2003,7 @@ const device_t i430lx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1985,7 +2017,7 @@ const device_t i430nx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1999,7 +2031,7 @@ const device_t i430fx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2013,7 +2045,7 @@ const device_t i430fx_rev02_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2027,7 +2059,7 @@ const device_t i430hx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2041,7 +2073,7 @@ const device_t i430vx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2055,7 +2087,7 @@ const device_t i430tx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2069,7 +2101,7 @@ const device_t i440fx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2083,7 +2115,7 @@ const device_t i440lx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2097,7 +2129,7 @@ const device_t i440ex_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2111,7 +2143,7 @@ const device_t i440bx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2125,7 +2157,7 @@ const device_t i440bx_no_agp_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2139,7 +2171,7 @@ const device_t i440gx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -2153,7 +2185,7 @@ const device_t i440zx_device = {
|
||||
.init = i4x0_init,
|
||||
.close = i4x0_close,
|
||||
.reset = i4x0_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -171,8 +171,7 @@ intel_82335_close(void *priv)
|
||||
static void *
|
||||
intel_82335_init(UNUSED(const device_t *info))
|
||||
{
|
||||
intel_82335_t *dev = (intel_82335_t *) malloc(sizeof(intel_82335_t));
|
||||
memset(dev, 0, sizeof(intel_82335_t));
|
||||
intel_82335_t *dev = (intel_82335_t *) calloc(1, sizeof(intel_82335_t));
|
||||
|
||||
memset(dev->regs, 0, sizeof(dev->regs));
|
||||
|
||||
@@ -209,7 +208,7 @@ const device_t intel_82335_device = {
|
||||
.init = intel_82335_init,
|
||||
.close = intel_82335_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -799,8 +799,8 @@ i450kx_close(void *priv)
|
||||
static void *
|
||||
i450kx_init(UNUSED(const device_t *info))
|
||||
{
|
||||
i450kx_t *dev = (i450kx_t *) malloc(sizeof(i450kx_t));
|
||||
memset(dev, 0, sizeof(i450kx_t));
|
||||
i450kx_t *dev = (i450kx_t *) calloc(1, sizeof(i450kx_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, pb_read, pb_write, dev, &dev->pb_slot); /* Device 19h: Intel 450KX PCI Bridge PB */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE_SEC, mc_read, mc_write, dev, &dev->mc_slot); /* Device 14h: Intel 450KX Memory Controller MC */
|
||||
|
||||
@@ -824,7 +824,7 @@ const device_t i450kx_device = {
|
||||
.init = i450kx_init,
|
||||
.close = i450kx_close,
|
||||
.reset = i450kx_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/lpt.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/chipset.h>
|
||||
@@ -59,7 +60,6 @@ typedef struct piix_io_trap_t {
|
||||
} piix_io_trap_t;
|
||||
|
||||
typedef struct _piix_ {
|
||||
uint8_t cur_readout_reg;
|
||||
uint8_t rev;
|
||||
uint8_t type;
|
||||
uint8_t func_shift;
|
||||
@@ -67,7 +67,6 @@ typedef struct _piix_ {
|
||||
uint8_t pci_slot;
|
||||
uint8_t no_mirq0;
|
||||
uint8_t regs[4][256];
|
||||
uint8_t readout_regs[256];
|
||||
uint16_t func0_id;
|
||||
uint16_t nvr_io_base;
|
||||
uint16_t acpi_io_base;
|
||||
@@ -157,6 +156,7 @@ piix_ide_handlers(piix_t *dev, int bus)
|
||||
uint16_t side;
|
||||
|
||||
if (bus & 0x01) {
|
||||
piix_log("Disabling primary IDE...\n");
|
||||
ide_pri_disable();
|
||||
|
||||
if (dev->type == 5) {
|
||||
@@ -172,11 +172,14 @@ piix_ide_handlers(piix_t *dev, int bus)
|
||||
ide_set_side(0, side);
|
||||
}
|
||||
|
||||
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80))
|
||||
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x41] & 0x80)) {
|
||||
piix_log("Enabling primary IDE...\n");
|
||||
ide_pri_enable();
|
||||
}
|
||||
}
|
||||
|
||||
if (bus & 0x02) {
|
||||
piix_log("Disabling secondary IDE...\n");
|
||||
ide_sec_disable();
|
||||
|
||||
if (dev->type == 5) {
|
||||
@@ -192,8 +195,10 @@ piix_ide_handlers(piix_t *dev, int bus)
|
||||
ide_set_side(1, side);
|
||||
}
|
||||
|
||||
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80))
|
||||
if ((dev->regs[1][0x04] & 0x01) && (dev->regs[1][0x43] & 0x80)) {
|
||||
piix_log("Enabling secondary IDE...\n");
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,6 +472,13 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
uint8_t *fregs;
|
||||
uint16_t base;
|
||||
|
||||
/* Dell OptiPlex Gn+ shows that register 02:FF is aliased in 01:FF. */
|
||||
if ((dev->type == 4) && (func == 1) && (addr == 0xff))
|
||||
func = 2;
|
||||
|
||||
if ((func == 1) || (addr == 0xf8) || (addr == 0xf9))
|
||||
piix_log("[W] %02X:%02X = %02X\n", func, addr, val);
|
||||
|
||||
/* Return on unsupported function. */
|
||||
if (dev->max_func > 0) {
|
||||
if (func > dev->max_func)
|
||||
@@ -599,14 +611,21 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
|
||||
if (dev->type == 3) {
|
||||
if (val & 0x20)
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
|
||||
else
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
|
||||
else
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
|
||||
}
|
||||
piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled");
|
||||
}
|
||||
break;
|
||||
case 0x76:
|
||||
if (dev->type > 1)
|
||||
fregs[addr] = val & 0x87;
|
||||
else if (dev->type <= 4)
|
||||
fregs[addr] = val & 0x8f;
|
||||
if ((dev->type == 1) && machine_has_jumpered_ecp_dma(machine, MACHINE_DMA_USE_MBDMA))
|
||||
lpt1_dma(((val & 0x08) || ((val & 0x07) == 0x04)) ? 0xff : (val & 0x07));
|
||||
break;
|
||||
case 0x77:
|
||||
if (dev->type > 1)
|
||||
fregs[addr] = val & 0x87;
|
||||
@@ -738,6 +757,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
fregs[addr] = val;
|
||||
break;
|
||||
case 0xb0:
|
||||
if (val & 0x10)
|
||||
warning("Write %02X to B0\n", val);
|
||||
if (dev->type == 4)
|
||||
fregs[addr] = (fregs[addr] & 0x8c) | (val & 0x73);
|
||||
else if (dev->type == 5)
|
||||
@@ -747,6 +768,8 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
alt_access = !!(val & 0x20);
|
||||
break;
|
||||
case 0xb1:
|
||||
if (val & 0x18)
|
||||
warning("Write %02X to B1\n", val);
|
||||
if (dev->type > 3)
|
||||
fregs[addr] = val & 0xdf;
|
||||
break;
|
||||
@@ -925,6 +948,12 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
if (dev->type > 4)
|
||||
fregs[addr] = val;
|
||||
break;
|
||||
case 0xf8:
|
||||
case 0xf9:
|
||||
/* Undocumented! */
|
||||
if (dev->type == 4)
|
||||
fregs[addr] = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1171,6 +1200,10 @@ piix_read(int func, int addr, void *priv)
|
||||
uint8_t ret = 0xff;
|
||||
const uint8_t *fregs;
|
||||
|
||||
/* Dell OptiPlex Gn+ shows that register 02:FF is aliased in 01:FF. */
|
||||
if ((dev->type == 4) && (func == 1) && (addr == 0xff))
|
||||
func = 2;
|
||||
|
||||
if ((dev->type == 3) && (func == 2) && (dev->max_func == 1) && (addr >= 0x40))
|
||||
ret = 0x00;
|
||||
|
||||
@@ -1185,31 +1218,6 @@ piix_read(int func, int addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
board_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
piix_t *dev = (piix_t *) priv;
|
||||
|
||||
if (port == 0x00e0)
|
||||
dev->cur_readout_reg = val;
|
||||
else if (port == 0x00e1)
|
||||
dev->readout_regs[dev->cur_readout_reg] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
board_read(uint16_t port, void *priv)
|
||||
{
|
||||
const piix_t *dev = (piix_t *) priv;
|
||||
uint8_t ret = 0x64;
|
||||
|
||||
if (port == 0x00e0)
|
||||
ret = dev->cur_readout_reg;
|
||||
else if (port == 0x00e1)
|
||||
ret = dev->readout_regs[dev->cur_readout_reg];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
piix_reset_hard(piix_t *dev)
|
||||
{
|
||||
@@ -1226,7 +1234,7 @@ piix_reset_hard(piix_t *dev)
|
||||
|
||||
sff_set_slot(dev->bm[1], dev->pci_slot);
|
||||
sff_set_irq_pin(dev->bm[1], PCI_INTA);
|
||||
sff_set_irq_line(dev->bm[1], 14);
|
||||
sff_set_irq_line(dev->bm[1], 15);
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
|
||||
}
|
||||
|
||||
@@ -1342,6 +1350,10 @@ piix_reset_hard(piix_t *dev)
|
||||
fregs[0x45] = 0x55;
|
||||
fregs[0x46] = 0x01;
|
||||
}
|
||||
if (dev->type == 4) {
|
||||
fregs[0xf8] = 0x30;
|
||||
fregs[0xf9] = 0x0f;
|
||||
}
|
||||
if ((dev->type == 1) && (dev->rev == 2))
|
||||
dev->max_func = 0; /* It starts with IDE disabled, then enables it. */
|
||||
else
|
||||
@@ -1538,8 +1550,7 @@ piix_speed_changed(void *priv)
|
||||
static void *
|
||||
piix_init(const device_t *info)
|
||||
{
|
||||
piix_t *dev = (piix_t *) malloc(sizeof(piix_t));
|
||||
memset(dev, 0, sizeof(piix_t));
|
||||
piix_t *dev = (piix_t *) calloc(1, sizeof(piix_t));
|
||||
|
||||
dev->type = info->local & 0x0f;
|
||||
/* If (dev->type == 4) and (dev->rev & 0x08), then this is PIIX4E. */
|
||||
@@ -1618,47 +1629,16 @@ piix_init(const device_t *info)
|
||||
else
|
||||
cpu_set_isa_pci_div(3);
|
||||
|
||||
dma_alias_set();
|
||||
if (dev->type > 1)
|
||||
dma_alias_set();
|
||||
else
|
||||
dma_alias_set_piix();
|
||||
|
||||
if (dev->type < 4)
|
||||
pci_enable_mirq(0);
|
||||
if (dev->type < 3)
|
||||
pci_enable_mirq(1);
|
||||
|
||||
dev->readout_regs[0] = 0xff;
|
||||
dev->readout_regs[1] = 0x40;
|
||||
dev->readout_regs[2] = 0xff;
|
||||
|
||||
/* Port E1 register 01 (TODO: Find how multipliers > 3.0 are defined):
|
||||
|
||||
Bit 6: 1 = can boot, 0 = no;
|
||||
Bit 7, 1 = multiplier (00 = 2.5, 01 = 2.0, 10 = 3.0, 11 = 1.5);
|
||||
Bit 5, 4 = bus speed (00 = 50 MHz, 01 = 66 MHz, 10 = 60 MHz, 11 = ????):
|
||||
Bit 7, 5, 4, 1: 0000 = 125 MHz, 0010 = 166 MHz, 0100 = 150 MHz, 0110 = ??? MHz;
|
||||
0001 = 100 MHz, 0011 = 133 MHz, 0101 = 120 MHz, 0111 = ??? MHz;
|
||||
1000 = 150 MHz, 1010 = 200 MHz, 1100 = 180 MHz, 1110 = ??? MHz;
|
||||
1001 = 75 MHz, 1011 = 100 MHz, 1101 = 90 MHz, 1111 = ??? MHz */
|
||||
|
||||
if (cpu_busspeed <= 40000000)
|
||||
dev->readout_regs[1] |= 0x30;
|
||||
else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000))
|
||||
dev->readout_regs[1] |= 0x00;
|
||||
else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000))
|
||||
dev->readout_regs[1] |= 0x20;
|
||||
else if (cpu_busspeed > 60000000)
|
||||
dev->readout_regs[1] |= 0x10;
|
||||
|
||||
if (cpu_dmulti <= 1.5)
|
||||
dev->readout_regs[1] |= 0x82;
|
||||
else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0))
|
||||
dev->readout_regs[1] |= 0x02;
|
||||
else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5))
|
||||
dev->readout_regs[1] |= 0x00;
|
||||
else if (cpu_dmulti > 2.5)
|
||||
dev->readout_regs[1] |= 0x80;
|
||||
|
||||
io_sethandler(0x00e0, 0x0002, board_read, NULL, NULL, board_write, NULL, NULL, dev);
|
||||
|
||||
#if 0
|
||||
device_add(&i8254_sec_device);
|
||||
#endif
|
||||
@@ -1674,7 +1654,7 @@ const device_t piix_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1688,7 +1668,7 @@ const device_t piix_no_mirq_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1702,7 +1682,7 @@ const device_t piix_rev02_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1716,7 +1696,7 @@ const device_t piix3_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1730,7 +1710,7 @@ const device_t piix3_ioapic_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1744,7 +1724,7 @@ const device_t piix4_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1758,7 +1738,7 @@ const device_t piix4e_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1772,7 +1752,7 @@ const device_t slc90e66_device = {
|
||||
.init = piix_init,
|
||||
.close = piix_close,
|
||||
.reset = piix_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = piix_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -355,7 +355,23 @@ sio_config_read(uint16_t port, UNUSED(void *priv))
|
||||
ret = 0xff;
|
||||
break;
|
||||
case 5:
|
||||
ret = 0xd3;
|
||||
/*
|
||||
Dell Dimension XPS P60 jumpers:
|
||||
- Bit 5: Disable CMOS Setup (1 = yes, 0 = no).
|
||||
|
||||
Dell OptiPlex 560/L jumpers:
|
||||
- Bit 1: Password (1 = disable, 0 = enable);
|
||||
- Bit 5: Clear CMOS (1 = no, 0 = yes).
|
||||
- Bits 7, 6: Board type:
|
||||
- 0, 0 = L;
|
||||
- 0, 1 = MT;
|
||||
- 1, 0 = M;
|
||||
- 1, 1 = M.
|
||||
*/
|
||||
if (!strcmp(machine_get_internal_name(), "opti560l"))
|
||||
ret = 0x20;
|
||||
else
|
||||
ret = 0xd3;
|
||||
|
||||
switch (cpu_pci_speed) {
|
||||
case 20000000:
|
||||
@@ -508,8 +524,7 @@ sio_speed_changed(void *priv)
|
||||
static void *
|
||||
sio_init(const device_t *info)
|
||||
{
|
||||
sio_t *dev = (sio_t *) malloc(sizeof(sio_t));
|
||||
memset(dev, 0, sizeof(sio_t));
|
||||
sio_t *dev = (sio_t *) calloc(1, sizeof(sio_t));
|
||||
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sio_read, sio_write, dev, &dev->pci_slot);
|
||||
|
||||
@@ -568,7 +583,7 @@ const device_t sio_device = {
|
||||
.init = sio_init,
|
||||
.close = sio_close,
|
||||
.reset = sio_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = sio_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -582,7 +597,7 @@ const device_t sio_zb_device = {
|
||||
.init = sio_init,
|
||||
.close = sio_close,
|
||||
.reset = sio_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = sio_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
131
src/chipset/isa486c.c
Normal file
131
src/chipset/isa486c.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#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/plat_unused.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct isa486c_t {
|
||||
uint8_t regs[3];
|
||||
} isa486c_t;
|
||||
|
||||
static void
|
||||
isa486c_recalcmapping(isa486c_t *dev)
|
||||
{
|
||||
uint32_t shflags = 0;
|
||||
uint32_t bases[5] = { 0x000c0000, 0x000c8000, 0x000d0000, 0x000d8000, 0x000e0000 };
|
||||
uint32_t sizes[5] = { 0x00008000, 0x00008000, 0x00008000, 0x00008000, 0x00020000 };
|
||||
|
||||
if (dev->regs[1] & 0x20)
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_INTERNAL;
|
||||
else
|
||||
shflags = MEM_READ_INTERNAL | MEM_WRITE_EXTANY;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 5; i++)
|
||||
if (dev->regs[1] & (1 << i)) {
|
||||
if (i == 4) {
|
||||
shadowbios = 1;
|
||||
shadowbios_write = !!(dev->regs[1] & 0x20);
|
||||
}
|
||||
|
||||
mem_set_mem_state_both(bases[i], sizes[i], shflags);
|
||||
} else
|
||||
mem_set_mem_state_both(bases[i], sizes[i], MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
isa486c_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
isa486c_t *dev = (isa486c_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x0023:
|
||||
dev->regs[0] = val;
|
||||
break;
|
||||
/*
|
||||
Port 25h:
|
||||
- Bit 0 = Video BIOS (C000-C7FF) shadow enabled;
|
||||
- Bit 1 = C800-C8FF shadow enabled;
|
||||
- Bit 2 = D000-D7FF shadow enabled;
|
||||
- Bit 3 = D800-DFFF shadow enabled;
|
||||
- Bit 4 = E000-FFFF shadow enabled (or F0000-FFFFF?);
|
||||
- Bit 5 = If set, read from ROM, write to shadow;
|
||||
- Bit 6 = KEN Video & BIOS enabled (cacheability!).
|
||||
*/
|
||||
case 0x0025:
|
||||
dev->regs[1] = val;
|
||||
isa486c_recalcmapping(dev);
|
||||
break;
|
||||
case 0x0027:
|
||||
dev->regs[2] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
isa486c_read(uint16_t addr, void *priv)
|
||||
{
|
||||
isa486c_t *dev = (isa486c_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x0023:
|
||||
ret = dev->regs[0];
|
||||
break;
|
||||
case 0x0025:
|
||||
ret = dev->regs[1];
|
||||
break;
|
||||
case 0x0027:
|
||||
ret = dev->regs[2];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
isa486c_close(void *priv)
|
||||
{
|
||||
isa486c_t *dev = (isa486c_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
isa486c_init(UNUSED(const device_t *info))
|
||||
{
|
||||
isa486c_t *dev = (isa486c_t *) calloc(1, sizeof(isa486c_t));
|
||||
|
||||
io_sethandler(0x0023, 0x0001, isa486c_read, NULL, NULL, isa486c_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0025, 0x0001, isa486c_read, NULL, NULL, isa486c_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0027, 0x0001, isa486c_read, NULL, NULL, isa486c_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t isa486c_device = {
|
||||
.name = "ASUS ISA-486C Gate Array",
|
||||
.internal_name = "isa486c",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = isa486c_init,
|
||||
.close = isa486c_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
473
src/chipset/laserxt.c
Normal file
473
src/chipset/laserxt.c
Normal file
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* 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 VTech LaserXT chipset.
|
||||
*
|
||||
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Jasmine Iwanek, <jriwanek@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2025 Sarah Walker.
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
* Copyright 2017-2025 Fred N. van Kempen.
|
||||
* Copyright 2025 Jasmine Iwanek.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/io.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nmi.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
#define EMS_TOTAL_MAX 0x00100000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t page;
|
||||
uint8_t ctrl;
|
||||
|
||||
uint32_t phys;
|
||||
uint32_t virt;
|
||||
|
||||
mem_mapping_t mapping;
|
||||
|
||||
uint8_t *ram;
|
||||
|
||||
void *parent;
|
||||
} lxt_ems_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ems_base_idx;
|
||||
|
||||
lxt_ems_t ems[4];
|
||||
|
||||
uint16_t io_base;
|
||||
uint32_t base;
|
||||
|
||||
uint32_t mem_size;
|
||||
|
||||
uint8_t *ram;
|
||||
|
||||
void *parent;
|
||||
} lxt_ems_board_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int is_lxt3;
|
||||
|
||||
lxt_ems_board_t *ems_boards[2];
|
||||
} lxt_t;
|
||||
|
||||
static void
|
||||
ems_update_virt(lxt_ems_t *dev, uint8_t new_page)
|
||||
{
|
||||
lxt_ems_board_t *board = (lxt_ems_board_t *) dev->parent;
|
||||
lxt_t *lxt = (lxt_t *) board->parent;
|
||||
|
||||
dev->page = new_page;
|
||||
|
||||
if (new_page & 0x80) {
|
||||
if (lxt->is_lxt3) {
|
||||
/* Point invalid pages at 1 MB which is outside the maximum. */
|
||||
if ((new_page & 0x7f) >= 0x40)
|
||||
dev->virt = EMS_TOTAL_MAX;
|
||||
else
|
||||
dev->virt = ((new_page & 0x7f) << 14);
|
||||
} else
|
||||
dev->virt = ((new_page & 0x0f) << 14) + ((new_page & 0x40) << 12);
|
||||
|
||||
if (dev->virt >= board->mem_size)
|
||||
dev->virt = EMS_TOTAL_MAX;
|
||||
} else
|
||||
dev->virt = EMS_TOTAL_MAX;
|
||||
|
||||
dev->ram = board->ram + dev->virt;
|
||||
|
||||
if ((new_page & 0x80) && (dev->virt != EMS_TOTAL_MAX)) {
|
||||
mem_mapping_enable(&dev->mapping);
|
||||
|
||||
mem_mapping_set_exec(&dev->mapping, dev->ram);
|
||||
mem_mapping_set_p(&dev->mapping, dev->ram);
|
||||
} else
|
||||
mem_mapping_disable(&dev->mapping);
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
lxt_ems_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
lxt_ems_board_t *dev = (lxt_ems_board_t *) priv;
|
||||
uint8_t reg = port >> 14;
|
||||
uint32_t saddrs[8] = { 0xc4000, 0xc8000, 0xcc000, 0xd0000,
|
||||
0xd4000, 0xd8000, 0xdc000, 0xe0000 };
|
||||
uint32_t saddr;
|
||||
|
||||
if (port & 0x0001) {
|
||||
dev->ems[reg].ctrl = val;
|
||||
|
||||
if (reg < 0x03) {
|
||||
dev->ems_base_idx = (dev->ems_base_idx & ~(0x04 >> (2 - reg))) |
|
||||
((dev->ems[reg].ctrl & 0x80) >> (7 - reg));
|
||||
|
||||
saddr = saddrs[dev->ems_base_idx];
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
uint32_t base = saddr + (i * 0x4000);
|
||||
mem_mapping_set_addr(&dev->ems[i].mapping, base, 0x4000);
|
||||
if (!(dev->ems[i].page & 0x80) || (dev->ems[i].virt == EMS_TOTAL_MAX))
|
||||
mem_mapping_disable(&dev->ems[i].mapping);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
} else if (!(port & 0x0001)) {
|
||||
dev->ems[reg].page = val;
|
||||
ems_update_virt(&dev->ems[reg], val);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lxt_ems_in(uint16_t port, void *priv)
|
||||
{
|
||||
lxt_ems_board_t *dev = (lxt_ems_board_t *) priv;
|
||||
uint8_t reg = port >> 14;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (port & 0x0001)
|
||||
ret = dev->ems[reg].ctrl;
|
||||
else
|
||||
ret = dev->ems[reg].page;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
lxt_ems_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
uint8_t *mem = (uint8_t *) priv;
|
||||
|
||||
mem[addr & 0x3fff] = val;
|
||||
}
|
||||
|
||||
static void
|
||||
lxt_ems_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
uint8_t *mem = (uint8_t *) priv;
|
||||
|
||||
*(uint16_t *) &(mem[addr & 0x3fff]) = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lxt_ems_read(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t *mem = (uint8_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = mem[addr & 0x3fff];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
lxt_ems_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
uint8_t *mem = (uint8_t *) priv;
|
||||
uint16_t ret = 0xff;
|
||||
|
||||
ret = *(uint16_t *) &(mem[addr & 0x3fff]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static lxt_ems_board_t *
|
||||
lxt_ems_init(lxt_t *parent, int en, uint16_t io, uint32_t mem)
|
||||
{
|
||||
lxt_ems_board_t *dev = (lxt_ems_board_t *) calloc(1, sizeof(lxt_ems_board_t));
|
||||
|
||||
if (en) {
|
||||
dev->parent = parent;
|
||||
|
||||
if (io != 0x0000) {
|
||||
io_sethandler(io , 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev);
|
||||
io_sethandler(io | 0x4000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev);
|
||||
io_sethandler(io | 0x8000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev);
|
||||
io_sethandler(io | 0xc000, 0x0002, lxt_ems_in, NULL, NULL, lxt_ems_out, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->ram = (uint8_t *) calloc(mem, sizeof(uint8_t));
|
||||
dev->mem_size = mem;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
uint8_t *ptr = dev->ram + (i << 14);
|
||||
|
||||
if (parent->is_lxt3)
|
||||
mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000,
|
||||
lxt_ems_read, lxt_ems_readw, NULL,
|
||||
lxt_ems_write, lxt_ems_writew, NULL,
|
||||
ptr, 0, ptr);
|
||||
else
|
||||
mem_mapping_add(&dev->ems[i].mapping, 0xe0000 + (i << 14), 0x4000,
|
||||
lxt_ems_read, NULL, NULL,
|
||||
lxt_ems_write, NULL, NULL,
|
||||
ptr, 0, ptr);
|
||||
|
||||
mem_mapping_disable(&dev->ems[i].mapping);
|
||||
|
||||
dev->ems[i].page = 0x7f;
|
||||
dev->ems[i].ctrl = (i == 3) ? 0x00 : 0x80;
|
||||
|
||||
dev->ems[i].parent = dev;
|
||||
|
||||
ems_update_virt(&(dev->ems[i]), dev->ems[i].page);
|
||||
}
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
lxt_close(void *priv)
|
||||
{
|
||||
lxt_t *dev = (lxt_t *) priv;
|
||||
int ems_boards = (1 - dev->is_lxt3) + 1;
|
||||
|
||||
for (int i = 0; i < ems_boards; i++)
|
||||
if (dev->ems_boards[i] != NULL) {
|
||||
if (dev->ems_boards[i]->ram != NULL)
|
||||
free(dev->ems_boards[i]->ram);
|
||||
free(dev->ems_boards[i]);
|
||||
}
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
lxt_init(const device_t *info)
|
||||
{
|
||||
lxt_t * dev = (lxt_t *) calloc(1, sizeof(lxt_t));
|
||||
int ems_boards = (1 - info->local) + 1;
|
||||
int ems_en[2] = { 0 };
|
||||
uint16_t ems_io[2] = { 0 };
|
||||
uint32_t ems_mem[2] = { 0 };
|
||||
char conf_str[512] = { 0 };
|
||||
|
||||
dev->is_lxt3 = info->local;
|
||||
|
||||
for (int i = 0; i < ems_boards; i++) {
|
||||
sprintf(conf_str, "ems_%i_enable", i + 1);
|
||||
ems_en[i] = device_get_config_int(conf_str);
|
||||
|
||||
sprintf(conf_str, "ems_%i_base", i + 1);
|
||||
ems_io[i] = device_get_config_hex16(conf_str);
|
||||
|
||||
sprintf(conf_str, "ems_%i_mem_size", i + 1);
|
||||
ems_mem[i] = device_get_config_int(conf_str) << 10;
|
||||
|
||||
dev->ems_boards[i] = lxt_ems_init(dev, ems_en[i], ems_io[i], ems_mem[i]);
|
||||
}
|
||||
|
||||
mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static const device_config_t laserxt_config[] = {
|
||||
{
|
||||
.name = "ems_1_base",
|
||||
.description = "EMS 1 Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "0x208", .value = 0x208 },
|
||||
{ .description = "0x218", .value = 0x218 },
|
||||
{ .description = "0x258", .value = 0x258 },
|
||||
{ .description = "0x268", .value = 0x268 },
|
||||
{ .description = "0x2A8", .value = 0x2a8 },
|
||||
{ .description = "0x2B8", .value = 0x2b8 },
|
||||
{ .description = "0x2E8", .value = 0x2e8 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_2_base",
|
||||
.description = "EMS 2 Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "0x208", .value = 0x208 },
|
||||
{ .description = "0x218", .value = 0x218 },
|
||||
{ .description = "0x258", .value = 0x258 },
|
||||
{ .description = "0x268", .value = 0x268 },
|
||||
{ .description = "0x2A8", .value = 0x2a8 },
|
||||
{ .description = "0x2B8", .value = 0x2b8 },
|
||||
{ .description = "0x2E8", .value = 0x2e8 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_1_mem_size",
|
||||
.description = "EMS 1 Memory Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 512,
|
||||
.step = 32
|
||||
},
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_2_mem_size",
|
||||
.description = "EMS 2 Memory Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 512,
|
||||
.step = 32
|
||||
},
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_1_enable",
|
||||
.description = "Enable EMS 1",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_2_enable",
|
||||
.description = "Enable EMS 2",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
};
|
||||
|
||||
const device_t laserxt_device = {
|
||||
.name = "VTech Laser Turbo XT",
|
||||
.internal_name = "laserxt",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = lxt_init,
|
||||
.close = lxt_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = laserxt_config
|
||||
};
|
||||
|
||||
static const device_config_t lxt3_config[] = {
|
||||
{
|
||||
.name = "ems_1_base",
|
||||
.description = "EMS Address",
|
||||
.type = CONFIG_HEX16,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = {
|
||||
{ .description = "Disabled", .value = 0 },
|
||||
{ .description = "0x208", .value = 0x208 },
|
||||
{ .description = "0x218", .value = 0x218 },
|
||||
{ .description = "0x258", .value = 0x258 },
|
||||
{ .description = "0x268", .value = 0x268 },
|
||||
{ .description = "0x2A8", .value = 0x2a8 },
|
||||
{ .description = "0x2B8", .value = 0x2b8 },
|
||||
{ .description = "0x2E8", .value = 0x2e8 },
|
||||
{ .description = "" }
|
||||
},
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_1_mem_size",
|
||||
.description = "EMS Memory Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = {
|
||||
.min = 0,
|
||||
.max = 1024,
|
||||
.step = 32
|
||||
},
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{
|
||||
.name = "ems_1_enable",
|
||||
.description = "Enable EMS",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_string = NULL,
|
||||
.default_int = 0,
|
||||
.file_filter = NULL,
|
||||
.spinner = { 0 },
|
||||
.selection = { { 0 } },
|
||||
.bios = { { 0 } }
|
||||
},
|
||||
{ .name = "", .description = "", .type = CONFIG_END }
|
||||
};
|
||||
|
||||
const device_t lxt3_device = {
|
||||
.name = "VTech Laser Turbo XT",
|
||||
.internal_name = "laserxt",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = lxt_init,
|
||||
.close = lxt_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = lxt3_config
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -73,26 +73,24 @@ olivetti_eva_write(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
case 0x069:
|
||||
dev->reg_069 = val;
|
||||
/*
|
||||
* Unfortunately, if triggered, the BIOS remapping function fails causing
|
||||
* a fatal error. Therefore, this code section is currently commented.
|
||||
*/
|
||||
#if 0
|
||||
if (val & 1) {
|
||||
mem_remap_top(0);
|
||||
if (val == 0x01) {
|
||||
/*
|
||||
* Set the register to 7 or above for the BIOS to trigger the
|
||||
* memory remapping function if shadowing is active.
|
||||
*/
|
||||
dev->reg_069 = 0x7;
|
||||
dev->reg_069 = 0x07;
|
||||
}
|
||||
if (val & 8) {
|
||||
if (val & 0x08) {
|
||||
/*
|
||||
* Activate shadowing for region e0000-fffff
|
||||
*/
|
||||
mem_remap_top(256);
|
||||
mem_set_mem_state_both(0xa0000, 0x60000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
mem_remap_top(384);
|
||||
mem_set_mem_state_both(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -134,8 +132,7 @@ olivetti_eva_close(void *priv)
|
||||
static void *
|
||||
olivetti_eva_init(UNUSED(const device_t *info))
|
||||
{
|
||||
olivetti_eva_t *dev = (olivetti_eva_t *) malloc(sizeof(olivetti_eva_t));
|
||||
memset(dev, 0, sizeof(olivetti_eva_t));
|
||||
olivetti_eva_t *dev = (olivetti_eva_t *) calloc(1, sizeof(olivetti_eva_t));
|
||||
|
||||
/* GA98 registers */
|
||||
dev->reg_065 = 0x00;
|
||||
@@ -144,7 +141,7 @@ olivetti_eva_init(UNUSED(const device_t *info))
|
||||
dev->reg_067 = 0x00;
|
||||
|
||||
/* RAM enable registers */
|
||||
dev->reg_069 = 0x0;
|
||||
dev->reg_069 = 0x00;
|
||||
|
||||
io_sethandler(0x0065, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0067, 0x0001, olivetti_eva_read, NULL, NULL, olivetti_eva_write, NULL, NULL, dev);
|
||||
@@ -153,13 +150,6 @@ olivetti_eva_init(UNUSED(const device_t *info))
|
||||
/* When shadowing is not enabled in BIOS, all upper memory is available as XMS */
|
||||
mem_remap_top(384);
|
||||
|
||||
/*
|
||||
* Default settings when NVRAM is cleared activate shadowing.
|
||||
* Thus, to avoid boot errors, remap only 256k from UMB to XMS.
|
||||
* Remove this block once BIOS memory remapping works.
|
||||
*/
|
||||
mem_remap_top(256);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -171,7 +161,7 @@ const device_t olivetti_eva_device = {
|
||||
.init = olivetti_eva_init,
|
||||
.close = olivetti_eva_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -31,6 +32,7 @@
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_OPTI283_LOG
|
||||
@@ -157,7 +159,20 @@ opti283_shadow_recalc(opti283_t *dev)
|
||||
rom = dev->regs[0x11] & (1 << ((i >> 2) + 4));
|
||||
opti283_log("OPTI 283: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_enable && rom) {
|
||||
if (sh_copy) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
@@ -170,13 +185,8 @@ opti283_shadow_recalc(opti283_t *dev)
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
if (sh_copy) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_EXTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti283_log("OPTI 283: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
@@ -215,34 +225,53 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
|
||||
opti283_t *dev = (opti283_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
if (dev->index == 0x01)
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti283_log("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = val;
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
case 0x10:
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0x80) | (val & 0x7f);
|
||||
break;
|
||||
|
||||
case 0x14: {
|
||||
double bus_clk;
|
||||
switch (val & 0x01) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
fallthrough;
|
||||
}
|
||||
case 0x11:
|
||||
case 0x12:
|
||||
case 0x13:
|
||||
dev->regs[dev->index] = val;
|
||||
opti283_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->index = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -250,11 +279,17 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
opti283_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const opti283_t *dev = (opti283_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
opti283_t *dev = (opti283_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24)
|
||||
if ((addr == 0x23) && (dev->index == 0x01))
|
||||
ret = dev->regs[dev->index];
|
||||
else if (addr == 0x24) {
|
||||
if ((dev->index >= 0x10) && (dev->index <= 0x14))
|
||||
ret = dev->regs[dev->index];
|
||||
|
||||
dev->index = 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -270,10 +305,10 @@ opti283_close(void *priv)
|
||||
static void *
|
||||
opti283_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti283_t *dev = (opti283_t *) malloc(sizeof(opti283_t));
|
||||
memset(dev, 0x00, sizeof(opti283_t));
|
||||
opti283_t *dev = (opti283_t *) calloc(1, sizeof(opti283_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0023, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x10] = 0x3f;
|
||||
@@ -296,6 +331,10 @@ opti283_init(UNUSED(const device_t *info))
|
||||
|
||||
opti283_shadow_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -307,7 +346,7 @@ const device_t opti283_device = {
|
||||
.init = opti283_init,
|
||||
.close = opti283_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -138,8 +138,7 @@ opti291_close(void *priv)
|
||||
static void *
|
||||
opti291_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti291_t *dev = (opti291_t *) malloc(sizeof(opti291_t));
|
||||
memset(dev, 0, sizeof(opti291_t));
|
||||
opti291_t *dev = (opti291_t *) calloc(1, sizeof(opti291_t));
|
||||
|
||||
io_sethandler(0x022, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
|
||||
io_sethandler(0x024, 0x0001, opti291_read, NULL, NULL, opti291_write, NULL, NULL, dev);
|
||||
@@ -161,7 +160,7 @@ const device_t opti291_device = {
|
||||
.init = opti291_init,
|
||||
.close = opti291_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -54,10 +54,34 @@ typedef struct mem_remapping_t {
|
||||
} mem_remapping_t;
|
||||
|
||||
typedef struct opti391_t {
|
||||
uint8_t type;
|
||||
uint8_t reg_base;
|
||||
uint8_t min_reg;
|
||||
uint8_t max_reg;
|
||||
|
||||
uint16_t shadowed;
|
||||
uint16_t old_start;
|
||||
|
||||
uint8_t index;
|
||||
uint8_t regs[256];
|
||||
} opti391_t;
|
||||
|
||||
static void
|
||||
opti391_recalcremap(opti391_t *dev)
|
||||
{
|
||||
if (dev->type < 2) {
|
||||
if ((mem_size > 8192) || (dev->shadowed & 0x0ff0) ||
|
||||
!(dev->regs[0x01] & 0x0f) || !(dev->regs[0x01] & 0x10)) {
|
||||
mem_remap_top_ex(0, dev->old_start);
|
||||
dev->old_start = 1024;
|
||||
} else {
|
||||
mem_remap_top_ex(0, dev->old_start);
|
||||
dev->old_start = (dev->regs[0x01] & 0x0f) * 1024;
|
||||
mem_remap_top_ex(-256, dev->old_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
opti391_shadow_recalc(opti391_t *dev)
|
||||
{
|
||||
@@ -70,24 +94,25 @@ opti391_shadow_recalc(opti391_t *dev)
|
||||
shadowbios = shadowbios_write = 0;
|
||||
|
||||
/* F0000-FFFFF */
|
||||
sh_enable = !(dev->regs[0x22] & 0x80);
|
||||
sh_enable = (dev->regs[0x02] & 0x80);
|
||||
if (sh_enable)
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
dev->shadowed |= 0xf000;
|
||||
|
||||
sh_write_internal = (dev->regs[0x26] & 0x40);
|
||||
sh_write_internal = (dev->regs[0x06] & 0x40);
|
||||
/* D0000-EFFFF */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
base = 0xd0000 + (i << 14);
|
||||
if (base >= 0xe0000) {
|
||||
sh_master = (dev->regs[0x22] & 0x40);
|
||||
sh_wp = (dev->regs[0x22] & 0x10);
|
||||
sh_master = (dev->regs[0x02] & 0x20);
|
||||
sh_wp = (dev->regs[0x02] & 0x08);
|
||||
} else {
|
||||
sh_master = (dev->regs[0x22] & 0x20);
|
||||
sh_wp = (dev->regs[0x22] & 0x08);
|
||||
sh_master = (dev->regs[0x02] & 0x40);
|
||||
sh_wp = (dev->regs[0x02] & 0x10);
|
||||
}
|
||||
sh_enable = dev->regs[0x23] & (1 << i);
|
||||
sh_enable = dev->regs[0x03] & (1 << i);
|
||||
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
@@ -95,22 +120,29 @@ opti391_shadow_recalc(opti391_t *dev)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
dev->shadowed |= (1 << (i + 4));
|
||||
} else if (sh_write_internal) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
dev->shadowed |= (1 << (i + 4));
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
dev->shadowed &= ~(1 << (i + 4));
|
||||
}
|
||||
} else if (sh_write_internal) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
dev->shadowed |= (1 << (i + 4));
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
dev->shadowed &= ~(1 << (i + 4));
|
||||
}
|
||||
}
|
||||
|
||||
/* C0000-CFFFF */
|
||||
sh_master = !(dev->regs[0x26] & 0x10);
|
||||
sh_wp = (dev->regs[0x26] & 0x20);
|
||||
sh_master = (dev->regs[0x06] & 0x10); /* OPTi 391 datasheet erratum! */
|
||||
sh_wp = (dev->regs[0x06] & 0x20);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
sh_enable = dev->regs[0x26] & (1 << i);
|
||||
sh_enable = dev->regs[0x06] & (1 << i);
|
||||
|
||||
if (sh_master) {
|
||||
if (sh_enable) {
|
||||
@@ -118,15 +150,24 @@ opti391_shadow_recalc(opti391_t *dev)
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (sh_write_internal)
|
||||
dev->shadowed |= (1 << i);
|
||||
} else if (sh_write_internal) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
dev->shadowed |= (1 << i);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
} else if (sh_write_internal)
|
||||
dev->shadowed &= ~(1 << i);
|
||||
}
|
||||
} else if (sh_write_internal) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
dev->shadowed |= (1 << i);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
dev->shadowed &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
opti391_recalcremap(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -134,7 +175,12 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *) priv;
|
||||
|
||||
opti391_log("[W] %04X = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
@@ -142,35 +188,92 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x24:
|
||||
opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x20:
|
||||
dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f);
|
||||
if ((dev->index <= 0x01) && (dev->type < 2)) switch (dev->index) {
|
||||
case 0x00:
|
||||
if (!(dev->regs[0x10] & 0x20) && (val & 0x20)) {
|
||||
softresetx86(); /* Pulse reset! */
|
||||
cpu_set_edx();
|
||||
flushmmucache();
|
||||
}
|
||||
dev->regs[dev->index + 0x10] = val;
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
case 0x24:
|
||||
case 0x25:
|
||||
case 0x27:
|
||||
case 0x28:
|
||||
case 0x29:
|
||||
case 0x2a:
|
||||
case 0x2b:
|
||||
dev->regs[dev->index] = val;
|
||||
case 0x01:
|
||||
dev->regs[dev->index + 0x10] = val;
|
||||
reset_on_hlt = !!(val & 0x02);
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x26:
|
||||
dev->regs[dev->index] = val;
|
||||
opti391_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
} else switch (dev->index - dev->reg_base) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0x00:
|
||||
if (dev->type == 2) {
|
||||
reset_on_hlt = !!(val & 0x02);
|
||||
if (!(dev->regs[dev->index - dev->reg_base] & 0x01) && (val & 0x01)) {
|
||||
softresetx86(); /* Pulse reset! */
|
||||
cpu_set_edx();
|
||||
flushmmucache();
|
||||
}
|
||||
dev->regs[dev->index - dev->reg_base] =
|
||||
(dev->regs[dev->index - dev->reg_base] & 0xc0) | (val & 0x3f);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
if (dev->type == 2) {
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x01] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
} else
|
||||
opti391_recalcremap(dev);
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
if (dev->type == 2)
|
||||
dev->regs[dev->index - dev->reg_base] = val & 0xf8;
|
||||
else
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
if (dev->type < 2) {
|
||||
mem_a20_alt = val & 0x08;
|
||||
mem_a20_recalc();
|
||||
}
|
||||
break;
|
||||
case 0x08:
|
||||
if (dev->type == 2)
|
||||
dev->regs[dev->index - dev->reg_base] = val & 0xe3;
|
||||
else {
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x40);
|
||||
cpu_update_waitstates();
|
||||
}
|
||||
break;
|
||||
case 0x0c:
|
||||
case 0x0d:
|
||||
if (dev->type < 2)
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x06:
|
||||
opti391_log("Write %02X: %02X\n", dev->index - dev->reg_base, val);
|
||||
dev->regs[dev->index - dev->reg_base] = val;
|
||||
opti391_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->index = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,11 +281,19 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
opti391_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const opti391_t *dev = (opti391_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
opti391_t *dev = (opti391_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24)
|
||||
ret = dev->regs[dev->index];
|
||||
if (addr == 0x24) {
|
||||
if ((dev->index <= 0x01) && (dev->type < 2))
|
||||
ret = dev->regs[dev->index + 0x10];
|
||||
else if ((dev->index >= dev->min_reg) && (dev->index <= dev->max_reg))
|
||||
ret = dev->regs[dev->index - dev->reg_base];
|
||||
|
||||
dev->index = 0xff;
|
||||
}
|
||||
|
||||
opti391_log("[R] %04X = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -196,38 +307,102 @@ opti391_close(void *priv)
|
||||
}
|
||||
|
||||
static void *
|
||||
opti391_init(UNUSED(const device_t *info))
|
||||
opti391_init(const device_t *info)
|
||||
{
|
||||
opti391_t *dev = (opti391_t *) malloc(sizeof(opti391_t));
|
||||
memset(dev, 0x00, sizeof(opti391_t));
|
||||
opti391_t *dev = (opti391_t *) calloc(1, sizeof(opti391_t));
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x21] = 0x84;
|
||||
dev->regs[0x24] = 0x07;
|
||||
dev->regs[0x25] = 0xf0;
|
||||
dev->regs[0x26] = 0x30;
|
||||
dev->regs[0x27] = 0x91;
|
||||
dev->regs[0x28] = 0x80;
|
||||
dev->regs[0x29] = 0x10;
|
||||
dev->regs[0x2a] = 0x80;
|
||||
dev->regs[0x2b] = 0x10;
|
||||
dev->type = info->local;
|
||||
|
||||
if (info->local == 2) {
|
||||
dev->reg_base = 0x20;
|
||||
dev->min_reg = 0x20;
|
||||
dev->max_reg = 0x2b;
|
||||
|
||||
dev->regs[0x02] = 0x84;
|
||||
dev->regs[0x04] = 0x07;
|
||||
dev->regs[0x05] = 0xf0;
|
||||
dev->regs[0x06] = 0x30;
|
||||
dev->regs[0x07] = 0x91;
|
||||
dev->regs[0x08] = 0x80;
|
||||
dev->regs[0x09] = 0x10;
|
||||
dev->regs[0x0a] = 0x80;
|
||||
dev->regs[0x0b] = 0x10;
|
||||
} else {
|
||||
dev->reg_base = 0x0f;
|
||||
dev->min_reg = 0x10;
|
||||
dev->max_reg = 0x1c;
|
||||
|
||||
dev->regs[0x01] = 0x01;
|
||||
dev->regs[0x02] = 0xe0;
|
||||
if (info->local == 1)
|
||||
/* Guess due to no OPTi 48x datasheet. */
|
||||
dev->regs[0x04] = 0x07;
|
||||
else
|
||||
dev->regs[0x04] = 0x77;
|
||||
dev->regs[0x05] = 0x60;
|
||||
dev->regs[0x06] = 0x10;
|
||||
dev->regs[0x07] = 0x50;
|
||||
if (info->local == 1) {
|
||||
/* Guess due to no OPTi 48x datasheet. */
|
||||
dev->regs[0x09] = 0x80; /* Non-Cacheable Block 1 */
|
||||
dev->regs[0x0b] = 0x80; /* Non-Cacheable Block 2 */
|
||||
dev->regs[0x0d] = 0x91; /* Cacheable Area */
|
||||
} else {
|
||||
dev->regs[0x09] = 0xe0; /* Non-Cacheable Block 1 */
|
||||
dev->regs[0x0b] = 0x10; /* Non-Cacheable Block 2 */
|
||||
dev->regs[0x0d] = 0x80; /* Cacheable Area */
|
||||
}
|
||||
dev->regs[0x0a] = 0x10;
|
||||
dev->regs[0x0c] = 0x10;
|
||||
}
|
||||
|
||||
dev->old_start = 1024;
|
||||
|
||||
opti391_shadow_recalc(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t opti391_device = {
|
||||
.name = "OPTi 82C391",
|
||||
.internal_name = "opti391",
|
||||
const device_t opti381_device = {
|
||||
.name = "OPTi 82C381",
|
||||
.internal_name = "opti381",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = opti391_init,
|
||||
.close = opti391_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti481_device = {
|
||||
.name = "OPTi 82C481",
|
||||
.internal_name = "opti481",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = opti391_init,
|
||||
.close = opti391_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti391_device = {
|
||||
.name = "OPTi 82C391",
|
||||
.internal_name = "opti391",
|
||||
.flags = 0,
|
||||
.local = 2,
|
||||
.init = opti391_init,
|
||||
.close = opti391_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
*
|
||||
* Implementation of the OPTi 82C493/82C495 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -28,10 +27,13 @@
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
typedef struct opti495_t {
|
||||
uint8_t type;
|
||||
uint8_t max;
|
||||
uint8_t idx;
|
||||
uint8_t regs[256];
|
||||
uint8_t scratch[2];
|
||||
@@ -55,6 +57,22 @@ opti495_log(const char *fmt, ...)
|
||||
# define opti495_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
OPTI493 = 0,
|
||||
OPTI495,
|
||||
OPTI495SLC,
|
||||
OPTI495SX,
|
||||
OPTI495XLC,
|
||||
TMAX
|
||||
};
|
||||
|
||||
/* OPTi 82C493: According to The Last Byte, bit 1 of register 22h, while unused, must still be writable. */
|
||||
static uint8_t masks[TMAX][0x1c] = { { 0x3f, 0xff, 0xff, 0xff, 0xf7, 0xfb, 0x7f, 0x9f, 0xe3, 0xff, 0xe3, 0xff },
|
||||
{ 0x3a, 0x7f, 0xff, 0xff, 0xf0, 0xfb, 0x7f, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
|
||||
{ 0x3a, 0x7f, 0xfc, 0xff, 0xf0, 0xfb, 0xff, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
|
||||
{ 0x3a, 0xff, 0xfd, 0xff, 0xf0, 0xfb, 0x7f, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
|
||||
{ 0x3a, 0xff, 0xfc, 0xff, 0xf0, 0xfb, 0xff, 0xbf, 0xe3, 0xff, 0x00, 0x00 } };
|
||||
|
||||
static void
|
||||
opti495_recalc(opti495_t *dev)
|
||||
{
|
||||
@@ -119,16 +137,25 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
opti495_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
dev->regs[dev->idx] = val;
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= dev->max)) {
|
||||
opti495_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
|
||||
dev->regs[dev->idx] = val & masks[dev->type][dev->idx - 0x20];
|
||||
if ((dev->type == OPTI493) && (dev->idx == 0x20))
|
||||
val |= 0x40;
|
||||
|
||||
switch (dev->idx) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
cpu_update_waitstates();
|
||||
@@ -139,36 +166,57 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x26:
|
||||
opti495_recalc(dev);
|
||||
break;
|
||||
default:
|
||||
|
||||
case 0x25: {
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * 2.0) / 5.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev->idx = 0xff;
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[~addr & 0x01] = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti495_read(uint16_t addr, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
const opti495_t *dev = (opti495_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
opti495_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= dev->max)) {
|
||||
ret = dev->regs[dev->idx];
|
||||
opti495_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
|
||||
dev->idx = 0xff;
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
@@ -192,8 +240,7 @@ opti495_close(void *priv)
|
||||
static void *
|
||||
opti495_init(const device_t *info)
|
||||
{
|
||||
opti495_t *dev = (opti495_t *) malloc(sizeof(opti495_t));
|
||||
memset(dev, 0, sizeof(opti495_t));
|
||||
opti495_t *dev = (opti495_t *) calloc(1, sizeof(opti495_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
@@ -202,8 +249,11 @@ opti495_init(const device_t *info)
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
if (info->local == 1) {
|
||||
dev->type = info->local;
|
||||
|
||||
if (info->local >= OPTI495) {
|
||||
/* 85C495 */
|
||||
dev->max = 0x29;
|
||||
dev->regs[0x20] = 0x02;
|
||||
dev->regs[0x21] = 0x20;
|
||||
dev->regs[0x22] = 0xe4;
|
||||
@@ -214,6 +264,7 @@ opti495_init(const device_t *info)
|
||||
dev->regs[0x29] = 0x10;
|
||||
} else {
|
||||
/* 85C493 */
|
||||
dev->max = 0x2b;
|
||||
dev->regs[0x20] = 0x40;
|
||||
dev->regs[0x22] = 0x84;
|
||||
dev->regs[0x24] = 0x87;
|
||||
@@ -229,6 +280,8 @@ opti495_init(const device_t *info)
|
||||
|
||||
io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -236,25 +289,39 @@ const device_t opti493_device = {
|
||||
.name = "OPTi 82C493",
|
||||
.internal_name = "opti493",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.local = OPTI493,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495_device = {
|
||||
const device_t opti495slc_device = {
|
||||
.name = "OPTi 82C495",
|
||||
.internal_name = "opti495",
|
||||
.internal_name = "opti495slc",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.local = OPTI495SLC,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t opti495sx_device = {
|
||||
.name = "OPTi 82C495SX",
|
||||
.internal_name = "opti495sx",
|
||||
.flags = 0,
|
||||
.local = OPTI495SX,
|
||||
.init = opti495_init,
|
||||
.close = opti495_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
360
src/chipset/opti498.c
Normal file
360
src/chipset/opti498.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C498 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2025 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/plat_fallthrough.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_OPTI498_LOG
|
||||
int opti498_do_log = ENABLE_OPTI498_LOG;
|
||||
|
||||
static void
|
||||
opti498_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (opti498_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define opti498_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct mem_remapping_t {
|
||||
uint32_t phys;
|
||||
uint32_t virt;
|
||||
} mem_remapping_t;
|
||||
|
||||
typedef struct opti498_t {
|
||||
uint8_t index;
|
||||
/* 0x30 for 496/497, 0x70 for 498. */
|
||||
uint8_t reg_base;
|
||||
uint8_t shadow_high;
|
||||
uint8_t regs[256];
|
||||
mem_remapping_t mem_remappings[2];
|
||||
mem_mapping_t mem_mappings[2];
|
||||
} opti498_t;
|
||||
|
||||
static uint8_t
|
||||
opti498_read_remapped_ram(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_ram((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
opti498_read_remapped_ramw(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_ramw((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
opti498_read_remapped_raml(uint32_t addr, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
return mem_read_raml((addr - dev->virt) + dev->phys, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_ram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_ram((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_ramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_ramw((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write_remapped_raml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
const mem_remapping_t *dev = (mem_remapping_t *) priv;
|
||||
|
||||
mem_write_raml((addr - dev->virt) + dev->phys, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_shadow_recalc(opti498_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t rbase;
|
||||
uint8_t sh_enable;
|
||||
uint8_t sh_mode;
|
||||
uint8_t rom;
|
||||
uint8_t sh_copy;
|
||||
|
||||
shadowbios = shadowbios_write = 0;
|
||||
dev->shadow_high = 0;
|
||||
|
||||
opti498_log("OPTI 498: %02X %02X %02X %02X\n", dev->regs[0x02], dev->regs[0x03], dev->regs[0x04], dev->regs[0x05]);
|
||||
|
||||
if (dev->regs[0x02] & 0x80) {
|
||||
if (dev->regs[0x04] & 0x02) {
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_EXTANY\n");
|
||||
} else {
|
||||
shadowbios_write = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_EXTANY, WRITE_INTERNAL\n");
|
||||
}
|
||||
} else {
|
||||
shadowbios = 1;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: F0000-FFFFF READ_INTERNAL, WRITE_DISABLED\n");
|
||||
}
|
||||
|
||||
sh_copy = dev->regs[0x02] & 0x08;
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
base = 0xc0000 + (i << 14);
|
||||
if (i >= 4)
|
||||
sh_enable = dev->regs[0x03] & (1 << (i - 4));
|
||||
else
|
||||
sh_enable = dev->regs[0x04] & (1 << (i + 4));
|
||||
sh_mode = dev->regs[0x02] & (1 << (i >> 2));
|
||||
rom = dev->regs[0x02] & (1 << ((i >> 2) + 4));
|
||||
opti498_log("OPTI 498: %i/%08X: %i, %i, %i\n", i, base, (i >= 4) ? (1 << (i - 4)) : (1 << (i + 4)), (1 << (i >> 2)), (1 << ((i >> 2) + 4)));
|
||||
|
||||
if (sh_copy) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else if (sh_enable && rom) {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios |= 1;
|
||||
if (base >= 0x000d0000)
|
||||
dev->shadow_high |= 1;
|
||||
|
||||
if (sh_mode) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
if (base >= 0x000e0000)
|
||||
shadowbios_write |= 1;
|
||||
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_INTERNAL, WRITE_INTERNAL\n", base, base + 0x3fff);
|
||||
}
|
||||
} else {
|
||||
if (base >= 0xe0000) {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTANY, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
} else {
|
||||
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_DISABLED);
|
||||
opti498_log("OPTI 498: %08X-%08X READ_EXTERNAL, WRITE_DISABLED\n", base, base + 0x3fff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rbase = ((uint32_t) (dev->regs[0x05] & 0x3f)) << 20;
|
||||
|
||||
if (rbase > 0) {
|
||||
dev->mem_remappings[0].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[0], rbase, 0x00020000);
|
||||
|
||||
if (!dev->shadow_high) {
|
||||
rbase += 0x00020000;
|
||||
dev->mem_remappings[1].virt = rbase;
|
||||
mem_mapping_set_addr(&dev->mem_mappings[1], rbase, 0x00020000);
|
||||
} else
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
} else {
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
uint8_t reg = dev->index - dev->reg_base;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
dev->index = val;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
opti498_log("OPTi 498: dev->regs[%02x] = %02x\n", dev->index, val);
|
||||
|
||||
if ((reg >= 0x00) && (reg <= 0x0b)) switch (reg) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x00:
|
||||
dev->regs[reg] = (dev->regs[reg] & 0xc0) | (val & 0x3f);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
case 0x07 ... 0x0b:
|
||||
dev->regs[reg] = val;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
dev->regs[reg] = val;
|
||||
opti498_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x06: {
|
||||
double bus_clk;
|
||||
dev->regs[reg] = val;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 8.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !!(val & 0x40);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->index = 0xff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
opti498_read(uint16_t addr, void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
uint8_t reg = dev->index - dev->reg_base;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x24) {
|
||||
if ((reg >= 0x00) && (reg <= 0x0b))
|
||||
ret = dev->regs[reg];
|
||||
|
||||
dev->index = 0xff;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
opti498_close(void *priv)
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
opti498_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti498_t *dev = (opti498_t *) calloc(1, sizeof(opti498_t));
|
||||
|
||||
dev->reg_base = info->local & 0xff;
|
||||
|
||||
io_sethandler(0x0022, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti498_read, NULL, NULL, opti498_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x00] = 0x1f;
|
||||
dev->regs[0x01] = 0x8f;
|
||||
dev->regs[0x02] = 0xf0;
|
||||
dev->regs[0x07] = 0x70;
|
||||
dev->regs[0x09] = 0x70;
|
||||
|
||||
dev->mem_remappings[0].phys = 0x000a0000;
|
||||
dev->mem_remappings[1].phys = 0x000d0000;
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[0], 0, 0x00020000,
|
||||
opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml,
|
||||
opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[0].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[0]);
|
||||
mem_mapping_disable(&dev->mem_mappings[0]);
|
||||
|
||||
mem_mapping_add(&dev->mem_mappings[1], 0, 0x00020000,
|
||||
opti498_read_remapped_ram, opti498_read_remapped_ramw, opti498_read_remapped_raml,
|
||||
opti498_write_remapped_ram, opti498_write_remapped_ramw, opti498_write_remapped_raml,
|
||||
&ram[dev->mem_remappings[1].phys], MEM_MAPPING_INTERNAL, &dev->mem_remappings[1]);
|
||||
mem_mapping_disable(&dev->mem_mappings[1]);
|
||||
|
||||
opti498_shadow_recalc(dev);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 8.0));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t opti498_device = {
|
||||
.name = "OPTi 82C498",
|
||||
.internal_name = "opti498",
|
||||
.flags = 0,
|
||||
.local = 0x70,
|
||||
.init = opti498_init,
|
||||
.close = opti498_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -38,6 +39,9 @@ typedef struct opti499_t {
|
||||
uint8_t scratch[2];
|
||||
} opti499_t;
|
||||
|
||||
/* According to The Last Byte, register 2Dh bit 7 must still be writable, even if it is unused. */
|
||||
static uint8_t masks[0x0e] = { 0x3f, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfb, 0xff, 0x00, 0xff };
|
||||
|
||||
#ifdef ENABLE_OPTI499_LOG
|
||||
int opti499_do_log = ENABLE_OPTI499_LOG;
|
||||
|
||||
@@ -84,7 +88,7 @@ opti499_recalc(opti499_t *dev)
|
||||
shflags = MEM_READ_INTERNAL;
|
||||
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
|
||||
if (dev->regs[0x2d] & (1 << ((i >> 1) + 2)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
@@ -101,13 +105,13 @@ opti499_recalc(opti499_t *dev)
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x26] & 0x40) {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
if (dev->regs[0x2d] & (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL;
|
||||
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
|
||||
} else {
|
||||
if (dev->regs[0x2d] && (1 << (i >> 1)))
|
||||
if (dev->regs[0x2d] & (1 << (i >> 1)))
|
||||
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
|
||||
else
|
||||
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
|
||||
@@ -126,22 +130,47 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
|
||||
dev->idx = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x20)
|
||||
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
|
||||
else
|
||||
dev->regs[dev->idx] = val;
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d) && (dev->idx != 0x2c)) {
|
||||
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
|
||||
|
||||
dev->regs[dev->idx] = val & masks[dev->idx - 0x20];
|
||||
if (dev->idx == 0x2a)
|
||||
dev->regs[dev->idx] |= 0x04;
|
||||
|
||||
switch (dev->idx) {
|
||||
case 0x20:
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x20: {
|
||||
double coeff = (val & 0x10) ? 1.0 : 2.0;
|
||||
double bus_clk;
|
||||
switch (dev->regs[0x25] & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = (cpu_busspeed * coeff) / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = (cpu_busspeed * coeff) / 5.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = (cpu_busspeed * coeff) / 4.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * coeff) / 3.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
reset_on_hlt = !(val & 0x02);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x21:
|
||||
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
|
||||
@@ -155,19 +184,37 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
|
||||
opti499_recalc(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
case 0x25: {
|
||||
double coeff = (dev->regs[0x20] & 0x10) ? 1.0 : 2.0;
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = (cpu_busspeed * coeff) / 8.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = (cpu_busspeed * coeff) / 6.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = (cpu_busspeed * coeff) / 5.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = (cpu_busspeed * coeff) / 4.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev->idx = 0xff;
|
||||
break;
|
||||
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[~addr & 0x01] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,25 +225,23 @@ opti499_read(uint16_t addr, void *priv)
|
||||
opti499_t *dev = (opti499_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
|
||||
if (dev->idx == 0x2d)
|
||||
ret = dev->regs[dev->idx] & 0xbf;
|
||||
else
|
||||
ret = dev->regs[dev->idx];
|
||||
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d) && (dev->idx != 0x2c)) {
|
||||
ret = dev->regs[dev->idx];
|
||||
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
|
||||
}
|
||||
dev->idx = 0xff;
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[~addr & 0x01];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -227,7 +272,7 @@ opti499_reset(void *priv)
|
||||
|
||||
opti499_recalc(dev);
|
||||
|
||||
free(dev);
|
||||
cpu_set_isa_speed((int) round((cpu_busspeed * 2.0) / 6.0));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -241,8 +286,7 @@ opti499_close(void *priv)
|
||||
static void *
|
||||
opti499_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti499_t *dev = (opti499_t *) malloc(sizeof(opti499_t));
|
||||
memset(dev, 0, sizeof(opti499_t));
|
||||
opti499_t *dev = (opti499_t *) calloc(1, sizeof(opti499_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
@@ -264,7 +308,7 @@ const device_t opti499_device = {
|
||||
.init = opti499_init,
|
||||
.close = opti499_close,
|
||||
.reset = opti499_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
typedef struct opti5x7_t {
|
||||
uint8_t idx;
|
||||
uint8_t is_pci;
|
||||
uint8_t regs[16];
|
||||
uint8_t regs[18];
|
||||
} opti5x7_t;
|
||||
|
||||
#ifdef ENABLE_OPTI5X7_LOG
|
||||
@@ -158,7 +158,7 @@ opti5x7_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const opti5x7_t *dev = (opti5x7_t *) priv;
|
||||
|
||||
return (addr == 0x24) ? dev->regs[dev->idx] : 0xff;
|
||||
return ((addr == 0x24) && (dev->idx < sizeof(dev->regs))) ? dev->regs[dev->idx] : 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -172,8 +172,7 @@ opti5x7_close(void *priv)
|
||||
static void *
|
||||
opti5x7_init(const device_t *info)
|
||||
{
|
||||
opti5x7_t *dev = (opti5x7_t *) malloc(sizeof(opti5x7_t));
|
||||
memset(dev, 0, sizeof(opti5x7_t));
|
||||
opti5x7_t *dev = (opti5x7_t *) calloc(1, sizeof(opti5x7_t));
|
||||
|
||||
dev->is_pci = info->local;
|
||||
|
||||
@@ -193,7 +192,7 @@ const device_t opti5x7_device = {
|
||||
.init = opti5x7_init,
|
||||
.close = opti5x7_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -207,7 +206,7 @@ const device_t opti5x7_pci_device = {
|
||||
.init = opti5x7_init,
|
||||
.close = opti5x7_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -218,7 +218,7 @@ const device_t opti601_device = {
|
||||
.init = opti602_init,
|
||||
.close = opti602_close,
|
||||
.reset = opti602_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -232,7 +232,7 @@ const device_t opti602_device = {
|
||||
.init = opti602_init,
|
||||
.close = opti602_close,
|
||||
.reset = opti602_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -394,8 +394,7 @@ opti822_close(void *priv)
|
||||
static void *
|
||||
opti822_init(UNUSED(const device_t *info))
|
||||
{
|
||||
opti822_t *dev = (opti822_t *) malloc(sizeof(opti822_t));
|
||||
memset(dev, 0, sizeof(opti822_t));
|
||||
opti822_t *dev = (opti822_t *) calloc(1, sizeof(opti822_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, opti822_pci_read, opti822_pci_write, dev, &dev->pci_slot);
|
||||
|
||||
@@ -412,7 +411,7 @@ const device_t opti822_device = {
|
||||
.init = opti822_init,
|
||||
.close = opti822_close,
|
||||
.reset = opti822_reset,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -42,6 +43,9 @@ typedef struct opti895_t {
|
||||
smram_t *smram;
|
||||
} opti895_t;
|
||||
|
||||
static uint8_t masks[0x10] = { 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xe3, 0xff, 0xe3, 0xff, 0x00, 0xff, 0xff, 0xff };
|
||||
|
||||
#ifdef ENABLE_OPTI895_LOG
|
||||
int opti895_do_log = ENABLE_OPTI895_LOG;
|
||||
|
||||
@@ -153,8 +157,12 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
break;
|
||||
case 0x24:
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
dev->regs[dev->idx] = val;
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f) && (dev->idx != 0x2c)) ||
|
||||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
|
||||
if (dev->idx > 0x2f)
|
||||
dev->regs[dev->idx] = val;
|
||||
else
|
||||
dev->regs[dev->idx] = val & masks[dev->idx - 0x20];
|
||||
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
|
||||
|
||||
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
|
||||
@@ -175,6 +183,27 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
|
||||
smram_state_change(dev->smram, 0, !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x25: {
|
||||
double bus_clk;
|
||||
switch (val & 0x03) {
|
||||
default:
|
||||
case 0x00:
|
||||
bus_clk = cpu_busspeed / 6.0;
|
||||
break;
|
||||
case 0x01:
|
||||
bus_clk = cpu_busspeed / 5.0;
|
||||
break;
|
||||
case 0x02:
|
||||
bus_clk = cpu_busspeed / 4.0;
|
||||
break;
|
||||
case 0x03:
|
||||
bus_clk = cpu_busspeed / 3.0;
|
||||
break;
|
||||
}
|
||||
cpu_set_isa_speed((int) round(bus_clk));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xe0:
|
||||
if (!(val & 0x01))
|
||||
dev->forced_green = 0;
|
||||
@@ -217,7 +246,8 @@ opti895_read(uint16_t addr, void *priv)
|
||||
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))) {
|
||||
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f) && (dev->idx != 0x2c)) ||
|
||||
((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;
|
||||
@@ -251,8 +281,7 @@ opti895_close(void *priv)
|
||||
static void *
|
||||
opti895_init(const device_t *info)
|
||||
{
|
||||
opti895_t *dev = (opti895_t *) malloc(sizeof(opti895_t));
|
||||
memset(dev, 0, sizeof(opti895_t));
|
||||
opti895_t *dev = (opti895_t *) calloc(1, sizeof(opti895_t));
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
@@ -287,6 +316,8 @@ opti895_init(const device_t *info)
|
||||
|
||||
smram_enable(dev->smram, 0x00030000, 0x000b0000, 0x00010000, 0, 1);
|
||||
|
||||
cpu_set_isa_speed((int) round(cpu_busspeed / 6.0));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -298,7 +329,7 @@ const device_t opti802g_device = {
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -312,7 +343,7 @@ const device_t opti802g_pci_device = {
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -326,7 +357,7 @@ const device_t opti895_device = {
|
||||
.init = opti895_init,
|
||||
.close = opti895_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -8,11 +8,9 @@
|
||||
*
|
||||
* Emulation of the Philips XT-compatible machines.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: EngiNerd <webmaster.crrc@yahoo.it>
|
||||
*
|
||||
* Copyright 2020-2021 EngiNerd.
|
||||
* Copyright 2020-2025 EngiNerd.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -23,6 +21,7 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/nmi.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
@@ -142,65 +141,8 @@ const device_t philips_device = {
|
||||
.init = philips_init,
|
||||
.close = philips_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
void
|
||||
machine_xt_philips_common_init(const machine_t *model)
|
||||
{
|
||||
machine_common_init(model);
|
||||
|
||||
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
|
||||
|
||||
nmi_init();
|
||||
|
||||
standalone_gameport_type = &gameport_device;
|
||||
|
||||
device_add(&keyboard_pc_device);
|
||||
|
||||
device_add(&philips_device);
|
||||
|
||||
device_add(&xta_hd20_device);
|
||||
}
|
||||
|
||||
int
|
||||
machine_xt_p3105_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p3105/philipsnms9100.bin",
|
||||
0x000fc000, 16384, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_xt_philips_common_init(model);
|
||||
|
||||
/* On-board FDC cannot be disabled */
|
||||
device_add(&fdc_xt_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
machine_xt_p3120_init(const machine_t *model)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = bios_load_linear("roms/machines/p3120/philips_p3120.bin",
|
||||
0x000f8000, 32768, 0);
|
||||
|
||||
if (bios_only || !ret)
|
||||
return ret;
|
||||
|
||||
machine_xt_philips_common_init(model);
|
||||
|
||||
device_add(&gc100a_device);
|
||||
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
123
src/chipset/sanyo.c
Normal file
123
src/chipset/sanyo.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 Philips XT-compatible machines.
|
||||
*
|
||||
* Authors: EngiNerd <webmaster.crrc@yahoo.it>
|
||||
*
|
||||
* Copyright 2020-2025 EngiNerd.
|
||||
*/
|
||||
#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 <86box/nmi.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/fdd.h>
|
||||
#include <86box/fdc.h>
|
||||
#include <86box/fdc_ext.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/ibm_5161.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/rom.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/plat_unused.h>
|
||||
|
||||
typedef struct sanyo_t {
|
||||
uint8_t reg;
|
||||
} sanyo_t;
|
||||
|
||||
#ifdef ENABLE_SANYO_LOG
|
||||
int sanyo_do_log = ENABLE_SANYO_LOG;
|
||||
|
||||
static void
|
||||
sanyo_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sanyo_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sanyo_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
sanyo_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sanyo_t *dev = (sanyo_t *) priv;
|
||||
|
||||
dev->reg = val;
|
||||
|
||||
cpu_waitstates = !(val & 0x01);
|
||||
cpu_update_waitstates();
|
||||
|
||||
sanyo_log("Sanyo MBC-17 Mainboard: Write %02x at %02x\n", val, port);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sanyo_read(uint16_t port, void *priv)
|
||||
{
|
||||
const sanyo_t *dev = (sanyo_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->reg;
|
||||
|
||||
sanyo_log("Sanyo MBC-17 Mainboard: Read %02x at %02x\n", ret, port);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sanyo_close(void *priv)
|
||||
{
|
||||
sanyo_t *dev = (sanyo_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sanyo_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sanyo_t *dev = (sanyo_t *) calloc(1, sizeof(sanyo_t));
|
||||
|
||||
dev->reg = cpu_waitstates ? 0x00 : 0x01;
|
||||
|
||||
io_sethandler(0x0063, 0x01, sanyo_read, NULL, NULL, sanyo_write, NULL, NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sanyo_device = {
|
||||
.name = "Sanyo MBC-17 Mainboard",
|
||||
.internal_name = "sanyo",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = sanyo_init,
|
||||
.close = sanyo_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,15 +66,17 @@ typedef struct ems_page_t {
|
||||
} ems_page_t;
|
||||
|
||||
typedef struct scat_t {
|
||||
int type;
|
||||
uint8_t max_reg;
|
||||
uint8_t reg_2xA;
|
||||
|
||||
int indx;
|
||||
uint8_t regs[256];
|
||||
uint8_t reg_2xA;
|
||||
uint8_t regs[256];
|
||||
|
||||
uint32_t xms_bound;
|
||||
|
||||
int external_is_RAS;
|
||||
int type;
|
||||
int indx;
|
||||
|
||||
int external_is_RAS;
|
||||
|
||||
ems_page_t null_page;
|
||||
ems_page_t page[32];
|
||||
@@ -1138,14 +1140,21 @@ scat_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (indx >= 24)
|
||||
base_addr += 0x30000;
|
||||
|
||||
if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000))
|
||||
mem_set_mem_state(base_addr, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if ((dev->regs[SCAT_EMS_CONTROL] & 0x80) && (dev->page[indx].regs_2x9 & 0x80)) {
|
||||
virt_addr = get_addr(dev, base_addr, &dev->page[indx]);
|
||||
if (virt_addr < ((uint32_t) mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[indx], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[indx], NULL);
|
||||
flushmmucache();
|
||||
|
||||
if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000))
|
||||
mem_set_mem_state(base_addr, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1161,6 +1170,9 @@ scat_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (indx >= 24)
|
||||
base_addr += 0x30000;
|
||||
|
||||
if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000))
|
||||
mem_set_mem_state(base_addr, 0x00004000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
|
||||
|
||||
if (dev->regs[SCAT_EMS_CONTROL] & 0x80) {
|
||||
if (val & 0x80) {
|
||||
virt_addr = get_addr(dev, base_addr, &dev->page[indx]);
|
||||
@@ -1173,6 +1185,9 @@ scat_out(uint16_t port, uint8_t val, void *priv)
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[indx], NULL);
|
||||
mem_mapping_enable(&dev->ems_mapping[indx]);
|
||||
|
||||
if ((base_addr >= 0x000a0000) && (base_addr < 0x00100000))
|
||||
mem_set_mem_state(base_addr, 0x00004000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else {
|
||||
mem_mapping_set_exec(&dev->ems_mapping[indx], ram + base_addr);
|
||||
mem_mapping_disable(&dev->ems_mapping[indx]);
|
||||
@@ -1233,7 +1248,8 @@ scat_in(uint16_t port, void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = dev->regs[dev->indx];
|
||||
if (dev->indx <= dev->max_reg)
|
||||
ret = dev->regs[dev->indx];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -1387,12 +1403,13 @@ scat_init(const device_t *info)
|
||||
uint32_t k;
|
||||
int sx;
|
||||
|
||||
dev = (scat_t *) malloc(sizeof(scat_t));
|
||||
memset(dev, 0x00, sizeof(scat_t));
|
||||
dev = (scat_t *) calloc(1, sizeof(scat_t));
|
||||
dev->type = info->local;
|
||||
|
||||
sx = (dev->type == 32) ? 1 : 0;
|
||||
|
||||
dev->max_reg = sx ? 0x64 : 0x4f;
|
||||
|
||||
for (uint32_t i = 0; i < sizeof(dev->regs); i++)
|
||||
dev->regs[i] = 0xff;
|
||||
|
||||
@@ -1490,7 +1507,7 @@ scat_init(const device_t *info)
|
||||
mem_mapping_add(&dev->ems_mapping[i], (i + 28) << 14, 0x04000,
|
||||
mem_read_scatb, mem_read_scatw, mem_read_scatl,
|
||||
mem_write_scatb, mem_write_scatw, mem_write_scatl,
|
||||
ram + ((i + 28) << 14), 0, &dev->page[i]);
|
||||
ram + ((i + 28) << 14), MEM_MAPPING_INTERNAL, &dev->page[i]);
|
||||
mem_mapping_disable(&dev->ems_mapping[i]);
|
||||
}
|
||||
} else {
|
||||
@@ -1503,7 +1520,7 @@ scat_init(const device_t *info)
|
||||
mem_read_scatb, mem_read_scatw, mem_read_scatl,
|
||||
mem_write_scatb, mem_write_scatw, mem_write_scatl,
|
||||
ram + ((i + (i >= 24 ? 28 : 16)) << 14),
|
||||
0, &dev->page[i]);
|
||||
MEM_MAPPING_INTERNAL, &dev->page[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1541,7 +1558,7 @@ const device_t scat_device = {
|
||||
.init = scat_init,
|
||||
.close = scat_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1555,7 +1572,7 @@ const device_t scat_4_device = {
|
||||
.init = scat_init,
|
||||
.close = scat_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
@@ -1569,7 +1586,7 @@ const device_t scat_sx_device = {
|
||||
.init = scat_init,
|
||||
.close = scat_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
@@ -41,7 +42,7 @@
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5511_LOG
|
||||
@@ -63,573 +64,53 @@ sis_5511_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5511_t {
|
||||
uint8_t index;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
uint8_t regs[16];
|
||||
uint8_t states[7];
|
||||
void *h2p;
|
||||
|
||||
uint8_t slic_regs[4096];
|
||||
void *p2i;
|
||||
void *ide;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[2][256];
|
||||
|
||||
mem_mapping_t slic_mapping;
|
||||
|
||||
sff8038i_t *bm[2];
|
||||
smram_t *smram;
|
||||
port_92_t *port_92;
|
||||
void *pit;
|
||||
nvr_t *nvr;
|
||||
|
||||
uint8_t (*pit_read_reg)(void *priv, uint8_t reg);
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5511_t;
|
||||
|
||||
static void
|
||||
sis_5511_shadow_recalc(sis_5511_t *dev)
|
||||
sis_5511_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x80; i <= 0x86; i++) {
|
||||
if (i == 0x86) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5511_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5511_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5511_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_smram_recalc(sis_5511_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x65] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
sis_5511_log("SiS 5511: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00) switch (addr) {
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= 0xb0;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
/* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC.
|
||||
The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h.
|
||||
The latter (bit 6) means the chipset intercepts all odd FXh to 64h.
|
||||
Bit 5 sets fast reset latency. This should be fixed on the other SiS
|
||||
chipsets as well. */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5e:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
if ((dev->pci_conf[0x68] & 1) && (val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x69] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x61 ... 0x64:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5511_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x6a ... 0x6e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x70: /* DRAM Bank Register 0-0 */
|
||||
case 0x72: /* DRAM Bank Register 0-1 */
|
||||
case 0x74: /* DRAM Bank Register 1-0 */
|
||||
case 0x76: /* DRAM Bank Register 1-1 */
|
||||
case 0x78: /* DRAM Bank Register 2-0 */
|
||||
case 0x7a: /* DRAM Bank Register 2-1 */
|
||||
case 0x7c: /* DRAM Bank Register 3-0 */
|
||||
case 0x7e: /* DRAM Bank Register 3-1 */
|
||||
spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x82);
|
||||
break;
|
||||
|
||||
case 0x71: /* DRAM Bank Register 0-0 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x75: /* DRAM Bank Register 1-0 */
|
||||
case 0x79: /* DRAM Bank Register 2-0 */
|
||||
case 0x7d: /* DRAM Bank Register 3-0 */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x73: /* DRAM Bank Register 0-1 */
|
||||
case 0x77: /* DRAM Bank Register 1-1 */
|
||||
case 0x7b: /* DRAM Bank Register 2-1 */
|
||||
case 0x7f: /* DRAM Bank Register 3-1 */
|
||||
dev->pci_conf[addr] = val & 0x83;
|
||||
break;
|
||||
|
||||
case 0x80 ... 0x85:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x90 ... 0x93: /* 5512 General Purpose Register Index */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000000:
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
dev->slic_regs[addr] = val;
|
||||
break;
|
||||
case 0x00000010:
|
||||
case 0x00000018:
|
||||
case 0x00000028:
|
||||
case 0x00000038:
|
||||
dev->slic_regs[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x00000030:
|
||||
dev->slic_regs[addr] = val & 0x0f;
|
||||
mem_mapping_set_addr(&dev->slic_mapping,
|
||||
(((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000);
|
||||
break;
|
||||
}
|
||||
if (func == 0x00)
|
||||
sis_5511_host_to_pci_write(addr, val, dev->h2p);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5511_read(UNUSED(int func), int addr, void *priv)
|
||||
sis_5511_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = dev->pci_conf[addr];
|
||||
ret = sis_5511_host_to_pci_read(addr, dev->h2p);
|
||||
|
||||
sis_5511_log("SiS 5511: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5511_slic_read(uint32_t addr, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
ret = dev->slic_regs[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sis_5513_pci_to_isa_write(int addr, uint8_t val, sis_5511_t *dev)
|
||||
{
|
||||
sis_5511_log("SiS 5513 P2I: [W] dev->pci_conf_sb[0][%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status */
|
||||
dev->pci_conf_sb[0][addr] = (dev->pci_conf_sb[0][addr] & 0x06) & ~(val & 0x30);
|
||||
break;
|
||||
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x41: /* INTA# Remapping Control Register */
|
||||
case 0x42: /* INTB# Remapping Control Register */
|
||||
case 0x43: /* INTC# Remapping Control Register */
|
||||
case 0x44: /* INTD# Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
pci_set_irq_routing(addr & 0x07, (val & 0x80) ? PCI_IRQ_DISABLED : (val & 0x0f));
|
||||
break;
|
||||
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x60: /* MIRQ0 Remapping Control Register */
|
||||
case 0x61: /* MIRQ1 Remapping Control Register */
|
||||
sis_5511_log("Set MIRQ routing: MIRQ%i -> %02X\n", addr & 0x01, val);
|
||||
dev->pci_conf_sb[0][addr] = val & 0xcf;
|
||||
if (val & 0x80)
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
|
||||
break;
|
||||
|
||||
case 0x62: /* On-board Device DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x63: /* IDEIRQ Remapping Control Register */
|
||||
sis_5511_log("Set MIRQ routing: IDEIRQ -> %02X\n", val);
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
if (val & 0x80)
|
||||
pci_set_mirq_routing(PCI_MIRQ2, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_mirq_routing(PCI_MIRQ2, val & 0xf);
|
||||
break;
|
||||
|
||||
case 0x64: /* GPIO0 Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x80;
|
||||
break;
|
||||
|
||||
case 0x66: /* GPIO0 Output Mode Control Register */
|
||||
case 0x67: /* GPIO0 Output Mode Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6a: /* GPIO Status Register */
|
||||
dev->pci_conf_sb[0][addr] |= (val & 0x10);
|
||||
dev->pci_conf_sb[0][addr] &= ~(val & 0x01);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_irq_handler(sis_5511_t *dev)
|
||||
{
|
||||
if (dev->pci_conf_sb[1][0x09] & 0x01) {
|
||||
/* Primary IDE is native. */
|
||||
sis_5511_log("Primary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->bm[0], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Primary IDE is legacy. */
|
||||
sis_5511_log("Primary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY);
|
||||
}
|
||||
|
||||
if (dev->pci_conf_sb[1][0x09] & 0x04) {
|
||||
/* Secondary IDE is native. */
|
||||
sis_5511_log("Secondary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Secondary IDE is legacy. */
|
||||
sis_5511_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_handler(sis_5511_t *dev)
|
||||
{
|
||||
uint8_t ide_io_on = dev->pci_conf_sb[1][0x04] & 0x01;
|
||||
|
||||
uint16_t native_base_pri_addr = (dev->pci_conf_sb[1][0x11] | dev->pci_conf_sb[1][0x10] << 8) & 0xfffe;
|
||||
uint16_t native_side_pri_addr = (dev->pci_conf_sb[1][0x15] | dev->pci_conf_sb[1][0x14] << 8) & 0xfffe;
|
||||
uint16_t native_base_sec_addr = (dev->pci_conf_sb[1][0x19] | dev->pci_conf_sb[1][0x18] << 8) & 0xfffe;
|
||||
uint16_t native_side_sec_addr = (dev->pci_conf_sb[1][0x1c] | dev->pci_conf_sb[1][0x1b] << 8) & 0xfffe;
|
||||
|
||||
uint16_t current_pri_base;
|
||||
uint16_t current_pri_side;
|
||||
uint16_t current_sec_base;
|
||||
uint16_t current_sec_side;
|
||||
|
||||
/* Primary Channel Programming */
|
||||
current_pri_base = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x01f0 : native_base_pri_addr;
|
||||
current_pri_side = (!(dev->pci_conf_sb[1][0x09] & 1)) ? 0x03f6 : native_side_pri_addr;
|
||||
|
||||
/* Secondary Channel Programming */
|
||||
current_sec_base = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0170 : native_base_sec_addr;
|
||||
current_sec_side = (!(dev->pci_conf_sb[1][0x09] & 4)) ? 0x0376 : native_side_sec_addr;
|
||||
|
||||
sis_5511_log("sis_5513_ide_handler(): Disabling primary IDE...\n");
|
||||
ide_pri_disable();
|
||||
sis_5511_log("sis_5513_ide_handler(): Disabling secondary IDE...\n");
|
||||
ide_sec_disable();
|
||||
|
||||
if (ide_io_on) {
|
||||
/* Primary Channel Setup */
|
||||
if (dev->pci_conf_sb[1][0x4a] & 0x02) {
|
||||
sis_5511_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base);
|
||||
ide_set_base(0, current_pri_base);
|
||||
sis_5511_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side);
|
||||
ide_set_side(0, current_pri_side);
|
||||
|
||||
sis_5511_log("sis_5513_ide_handler(): Enabling primary IDE...\n");
|
||||
ide_pri_enable();
|
||||
|
||||
sis_5511_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
|
||||
}
|
||||
|
||||
/* Secondary Channel Setup */
|
||||
if (dev->pci_conf_sb[1][0x4a] & 0x04) {
|
||||
sis_5511_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base);
|
||||
ide_set_base(1, current_sec_base);
|
||||
sis_5511_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side);
|
||||
ide_set_side(1, current_sec_side);
|
||||
|
||||
sis_5511_log("sis_5513_ide_handler(): Enabling secondary IDE...\n");
|
||||
ide_sec_enable();
|
||||
|
||||
sis_5511_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
|
||||
}
|
||||
}
|
||||
|
||||
sff_bus_master_handler(dev->bm[0], ide_io_on,
|
||||
((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 0);
|
||||
sff_bus_master_handler(dev->bm[1], ide_io_on,
|
||||
((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8)) + 8);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5513_ide_write(int addr, uint8_t val, sis_5511_t *dev)
|
||||
{
|
||||
sis_5511_log("SiS 5513 IDE: [W] dev->pci_conf_sb[1][%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x05;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x06: /* Status low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x20;
|
||||
break;
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x06) & ~(val & 0x38);
|
||||
break;
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
dev->pci_conf_sb[1][addr] = (dev->pci_conf_sb[1][addr] & 0x8a) | (val & 0x05);
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x0d: /* Latency Timer */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
/* Primary Base Address */
|
||||
case 0x10:
|
||||
case 0x11:
|
||||
case 0x14:
|
||||
case 0x15:
|
||||
fallthrough;
|
||||
|
||||
/* Secondary Base Address */
|
||||
case 0x18:
|
||||
case 0x19:
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
fallthrough;
|
||||
|
||||
/* Bus Mastering Base Address */
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
if (addr == 0x20)
|
||||
dev->pci_conf_sb[1][addr] = (val & 0xe0) | 0x01;
|
||||
else
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x30: /* Expansion ROM Base Address */
|
||||
case 0x31: /* Expansion ROM Base Address */
|
||||
case 0x32: /* Expansion ROM Base Address */
|
||||
case 0x33: /* Expansion ROM Base Address */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
dev->pci_conf_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 & 0x07;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x9e;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control Register 1 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
switch (func) {
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev);
|
||||
break;
|
||||
case 1:
|
||||
sis_5513_ide_write(addr, val, dev);
|
||||
break;
|
||||
}
|
||||
sis_5511_log("SiS 5513: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
else if (func == 0x01)
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -638,281 +119,21 @@ sis_5513_read(int func, int addr, void *priv)
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00) {
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pci_conf_sb[func][addr];
|
||||
break;
|
||||
case 0x4c ... 0x4f:
|
||||
ret = pic_read_icw(0, addr & 0x03);
|
||||
break;
|
||||
case 0x50 ... 0x53:
|
||||
ret = pic_read_icw(1, addr & 0x03);
|
||||
break;
|
||||
case 0x54 ... 0x55:
|
||||
ret = pic_read_ocw(0, addr & 0x01);
|
||||
break;
|
||||
case 0x56 ... 0x57:
|
||||
ret = pic_read_ocw(1, addr & 0x01);
|
||||
break;
|
||||
case 0x58 ... 0x5f:
|
||||
ret = dev->pit_read_reg(dev->pit, addr & 0x07);
|
||||
break;
|
||||
}
|
||||
if (func == 0x00)
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
else if (func == 0x01)
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
|
||||
sis_5511_log("SiS 5513 P2I: [R] dev->pci_conf_sb[0][%02X] = %02X\n", addr, ret);
|
||||
} else if (func == 0x01) {
|
||||
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);
|
||||
}
|
||||
sis_5511_log("SiS 5513: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_isa_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->index = val - 0x50;
|
||||
break;
|
||||
case 0x23:
|
||||
sis_5511_log("SiS 5513 ISA: [W] dev->regs[%02X] = %02X\n", dev->index + 0x50, val);
|
||||
|
||||
switch (dev->index) {
|
||||
case 0x00:
|
||||
dev->regs[dev->index] = val & 0xed;
|
||||
switch (val >> 6) {
|
||||
case 0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
nvr_bank_set(0, !!(val & 0x08), dev->nvr);
|
||||
break;
|
||||
case 0x01:
|
||||
dev->regs[dev->index] = val & 0xf4;
|
||||
break;
|
||||
case 0x03:
|
||||
dev->regs[dev->index] = val & 3;
|
||||
break;
|
||||
case 0x04: /* BIOS Register */
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
case 0x05:
|
||||
dev->regs[dev->index] = val;
|
||||
outb(0x70, val);
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0a:
|
||||
case 0x0b:
|
||||
dev->regs[dev->index] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5513_isa_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (addr == 0x23) {
|
||||
if (dev->index == 0x05)
|
||||
ret = inb(0x70);
|
||||
else
|
||||
ret = dev->regs[dev->index];
|
||||
|
||||
sis_5511_log("SiS 5513 ISA: [R] dev->regs[%02X] = %02X\n", dev->index + 0x50, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_reset(void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
/* SiS 5511 */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x11;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x20;
|
||||
dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00;
|
||||
dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = 0x00;
|
||||
dev->pci_conf[0x67] = 0xff;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = 0x00;
|
||||
dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff;
|
||||
dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff;
|
||||
dev->pci_conf[0x6f] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04;
|
||||
dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04;
|
||||
dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80;
|
||||
dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00;
|
||||
dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5511_smram_recalc(dev);
|
||||
sis_5511_shadow_recalc(dev);
|
||||
|
||||
flushmmucache();
|
||||
|
||||
memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t));
|
||||
dev->slic_regs[0x18] = 0x0f;
|
||||
|
||||
mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000);
|
||||
|
||||
/* SiS 5513 */
|
||||
dev->pci_conf_sb[0][0x00] = 0x39;
|
||||
dev->pci_conf_sb[0][0x01] = 0x10;
|
||||
dev->pci_conf_sb[0][0x02] = 0x08;
|
||||
dev->pci_conf_sb[0][0x03] = 0x00;
|
||||
dev->pci_conf_sb[0][0x04] = 0x07;
|
||||
dev->pci_conf_sb[0][0x05] = dev->pci_conf_sb[0][0x06] = 0x00;
|
||||
dev->pci_conf_sb[0][0x07] = 0x02;
|
||||
dev->pci_conf_sb[0][0x08] = dev->pci_conf_sb[0][0x09] = 0x00;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
dev->pci_conf_sb[0][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[0][0x40] = 0x00;
|
||||
dev->pci_conf_sb[0][0x41] = dev->pci_conf_sb[0][0x42] = 0x80;
|
||||
dev->pci_conf_sb[0][0x43] = dev->pci_conf_sb[0][0x44] = 0x80;
|
||||
dev->pci_conf_sb[0][0x48] = dev->pci_conf_sb[0][0x49] = 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][0x04] = dev->pci_conf_sb[1][0x05] = 0x00;
|
||||
dev->pci_conf_sb[1][0x06] = dev->pci_conf_sb[1][0x07] = 0x00;
|
||||
dev->pci_conf_sb[1][0x08] = 0x00;
|
||||
dev->pci_conf_sb[1][0x09] = 0x8a;
|
||||
dev->pci_conf_sb[1][0x0a] = dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0c] = dev->pci_conf_sb[1][0x0d] = 0x00;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[1][0x0f] = 0x00;
|
||||
dev->pci_conf_sb[1][0x10] = 0xf1;
|
||||
dev->pci_conf_sb[1][0x11] = 0x01;
|
||||
dev->pci_conf_sb[1][0x14] = 0xf5;
|
||||
dev->pci_conf_sb[1][0x15] = 0x03;
|
||||
dev->pci_conf_sb[1][0x18] = 0x71;
|
||||
dev->pci_conf_sb[1][0x19] = 0x01;
|
||||
dev->pci_conf_sb[1][0x1c] = 0x75;
|
||||
dev->pci_conf_sb[1][0x1d] = 0x03;
|
||||
dev->pci_conf_sb[1][0x20] = 0x01;
|
||||
dev->pci_conf_sb[1][0x21] = 0xf0;
|
||||
dev->pci_conf_sb[1][0x22] = dev->pci_conf_sb[1][0x23] = 0x00;
|
||||
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
|
||||
sis_5511_close(void *priv)
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -920,53 +141,18 @@ static void *
|
||||
sis_5511_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5511_t *dev = (sis_5511_t *) calloc(1, sizeof(sis_5511_t));
|
||||
uint8_t pit_is_fast = (((pit_mode == -1) && is486) || (pit_mode == 1));
|
||||
|
||||
/* Device 0: SiS 5511 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5511_read, sis_5511_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5513 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5513_read, sis_5513_write, dev, &dev->sb_slot);
|
||||
|
||||
/* SLiC Memory Mapped Registers */
|
||||
mem_mapping_add(&dev->slic_mapping,
|
||||
0xffc00000, 0x00001000,
|
||||
sis_5511_slic_read,
|
||||
NULL,
|
||||
NULL,
|
||||
sis_5511_slic_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL,
|
||||
dev);
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
/* Ports 22h-23h: SiS 5513 ISA */
|
||||
io_sethandler(0x0022, 0x0002, sis_5513_isa_read, NULL, NULL, sis_5513_isa_write, NULL, NULL, dev);
|
||||
dev->h2p = device_add_linked(&sis_5511_h2p_device, dev->sis);
|
||||
|
||||
/* MIRQ */
|
||||
pci_enable_mirq(0);
|
||||
pci_enable_mirq(1);
|
||||
|
||||
/* IDEIRQ */
|
||||
pci_enable_mirq(2);
|
||||
|
||||
/* Port 92h */
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
|
||||
/* SFF IDE */
|
||||
dev->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* PIT */
|
||||
dev->pit = device_find_first_priv(DEVICE_PIT);
|
||||
dev->pit_read_reg = pit_is_fast ? pitf_read_reg : pit_read_reg;
|
||||
|
||||
/* NVR */
|
||||
dev->nvr = device_add(&at_mb_nvr_device);
|
||||
|
||||
sis_5511_reset(dev);
|
||||
dev->p2i = device_add_linked(&sis_5513_p2i_device, dev->sis);
|
||||
dev->ide = device_add_linked(&sis_5513_ide_device, dev->sis);
|
||||
|
||||
return dev;
|
||||
}
|
||||
@@ -978,8 +164,8 @@ const device_t sis_5511_device = {
|
||||
.local = 0,
|
||||
.init = sis_5511_init,
|
||||
.close = sis_5511_close,
|
||||
.reset = sis_5511_reset,
|
||||
{ .available = NULL },
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
|
||||
462
src/chipset/sis_5511_h2p.c
Normal file
462
src/chipset/sis_5511_h2p.c
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5511 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5511_HOST_TO_PCI_LOG
|
||||
int sis_5511_host_to_pci_do_log = ENABLE_SIS_5511_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5511_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5511_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5511_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5511_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
uint8_t slic_regs[4096];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
|
||||
mem_mapping_t slic_mapping;
|
||||
} sis_5511_host_to_pci_t;
|
||||
|
||||
static void
|
||||
sis_5511_shadow_recalc(sis_5511_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x80; i <= 0x86; i++) {
|
||||
if (i == 0x86) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5511_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5511_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5511_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_smram_recalc(sis_5511_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x65] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x65] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5511_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
sis_5511_host_to_pci_log("SiS 5511 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= 0xb0;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x56 ... 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
/* TODO: Fast Gate A20 Emulation and Fast Reset Emulation on the KBC.
|
||||
The former (bit 7) means the chipset intercepts D1h to 64h and 00h to 60h.
|
||||
The latter (bit 6) means the chipset intercepts all odd FXh to 64h.
|
||||
Bit 5 sets fast reset latency. This should be fixed on the other SiS
|
||||
chipsets as well. */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
dev->pci_conf[addr] = val & 0xf7;
|
||||
break;
|
||||
|
||||
case 0x5c:
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
break;
|
||||
|
||||
case 0x5d:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5e:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf[addr] = val & 0x3e;
|
||||
if ((dev->pci_conf[0x68] & 1) && (val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x69] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x61 ... 0x64:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5511_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x66:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x6a ... 0x6e:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6f:
|
||||
dev->pci_conf[addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x70: /* DRAM Bank Register 0-0 */
|
||||
case 0x72: /* DRAM Bank Register 0-1 */
|
||||
case 0x74: /* DRAM Bank Register 1-0 */
|
||||
case 0x76: /* DRAM Bank Register 1-1 */
|
||||
case 0x78: /* DRAM Bank Register 2-0 */
|
||||
case 0x7a: /* DRAM Bank Register 2-1 */
|
||||
case 0x7c: /* DRAM Bank Register 3-0 */
|
||||
case 0x7e: /* DRAM Bank Register 3-1 */
|
||||
spd_write_drbs(dev->pci_conf, 0x70, 0x7e, 0x02);
|
||||
break;
|
||||
|
||||
case 0x71: /* DRAM Bank Register 0-0 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x75: /* DRAM Bank Register 1-0 */
|
||||
case 0x79: /* DRAM Bank Register 2-0 */
|
||||
case 0x7d: /* DRAM Bank Register 3-0 */
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
break;
|
||||
|
||||
case 0x73: /* DRAM Bank Register 0-1 */
|
||||
case 0x77: /* DRAM Bank Register 1-1 */
|
||||
case 0x7b: /* DRAM Bank Register 2-1 */
|
||||
case 0x7f: /* DRAM Bank Register 3-1 */
|
||||
dev->pci_conf[addr] = val & 0x83;
|
||||
break;
|
||||
|
||||
case 0x80 ... 0x85:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5511_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x90 ... 0x93: /* 5512 General Purpose Register Index */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5511_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5511_host_to_pci_log("SiS 5511 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_slic_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000000:
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
dev->slic_regs[addr] = val;
|
||||
break;
|
||||
case 0x00000010:
|
||||
case 0x00000018:
|
||||
case 0x00000028:
|
||||
case 0x00000038:
|
||||
dev->slic_regs[addr] = val & 0x01;
|
||||
break;
|
||||
case 0x00000030:
|
||||
dev->slic_regs[addr] = val & 0x0f;
|
||||
mem_mapping_set_addr(&dev->slic_mapping,
|
||||
(((uint32_t) (val & 0x0f)) << 28) | 0x0fc00000, 0x00001000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5511_slic_read(uint32_t addr, void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr &= 0x00000fff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00000008: /* 0x00000008 is a SiS 5512 register. */
|
||||
ret = dev->slic_regs[addr];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x11;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x07;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x20;
|
||||
dev->pci_conf[0x53] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = dev->pci_conf[0x56] = 0x00;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5b] = dev->pci_conf[0x5c] = 0x00;
|
||||
dev->pci_conf[0x5d] = dev->pci_conf[0x5e] = 0x00;
|
||||
dev->pci_conf[0x5f] = dev->pci_conf[0x60] = 0x00;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x62] = 0xff;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x66] = 0x00;
|
||||
dev->pci_conf[0x67] = 0xff;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = 0x00;
|
||||
dev->pci_conf[0x6b] = dev->pci_conf[0x6c] = 0xff;
|
||||
dev->pci_conf[0x6d] = dev->pci_conf[0x6e] = 0xff;
|
||||
dev->pci_conf[0x6f] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x72] = 0x04;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x76] = 0x04;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x7a] = 0x04;
|
||||
dev->pci_conf[0x7c] = dev->pci_conf[0x7e] = 0x04;
|
||||
dev->pci_conf[0x71] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x73] = dev->pci_conf[0x77] = 0x80;
|
||||
dev->pci_conf[0x79] = dev->pci_conf[0x7d] = 0x00;
|
||||
dev->pci_conf[0x7b] = dev->pci_conf[0x7f] = 0x80;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5511_smram_recalc(dev);
|
||||
sis_5511_shadow_recalc(dev);
|
||||
|
||||
flushmmucache();
|
||||
|
||||
memset(dev->slic_regs, 0x00, 4096 * sizeof(uint8_t));
|
||||
dev->slic_regs[0x18] = 0x0f;
|
||||
|
||||
mem_mapping_set_addr(&dev->slic_mapping, 0xffc00000, 0x00001000);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5511_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5511_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5511_host_to_pci_t *dev = (sis_5511_host_to_pci_t *) calloc(1, sizeof(sis_5511_host_to_pci_t));
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* SLiC Memory Mapped Registers */
|
||||
mem_mapping_add(&dev->slic_mapping,
|
||||
0xffc00000, 0x00001000,
|
||||
sis_5511_slic_read,
|
||||
NULL,
|
||||
NULL,
|
||||
sis_5511_slic_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL,
|
||||
dev);
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
sis_5511_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5511_h2p_device = {
|
||||
.name = "SiS 5511 Host to PCI bridge",
|
||||
.internal_name = "sis_5511_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5511_host_to_pci_init,
|
||||
.close = sis_5511_host_to_pci_close,
|
||||
.reset = sis_5511_host_to_pci_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
505
src/chipset/sis_5513_ide.c
Normal file
505
src/chipset/sis_5513_ide.c
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5513 IDE controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5513_IDE_LOG
|
||||
int sis_5513_ide_do_log = ENABLE_SIS_5513_IDE_LOG;
|
||||
|
||||
static void
|
||||
sis_5513_ide_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5513_ide_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5513_ide_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5513_ide_t {
|
||||
uint8_t rev;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5513_ide_t;
|
||||
|
||||
static void
|
||||
sis_5513_ide_irq_handler(sis_5513_ide_t *dev)
|
||||
{
|
||||
if (dev->pci_conf[0x09] & 0x01) {
|
||||
/* Primary IDE is native. */
|
||||
sis_5513_ide_log("Primary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Primary IDE is legacy. */
|
||||
sis_5513_ide_log("Primary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->sis->bm[0], IRQ_MODE_LEGACY);
|
||||
}
|
||||
|
||||
if (dev->pci_conf[0x09] & 0x04) {
|
||||
/* Secondary IDE is native. */
|
||||
sis_5513_ide_log("Secondary IDE IRQ mode: Native, Native\n");
|
||||
sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_SIS_551X);
|
||||
} else {
|
||||
/* Secondary IDE is legacy. */
|
||||
sis_5513_ide_log("Secondary IDE IRQ mode: IRQ14, IRQ15\n");
|
||||
sff_set_irq_mode(dev->sis->bm[1], IRQ_MODE_LEGACY);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_handler(sis_5513_ide_t *dev)
|
||||
{
|
||||
uint8_t ide_io_on = dev->pci_conf[0x04] & 0x01;
|
||||
|
||||
uint16_t native_base_pri_addr = (dev->pci_conf[0x11] | dev->pci_conf[0x10] << 8) & 0xfffe;
|
||||
uint16_t native_side_pri_addr = (dev->pci_conf[0x15] | dev->pci_conf[0x14] << 8) & 0xfffe;
|
||||
uint16_t native_base_sec_addr = (dev->pci_conf[0x19] | dev->pci_conf[0x18] << 8) & 0xfffe;
|
||||
uint16_t native_side_sec_addr = (dev->pci_conf[0x1c] | dev->pci_conf[0x1b] << 8) & 0xfffe;
|
||||
|
||||
uint16_t current_pri_base;
|
||||
uint16_t current_pri_side;
|
||||
uint16_t current_sec_base;
|
||||
uint16_t current_sec_side;
|
||||
|
||||
/* Primary Channel Programming */
|
||||
current_pri_base = (!(dev->pci_conf[0x09] & 1)) ? 0x01f0 : native_base_pri_addr;
|
||||
current_pri_side = (!(dev->pci_conf[0x09] & 1)) ? 0x03f6 : native_side_pri_addr;
|
||||
|
||||
/* Secondary Channel Programming */
|
||||
current_sec_base = (!(dev->pci_conf[0x09] & 4)) ? 0x0170 : native_base_sec_addr;
|
||||
current_sec_side = (!(dev->pci_conf[0x09] & 4)) ? 0x0376 : native_side_sec_addr;
|
||||
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Disabling primary IDE...\n");
|
||||
ide_pri_disable();
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Disabling secondary IDE...\n");
|
||||
ide_sec_disable();
|
||||
|
||||
if (ide_io_on) {
|
||||
/* Primary Channel Setup */
|
||||
if (dev->pci_conf[0x4a] & 0x02) {
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE base now %04X...\n", current_pri_base);
|
||||
ide_set_base(0, current_pri_base);
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Primary IDE side now %04X...\n", current_pri_side);
|
||||
ide_set_side(0, current_pri_side);
|
||||
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Enabling primary IDE...\n");
|
||||
ide_pri_enable();
|
||||
|
||||
sis_5513_ide_log("SiS 5513 PRI: BASE %04x SIDE %04x\n", current_pri_base, current_pri_side);
|
||||
}
|
||||
|
||||
/* Secondary Channel Setup */
|
||||
if (dev->pci_conf[0x4a] & 0x04) {
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE base now %04X...\n", current_sec_base);
|
||||
ide_set_base(1, current_sec_base);
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Secondary IDE side now %04X...\n", current_sec_side);
|
||||
ide_set_side(1, current_sec_side);
|
||||
|
||||
sis_5513_ide_log("sis_5513_ide_handler(): Enabling secondary IDE...\n");
|
||||
ide_sec_enable();
|
||||
|
||||
sis_5513_ide_log("SiS 5513: BASE %04x SIDE %04x\n", current_sec_base, current_sec_side);
|
||||
}
|
||||
}
|
||||
|
||||
sff_bus_master_handler(dev->sis->bm[0], ide_io_on,
|
||||
((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 0);
|
||||
sff_bus_master_handler(dev->sis->bm[1], ide_io_on,
|
||||
((dev->pci_conf[0x20] & 0xf0) | (dev->pci_conf[0x21] << 8)) + 8);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5513_ide_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
|
||||
sis_5513_ide_log("SiS 5513 IDE: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf[addr] = val & 0x05;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x06: /* Status low byte */
|
||||
dev->pci_conf[addr] = val & 0x20;
|
||||
break;
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x06) & ~(val & 0x38);
|
||||
break;
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
switch (dev->rev) {
|
||||
case 0xd0:
|
||||
if (dev->sis->ide_bits_1_3_writable)
|
||||
val |= 0x0a;
|
||||
fallthrough;
|
||||
case 0x00:
|
||||
case 0xd1:
|
||||
val &= 0xbf;
|
||||
fallthrough;
|
||||
case 0xc0:
|
||||
switch (val & 0x0a) {
|
||||
case 0x00:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x85) | (val & 0x4a);
|
||||
break;
|
||||
case 0x02:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x84) | (val & 0x4b);
|
||||
break;
|
||||
case 0x08:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x81) | (val & 0x4e);
|
||||
break;
|
||||
case 0x0a:
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0x80) | (val & 0x4f);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
case 0x0d: /* Latency Timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
/* Primary Base Address */
|
||||
case 0x10 ... 0x11:
|
||||
case 0x14 ... 0x15:
|
||||
fallthrough;
|
||||
|
||||
/* Secondary Base Address */
|
||||
case 0x18 ... 0x19:
|
||||
case 0x1c ... 0x1d:
|
||||
fallthrough;
|
||||
|
||||
/* Bus Mastering Base Address */
|
||||
case 0x20 ... 0x21:
|
||||
if (addr == 0x20)
|
||||
dev->pci_conf[addr] = (val & 0xe0) | 0x01;
|
||||
else if ((addr & 0x07) == 0x00)
|
||||
dev->pci_conf[addr] = (val & 0xf8) | 0x01;
|
||||
else if ((addr & 0x07) == 0x04)
|
||||
dev->pci_conf[addr] = (val & 0xfc) | 0x01;
|
||||
else
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x2c ... 0x2f:
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x30 ... 0x33: /* Expansion ROM Base Address */
|
||||
#ifdef DATASHEET
|
||||
dev->pci_conf[addr] = val;
|
||||
#else
|
||||
if (dev->rev == 0x00)
|
||||
dev->pci_conf[addr] = val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val & 0xcf;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
|
||||
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
|
||||
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val & 0xe7;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x49: /* IDE Command Active Time Control */
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
switch (dev->rev) {
|
||||
case 0x00:
|
||||
dev->pci_conf[addr] = val & 0x9e;
|
||||
break;
|
||||
case 0xc0:
|
||||
dev->pci_conf[addr] = val & 0xaf;
|
||||
break;
|
||||
case 0xd0:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
sis_5513_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control Register 1 */
|
||||
if (dev->rev >= 0xc0)
|
||||
dev->pci_conf[addr] = val;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
if (dev->rev >= 0xd0)
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5513_ide_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
ret = dev->pci_conf[addr];
|
||||
break;
|
||||
case 0x09:
|
||||
ret = dev->pci_conf[addr];
|
||||
if (dev->rev >= 0xc0) {
|
||||
if (dev->pci_conf[0x09] & 0x40)
|
||||
ret |= ((dev->pci_conf[0x4a] & 0x06) << 3);
|
||||
if ((dev->rev == 0xd0) && dev->sis->ide_bits_1_3_writable)
|
||||
ret |= 0x0a;
|
||||
}
|
||||
break;
|
||||
case 0x3d:
|
||||
if (dev->rev >= 0xc0)
|
||||
ret = (dev->pci_conf[0x09] & 0x05) ? PCI_INTA : 0x00;
|
||||
else
|
||||
ret = (((dev->pci_conf[0x4b] & 0xc0) == 0xc0) ||
|
||||
(dev->pci_conf[0x09] & 0x05)) ? PCI_INTA : 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5513_ide_log("SiS 5513 IDE: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_reset(void *priv)
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x13;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = dev->pci_conf[0x07] = 0x00;
|
||||
dev->pci_conf[0x08] = (dev->rev == 0xd1) ? 0xd0 : dev->rev;
|
||||
dev->pci_conf[0x09] = 0x8a;
|
||||
dev->pci_conf[0x0a] = dev->pci_conf[0x0b] = 0x01;
|
||||
dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x80;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = 0xf1;
|
||||
dev->pci_conf[0x11] = 0x01;
|
||||
dev->pci_conf[0x14] = 0xf5;
|
||||
dev->pci_conf[0x15] = 0x03;
|
||||
dev->pci_conf[0x18] = 0x71;
|
||||
dev->pci_conf[0x19] = 0x01;
|
||||
dev->pci_conf[0x1c] = 0x75;
|
||||
dev->pci_conf[0x1d] = 0x03;
|
||||
dev->pci_conf[0x20] = 0x01;
|
||||
dev->pci_conf[0x21] = 0xf0;
|
||||
dev->pci_conf[0x22] = dev->pci_conf[0x23] = 0x00;
|
||||
dev->pci_conf[0x24] = dev->pci_conf[0x25] = 0x00;
|
||||
dev->pci_conf[0x26] = dev->pci_conf[0x27] = 0x00;
|
||||
dev->pci_conf[0x28] = dev->pci_conf[0x29] = 0x00;
|
||||
dev->pci_conf[0x2a] = dev->pci_conf[0x2b] = 0x00;
|
||||
switch (dev->rev) {
|
||||
case 0x00:
|
||||
case 0xd0:
|
||||
case 0xd1:
|
||||
dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00;
|
||||
break;
|
||||
case 0xc0:
|
||||
#ifdef DATASHEET
|
||||
dev->pci_conf[0x2c] = dev->pci_conf[0x2d] = 0x00;
|
||||
#else
|
||||
/* The only Linux lspci listing I could find of this chipset,
|
||||
shows a subsystem of 0058:0000. */
|
||||
dev->pci_conf[0x2c] = 0x58;
|
||||
dev->pci_conf[0x2d] = 0x00;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
dev->pci_conf[0x2e] = dev->pci_conf[0x2f] = 0x00;
|
||||
dev->pci_conf[0x30] = dev->pci_conf[0x31] = 0x00;
|
||||
dev->pci_conf[0x32] = dev->pci_conf[0x33] = 0x00;
|
||||
dev->pci_conf[0x40] = dev->pci_conf[0x41] = 0x00;
|
||||
dev->pci_conf[0x42] = dev->pci_conf[0x43] = 0x00;
|
||||
dev->pci_conf[0x44] = dev->pci_conf[0x45] = 0x00;
|
||||
dev->pci_conf[0x46] = dev->pci_conf[0x47] = 0x00;
|
||||
dev->pci_conf[0x48] = dev->pci_conf[0x49] = 0x00;
|
||||
dev->pci_conf[0x4a] = 0x06;
|
||||
dev->pci_conf[0x4b] = 0x00;
|
||||
dev->pci_conf[0x4c] = dev->pci_conf[0x4d] = 0x00;
|
||||
dev->pci_conf[0x4e] = dev->pci_conf[0x4f] = 0x00;
|
||||
|
||||
sis_5513_ide_irq_handler(dev);
|
||||
sis_5513_ide_handler(dev);
|
||||
|
||||
sff_bus_master_reset(dev->sis->bm[0]);
|
||||
sff_bus_master_reset(dev->sis->bm[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5513_ide_close(void *priv)
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5513_ide_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5513_ide_t *dev = (sis_5513_ide_t *) calloc(1, sizeof(sis_5513_ide_t));
|
||||
|
||||
dev->rev = info->local;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* SFF IDE */
|
||||
dev->sis->bm[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->sis->bm[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
sis_5513_ide_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5513_ide_device = {
|
||||
.name = "SiS 5513 IDE controller",
|
||||
.internal_name = "sis_5513_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5572_ide_device = {
|
||||
.name = "SiS 5572 IDE controller",
|
||||
.internal_name = "sis_5572_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xc0,
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5582_ide_device = {
|
||||
.name = "SiS 5582 IDE controller",
|
||||
.internal_name = "sis_5582_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xd0,
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5591_5600_ide_device = {
|
||||
.name = "SiS 5591/(5)600 IDE controller",
|
||||
.internal_name = "sis_5591_5600_ide",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xd1, /* D0, but we need to distinguish them. */
|
||||
.init = sis_5513_ide_init,
|
||||
.close = sis_5513_ide_close,
|
||||
.reset = sis_5513_ide_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
1387
src/chipset/sis_5513_p2i.c
Normal file
1387
src/chipset/sis_5513_p2i.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
459
src/chipset/sis_5571_h2p.c
Normal file
459
src/chipset/sis_5571_h2p.c
Normal file
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5571 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5571_HOST_TO_PCI_LOG
|
||||
int sis_5571_host_to_pci_do_log = ENABLE_SIS_5571_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5571_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5571_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5571_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5571_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
} sis_5571_host_to_pci_t;
|
||||
|
||||
static void
|
||||
sis_5571_shadow_recalc(sis_5571_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x70; i <= 0x76; i++) {
|
||||
if (i == 0x76) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5571_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5571_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5571_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_smram_recalc(sis_5571_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0xa3] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
|
||||
sis_5571_host_to_pci_log("SiS 5571 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - low byte */
|
||||
case 0x05: /* Command - high byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02);
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xb8);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: /* Host Interface and DRAM arbiter */
|
||||
dev->pci_conf[addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x51: /* CACHE */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
break;
|
||||
|
||||
case 0x53: /* DRAM */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x54: /* FP/EDO */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0x56: /* MDLE delay */
|
||||
dev->pci_conf[addr] = val & 0x07;
|
||||
break;
|
||||
|
||||
case 0x57: /* SDRAM */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x59: /* Buffer strength and current rating */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
/* Undocumented - DRAM bank registers, the exact layout is currently unknown. */
|
||||
case 0x60 ... 0x6b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x75:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5571_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5571_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xcc;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
/* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */
|
||||
break;
|
||||
|
||||
case 0x84 ... 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x90: /* PMU control register */
|
||||
case 0x91: /* Address trap for green function */
|
||||
case 0x92:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93: /* STPCLK# and APM SMI control */
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
if ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x9d] |= 0x01;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94: /* 6x86 and Green function control */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95: /* Test mode control */
|
||||
case 0x96: /* Time slot and Programmable 10-bit I/O port definition */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x97: /* programmable 10-bit I/O port address */
|
||||
case 0x98: /* Programmable 16-bit I/O port */
|
||||
case 0x99 ... 0x9c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9d:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x9e: /* STPCLK# Assertion Timer */
|
||||
case 0x9f: /* STPCLK# De-assertion Timer */
|
||||
case 0xa0 ... 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa3: /* SMRAM access control and Power supply control */
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5571_smram_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5571_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5571_host_to_pci_log("SiS 5571 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x71;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x00;
|
||||
dev->pci_conf[0x09] = 0x00;
|
||||
dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x00;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
|
||||
dev->pci_conf[0x50] = 0x00;
|
||||
dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x00;
|
||||
dev->pci_conf[0x53] = 0x00;
|
||||
dev->pci_conf[0x54] = 0x54;
|
||||
dev->pci_conf[0x55] = 0x54;
|
||||
dev->pci_conf[0x56] = 0x03;
|
||||
dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = 0x00;
|
||||
dev->pci_conf[0x5a] = 0x00;
|
||||
|
||||
/* Undocumented DRAM bank registers. */
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x62] = 0x04;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x66] = 0x04;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x6a] = 0x04;
|
||||
dev->pci_conf[0x61] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x63] = dev->pci_conf[0x67] = 0x80;
|
||||
dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6b] = 0x80;
|
||||
|
||||
dev->pci_conf[0x70] = 0x00;
|
||||
dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = 0x00;
|
||||
dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = 0x00;
|
||||
dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = 0x00;
|
||||
|
||||
dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = 0x00;
|
||||
dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = 0x00;
|
||||
dev->pci_conf[0x7b] = 0x00;
|
||||
|
||||
dev->pci_conf[0x80] = 0x00;
|
||||
dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = 0x00;
|
||||
dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = 0x00;
|
||||
dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = 0x00;
|
||||
dev->pci_conf[0x87] = 0x00;
|
||||
|
||||
dev->pci_conf[0x8c] = 0x00;
|
||||
dev->pci_conf[0x8d] = 0x00;
|
||||
dev->pci_conf[0x8e] = 0x00;
|
||||
dev->pci_conf[0x8f] = 0x00;
|
||||
|
||||
dev->pci_conf[0x90] = 0x00;
|
||||
dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = 0x00;
|
||||
dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = 0x00;
|
||||
dev->pci_conf[0x95] = 0x00;
|
||||
dev->pci_conf[0x96] = 0x00;
|
||||
dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = 0x00;
|
||||
dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = 0x00;
|
||||
dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0x9c] = 0x00;
|
||||
dev->pci_conf[0x9d] = 0x00;
|
||||
dev->pci_conf[0x9e] = 0xff;
|
||||
dev->pci_conf[0x9f] = 0xff;
|
||||
|
||||
dev->pci_conf[0xa0] = 0xff;
|
||||
dev->pci_conf[0xa1] = 0x00;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
dev->pci_conf[0xa3] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5571_smram_recalc(dev);
|
||||
sis_5571_shadow_recalc(dev);
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5571_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5571_host_to_pci_t *dev = (sis_5571_host_to_pci_t *) calloc(1, sizeof(sis_5571_host_to_pci_t));
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
sis_5571_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5571_h2p_device = {
|
||||
.name = "SiS 5571 Host to PCI bridge",
|
||||
.internal_name = "sis_5571_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5571_host_to_pci_init,
|
||||
.close = sis_5571_host_to_pci_close,
|
||||
.reset = sis_5571_host_to_pci_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
771
src/chipset/sis_5571_old.c
Normal file
771
src/chipset/sis_5571_old.c
Normal file
@@ -0,0 +1,771 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5571 Chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#include <86box/chipset.h>
|
||||
|
||||
/* Shadow RAM */
|
||||
#define LSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define LSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define MSB_READ ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define MSB_WRITE ((dev->pci_conf[0x70 + (cur_reg & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
#define SYSTEM_READ ((dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY)
|
||||
#define SYSTEM_WRITE ((dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)
|
||||
|
||||
/* IDE Flags (1 Native / 0 Compatibility)*/
|
||||
#define PRIMARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 1)
|
||||
#define SECONDARY_COMP_NAT_SWITCH (dev->pci_conf_sb[1][9] & 4)
|
||||
#define PRIMARY_NATIVE_BASE (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10] & 0xf8)
|
||||
#define PRIMARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14] & 0xfc)) + 2)
|
||||
#define SECONDARY_NATIVE_BASE (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18] & 0xf8)
|
||||
#define SECONDARY_NATIVE_SIDE (((dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c] & 0xfc)) + 2)
|
||||
#define BUS_MASTER_BASE ((dev->pci_conf_sb[1][0x20] & 0xf0) | (dev->pci_conf_sb[1][0x21] << 8))
|
||||
|
||||
#ifdef ENABLE_SIS_5571_LOG
|
||||
int sis_5571_do_log = ENABLE_SIS_5571_LOG;
|
||||
|
||||
static void
|
||||
sis_5571_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5571_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5571_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5571_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
uint8_t pad;
|
||||
uint8_t usb_irq_state;
|
||||
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t pci_conf_sb[3][256];
|
||||
|
||||
port_92_t *port_92;
|
||||
sff8038i_t *ide_drive[2];
|
||||
smram_t *smram;
|
||||
usb_t *usb;
|
||||
} sis_5571_t;
|
||||
|
||||
static void
|
||||
sis_5571_shadow_recalc(int cur_reg, sis_5571_t *dev)
|
||||
{
|
||||
if (cur_reg != 0x76) {
|
||||
mem_set_mem_state_both(0xc0000 + (0x8000 * (cur_reg & 0x07)), 0x4000, LSB_READ | LSB_WRITE);
|
||||
mem_set_mem_state_both(0xc4000 + (0x8000 * (cur_reg & 0x07)), 0x4000, MSB_READ | MSB_WRITE);
|
||||
} else
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, SYSTEM_READ | SYSTEM_WRITE);
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_smm_recalc(sis_5571_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch ((dev->pci_conf[0xa3] & 0xc0) >> 6) {
|
||||
case 0x00:
|
||||
smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x01:
|
||||
smram_enable(dev->smram, 0xe0000, 0xa0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x02:
|
||||
smram_enable(dev->smram, 0xe0000, 0xb0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
case 0x03:
|
||||
smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_ide_handler(sis_5571_t *dev)
|
||||
{
|
||||
ide_pri_disable();
|
||||
ide_sec_disable();
|
||||
if (dev->pci_conf_sb[1][4] & 1) {
|
||||
if (dev->pci_conf_sb[1][0x4a] & 4) {
|
||||
ide_set_base(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_BASE : 0x1f0);
|
||||
ide_set_side(0, PRIMARY_COMP_NAT_SWITCH ? PRIMARY_NATIVE_SIDE : 0x3f6);
|
||||
ide_pri_enable();
|
||||
}
|
||||
if (dev->pci_conf_sb[1][0x4a] & 2) {
|
||||
ide_set_base(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_BASE : 0x170);
|
||||
ide_set_side(1, SECONDARY_COMP_NAT_SWITCH ? SECONDARY_NATIVE_SIDE : 0x376);
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sis_5571_bm_handler(sis_5571_t *dev)
|
||||
{
|
||||
sff_bus_master_handler(dev->ide_drive[0], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE);
|
||||
sff_bus_master_handler(dev->ide_drive[1], dev->pci_conf_sb[1][4] & 4, BUS_MASTER_BASE + 8);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_pci_bridge_write(UNUSED(int func), int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - low byte */
|
||||
case 0x05: /* Command - high byte */
|
||||
dev->pci_conf[addr] |= val;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= val & 0xbe;
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x50: /* Host Interface and DRAM arbiter */
|
||||
dev->pci_conf[addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x51: /* CACHE */
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
break;
|
||||
|
||||
case 0x53: /* DRAM */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x54: /* FP/EDO */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xe0;
|
||||
break;
|
||||
|
||||
case 0x56: /* MDLE delay */
|
||||
case 0x57: /* SDRAM */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x59: /* Buffer strength and current rating */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x60: /* Undocumented */
|
||||
case 0x61: /* Undocumented */
|
||||
case 0x62: /* Undocumented */
|
||||
case 0x63: /* Undocumented */
|
||||
case 0x64: /* Undocumented */
|
||||
case 0x65: /* Undocumented */
|
||||
case 0x66: /* Undocumented */
|
||||
case 0x67: /* Undocumented */
|
||||
case 0x68: /* Undocumented */
|
||||
case 0x69: /* Undocumented */
|
||||
case 0x6a: /* Undocumented */
|
||||
case 0x6b: /* Undocumented */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x72:
|
||||
case 0x73:
|
||||
case 0x74:
|
||||
case 0x75:
|
||||
case 0x76: /* Attribute of shadow RAM for BIOS area */
|
||||
dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8);
|
||||
sis_5571_shadow_recalc(addr, dev);
|
||||
sis_5571_smm_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xcc;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
port_92_set_features(dev->port_92, !!(val & 0x40), !!(val & 0x80));
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x90: /* PMU control register */
|
||||
case 0x91: /* Address trap for green function */
|
||||
case 0x92:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93: /* STPCLK# and APM SMI control */
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
if ((dev->pci_conf[0x9b] & 1) && !!(val & 2)) {
|
||||
smi_raise();
|
||||
dev->pci_conf[0x9d] |= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94: /* 6x86 and Green function control */
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95: /* Test mode control */
|
||||
case 0x96: /* Time slot and Programmable 10-bit I/O port definition */
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x97: /* programmable 10-bit I/O port address */
|
||||
case 0x98: /* Programmable 16-bit I/O port */
|
||||
case 0x99:
|
||||
case 0x9a:
|
||||
case 0x9b:
|
||||
case 0x9c:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x9d:
|
||||
dev->pci_conf[addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x9e: /* STPCLK# Assertion Timer */
|
||||
case 0x9f: /* STPCLK# De-assertion Timer */
|
||||
case 0xa0:
|
||||
case 0xa1:
|
||||
case 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0xa3: /* SMRAM access control and Power supply control */
|
||||
dev->pci_conf[addr] = val & 0xd0;
|
||||
sis_5571_smm_recalc(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
memory_pci_bridge_read(UNUSED(int func), int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
sis_5571_log("SiS5571: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]);
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
static void
|
||||
pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
switch (func) {
|
||||
case 0: /* Bridge */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command */
|
||||
dev->pci_conf_sb[0][addr] |= val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status */
|
||||
dev->pci_conf_sb[0][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x40: /* BIOS Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x41: /* INTA# Remapping Control Register */
|
||||
case 0x42: /* INTB# Remapping Control Register */
|
||||
case 0x43: /* INTC# Remapping Control Register */
|
||||
case 0x44: /* INTD# Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
pci_set_irq_routing((addr & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xec;
|
||||
switch ((val & 0xc0) >> 6) {
|
||||
case 0:
|
||||
cpu_set_isa_speed(7159091);
|
||||
break;
|
||||
case 1:
|
||||
cpu_set_isa_pci_div(4);
|
||||
break;
|
||||
case 2:
|
||||
cpu_set_isa_pci_div(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x46:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xec;
|
||||
break;
|
||||
|
||||
case 0x47: /* DMA Clock and Wait State Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3e;
|
||||
break;
|
||||
|
||||
case 0x48: /* ISA Master/DMA Memory Cycle Control Register 1 */
|
||||
case 0x49: /* ISA Master/DMA Memory Cycle Control Register 2 */
|
||||
case 0x4a: /* ISA Master/DMA Memory Cycle Control Register 3 */
|
||||
case 0x4b: /* ISA Master/DMA Memory Cycle Control Register 4 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4c:
|
||||
case 0x4d:
|
||||
case 0x4e:
|
||||
case 0x4f:
|
||||
case 0x50:
|
||||
case 0x51:
|
||||
case 0x52:
|
||||
case 0x53:
|
||||
case 0x54:
|
||||
case 0x55:
|
||||
case 0x56:
|
||||
case 0x57:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
case 0x5d:
|
||||
case 0x5e:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x5f:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x3f;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x61: /* MIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED);
|
||||
break;
|
||||
|
||||
case 0x62: /* On-board Device DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x0f;
|
||||
dma_set_drq((val & 0x07), 1);
|
||||
break;
|
||||
|
||||
case 0x63: /* IDEIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x8f;
|
||||
if (val & 0x80) {
|
||||
sff_set_irq_line(dev->ide_drive[0], val & 0x0f);
|
||||
sff_set_irq_line(dev->ide_drive[1], val & 0x0f);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x64: /* GPIO Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xef;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x1b;
|
||||
break;
|
||||
|
||||
case 0x66: /* GPIO Output Mode Control Register */
|
||||
case 0x67: /* GPIO Output Mode Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x68: /* USBIRQ Remapping Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0x1b;
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x6b:
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x6c:
|
||||
dev->pci_conf_sb[0][addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x6e: /* Software-Controlled Interrupt Request, Channels 7-0 */
|
||||
case 0x6f: /* Software-Controlled Interrupt Request, channels 15-8 */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
dev->pci_conf_sb[0][addr] = val & 0xde;
|
||||
break;
|
||||
|
||||
case 0x71: /* Type-F DMA Control Register */
|
||||
dev->pci_conf_sb[0][addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x72: /* SMI Triggered By IRQ/GPIO Control */
|
||||
case 0x73: /* SMI Triggered By IRQ/GPIO Control */
|
||||
dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val;
|
||||
break;
|
||||
|
||||
case 0x74: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */
|
||||
case 0x75: /* System Standby Timer Reload, System Standby State Exit And Throttling State Exit Control */
|
||||
case 0x76: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
|
||||
case 0x77: /* Monitor Standby Timer Reload And Monitor Standby State ExitControl */
|
||||
dev->pci_conf_sb[0][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
case 1: /* IDE Controller */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command low byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0x05;
|
||||
sis_5571_ide_handler(dev);
|
||||
sis_5571_bm_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x07: /* Status high byte */
|
||||
dev->pci_conf_sb[1][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x09: /* Programming Interface Byte */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xcf;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Latency Time */
|
||||
case 0x10: /* Primary Channel Base Address Register */
|
||||
case 0x11: /* Primary Channel Base Address Register */
|
||||
case 0x12: /* Primary Channel Base Address Register */
|
||||
case 0x13: /* Primary Channel Base Address Register */
|
||||
case 0x14: /* Primary Channel Base Address Register */
|
||||
case 0x15: /* Primary Channel Base Address Register */
|
||||
case 0x16: /* Primary Channel Base Address Register */
|
||||
case 0x17: /* Primary Channel Base Address Register */
|
||||
case 0x18: /* Secondary Channel Base Address Register */
|
||||
case 0x19: /* Secondary Channel Base Address Register */
|
||||
case 0x1a: /* Secondary Channel Base Address Register */
|
||||
case 0x1b: /* Secondary Channel Base Address Register */
|
||||
case 0x1c: /* Secondary Channel Base Address Register */
|
||||
case 0x1d: /* Secondary Channel Base Address Register */
|
||||
case 0x1e: /* Secondary Channel Base Address Register */
|
||||
case 0x1f: /* Secondary Channel Base Address Register */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x20: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x21: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x22: /* Bus Master IDE Control Register Base Address */
|
||||
case 0x23: /* Bus Master IDE Control Register Base Address */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
sis_5571_bm_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x30: /* Expansion ROM Base Address */
|
||||
case 0x31: /* Expansion ROM Base Address */
|
||||
case 0x32: /* Expansion ROM Base Address */
|
||||
case 0x33: /* Expansion ROM Base Address */
|
||||
case 0x40: /* IDE Primary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x41: /* IDE Primary Channel/Master Drive DataActive Time Control */
|
||||
case 0x42: /* IDE Primary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x43: /* IDE Primary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x44: /* IDE Secondary Channel/Master Drive Data Recovery Time Control */
|
||||
case 0x45: /* IDE Secondary Channel/Master Drive Data Active Time Control */
|
||||
case 0x46: /* IDE Secondary Channel/Slave Drive Data Recovery Time Control */
|
||||
case 0x47: /* IDE Secondary Channel/Slave Drive Data Active Time Control */
|
||||
case 0x48: /* IDE Command Recovery Time Control */
|
||||
case 0x49: /* IDE Command Active Time Control */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
case 0x4a: /* IDE General Control Register 0 */
|
||||
dev->pci_conf_sb[1][addr] = val & 0xaf;
|
||||
sis_5571_ide_handler(dev);
|
||||
break;
|
||||
|
||||
case 0x4b: /* IDE General Control register 1 */
|
||||
case 0x4c: /* Prefetch Count of Primary Channel (Low Byte) */
|
||||
case 0x4d: /* Prefetch Count of Primary Channel (High Byte) */
|
||||
case 0x4e: /* Prefetch Count of Secondary Channel (Low Byte) */
|
||||
case 0x4f: /* Prefetch Count of Secondary Channel (High Byte) */
|
||||
dev->pci_conf_sb[1][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
case 2: /* USB Controller */
|
||||
switch (addr) {
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf_sb[2][addr] = val;
|
||||
ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1);
|
||||
break;
|
||||
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf_sb[2][addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x06: /* Status - Low Byte */
|
||||
dev->pci_conf_sb[2][addr] &= val & 0xc0;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf_sb[2][addr] &= val;
|
||||
break;
|
||||
|
||||
case 0x10: /* Memory Space Base Address Register */
|
||||
case 0x11: /* Memory Space Base Address Register */
|
||||
case 0x12: /* Memory Space Base Address Register */
|
||||
case 0x13: /* Memory Space Base Address Register */
|
||||
dev->pci_conf_sb[2][addr] = val & ((addr == 0x11) ? 0x0f : 0xff);
|
||||
ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[2][4] & 1);
|
||||
break;
|
||||
|
||||
case 0x14: /* IO Space Base Address Register */
|
||||
case 0x15: /* IO Space Base Address Register */
|
||||
case 0x16: /* IO Space Base Address Register */
|
||||
case 0x17: /* IO Space Base Address Register */
|
||||
case 0x3c: /* Interrupt Line */
|
||||
dev->pci_conf_sb[2][addr] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] = %02x\n", addr, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pci_isa_bridge_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
switch (func) {
|
||||
case 0:
|
||||
sis_5571_log("SiS5571-SB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]);
|
||||
return dev->pci_conf_sb[0][addr];
|
||||
case 1:
|
||||
sis_5571_log("SiS5571-IDE: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]);
|
||||
return dev->pci_conf_sb[1][addr];
|
||||
case 2:
|
||||
sis_5571_log("SiS5571-USB: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]);
|
||||
return dev->pci_conf_sb[2][addr];
|
||||
|
||||
default:
|
||||
return 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_reset(void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
/* Memory/PCI Bridge */
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x71;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0xfd;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x9e] = 0xff;
|
||||
dev->pci_conf[0x9f] = 0xff;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
|
||||
/* PCI to ISA bridge */
|
||||
dev->pci_conf_sb[0][0x00] = 0x39;
|
||||
dev->pci_conf_sb[0][0x01] = 0x10;
|
||||
dev->pci_conf_sb[0][0x02] = 0x08;
|
||||
dev->pci_conf_sb[0][0x04] = 0xfd;
|
||||
dev->pci_conf_sb[0][0x08] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[0][0x0b] = 0x06;
|
||||
|
||||
/* IDE Controller */
|
||||
dev->pci_conf_sb[1][0x00] = 0x39;
|
||||
dev->pci_conf_sb[1][0x01] = 0x10;
|
||||
dev->pci_conf_sb[1][0x02] = 0x13;
|
||||
dev->pci_conf_sb[1][0x03] = 0x55;
|
||||
dev->pci_conf_sb[1][0x08] = 0xc0;
|
||||
dev->pci_conf_sb[1][0x0a] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0b] = 0x01;
|
||||
dev->pci_conf_sb[1][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[1][0x4a] = 0x06;
|
||||
sff_set_slot(dev->ide_drive[0], dev->sb_slot);
|
||||
sff_set_slot(dev->ide_drive[1], dev->sb_slot);
|
||||
sff_bus_master_reset(dev->ide_drive[0]);
|
||||
sff_bus_master_reset(dev->ide_drive[1]);
|
||||
|
||||
/* USB Controller */
|
||||
dev->pci_conf_sb[2][0x00] = 0x39;
|
||||
dev->pci_conf_sb[2][0x01] = 0x10;
|
||||
dev->pci_conf_sb[2][0x02] = 0x01;
|
||||
dev->pci_conf_sb[2][0x03] = 0x70;
|
||||
dev->pci_conf_sb[2][0x08] = 0xb0;
|
||||
dev->pci_conf_sb[2][0x09] = 0x10;
|
||||
dev->pci_conf_sb[2][0x0a] = 0x03;
|
||||
dev->pci_conf_sb[2][0x0b] = 0xc0;
|
||||
dev->pci_conf_sb[2][0x0e] = 0x80;
|
||||
dev->pci_conf_sb[2][0x14] = 0x01;
|
||||
dev->pci_conf_sb[2][0x3d] = 0x01;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5571_close(void *priv)
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5571_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5571_t *dev = (sis_5571_t *) calloc(1, sizeof(sis_5571_t));
|
||||
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev, &dev->nb_slot);
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev, &dev->sb_slot);
|
||||
|
||||
/* MIRQ */
|
||||
pci_enable_mirq(0);
|
||||
|
||||
/* Port 92 & SMRAM */
|
||||
dev->port_92 = device_add(&port_92_pci_device);
|
||||
dev->smram = smram_add();
|
||||
|
||||
/* SFF IDE */
|
||||
dev->ide_drive[0] = device_add_inst(&sff8038i_device, 1);
|
||||
dev->ide_drive[1] = device_add_inst(&sff8038i_device, 2);
|
||||
|
||||
/* USB */
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
sis_5571_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5571_device = {
|
||||
.name = "SiS 5571",
|
||||
.internal_name = "sis_5571",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5571_init,
|
||||
.close = sis_5571_close,
|
||||
.reset = sis_5571_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
323
src/chipset/sis_5572_usb.c
Normal file
323
src/chipset/sis_5572_usb.c
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5572 USB controller.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5572_USB_LOG
|
||||
int sis_5572_usb_do_log = ENABLE_SIS_5572_USB_LOG;
|
||||
|
||||
static void
|
||||
sis_5572_usb_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5572_usb_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5572_usb_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5572_usb_t {
|
||||
uint8_t rev;
|
||||
|
||||
uint8_t usb_unk_regs[256];
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
uint16_t usb_unk_base;
|
||||
|
||||
usb_t *usb;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5572_usb_t;
|
||||
|
||||
/* SiS 5572 unknown I/O port (second USB PCI BAR). */
|
||||
static void
|
||||
sis_5572_usb_unk_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
addr = (addr - dev->usb_unk_base) & 0x07;
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB UNK: [W] dev->usb_unk_regs[%02X] = %02X\n", addr, val);
|
||||
|
||||
dev->usb_unk_regs[addr] = val;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5572_usb_unk_read(uint16_t addr, void *priv)
|
||||
{
|
||||
const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = (addr - dev->usb_unk_base) & 0x07;
|
||||
|
||||
ret = dev->usb_unk_regs[addr & 0x07];
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB UNK: [R] dev->usb_unk_regs[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
sis_5572_usb_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (dev->sis->usb_enabled) switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
if (dev->rev == 0xb0)
|
||||
dev->pci_conf[addr] = val & 0x47;
|
||||
else
|
||||
dev->pci_conf[addr] = val & 0x57;
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_removehandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
if (dev->pci_conf[0x04] & 0x01)
|
||||
io_sethandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
ohci_update_mem_mapping(dev->usb,
|
||||
dev->pci_conf[0x11], dev->pci_conf[0x12],
|
||||
dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02);
|
||||
break;
|
||||
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x01;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xf9);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Latency Timer */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x11 ... 0x13: /* Memory Space Base Address Register */
|
||||
dev->pci_conf[addr] = val & ((addr == 0x11) ? 0xf0 : 0xff);
|
||||
ohci_update_mem_mapping(dev->usb,
|
||||
dev->pci_conf[0x11], dev->pci_conf[0x12],
|
||||
dev->pci_conf[0x13], dev->pci_conf[4] & 0x02);
|
||||
break;
|
||||
|
||||
case 0x14 ... 0x15: /* IO Space Base Address Register */
|
||||
if (dev->rev == 0xb0) {
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_removehandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
dev->pci_conf[addr] = val;
|
||||
dev->usb_unk_base = (dev->pci_conf[0x14] & 0xf8) |
|
||||
(dev->pci_conf[0x15] << 8);
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_sethandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2c ... 0x2f:
|
||||
if (dev->rev == 0x11)
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x3c: /* Interrupt Line */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5572_usb_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->sis->usb_enabled) {
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5572_usb_log("SiS 5572 USB: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5572_usb_reset(void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x01;
|
||||
dev->pci_conf[0x03] = 0x70;
|
||||
dev->pci_conf[0x04] = dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = (dev->rev == 0xb0) ? 0x00 : 0x80;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = dev->rev;
|
||||
dev->pci_conf[0x09] = 0x10;
|
||||
dev->pci_conf[0x0a] = 0x03;
|
||||
dev->pci_conf[0x0b] = 0x0c;
|
||||
dev->pci_conf[0x0c] = dev->pci_conf[0x0d] = 0x00;
|
||||
dev->pci_conf[0x0e] = 0x80 /* 0x10 - Datasheet erratum - header type 0x10 is invalid! */;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = 0x00;
|
||||
dev->pci_conf[0x11] = 0x00;
|
||||
dev->pci_conf[0x12] = 0x00;
|
||||
dev->pci_conf[0x13] = 0x00;
|
||||
if (dev->rev == 0xb0) {
|
||||
dev->pci_conf[0x14] = 0x01;
|
||||
dev->pci_conf[0x15] = 0x00;
|
||||
dev->pci_conf[0x16] = 0x00;
|
||||
dev->pci_conf[0x17] = 0x00;
|
||||
} else if (dev->rev == 0x11) {
|
||||
dev->pci_conf[0x2c] = 0x00;
|
||||
dev->pci_conf[0x2d] = 0x00;
|
||||
dev->pci_conf[0x2e] = 0x00;
|
||||
dev->pci_conf[0x2f] = 0x00;
|
||||
}
|
||||
dev->pci_conf[0x3c] = 0x00;
|
||||
dev->pci_conf[0x3d] = PCI_INTA;
|
||||
dev->pci_conf[0x3e] = 0x00;
|
||||
dev->pci_conf[0x3f] = 0x00;
|
||||
|
||||
if (dev->rev == 0xb0) {
|
||||
ohci_update_mem_mapping(dev->usb,
|
||||
dev->pci_conf[0x11], dev->pci_conf[0x12],
|
||||
dev->pci_conf[0x13], dev->pci_conf[0x04] & 0x02);
|
||||
|
||||
if (dev->usb_unk_base != 0x0000) {
|
||||
io_removehandler(dev->usb_unk_base, 0x0002,
|
||||
sis_5572_usb_unk_read, NULL, NULL,
|
||||
sis_5572_usb_unk_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
dev->usb_unk_base = 0x0000;
|
||||
|
||||
memset(dev->usb_unk_regs, 0x00, sizeof(dev->usb_unk_regs));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5572_usb_close(void *priv)
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5572_usb_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5572_usb_t *dev = (sis_5572_usb_t *) calloc(1, sizeof(sis_5572_usb_t));
|
||||
|
||||
dev->rev = info->local;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* USB */
|
||||
dev->usb = device_add(&usb_device);
|
||||
|
||||
sis_5572_usb_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5572_usb_device = {
|
||||
.name = "SiS 5572 USB controller",
|
||||
.internal_name = "sis_5572_usb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xb0,
|
||||
.init = sis_5572_usb_init,
|
||||
.close = sis_5572_usb_close,
|
||||
.reset = sis_5572_usb_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5582_usb_device = {
|
||||
.name = "SiS 5582 USB controller",
|
||||
.internal_name = "sis_5582_usb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0xe0,
|
||||
.init = sis_5572_usb_init,
|
||||
.close = sis_5572_usb_close,
|
||||
.reset = sis_5572_usb_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5595_usb_device = {
|
||||
.name = "SiS 5595 USB controller",
|
||||
.internal_name = "sis_5595_usb",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x11,
|
||||
.init = sis_5572_usb_init,
|
||||
.close = sis_5572_usb_close,
|
||||
.reset = sis_5572_usb_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
187
src/chipset/sis_5581.c
Normal file
187
src/chipset/sis_5581.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5581/5582 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5581_LOG
|
||||
int sis_5581_do_log = ENABLE_SIS_5581_LOG;
|
||||
|
||||
static void
|
||||
sis_5581_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5581_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5581_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5581_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
void *h2p;
|
||||
void *p2i;
|
||||
void *ide;
|
||||
void *usb;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5581_t;
|
||||
|
||||
static void
|
||||
sis_5581_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
|
||||
sis_5581_log("SiS 5581: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5581_host_to_pci_write(addr, val, dev->h2p);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5581_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = sis_5581_host_to_pci_read(addr, dev->h2p);
|
||||
|
||||
sis_5581_log("SiS 5581: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5582_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
|
||||
sis_5581_log("SiS 5582: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
break;
|
||||
case 0x02:
|
||||
sis_5572_usb_write(addr, val, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5582_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = sis_5572_usb_read(addr, dev->usb);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5581_log("SiS 5582: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_close(void *priv)
|
||||
{
|
||||
sis_5581_t *dev = (sis_5581_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5581_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5581_t *dev = (sis_5581_t *) calloc(1, sizeof(sis_5581_t));
|
||||
|
||||
/* Device 0: SiS 5581 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5581_read, sis_5581_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5582 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5582_read, sis_5582_write, dev, &dev->sb_slot);
|
||||
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
dev->p2i = device_add_linked(&sis_5582_p2i_device, dev->sis);
|
||||
dev->h2p = device_add_linked(&sis_5581_h2p_device, dev->sis);
|
||||
dev->ide = device_add_linked(&sis_5582_ide_device, dev->sis);
|
||||
dev->usb = device_add_linked(&sis_5582_usb_device, dev->sis);
|
||||
|
||||
device_add_params(&kbc_at_device, (void *) KBC_VEN_SIS);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5581_device = {
|
||||
.name = "SiS 5581",
|
||||
.internal_name = "sis_5581",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5581_init,
|
||||
.close = sis_5581_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
553
src/chipset/sis_5581_h2p.c
Normal file
553
src/chipset/sis_5581_h2p.c
Normal file
@@ -0,0 +1,553 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5581 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5581_HOST_TO_PCI_LOG
|
||||
int sis_5581_host_to_pci_do_log = ENABLE_SIS_5581_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5581_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5581_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5581_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t installed;
|
||||
uint8_t code;
|
||||
uint32_t phys_size;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct sis_5581_io_trap_t {
|
||||
void *priv;
|
||||
void *trap;
|
||||
uint8_t flags, mask;
|
||||
uint8_t *sts_reg, sts_mask;
|
||||
uint16_t addr;
|
||||
} sis_5581_io_trap_t;
|
||||
|
||||
typedef struct sis_5581_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
uint8_t states[7];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
|
||||
sis_5581_io_trap_t io_traps[10];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
} sis_5581_host_to_pci_t;
|
||||
|
||||
static uint8_t bank_codes[7] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a, 0x2b };
|
||||
|
||||
static uint32_t bank_sizes[7] = { 0x00800000, /* 8 MB */
|
||||
0x01000000, /* 16 MB */
|
||||
0x02000000, /* 32 MB */
|
||||
0x04000000, /* 64 MB */
|
||||
0x08000000, /* 128 MB */
|
||||
0x10000000, /* 256 MB */
|
||||
0x20000000 }; /* 512 MB */
|
||||
|
||||
static void
|
||||
sis_5581_shadow_recalc(sis_5581_host_to_pci_t *dev)
|
||||
{
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (uint8_t i = 0x70; i <= 0x76; i++) {
|
||||
if (i == 0x76) {
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(0xf0000, 0x10000, state);
|
||||
sis_5581_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0xa0) {
|
||||
state = (dev->pci_conf[i] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base, 0x4000, state);
|
||||
sis_5581_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
}
|
||||
|
||||
if ((dev->states[i & 0x0f] ^ dev->pci_conf[i]) & 0x0a) {
|
||||
state = (dev->pci_conf[i] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (dev->pci_conf[i] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_both(base + 0x4000, 0x4000, state);
|
||||
sis_5581_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
}
|
||||
}
|
||||
|
||||
dev->states[i & 0x0f] = dev->pci_conf[i];
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_io(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val),
|
||||
void *priv)
|
||||
{
|
||||
sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv;
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) trap->priv;
|
||||
|
||||
trap->sts_reg[0x04] |= trap->sts_mask;
|
||||
|
||||
if (trap->sts_reg[0x00] & trap->sts_mask)
|
||||
acpi_sis5582_pmu_event(dev->sis->acpi);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_io_mask(int size, uint16_t addr, uint8_t write, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5581_io_trap_t *trap = (sis_5581_io_trap_t *) priv;
|
||||
|
||||
if ((addr & trap->mask) == (trap->addr & trap->mask))
|
||||
sis_5581_trap_io(size, addr, write, val, priv);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_update_devctl(sis_5581_host_to_pci_t *dev, uint8_t trap_id, uint8_t enable,
|
||||
uint8_t flags, uint8_t mask, uint8_t *sts_reg, uint8_t sts_mask,
|
||||
uint16_t addr, uint16_t size)
|
||||
{
|
||||
sis_5581_io_trap_t *trap = &dev->io_traps[trap_id];
|
||||
|
||||
/* Set up Device I/O traps dynamically. */
|
||||
if (enable && !trap->trap) {
|
||||
trap->priv = (void *) dev;
|
||||
trap->flags = flags;
|
||||
trap->mask = mask;
|
||||
trap->addr = addr;
|
||||
if (flags & 0x08)
|
||||
trap->trap = io_trap_add(sis_5581_trap_io_mask, trap);
|
||||
else
|
||||
trap->trap = io_trap_add(sis_5581_trap_io, trap);
|
||||
trap->sts_reg = sts_reg;
|
||||
trap->sts_mask = sts_mask;
|
||||
}
|
||||
|
||||
/* Remap I/O trap. */
|
||||
io_trap_remap(trap->trap, enable, addr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_trap_update(void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
uint8_t trap_id = 0;
|
||||
uint8_t *fregs = dev->pci_conf;
|
||||
uint16_t temp;
|
||||
uint8_t mask;
|
||||
uint8_t on;
|
||||
|
||||
on = fregs[0x9a];
|
||||
|
||||
temp = ((fregs[0x96] & 0x02) | (fregs[0x97] << 2)) & 0x03ff;
|
||||
mask = ~((1 << ((fregs[0x96] >> 3) & 0x07)) - 1);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x40, 0x08, mask, &(fregs[0x9c]), 0x40, temp, 0x80);
|
||||
|
||||
temp = fregs[0x98] | (fregs[0x99] << 8);
|
||||
mask = 0xff;
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x20, 0x08, mask, &(fregs[0x9c]), 0x20, temp, 0x80);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x378, 0x08);
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x10, 0x00, 0xff, &(fregs[0x9c]), 0x10, 0x278, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x9c]), 0x08, 0x3f8, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x04, 0x00, 0xff, &(fregs[0x9c]), 0x04, 0x2f8, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x02, 0x00, 0xff, &(fregs[0x9c]), 0x02, 0x1f0, 0x08);
|
||||
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x01, 0x00, 0xff, &(fregs[0x9c]), 0x01, 0x170, 0x08);
|
||||
|
||||
on = fregs[0x9b];
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x064, 0x01);
|
||||
sis_5581_trap_update_devctl(dev, trap_id++,
|
||||
on & 0x08, 0x00, 0xff, &(fregs[0x9d]), 0x08, 0x060, 0x01);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_smram_recalc(sis_5581_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0xa3] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0xa3] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
void
|
||||
sis_5581_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
|
||||
sis_5581_host_to_pci_log("SiS 5581 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfc) | (val & 0x03);
|
||||
break;
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x02;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xb8);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
case 0x50:
|
||||
case 0x54:
|
||||
case 0x56 ... 0x57:
|
||||
case 0x59:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x40);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x52:
|
||||
dev->pci_conf[addr] = val & 0xeb;
|
||||
break;
|
||||
|
||||
case 0x53:
|
||||
case 0x55:
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
dev->pci_conf[addr] = val & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x62:
|
||||
dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = dev->ram_banks[0].installed |
|
||||
(dev->ram_banks[1].installed << 1) |
|
||||
(dev->ram_banks[2].installed << 2);
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x75:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5581_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5581_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x77: /* Characteristics of non-cacheable area */
|
||||
dev->pci_conf[addr] = val & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x78: /* Allocation of Non-Cacheable area #1 */
|
||||
case 0x79: /* NCA1REG2 */
|
||||
case 0x7a: /* Allocation of Non-Cacheable area #2 */
|
||||
case 0x7b: /* NCA2REG2 */
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x80: /* PCI master characteristics */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x81:
|
||||
dev->pci_conf[addr] = val & 0xde;
|
||||
break;
|
||||
|
||||
case 0x82:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x83: /* CPU to PCI characteristics */
|
||||
dev->pci_conf[addr] = val;
|
||||
/* TODO: Implement Fast A20 and Fast reset stuff on the KBC already! */
|
||||
break;
|
||||
|
||||
case 0x84 ... 0x86:
|
||||
case 0x88 ... 0x8b:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x87: /* Miscellanea */
|
||||
dev->pci_conf[addr] = val & 0xfe;
|
||||
break;
|
||||
|
||||
case 0x8c ... 0x92:
|
||||
case 0x9e ... 0xa2:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x93:
|
||||
dev->pci_conf[addr] = val;
|
||||
if (val & 0x02) {
|
||||
dev->pci_conf[0x9d] |= 0x01;
|
||||
if (dev->pci_conf[0x9b] & 0x01)
|
||||
acpi_sis5582_pmu_event(dev->sis->acpi);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x94:
|
||||
dev->pci_conf[addr] = val & 0xf8;
|
||||
break;
|
||||
|
||||
case 0x95:
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
break;
|
||||
|
||||
case 0x96:
|
||||
dev->pci_conf[addr] = val & 0xfb;
|
||||
sis_5581_trap_update(dev);
|
||||
break;
|
||||
case 0x97 ... 0x9b:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5581_trap_update(dev);
|
||||
break;
|
||||
|
||||
case 0x9c ... 0x9d:
|
||||
dev->pci_conf[addr] &= ~val;
|
||||
break;
|
||||
|
||||
case 0xa3:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5581_smram_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5581_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5581_host_to_pci_log("SiS 5581 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x97;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = dev->pci_conf[0x06] = 0x00;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x02;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0xff;
|
||||
dev->pci_conf[0x0e] = dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x50] = dev->pci_conf[0x51] = 0x00;
|
||||
dev->pci_conf[0x52] = 0x00;
|
||||
dev->pci_conf[0x53] = 0x38;
|
||||
dev->pci_conf[0x54] = 0x54;
|
||||
dev->pci_conf[0x55] = 0x00;
|
||||
dev->pci_conf[0x56] = 0x80;
|
||||
dev->pci_conf[0x57] = dev->pci_conf[0x58] = 0x00;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = 0x00;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0x00;
|
||||
dev->pci_conf[0x86] = dev->pci_conf[0x87] = 0x00;
|
||||
dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00;
|
||||
dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00;
|
||||
dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = dev->pci_conf[0x95] = 0x00;
|
||||
dev->pci_conf[0x96] = dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00;
|
||||
dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0xff;
|
||||
dev->pci_conf[0xa0] = 0xff;
|
||||
dev->pci_conf[0xa1] = 0x00;
|
||||
dev->pci_conf[0xa2] = 0xff;
|
||||
dev->pci_conf[0xa3] = 0x00;
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5581_shadow_recalc(dev);
|
||||
|
||||
sis_5581_trap_update(dev);
|
||||
|
||||
sis_5581_smram_recalc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5581_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5581_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5581_host_to_pci_t *dev = (sis_5581_host_to_pci_t *) calloc(1, sizeof(sis_5581_host_to_pci_t));
|
||||
uint32_t total_mem = mem_size << 10;
|
||||
ram_bank_t *rb;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* Calculate the physical RAM banks. */
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
rb = &(dev->ram_banks[i]);
|
||||
uint32_t size = 0x00000000;
|
||||
uint8_t index = 0;
|
||||
for (int8_t j = 6; j >= 0; j--) {
|
||||
uint32_t *bs = &(bank_sizes[j]);
|
||||
if (*bs <= total_mem) {
|
||||
size = *bs;
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (size != 0x00000000) {
|
||||
rb->installed = 1;
|
||||
rb->code = bank_codes[index];
|
||||
rb->phys_size = size;
|
||||
total_mem -= size;
|
||||
} else
|
||||
rb->installed = 0;
|
||||
}
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
sis_5581_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5581_h2p_device = {
|
||||
.name = "SiS 5581 Host to PCI bridge",
|
||||
.internal_name = "sis_5581_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5581_host_to_pci_init,
|
||||
.close = sis_5581_host_to_pci_close,
|
||||
.reset = sis_5581_host_to_pci_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
213
src/chipset/sis_5591.c
Normal file
213
src/chipset/sis_5591.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5591/5592 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/keyboard.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5591_LOG
|
||||
int sis_5591_do_log = ENABLE_SIS_5591_LOG;
|
||||
|
||||
static void
|
||||
sis_5591_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5591_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5591_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct sis_5591_t {
|
||||
uint8_t nb_slot;
|
||||
uint8_t sb_slot;
|
||||
|
||||
void *h2p;
|
||||
void *p2i;
|
||||
void *ide;
|
||||
void *usb;
|
||||
void *pmu;
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
} sis_5591_t;
|
||||
|
||||
static void
|
||||
sis_5591_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
|
||||
sis_5591_log("SiS 5591: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
if (func == 0x00)
|
||||
sis_5591_host_to_pci_write(addr, val, dev->h2p);
|
||||
else if (func == 0x01)
|
||||
sis_5513_ide_write(addr, val, dev->ide);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5591_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (func == 0x00)
|
||||
ret = sis_5591_host_to_pci_read(addr, dev->h2p);
|
||||
else if (func == 0x01)
|
||||
ret = sis_5513_ide_read(addr, dev->ide);
|
||||
|
||||
sis_5591_log("SiS 5591: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5595_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
|
||||
sis_5591_log("SiS 5595: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
sis_5513_pci_to_isa_write(addr, val, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
sis_5595_pmu_write(addr, val, dev->pmu);
|
||||
break;
|
||||
case 0x02:
|
||||
sis_5572_usb_write(addr, val, dev->usb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sis_5595_read(int func, int addr, void *priv)
|
||||
{
|
||||
const sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (func) {
|
||||
case 0x00:
|
||||
ret = sis_5513_pci_to_isa_read(addr, dev->p2i);
|
||||
break;
|
||||
case 0x01:
|
||||
ret = sis_5595_pmu_read(addr, dev->pmu);
|
||||
break;
|
||||
case 0x02:
|
||||
ret = sis_5572_usb_read(addr, dev->usb);
|
||||
break;
|
||||
}
|
||||
|
||||
sis_5591_log("SiS 5592: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_close(void *priv)
|
||||
{
|
||||
sis_5591_t *dev = (sis_5591_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5591_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5591_t *dev = (sis_5591_t *) calloc(1, sizeof(sis_5591_t));
|
||||
|
||||
/* Device 0: SiS 5591 */
|
||||
pci_add_card(PCI_ADD_NORTHBRIDGE, sis_5591_read, sis_5591_write, dev, &dev->nb_slot);
|
||||
/* Device 1: SiS 5595 */
|
||||
pci_add_card(PCI_ADD_SOUTHBRIDGE, sis_5595_read, sis_5595_write, dev, &dev->sb_slot);
|
||||
|
||||
dev->sis = device_add(&sis_55xx_common_device);
|
||||
|
||||
dev->ide = device_add_linked(&sis_5591_5600_ide_device, dev->sis);
|
||||
if (info->local)
|
||||
dev->p2i = device_add_linked(&sis_5595_1997_p2i_device, dev->sis);
|
||||
else
|
||||
dev->p2i = device_add_linked(&sis_5595_p2i_device, dev->sis);
|
||||
dev->h2p = device_add_linked(&sis_5591_h2p_device, dev->sis);
|
||||
dev->usb = device_add_linked(&sis_5595_usb_device, dev->sis);
|
||||
if (info->local)
|
||||
dev->pmu = device_add_linked(&sis_5595_1997_pmu_device, dev->sis);
|
||||
else
|
||||
dev->pmu = device_add_linked(&sis_5595_pmu_device, dev->sis);
|
||||
|
||||
device_add_params(&kbc_at_device, (void *) KBC_VEN_SIS);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5591_1997_device = {
|
||||
.name = "SiS 5591 (1997)",
|
||||
.internal_name = "sis_5591_1997",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 1,
|
||||
.init = sis_5591_init,
|
||||
.close = sis_5591_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sis_5591_device = {
|
||||
.name = "SiS 5591",
|
||||
.internal_name = "sis_5591",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = sis_5591_init,
|
||||
.close = sis_5591_close,
|
||||
.reset = NULL,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
494
src/chipset/sis_5591_h2p.c
Normal file
494
src/chipset/sis_5591_h2p.c
Normal file
@@ -0,0 +1,494 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5591 Host to PCI bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2024 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/timer.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/hdd.h>
|
||||
#include <86box/hdc.h>
|
||||
#include <86box/hdc_ide.h>
|
||||
#include <86box/hdc_ide_sff8038i.h>
|
||||
#include <86box/pci.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/pit.h>
|
||||
#include <86box/pit_fast.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/plat_unused.h>
|
||||
#include <86box/port_92.h>
|
||||
#include <86box/smram.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/apm.h>
|
||||
#include <86box/ddma.h>
|
||||
#include <86box/acpi.h>
|
||||
#include <86box/smbus.h>
|
||||
#include <86box/sis_55xx.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/usb.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_SIS_5591_HOST_TO_PCI_LOG
|
||||
int sis_5591_host_to_pci_do_log = ENABLE_SIS_5591_HOST_TO_PCI_LOG;
|
||||
|
||||
static void
|
||||
sis_5591_host_to_pci_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (sis_5591_host_to_pci_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define sis_5591_host_to_pci_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t installed;
|
||||
uint8_t code;
|
||||
uint32_t phys_size;
|
||||
} ram_bank_t;
|
||||
|
||||
typedef struct sis_5591_host_to_pci_t {
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
uint8_t states[7];
|
||||
uint8_t states_bus[7];
|
||||
|
||||
ram_bank_t ram_banks[3];
|
||||
|
||||
sis_55xx_common_t *sis;
|
||||
|
||||
smram_t *smram;
|
||||
|
||||
agpgart_t *agpgart;
|
||||
} sis_5591_host_to_pci_t;
|
||||
|
||||
static uint8_t bank_codes[6] = { 0x00, 0x20, 0x24, 0x22, 0x26, 0x2a };
|
||||
|
||||
static uint32_t bank_sizes[6] = { 0x00800000, /* 8 MB */
|
||||
0x01000000, /* 16 MB */
|
||||
0x02000000, /* 32 MB */
|
||||
0x04000000, /* 64 MB */
|
||||
0x08000000, /* 128 MB */
|
||||
0x10000000 }; /* 256 MB */
|
||||
|
||||
static void
|
||||
sis_5591_shadow_recalc(sis_5591_host_to_pci_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t state;
|
||||
uint8_t val;
|
||||
|
||||
for (uint8_t i = 0x70; i <= 0x76; i++) {
|
||||
if (i == 0x76) {
|
||||
val = dev->pci_conf[i];
|
||||
if ((dev->states[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_cpu_both(0xf0000, 0x10000, state);
|
||||
sis_5591_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
|
||||
dev->states[i & 0x0f] = val;
|
||||
}
|
||||
|
||||
if (!(dev->pci_conf[0x76] & 0x08))
|
||||
val &= 0x5f;
|
||||
if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_bus_both(0xf0000, 0x10000, state);
|
||||
sis_5591_host_to_pci_log("000F0000-000FFFFF\n");
|
||||
|
||||
dev->states_bus[i & 0x0f] = val;
|
||||
}
|
||||
} else {
|
||||
base = ((i & 0x07) << 15) + 0xc0000;
|
||||
|
||||
val = dev->pci_conf[i];
|
||||
if ((dev->states[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_cpu_both(base, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
|
||||
dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0x0f) | (val & 0xf0);
|
||||
}
|
||||
if ((dev->states[i & 0x0f] ^ val) & 0x0a) {
|
||||
state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_cpu_both(base + 0x4000, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
|
||||
dev->states[i & 0x0f] = (dev->states[i & 0x0f] & 0xf0) | (val & 0x0f);
|
||||
}
|
||||
|
||||
if (!(dev->pci_conf[0x76] & 0x08))
|
||||
val &= 0x55;
|
||||
if ((dev->states_bus[i & 0x0f] ^ val) & 0xa0) {
|
||||
state = (val & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_bus_both(base, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base, base + 0x3fff);
|
||||
|
||||
dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0x0f) | (val & 0xf0);
|
||||
}
|
||||
if ((dev->states_bus[i & 0x0f] ^ val) & 0x0a) {
|
||||
state = (val & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY;
|
||||
state |= (val & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY;
|
||||
mem_set_mem_state_bus_both(base + 0x4000, 0x4000, state);
|
||||
sis_5591_host_to_pci_log("%08X-%08X\n", base + 0x4000, base + 0x7fff);
|
||||
|
||||
dev->states_bus[i & 0x0f] = (dev->states_bus[i & 0x0f] & 0xf0) | (val & 0x0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_smram_recalc(sis_5591_host_to_pci_t *dev)
|
||||
{
|
||||
smram_disable_all();
|
||||
|
||||
switch (dev->pci_conf[0x68] >> 6) {
|
||||
case 0:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000e0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
case 1:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000a0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
case 2:
|
||||
smram_enable(dev->smram, 0x000e0000, 0x000b0000, 0x8000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
case 3:
|
||||
smram_enable(dev->smram, 0x000a0000, 0x000a0000, 0x10000, dev->pci_conf[0x68] & 0x10, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_mask_bar(uint8_t *regs, void *agpgart)
|
||||
{
|
||||
uint32_t bar;
|
||||
uint32_t sizes[8] = { 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x00000000 } ;
|
||||
|
||||
/* Make sure the aperture's base is aligned to its size. */
|
||||
bar = (regs[0x13] << 24) | (regs[0x12] << 16);
|
||||
bar &= (sizes[(regs[0x94] >> 4) & 0x07] | 0xf0000000);
|
||||
regs[0x12] = (bar >> 16) & 0xff;
|
||||
regs[0x13] = (bar >> 24) & 0xff;
|
||||
|
||||
if (!agpgart)
|
||||
return;
|
||||
|
||||
/* Map aperture and GART. */
|
||||
agpgart_set_aperture(agpgart,
|
||||
bar,
|
||||
sizes[(regs[0x94] >> 4) & 0x07],
|
||||
!!(regs[0x94] & 0x02));
|
||||
if (regs[0x94] & 0x01)
|
||||
agpgart_set_gart(agpgart, (regs[0x91] << 8) | (regs[0x92] << 16) | (regs[0x93] << 24));
|
||||
else
|
||||
agpgart_set_gart(agpgart, 0x00000000);
|
||||
}
|
||||
|
||||
void
|
||||
sis_5591_host_to_pci_write(int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
|
||||
sis_5591_host_to_pci_log("SiS 5591 H2P: [W] dev->pci_conf[%02X] = %02X\n", addr, val);
|
||||
|
||||
switch (addr) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x04: /* Command - Low Byte */
|
||||
dev->pci_conf[addr] = (dev->pci_conf[addr] & 0xfd) | (val & 0x02);
|
||||
break;
|
||||
case 0x05: /* Command - High Byte */
|
||||
dev->pci_conf[addr] = val & 0x03;
|
||||
break;
|
||||
|
||||
case 0x07: /* Status - High Byte */
|
||||
dev->pci_conf[addr] &= ~(val & 0xf0);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
dev->pci_conf[addr] = val & 0xc0;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
case 0x13:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
|
||||
case 0x51:
|
||||
dev->pci_conf[addr] = val;
|
||||
cpu_cache_ext_enabled = !!(val & 0x80);
|
||||
cpu_update_waitstates();
|
||||
break;
|
||||
|
||||
case 0x60 ... 0x62:
|
||||
dev->pci_conf[addr] = dev->ram_banks[addr & 0x0f].code | 0xc0;
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
dev->pci_conf[addr] = dev->ram_banks[0].installed |
|
||||
(dev->ram_banks[1].installed << 1) |
|
||||
(dev->ram_banks[2].installed << 2);
|
||||
break;
|
||||
|
||||
case 0x68:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5591_smram_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x70 ... 0x75:
|
||||
dev->pci_conf[addr] = val & 0xee;
|
||||
sis_5591_shadow_recalc(dev);
|
||||
break;
|
||||
case 0x76:
|
||||
dev->pci_conf[addr] = val & 0xe8;
|
||||
sis_5591_shadow_recalc(dev);
|
||||
break;
|
||||
|
||||
case 0x0d: /* Master latency timer */
|
||||
case 0x50:
|
||||
case 0x52:
|
||||
case 0x54 ... 0x5a:
|
||||
case 0x5c ... 0x5f:
|
||||
case 0x64 ... 0x65:
|
||||
case 0x69 ... 0x6c:
|
||||
case 0x77 ... 0x7b:
|
||||
case 0x80 ... 0x8d:
|
||||
case 0x90:
|
||||
case 0x97 ... 0xab:
|
||||
case 0xb0:
|
||||
case 0xc8 ... 0xcb:
|
||||
case 0xd4 ... 0xda:
|
||||
case 0xe0 ... 0xe3:
|
||||
case 0xef:
|
||||
dev->pci_conf[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x91 ... 0x93:
|
||||
dev->pci_conf[addr] = val;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
case 0x94:
|
||||
dev->pci_conf[addr] = val & 0x7f;
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
break;
|
||||
|
||||
case 0xb2:
|
||||
dev->pci_conf[addr] &= ~(val & 0x01);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
sis_5591_host_to_pci_read(int addr, void *priv)
|
||||
{
|
||||
const sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
ret = dev->pci_conf[addr];
|
||||
|
||||
sis_5591_host_to_pci_log("SiS 5591 H2P: [R] dev->pci_conf[%02X] = %02X\n", addr, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_host_to_pci_reset(void *priv)
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
|
||||
dev->pci_conf[0x00] = 0x39;
|
||||
dev->pci_conf[0x01] = 0x10;
|
||||
dev->pci_conf[0x02] = 0x91;
|
||||
dev->pci_conf[0x03] = 0x55;
|
||||
dev->pci_conf[0x04] = 0x05;
|
||||
dev->pci_conf[0x05] = 0x00;
|
||||
dev->pci_conf[0x06] = 0x10;
|
||||
dev->pci_conf[0x07] = 0x02;
|
||||
dev->pci_conf[0x08] = 0x02;
|
||||
dev->pci_conf[0x09] = dev->pci_conf[0x0a] = 0x00;
|
||||
dev->pci_conf[0x0b] = 0x06;
|
||||
dev->pci_conf[0x0c] = 0x00;
|
||||
dev->pci_conf[0x0d] = 0xff;
|
||||
dev->pci_conf[0x0e] = 0x80;
|
||||
dev->pci_conf[0x0f] = 0x00;
|
||||
dev->pci_conf[0x10] = dev->pci_conf[0x11] = 0x00;
|
||||
dev->pci_conf[0x12] = dev->pci_conf[0x13] = 0x00;
|
||||
dev->pci_conf[0x34] = 0xc0;
|
||||
dev->pci_conf[0x50] = 0x00;
|
||||
dev->pci_conf[0x51] = 0x18;
|
||||
dev->pci_conf[0x52] = dev->pci_conf[0x54] = 0x00;
|
||||
dev->pci_conf[0x55] = 0x0e;
|
||||
dev->pci_conf[0x56] = 0x40;
|
||||
dev->pci_conf[0x57] = 0x00;
|
||||
dev->pci_conf[0x58] = 0x50;
|
||||
dev->pci_conf[0x59] = dev->pci_conf[0x5a] = 0x00;
|
||||
dev->pci_conf[0x5c] = dev->pci_conf[0x5d] = 0x00;
|
||||
dev->pci_conf[0x5e] = dev->pci_conf[0x5f] = 0x00;
|
||||
dev->pci_conf[0x60] = dev->pci_conf[0x61] = 0x00;
|
||||
dev->pci_conf[0x62] = 0x00;
|
||||
dev->pci_conf[0x63] = 0xff;
|
||||
dev->pci_conf[0x64] = dev->pci_conf[0x65] = 0x00;
|
||||
dev->pci_conf[0x68] = dev->pci_conf[0x69] = 0x00;
|
||||
dev->pci_conf[0x6a] = dev->pci_conf[0x6b] = 0x00;
|
||||
dev->pci_conf[0x6c] = 0x00;
|
||||
dev->pci_conf[0x70] = dev->pci_conf[0x71] = 0x00;
|
||||
dev->pci_conf[0x72] = dev->pci_conf[0x73] = 0x00;
|
||||
dev->pci_conf[0x74] = dev->pci_conf[0x75] = 0x00;
|
||||
dev->pci_conf[0x76] = dev->pci_conf[0x77] = 0x00;
|
||||
dev->pci_conf[0x78] = dev->pci_conf[0x79] = 0x00;
|
||||
dev->pci_conf[0x7a] = dev->pci_conf[0x7b] = 0x00;
|
||||
dev->pci_conf[0x80] = dev->pci_conf[0x81] = 0x00;
|
||||
dev->pci_conf[0x82] = dev->pci_conf[0x83] = 0x00;
|
||||
dev->pci_conf[0x84] = dev->pci_conf[0x85] = 0xff;
|
||||
dev->pci_conf[0x86] = 0xff;
|
||||
dev->pci_conf[0x87] = 0x00;
|
||||
dev->pci_conf[0x88] = dev->pci_conf[0x89] = 0x00;
|
||||
dev->pci_conf[0x8a] = dev->pci_conf[0x8b] = 0x00;
|
||||
dev->pci_conf[0x8c] = dev->pci_conf[0x8d] = 0x00;
|
||||
dev->pci_conf[0x90] = dev->pci_conf[0x91] = 0x00;
|
||||
dev->pci_conf[0x92] = dev->pci_conf[0x93] = 0x00;
|
||||
dev->pci_conf[0x94] = dev->pci_conf[0x97] = 0x00;
|
||||
dev->pci_conf[0x98] = dev->pci_conf[0x99] = 0x00;
|
||||
dev->pci_conf[0x9a] = dev->pci_conf[0x9b] = 0x00;
|
||||
dev->pci_conf[0x9c] = dev->pci_conf[0x9d] = 0x00;
|
||||
dev->pci_conf[0x9e] = dev->pci_conf[0x9f] = 0x00;
|
||||
dev->pci_conf[0xa0] = dev->pci_conf[0xa1] = 0x00;
|
||||
dev->pci_conf[0xa2] = dev->pci_conf[0xa3] = 0x00;
|
||||
dev->pci_conf[0xa4] = dev->pci_conf[0xa5] = 0x00;
|
||||
dev->pci_conf[0xa6] = dev->pci_conf[0xa7] = 0x00;
|
||||
dev->pci_conf[0xa8] = dev->pci_conf[0xa9] = 0x00;
|
||||
dev->pci_conf[0xaa] = dev->pci_conf[0xab] = 0x00;
|
||||
dev->pci_conf[0xb0] = dev->pci_conf[0xb2] = 0x00;
|
||||
dev->pci_conf[0xc0] = 0x02;
|
||||
dev->pci_conf[0xc1] = 0x00;
|
||||
dev->pci_conf[0xc2] = 0x10;
|
||||
dev->pci_conf[0xc3] = 0x00;
|
||||
dev->pci_conf[0xc4] = 0x03;
|
||||
dev->pci_conf[0xc5] = 0x02;
|
||||
dev->pci_conf[0xc6] = 0x00;
|
||||
dev->pci_conf[0xc7] = 0x1f;
|
||||
dev->pci_conf[0xc8] = dev->pci_conf[0xc9] = 0x00;
|
||||
dev->pci_conf[0xca] = dev->pci_conf[0xcb] = 0x00;
|
||||
dev->pci_conf[0xd4] = dev->pci_conf[0xd5] = 0x00;
|
||||
dev->pci_conf[0xd6] = dev->pci_conf[0xd7] = 0x00;
|
||||
dev->pci_conf[0xd8] = dev->pci_conf[0xd9] = 0x00;
|
||||
dev->pci_conf[0xda] = 0x00;
|
||||
dev->pci_conf[0xe0] = dev->pci_conf[0xe1] = 0x00;
|
||||
dev->pci_conf[0xe2] = dev->pci_conf[0xe3] = 0x00;
|
||||
dev->pci_conf[0xef] = 0x00;
|
||||
|
||||
sis_5591_mask_bar(dev->pci_conf, dev->agpgart);
|
||||
|
||||
cpu_cache_ext_enabled = 0;
|
||||
cpu_update_waitstates();
|
||||
|
||||
sis_5591_shadow_recalc(dev);
|
||||
|
||||
sis_5591_smram_recalc(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
sis_5591_host_to_pci_close(void *priv)
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) priv;
|
||||
|
||||
smram_del(dev->smram);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
static void *
|
||||
sis_5591_host_to_pci_init(UNUSED(const device_t *info))
|
||||
{
|
||||
sis_5591_host_to_pci_t *dev = (sis_5591_host_to_pci_t *) calloc(1, sizeof(sis_5591_host_to_pci_t));
|
||||
uint32_t total_mem = mem_size << 10;
|
||||
ram_bank_t *rb;
|
||||
|
||||
dev->sis = device_get_common_priv();
|
||||
|
||||
/* Calculate the physical RAM banks. */
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
rb = &(dev->ram_banks[i]);
|
||||
uint32_t size = 0x00000000;
|
||||
uint8_t index = 0;
|
||||
for (int8_t j = 5; j >= 0; j--) {
|
||||
uint32_t *bs = &(bank_sizes[j]);
|
||||
if (*bs <= total_mem) {
|
||||
size = *bs;
|
||||
index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (size != 0x00000000) {
|
||||
rb->installed = 1;
|
||||
rb->code = bank_codes[index];
|
||||
rb->phys_size = size;
|
||||
total_mem -= size;
|
||||
} else
|
||||
rb->installed = 0;
|
||||
}
|
||||
|
||||
/* SMRAM */
|
||||
dev->smram = smram_add();
|
||||
|
||||
device_add(&sis_5xxx_agp_device);
|
||||
dev->agpgart = device_add(&agpgart_device);
|
||||
|
||||
sis_5591_host_to_pci_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
const device_t sis_5591_h2p_device = {
|
||||
.name = "SiS 5591 Host to PCI bridge",
|
||||
.internal_name = "sis_5591_host_to_pci",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0x00,
|
||||
.init = sis_5591_host_to_pci_init,
|
||||
.close = sis_5591_host_to_pci_close,
|
||||
.reset = sis_5591_host_to_pci_reset,
|
||||
.available = NULL,
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user