From 015c6b115186c6d1555b4636c44e3be74da1a83b Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Tue, 16 Nov 2021 00:22:46 -0300 Subject: [PATCH 01/19] Jenkins: Trigger deferred failure when any build of any stage fails --- .ci/Jenkinsfile | 43 ++++++++++++++++++++++++++----------------- .ci/build.sh | 14 +++++++++++--- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index f60bf06d8..360b5e1b7 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -48,7 +48,7 @@ def saveArtifacts() { archiveArtifacts artifacts: "${env.JOB_BASE_NAME}-*" } -def anySuccess = false +def successCount = 0 def buildChain = [ '86Box': '86Box-Dev', @@ -75,32 +75,40 @@ pipeline { stages { stage('Build Windows') { + agent { + node { + label 'windows' + } + } + steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - node('windows') { - gitClone() - windowsBuild() - saveArtifacts() - } + gitClone() + windowsBuild() + saveArtifacts() script { - anySuccess = true + successCount += 1 } } } } stage('Build Linux') { + agent { + node { + label 'debian' + } + } + steps { catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - node('debian') { - gitClone() - unixBuild() - saveArtifacts() - } + gitClone() + unixBuild() + saveArtifacts() script { - anySuccess = true + successCount += 1 } } } @@ -110,11 +118,12 @@ pipeline { post { always { script { + /* Trigger next job is applicable. */ if (buildChain[env.JOB_BASE_NAME]) { def nextJob = buildChain[env.JOB_BASE_NAME] + /* Set next build number for the next job. */ try { - /* Set next build number for this job. */ def job = Jenkins.instance.getItem(nextJob) job.nextBuildNumber = env.BUILD_NUMBER as Integer job.saveNextBuildNumber() @@ -122,7 +131,7 @@ pipeline { println "[!] Could not set next build number for [$nextJob], make sure all required script approvals are in place" } - /* Trigger this job. */ + /* Trigger next job. */ build propagate: false, wait: false, job: nextJob, @@ -132,8 +141,8 @@ pipeline { ] } - if (!anySuccess) { - println "[!] Failing build because all build stages failed" + if (successCount < 2) { + println "[!] Failing build because a build stage failed" currentBuild.result = 'FAILURE' } diff --git a/.ci/build.sh b/.ci/build.sh index 63a758542..1fa2d29b6 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -122,6 +122,7 @@ build() { if [ -z "$job_name" ] then echo [!] Missing environment variables: received JOB_BASE_NAME=[$JOB_BASE_NAME] BUILD_TYPE=[$BUILD_TYPE] BUILD_NUMBER=[$BUILD_NUMBER] GIT_COMMIT=[$GIT_COMMIT] + job_status=1 return 1 fi @@ -145,11 +146,12 @@ build() { echo [-] Switching to MSYSTEM [$msys] cd "$cwd" CHERE_INVOKING=yes MSYSTEM="$msys" JOB_BASE_NAME="$JOB_BASE_NAME" BUILD_TYPE="$BUILD_TYPE" BUILD_NUMBER="$BUILD_NUMBER" GIT_COMMIT="$GIT_COMMIT" \ - bash -lc 'exec "'$0'" -b "'$arch'" '"$cmake_flags" && job_status=0 # make sure the main script exits cleanly on any success + bash -lc 'exec "'$0'" -b "'$arch'" '"$cmake_flags" return $? fi else echo [!] No MSYSTEM for architecture [$arch] + job_status=1 return 2 fi echo [-] Using MSYSTEM [$MSYSTEM] @@ -253,6 +255,7 @@ EOF if [ $? -gt 0 ] then echo [!] CMake failed with status [$status] + job_status=1 return 3 fi @@ -263,6 +266,7 @@ EOF if [ $status -gt 0 ] then echo [!] Make failed with status [$status] + job_status=1 return 4 fi @@ -273,6 +277,7 @@ EOF if [ ! -d "archive_tmp" ] then echo [!] Archive directory creation failed + job_status=1 return 5 fi @@ -337,6 +342,7 @@ EOF if [ $status -gt 0 ] then echo [!] Executable move failed with status [$status] + job_status=1 return 6 fi @@ -363,12 +369,12 @@ EOF if [ $status -gt 0 ] then echo [!] Artifact archive creation failed with status [$status] + job_status=1 return 7 fi # All good. echo [-] Build of [$job_name] [$build_type] [$build_qualifier] [$git_hash] for [$arch] with flags [$cmake_flags] successful - job_status=0 } tarball() { @@ -383,6 +389,7 @@ tarball() { if [ -z "$job_name" ] then echo [!] Missing environment variable: received JOB_BASE_NAME=[$JOB_BASE_NAME] + job_status=1 return 1 fi @@ -405,6 +412,7 @@ tarball() { if [ $? -gt 0 ] then echo [!] Tarball creation failed with status [$status] + job_status=1 return 2 fi @@ -415,7 +423,7 @@ tarball() { project=86Box cwd=$(pwd) first_build=1 -job_status=1 +job_status=0 # Parse arguments. single_build=0 From 3c95135d59bd1d98df9130d29f389b07640031ea Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 14:43:48 -0300 Subject: [PATCH 02/19] Adapt build script to the new new Jenkins pipeline --- .ci/build.sh | 726 +++++++++++++++++++-------------------------------- 1 file changed, 272 insertions(+), 454 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 1fa2d29b6..3df1623f2 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -33,6 +33,7 @@ # - TBD # +# Define common functions. alias is_windows='[ ! -z "$MSYSTEM" ]' alias is_mac='uname -s | grep -q Darwin' @@ -104,98 +105,140 @@ make_tar() { return $? } -build() { - # Create a line gap between builds. - [ $first_build -eq 0 ] && echo - first_build=0 +# Set common variables. +project=86Box +cwd=$(pwd) - # Set argument and environment variables. - local job_name=$JOB_BASE_NAME - local build_type=$BUILD_TYPE - local git_hash=$(echo $GIT_COMMIT | cut -c1-8) - local arch=$1 - shift - local cmake_flags=$* - local cmake_flags_extra= +# Parse arguments. +package_name= +arch= +tarball_name= +while [ $# -gt 0 ] +do + case $1 in + -b) + shift + package_name="$1" + shift + arch="$1" + shift + ;; - # Check if at least the job name was received. - if [ -z "$job_name" ] + -s) + shift + tarball_name="$1" + shift + ;; + + *) + break + ;; + esac +done +cmake_flags=$* +cmake_flags_extra= + +# Check if mandatory arguments were specified. +if [ -z "$package_name" -a -z "$tarball_name" ] +then + echo '[!] Usage: build.sh -b {package_name} {architecture} [cmake_flags...]' + echo ' build.sh -s {source_tarball_name}' + exit 100 +fi + +# Switch to the correct directory. +[ -e "build.sh" ] && cd .. + +# Make source tarball if requested. +if [ ! -z "$tarball_name" ] +then + echo [-] Making source tarball [$tarball_name] + + # Clean local tree of gitignored files. + git clean -dfX + + # Save current HEAD commit to VERSION. + git log --stat -1 > VERSION || rm -f VERSION + + # Archive source. + make_tar $tarball_name.tar + status=$? + + # Check if the archival succeeded. + if [ $status -ne 0 ] then - echo [!] Missing environment variables: received JOB_BASE_NAME=[$JOB_BASE_NAME] BUILD_TYPE=[$BUILD_TYPE] BUILD_NUMBER=[$BUILD_NUMBER] GIT_COMMIT=[$GIT_COMMIT] - job_status=1 - return 1 - fi - - echo [-] Building [$job_name] [$build_type] [$build_qualifier] [$git_hash] for [$arch] with flags [$cmake_flags] - - # Switch to the correct directory. - cd "$cwd" - [ -e "build.sh" ] && cd .. - - # Perform platform-specific setup. - if is_windows - then - # Switch into the correct MSYSTEM if required. - local msys=MINGW$arch - [ ! -d "/$msys" ] && local msys=CLANG$arch - if [ -d "/$msys" ] - then - if [ "$MSYSTEM" != "$msys" ] - then - # Call build with the correct MSYSTEM. - echo [-] Switching to MSYSTEM [$msys] - cd "$cwd" - CHERE_INVOKING=yes MSYSTEM="$msys" JOB_BASE_NAME="$JOB_BASE_NAME" BUILD_TYPE="$BUILD_TYPE" BUILD_NUMBER="$BUILD_NUMBER" GIT_COMMIT="$GIT_COMMIT" \ - bash -lc 'exec "'$0'" -b "'$arch'" '"$cmake_flags" - return $? - fi - else - echo [!] No MSYSTEM for architecture [$arch] - job_status=1 - return 2 - fi - echo [-] Using MSYSTEM [$MSYSTEM] - elif is_mac - then - # macOS lacks nproc, but sysctl can do the same job. - alias nproc='sysctl -n hw.logicalcpu' + echo [!] Tarball creation failed with status [$status] + exit 1 else - # Determine Debian architecture. - case $arch in - x86) local arch_deb="i386";; - x86_64) local arch_deb="amd64";; - arm32) local arch_deb="armhf";; - *) local arch_deb="$arch";; - esac + echo [-] Source tarball [$tarball_name] created successfully + [ -z "$package_name" ] && exit 0 + fi +fi - # Establish general and architecture-specific dependencies. - local pkgs="cmake git tar xz-utils dpkg-dev rpm" - if [ "$(dpkg --print-architecture)" = "$arch_deb" ] +echo [-] Building [$package_name] for [$arch] with flags [$cmake_flags] + +# Perform platform-specific setup. +if is_windows +then + # Switch into the correct MSYSTEM if required. + msys=MINGW$arch + [ ! -d "/$msys" ] && msys=CLANG$arch + if [ -d "/$msys" ] + then + if [ "$MSYSTEM" != "$msys" ] then - local pkgs="$pkgs build-essential" - else - sudo dpkg --add-architecture $arch_deb - local pkgs="$pkgs crossbuild-essential-$arch_deb" + # Call build with the correct MSYSTEM. + echo [-] Switching to MSYSTEM [$msys] + cd "$cwd" + CHERE_INVOKING=yes MSYSTEM="$msys" bash -lc 'exec "'"$0"'" -b "'"$package_name"'" "'"$arch"'" '"$cmake_flags" + exit $? fi - local libpkgs="" - local longest_libpkg=0 - for pkg in libc6-dev linux-libc-dev libopenal-dev libfreetype6-dev libsdl2-dev libpng-dev - do - local libpkgs="$libpkgs $pkg:$arch_deb" - local length=$(echo -n $pkg | sed 's/-dev$//g' | wc -c) - [ $length -gt $longest_libpkg ] && longest_libpkg=$length - done + else + echo [!] No MSYSTEM for architecture [$arch] + exit 2 + fi + echo [-] Using MSYSTEM [$MSYSTEM] +elif is_mac +then + # macOS lacks nproc, but sysctl can do the same job. + alias nproc='sysctl -n hw.logicalcpu' +else + # Determine Debian architecture. + case $arch in + x86) arch_deb="i386";; + x86_64) arch_deb="amd64";; + arm32) arch_deb="armhf";; + *) arch_deb="$arch";; + esac - # Determine GNU toolchain architecture. - case $arch in - x86) local arch_gnu="i686-linux-gnu";; - arm32) local arch_gnu="arm-linux-gnueabihf";; - arm64) local arch_gnu="aarch64-linux-gnu";; - *) local arch_gnu="$arch-linux-gnu";; - esac + # Establish general and architecture-specific dependencies. + pkgs="cmake git tar xz-utils dpkg-dev rpm" + if [ "$(dpkg --print-architecture)" = "$arch_deb" ] + then + pkgs="$pkgs build-essential" + else + sudo dpkg --add-architecture $arch_deb + pkgs="$pkgs crossbuild-essential-$arch_deb" + fi + libpkgs="" + longest_libpkg=0 + for pkg in libc6-dev linux-libc-dev libopenal-dev libfreetype6-dev libsdl2-dev libpng-dev + do + libpkgs="$libpkgs $pkg:$arch_deb" + length=$(echo -n $pkg | sed 's/-dev$//g' | wc -c) + [ $length -gt $longest_libpkg ] && longest_libpkg=$length + done - # Create CMake toolchain file. - cat << EOF > toolchain.cmake + # Determine GNU toolchain architecture. + case $arch in + x86) arch_gnu="i686-linux-gnu";; + arm32) arch_gnu="arm-linux-gnueabihf";; + arm64) arch_gnu="aarch64-linux-gnu";; + *) arch_gnu="$arch-linux-gnu";; + esac + + # Create CMake toolchain file. + cat << EOF > toolchain.cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR $arch) @@ -213,380 +256,155 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) EOF - local cmake_flags_extra="$cmake_flags_extra -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake" + cmake_flags_extra="$cmake_flags_extra -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake" - # Install or update dependencies. - echo [-] Installing dependencies through apt - sudo apt-get update - DEBIAN_FRONTEND=noninteractive sudo apt-get -y install $pkgs $libpkgs - sudo apt-get clean - fi - - # Clean workspace. - echo [-] Cleaning workspace - try_make clean > /dev/null - rm -rf build - find . \( -name Makefile -o -name CMakeCache.txt -o -name CMakeFiles \) -exec rm -rf "{}" \; 2> /dev/null - - # Determine available dynarec types for this architecture, and - # also specify ARCH right away to skip the arch_detect process. - case $arch in - # old dynarec available - 32 | x86) local cmake_flags_extra="$cmake_flags_extra -D ARCH=i386";; - 64 | x86_64) local cmake_flags_extra="$cmake_flags_extra -D ARCH=x86_64";; - # new dynarec only - ARM32 | arm32) local cmake_flags_extra="$cmake_flags_extra -D NEW_DYNAREC=ON -D ARCH=arm";; - ARM64 | arm64) local cmake_flags_extra="$cmake_flags_extra -D NEW_DYNAREC=ON -D ARCH=arm64";; - # no dynarec - *) local cmake_flags_extra="$cmake_flags_extra -D DYNAREC=OFF";; - esac - - # Determine additional CMake flags. - [ ! -z "$build_type" ] && local cmake_flags_extra="$cmake_flags_extra -D BUILD_TYPE=\"$build_type\"" - [ ! -z "$build_qualifier" ] && local cmake_flags_extra="$cmake_flags_extra -D EMU_BUILD=\"$build_qualifier\"" - [ ! -z "$build_number" ] && local cmake_flags_extra="$cmake_flags_extra -D EMU_BUILD_NUM=\"$build_number\"" - [ ! -z "$git_hash" ] && local cmake_flags_extra="$cmake_flags_extra -D EMU_GIT_HASH=\"$git_hash\"" - local cmake_flags_extra="$cmake_flags_extra -D EMU_COPYRIGHT_YEAR=\"$(date +%Y)\"" - - # Run CMake. - echo [-] Running CMake with flags [$cmake_flags $cmake_flags_extra] - eval cmake -G \"Unix Makefiles\" $cmake_flags $cmake_flags_extra . - local status=$? - if [ $? -gt 0 ] - then - echo [!] CMake failed with status [$status] - job_status=1 - return 3 - fi - - # Run actual build. - echo [-] Running build - try_make - local status=$? - if [ $status -gt 0 ] - then - echo [!] Make failed with status [$status] - job_status=1 - return 4 - fi - - # Create temporary directory for archival. - echo [-] Gathering archive files - rm -rf archive_tmp - mkdir archive_tmp - if [ ! -d "archive_tmp" ] - then - echo [!] Archive directory creation failed - job_status=1 - return 5 - fi - - # Archive the executable and its dependencies. - # The executable should always be archived last for the check after this block. - local status=$? - if is_windows - then - # Determine Program Files directory for Ghostscript and 7-Zip. - # Manual checks because MSYS is bad at passing the ProgramFiles variables. - local pf="/c/Program Files" - local sevenzip="$pf/7-Zip/7z.exe" - [ "$arch" = "32" -a -d "/c/Program Files (x86)" ] && pf="/c/Program Files (x86)" - - # Archive freetype from local MSYS installation. - .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a archive_tmp/freetype.dll - - # Archive Ghostscript DLL from local official distribution installation. - for gs in "$pf"/gs/gs*.*.* - do - cp -p "$gs"/bin/gsdll*.dll archive_tmp/ - done - - # Archive Discord Game SDK DLL from their CDN. - local discordarch= - [ "$arch" = "32" ] && local discordarch=x86 - [ "$arch" = "64" ] && local discordarch=x86_64 - if [ ! -z "$discordarch" ] - then - [ ! -e "discord_game_sdk.zip" ] && wget -qOdiscord_game_sdk.zip https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip - "$sevenzip" e -y -oarchive_tmp discord_game_sdk.zip lib/$discordarch/discord_game_sdk.dll - fi - - # Archive other DLLs from local directory. - cp -p /home/$project/dll$arch/* archive_tmp/ - - # Archive executable. - mv "$build_dir"/src/$project.exe archive_tmp/ - local status=$? - elif is_mac - then - # TBD - : - else - # Archive readme with library package versions. - echo Libraries used to compile this $arch build of $project: > archive_tmp/README - dpkg-query -f '${Package} ${Version}\n' -W $libpkgs | sed "s/-dev / /g" | while IFS=" " read pkg version - do - for i in $(seq $(expr $longest_libpkg - $(echo -n $pkg | wc -c))) - do - echo -n " " >> archive_tmp/README - done - echo $pkg $version >> archive_tmp/README - done - - # Archive executable. - mv "$build_dir"/src/$project archive_tmp/ - local status=$? - fi - - # Check if the executable move succeeded. - if [ $status -gt 0 ] - then - echo [!] Executable move failed with status [$status] - job_status=1 - return 6 - fi - - # Produce artifact archive. - echo [-] Creating artifact archive - cd archive_tmp - if is_windows - then - # Create zip. - "$sevenzip" a -y -mx9 "..\\$job_name-Windows-$arch$build_fn.zip" * - local status=$? - elif is_mac - then - # TBD - : - else - # Create binary tarball. - VERBOSE=1 make_tar ../$job_name-Linux-$arch$build_fn.tar - local status=$? - fi - cd .. - - # Check if the archival succeeded. - if [ $status -gt 0 ] - then - echo [!] Artifact archive creation failed with status [$status] - job_status=1 - return 7 - fi - - # All good. - echo [-] Build of [$job_name] [$build_type] [$build_qualifier] [$git_hash] for [$arch] with flags [$cmake_flags] successful -} - -tarball() { - # Create a line gap between builds. - [ $first_build -eq 0 ] && echo - first_build=0 - - # Set argument and environment variables. - local job_name=$JOB_BASE_NAME - - # Check if the job name was received. - if [ -z "$job_name" ] - then - echo [!] Missing environment variable: received JOB_BASE_NAME=[$JOB_BASE_NAME] - job_status=1 - return 1 - fi - - echo [-] Making source tarball for [$job_name] - - # Switch to the correct directory. - cd "$cwd" - [ -e "build.sh" ] && cd .. - - # Clean local tree of gitignored files. - git clean -dfX - - # Save current HEAD commit to VERSION. - git log -1 > VERSION || rm -f VERSION - - # Archive source. - make_tar $job_name-Source$build_fn.tar - - # Check if the archival succeeded. - if [ $? -gt 0 ] - then - echo [!] Tarball creation failed with status [$status] - job_status=1 - return 2 - fi - - echo [-] Source tarball for [$job_name] created successfully -} - -# Set common variables. -project=86Box -cwd=$(pwd) -first_build=1 -job_status=0 - -# Parse arguments. -single_build=0 -tarball=0 -args=0 -while [ $# -gt 0 ] -do - case $1 in - -b) - # Execute single build. - [ -z "$JOB_BASE_NAME" ] && JOB_BASE_NAME=$project-Custom - single_build=1 - shift - break - ;; - - -t) - # Create tarball. - [ -z "$JOB_BASE_NAME" ] && JOB_BASE_NAME=$project - tarball=1 - shift - ;; - - *) - # Allow for manually specifying Jenkins variables. - if [ $args -eq 0 ] - then - JOB_BASE_NAME=$1 - args=1 - elif [ $args -eq 1 ] - then - BUILD_TYPE=$1 - args=2 - elif [ $args -eq 2 ] - then - BUILD_NUMBER=$1 - args=3 - elif [ $args -eq 3 ] - then - GIT_COMMIT=$1 - args=4 - fi - shift - ;; - esac -done - -# Check if at least the job name was specified. -if [ -z "$JOB_BASE_NAME" ] -then - echo [!] Manual usage: build.sh [{job_name} [{build_type} [{build_number'|"'build_qualifier'"'} [git_hash]]]] [-t] [-b {architecture} [cmake_flags...]] - exit 100 + # Install or update dependencies. + echo [-] Installing dependencies through apt + sudo apt-get update + DEBIAN_FRONTEND=noninteractive sudo apt-get -y install $pkgs $libpkgs + sudo apt-get clean fi -# Generate build information. Note that variable names are case sensitive. -build_number=$BUILD_NUMBER -if echo $build_number | grep -q " " -then - # A full build qualifier was specified. - build_qualifier="$build_number" - build_fn="-"$(echo "$build_number" | rev | cut -f1 -d" " | rev | tr '\\/:*?"<>|' '_') - build_number= # no build number -elif [ ! -z "$build_number" ] -then - # A build number was specified. - build_qualifier="build $build_number" - build_fn="-b$build_number" - build_number=$(echo "$build_number" | sed "s/[^0-9]//g") # remove non-numeric characters from build number -else - # No build data was specified. - build_number= - build_qualifier= - build_fn= -fi +# Clean workspace. +echo [-] Cleaning workspace +try_make clean > /dev/null +rm -rf build +find . \( -name Makefile -o -name CMakeCache.txt -o -name CMakeFiles \) -exec rm -rf "{}" \; 2> /dev/null -# Make tarball if requested. -if [ $tarball -ne 0 ] -then - tarball - status=$? - [ $single_build -eq 0 ] && exit $status -fi - -# Run single build if requested. -if [ $single_build -ne 0 ] -then - build $* - exit $? -fi - -# Run builds according to the Jenkins job name. -case $JOB_BASE_NAME in - $project | $project-TestBuildPleaseIgnore*) - if is_windows - then - build 32 --preset=regular - build 64 --preset=regular - elif is_mac - then - build Universal --preset=regular - else - tarball - build x86 --preset=regular - build x86_64 --preset=regular - build arm32 --preset=regular - build arm64 --preset=regular - fi - ;; - - $project-Debug) - if is_windows - then - build 32 --preset=debug - build 64 --preset=debug - elif is_mac - then - build Universal --preset=debug - else - build x86 --preset=debug - build x86_64 --preset=debug - build arm32 --preset=debug - build arm64 --preset=debug - fi - ;; - - $project-Dev) - if is_windows - then - build 32 --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - build 64 --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - elif is_mac - then - build Universal --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - else - build x86 --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - build x86_64 --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - build arm32 --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - build arm64 --preset=experimental -D NEW_DYNAREC=ON -D VNC=OFF - fi - ;; - - $project-DevODR) - if is_windows - then - build 32 --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - build 64 --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - elif is_mac - then - build Universal --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - else - build x86 --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - build x86_64 --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - build arm32 --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - build arm64 --preset=experimental -D NEW_DYNAREC=OFF -D VNC=OFF - fi - ;; - - *) - echo [!] Unknown job name $JOB_BASE_NAME - exit 1 - ;; +# Determine ARCH to skip the arch_detect process. +case $arch in + 32 | x86) cmake_flags_extra="$cmake_flags_extra -D ARCH=i386";; + 64 | x86_64) cmake_flags_extra="$cmake_flags_extra -D ARCH=x86_64";; + ARM32 | arm32) cmake_flags_extra="$cmake_flags_extra -D ARCH=arm";; + ARM64 | arm64) cmake_flags_extra="$cmake_flags_extra -D ARCH=arm64";; + *) cmake_flags_extra="$cmake_flags_extra -D ARCH=$arch";; esac -echo -echo [-] Exiting with status [$job_status] -exit $job_status +# Add git hash and copyright year. +git_hash="$(git rev-parse --short HEAD 2> /dev/null)" +[ ! -z "$git_hash" ] && cmake_flags_extra="$cmake_flags_extra -D EMU_GIT_HASH=\"$git_hash\"" +cmake_flags_extra="$cmake_flags_extra -D EMU_COPYRIGHT_YEAR=\"$(date +%Y)\"" + +# Run CMake. +echo [-] Running CMake with flags [$cmake_flags $cmake_flags_extra] +eval cmake -G \"Unix Makefiles\" $cmake_flags $cmake_flags_extra . +status=$? +if [ $status -ne 0 ] +then + echo [!] CMake failed with status [$status] + exit 3 +fi + +# Run actual build. +echo [-] Running build +try_make +status=$? +if [ $status -ne 0 ] +then + echo [!] Make failed with status [$status] + exit 4 +fi + +# Create temporary directory for archival. +echo [-] Gathering archive files +rm -rf archive_tmp +mkdir archive_tmp +if [ ! -d "archive_tmp" ] +then + echo [!] Archive directory creation failed + exit 5 +fi + +# Archive the executable and its dependencies. +# The executable should always be archived last for the check after this block. +status=0 +if is_windows +then + # Determine Program Files directory for Ghostscript and 7-Zip. + # Manual checks because MSYS is bad at passing the ProgramFiles variables. + pf="/c/Program Files" + sevenzip="$pf/7-Zip/7z.exe" + [ "$arch" = "32" -a -d "/c/Program Files (x86)" ] && pf="/c/Program Files (x86)" + + # Archive freetype from local MSYS installation. + .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a archive_tmp/freetype.dll + + # Archive Ghostscript DLL from local official distribution installation. + for gs in "$pf"/gs/gs*.*.* + do + cp -p "$gs"/bin/gsdll*.dll archive_tmp/ + done + + # Archive Discord Game SDK DLL from their CDN. + discordarch= + [ "$arch" = "32" ] && discordarch=x86 + [ "$arch" = "64" ] && discordarch=x86_64 + if [ ! -z "$discordarch" ] + then + [ ! -e "discord_game_sdk.zip" ] && wget -qOdiscord_game_sdk.zip https://dl-game-sdk.discordapp.net/2.5.6/discord_game_sdk.zip + "$sevenzip" e -y -oarchive_tmp discord_game_sdk.zip lib/$discordarch/discord_game_sdk.dll + fi + + # Archive other DLLs from local directory. + cp -p /home/$project/dll$arch/* archive_tmp/ + + # Archive executable. + mv "$build_dir"/src/$project.exe archive_tmp/ + status=$? +elif is_mac +then + # TBD + : +else + # Archive readme with library package versions. + echo Libraries used to compile this $arch build of $project: > archive_tmp/README + dpkg-query -f '${Package} ${Version}\n' -W $libpkgs | sed "s/-dev / /g" | while IFS=" " read pkg version + do + for i in $(seq $(expr $longest_libpkg - $(echo -n $pkg | wc -c))) + do + echo -n " " >> archive_tmp/README + done + echo $pkg $version >> archive_tmp/README + done + + # Archive executable. + mv "$build_dir"/src/$project archive_tmp/ + status=$? +fi + +# Check if the executable move succeeded. +if [ $status -ne 0 ] +then + echo [!] Executable move failed with status [$status] + exit 6 +fi + +# Produce artifact archive. +echo [-] Creating artifact archive +cd archive_tmp +if is_windows +then + # Create zip. + "$sevenzip" a -y -mx9 "..\\$package_name.zip" * + status=$? +elif is_mac +then + # TBD + : +else + # Create binary tarball. + VERBOSE=1 make_tar ../$package_name.tar + status=$? +fi +cd .. + +# Check if the archival succeeded. +if [ $status -ne 0 ] +then + echo [!] Artifact archive creation failed with status [$status] + exit 7 +fi + +# All good. +echo [-] Build of [$package_name] for [$arch] with flags [$cmake_flags] successful +exit 0 From 767b09129cd731cf1bb4ce8c1c6e6823db87b1b4 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 15:09:21 -0300 Subject: [PATCH 03/19] Fix build script --- .ci/build.sh | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 3df1623f2..5bb97280d 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -113,6 +113,7 @@ cwd=$(pwd) package_name= arch= tarball_name= +cmake_flags= while [ $# -gt 0 ] do case $1 in @@ -131,11 +132,22 @@ do ;; *) - break + if echo $1 | grep -q " " + then + cmake_flag="\"$1\"" + else + cmake_flag="$1" + fi + if [ -z "$cmake_flags" ] + then + cmake_flags="$cmake_flag" + else + cmake_flags="$cmake_flags $cmake_flag" + fi + shift ;; esac done -cmake_flags=$* cmake_flags_extra= # Check if mandatory arguments were specified. @@ -277,13 +289,13 @@ case $arch in 64 | x86_64) cmake_flags_extra="$cmake_flags_extra -D ARCH=x86_64";; ARM32 | arm32) cmake_flags_extra="$cmake_flags_extra -D ARCH=arm";; ARM64 | arm64) cmake_flags_extra="$cmake_flags_extra -D ARCH=arm64";; - *) cmake_flags_extra="$cmake_flags_extra -D ARCH=$arch";; + *) cmake_flags_extra="$cmake_flags_extra -D \"ARCH=$arch\"";; esac # Add git hash and copyright year. -git_hash="$(git rev-parse --short HEAD 2> /dev/null)" -[ ! -z "$git_hash" ] && cmake_flags_extra="$cmake_flags_extra -D EMU_GIT_HASH=\"$git_hash\"" -cmake_flags_extra="$cmake_flags_extra -D EMU_COPYRIGHT_YEAR=\"$(date +%Y)\"" +git_hash=$(git rev-parse --short HEAD 2> /dev/null) +[ ! -z "$git_hash" ] && cmake_flags_extra="$cmake_flags_extra -D \"EMU_GIT_HASH=$git_hash\"" +cmake_flags_extra="$cmake_flags_extra -D \"EMU_COPYRIGHT_YEAR=$(date +%Y)\"" # Run CMake. echo [-] Running CMake with flags [$cmake_flags $cmake_flags_extra] From fbb7cecce038b62626cb15ef163c3d7c464c09a2 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 17:46:17 -0300 Subject: [PATCH 04/19] Add target to build script gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 641660680..992c9ebb2 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ Makefile /*.tar /*.tar.* /VERSION +/target # Visual Studio Code /.vs From daa8f6731c6f294d732e201564a9d094f8cf06d0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 18:01:15 -0300 Subject: [PATCH 05/19] More improvements to the build script --- .ci/build.sh | 11 +++++++---- .gitignore | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 5bb97280d..f3f8de39c 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -159,7 +159,10 @@ then fi # Switch to the correct directory. -[ -e "build.sh" ] && cd .. +while [ ! -e ".ci/build.sh" ] +do + cd .. +done # Make source tarball if requested. if [ ! -z "$tarball_name" ] @@ -173,7 +176,7 @@ then git log --stat -1 > VERSION || rm -f VERSION # Archive source. - make_tar $tarball_name.tar + make_tar "$cwd/$tarball_name.tar" status=$? # Check if the archival succeeded. @@ -397,7 +400,7 @@ cd archive_tmp if is_windows then # Create zip. - "$sevenzip" a -y -mx9 "..\\$package_name.zip" * + "$sevenzip" a -y -mx9 "$(cygpath -w "$cwd")\\$package_name.zip" * status=$? elif is_mac then @@ -405,7 +408,7 @@ then : else # Create binary tarball. - VERBOSE=1 make_tar ../$package_name.tar + VERBOSE=1 make_tar "$cwd/$package_name.tar" status=$? fi cd .. diff --git a/.gitignore b/.gitignore index 992c9ebb2..3d1cf31fa 100644 --- a/.gitignore +++ b/.gitignore @@ -29,11 +29,11 @@ Makefile # Build scripts /archive_tmp /static2dll.* -/*.zip -/*.tar -/*.tar.* /VERSION /target +*.zip +*.tar +*.tar.* # Visual Studio Code /.vs From f15f2c96e98298b4894826c029ea9a157b78d6c0 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 18:11:10 -0300 Subject: [PATCH 06/19] Jenkins: Recreate output directory if it was deleted --- .ci/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ci/build.sh b/.ci/build.sh index f3f8de39c..99b29f2ae 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -172,6 +172,9 @@ then # Clean local tree of gitignored files. git clean -dfX + # Recreate output directory if it was removed by git clean. + [ ! -d "$cwd" ] && mkdir -p "$cwd" + # Save current HEAD commit to VERSION. git log --stat -1 > VERSION || rm -f VERSION From 09529eaf2fa8624be4fb1483e997fa9d292cc0ed Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 18:16:23 -0300 Subject: [PATCH 07/19] Remove target from gitignore as it was causing problems --- .ci/build.sh | 3 --- .gitignore | 1 - 2 files changed, 4 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 99b29f2ae..f3f8de39c 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -172,9 +172,6 @@ then # Clean local tree of gitignored files. git clean -dfX - # Recreate output directory if it was removed by git clean. - [ ! -d "$cwd" ] && mkdir -p "$cwd" - # Save current HEAD commit to VERSION. git log --stat -1 > VERSION || rm -f VERSION diff --git a/.gitignore b/.gitignore index 3d1cf31fa..35f3dc8af 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ Makefile /archive_tmp /static2dll.* /VERSION -/target *.zip *.tar *.tar.* From 4e337a3f1fc8a1a7ae7353761cdabd5c0199b0a7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 18:45:20 -0300 Subject: [PATCH 08/19] Actually fix the tar deletion issue --- .ci/build.sh | 8 +++++++- .gitignore | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index f3f8de39c..35746cff2 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -172,20 +172,26 @@ then # Clean local tree of gitignored files. git clean -dfX + # Recreate output directory if it was removed by git clean. + [ ! -d "$cwd" ] && mkdir -p "$cwd" + # Save current HEAD commit to VERSION. git log --stat -1 > VERSION || rm -f VERSION # Archive source. - make_tar "$cwd/$tarball_name.tar" + rm -f "$tarball_name.tar*" + make_tar "$tarball_name.tar" status=$? # Check if the archival succeeded. if [ $status -ne 0 ] then echo [!] Tarball creation failed with status [$status] + rm -f "$tarball_name.tar*" exit 1 else echo [-] Source tarball [$tarball_name] created successfully + mv "$tarball_name.tar*" "$cwd/" [ -z "$package_name" ] && exit 0 fi fi diff --git a/.gitignore b/.gitignore index 35f3dc8af..3d1cf31fa 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ Makefile /archive_tmp /static2dll.* /VERSION +/target *.zip *.tar *.tar.* From 155104467e459e6cf7993b0a08625480fba95c08 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 17 Nov 2021 20:22:30 -0300 Subject: [PATCH 09/19] Fix build script wildcards --- .ci/build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 35746cff2..a8d517be0 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -179,7 +179,7 @@ then git log --stat -1 > VERSION || rm -f VERSION # Archive source. - rm -f "$tarball_name.tar*" + rm -f "$tarball_name.tar"* make_tar "$tarball_name.tar" status=$? @@ -187,11 +187,11 @@ then if [ $status -ne 0 ] then echo [!] Tarball creation failed with status [$status] - rm -f "$tarball_name.tar*" + rm -f "$tarball_name.tar"* exit 1 else echo [-] Source tarball [$tarball_name] created successfully - mv "$tarball_name.tar*" "$cwd/" + mv "$tarball_name.tar"* "$cwd/" [ -z "$package_name" ] && exit 0 fi fi From b0d37fc63ae9eb70bff1e7ae25825e18d93760ed Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 18 Nov 2021 19:17:47 -0300 Subject: [PATCH 10/19] Remove target from gitignore as it's no longer used --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3d1cf31fa..35f3dc8af 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ Makefile /archive_tmp /static2dll.* /VERSION -/target *.zip *.tar *.tar.* From e86ba44b7d18afdb11059239c66e5964fe39d5f9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 18 Nov 2021 19:22:19 -0300 Subject: [PATCH 11/19] Minor build script improvements --- .ci/build.sh | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index a8d517be0..690565a56 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -151,18 +151,15 @@ done cmake_flags_extra= # Check if mandatory arguments were specified. -if [ -z "$package_name" -a -z "$tarball_name" ] +if [ -z "$package_name" -a -z "$tarball_name" ] || [ ! -z "$package_name" -a -z "$arch" ] then echo '[!] Usage: build.sh -b {package_name} {architecture} [cmake_flags...]' echo ' build.sh -s {source_tarball_name}' exit 100 fi -# Switch to the correct directory. -while [ ! -e ".ci/build.sh" ] -do - cd .. -done +# Switch to the repository root directory. +cd "$(dirname "$0")/.." # Make source tarball if requested. if [ ! -z "$tarball_name" ] @@ -172,26 +169,23 @@ then # Clean local tree of gitignored files. git clean -dfX - # Recreate output directory if it was removed by git clean. + # Recreate working directory if it was removed by git clean. [ ! -d "$cwd" ] && mkdir -p "$cwd" # Save current HEAD commit to VERSION. git log --stat -1 > VERSION || rm -f VERSION # Archive source. - rm -f "$tarball_name.tar"* - make_tar "$tarball_name.tar" + make_tar "$cwd/$tarball_name.tar" status=$? # Check if the archival succeeded. if [ $status -ne 0 ] then echo [!] Tarball creation failed with status [$status] - rm -f "$tarball_name.tar"* exit 1 else echo [-] Source tarball [$tarball_name] created successfully - mv "$tarball_name.tar"* "$cwd/" [ -z "$package_name" ] && exit 0 fi fi From cae0ed730b4e66dfc06093c998bf0c45ef6a5114 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 18 Nov 2021 19:46:23 -0300 Subject: [PATCH 12/19] win_dynld: Add GetLastError() to failure log --- src/win/win_dynld.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 41942ba61..96ed1666e 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -55,7 +55,7 @@ dynld_module(const char *name, dllimp_t *table) /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found!\n", name); + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); return(NULL); } @@ -74,6 +74,7 @@ dynld_module(const char *name, dllimp_t *table) } /* All good. */ + pclog("loaded %s\n", name); return((void *)h); } From d5efe6cab5c7ba621e25304bbfcefa78a7d0684a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 18 Nov 2021 19:47:57 -0300 Subject: [PATCH 13/19] win_dynld: Add GetLastError() to GetProcAddress as well --- src/win/win_dynld.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 96ed1666e..c0f9b4488 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -63,8 +63,8 @@ dynld_module(const char *name, dllimp_t *table) for (imp=table; imp->name!=NULL; imp++) { func = GetProcAddress(h, imp->name); if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found!\n", - name, imp->name); + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); FreeLibrary(h); return(NULL); } From e29dafa17a56f58c3d91b16ecd23618b88ca2de0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 18 Nov 2021 23:58:04 +0100 Subject: [PATCH 14/19] Changes list 5: Added the AT&T 2xc498 Precision RAMDAC. Added 1MB configurations to the Cirrus Logic GD5434 as well as re-organized the memory size options of the other Cirrus cards. Separated the et4000w32/i blitter from the standard et4000w32p blitter and properly implemented the X/Y Count route. Added several Diamond Cirrus cards. Added Number Nine S3 cards (868 and 968-based). Fixed the WD90c30 1MB modes. Re-organized the video card names. --- src/include/86box/vid_svga.h | 3 + src/include/86box/video.h | 10 +- src/video/CMakeLists.txt | 2 +- src/video/vid_att2xc498_ramdac.c | 186 ++++++ src/video/vid_cl54xx.c | 476 +++++++++---- src/video/vid_et4000w32.c | 1063 ++++++++++++++++++++++-------- src/video/vid_paradise.c | 378 +++++++---- src/video/vid_s3.c | 193 ++++-- src/video/vid_table.c | 24 +- src/win/Makefile.mingw | 1 + 10 files changed, 1747 insertions(+), 589 deletions(-) create mode 100644 src/video/vid_att2xc498_ramdac.c diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 9022a4a86..4380e041b 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -226,6 +226,8 @@ extern void ati68860_hwcursor_draw(svga_t *svga, int displine); extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); +extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga); +extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga); extern float av9194_getclock(int clock, void *p); extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga); @@ -278,6 +280,7 @@ extern const device_t ati68860_ramdac_device; extern const device_t att490_ramdac_device; extern const device_t att491_ramdac_device; extern const device_t att492_ramdac_device; +extern const device_t att498_ramdac_device; extern const device_t av9194_device; extern const device_t bt484_ramdac_device; extern const device_t att20c504_ramdac_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 166770154..3e0c74ce9 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -226,24 +226,28 @@ extern const device_t compaq_ati28800_device; extern const device_t ati28800_wonderxl24_device; #endif -/* Cirrus Logic CL-GD 54xx */ +/* Cirrus Logic GD54xx */ extern const device_t gd5401_isa_device; extern const device_t gd5402_isa_device; extern const device_t gd5402_onboard_device; extern const device_t gd5420_isa_device; extern const device_t gd5422_isa_device; extern const device_t gd5424_vlb_device; +extern const device_t gd5426_isa_device; +extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device; extern const device_t gd5426_vlb_device; extern const device_t gd5426_onboard_device; extern const device_t gd5428_isa_device; extern const device_t gd5428_vlb_device; +extern const device_t gd5428_diamond_speedstar_pro_b1_vlb_device; extern const device_t gd5428_mca_device; extern const device_t gd5428_onboard_device; extern const device_t gd5429_isa_device; extern const device_t gd5429_vlb_device; -extern const device_t gd5430_vlb_device; +extern const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device; extern const device_t gd5430_pci_device; extern const device_t gd5434_isa_device; +extern const device_t gd5434_diamond_speedstar_64_a3_isa_device; extern const device_t gd5434_onboard_pci_device; extern const device_t gd5434_vlb_device; extern const device_t gd5434_pci_device; @@ -369,6 +373,7 @@ extern const device_t s3_mirocrystal_20sv_964_pci_device; extern const device_t s3_mirocrystal_20sd_864_vlb_device; extern const device_t s3_phoenix_vision864_pci_device; extern const device_t s3_phoenix_vision864_vlb_device; +extern const device_t s3_9fx_531_pci_device; extern const device_t s3_phoenix_vision868_pci_device; extern const device_t s3_phoenix_vision868_vlb_device; extern const device_t s3_diamond_stealth64_pci_device; @@ -376,6 +381,7 @@ extern const device_t s3_diamond_stealth64_vlb_device; extern const device_t s3_diamond_stealth64_964_pci_device; extern const device_t s3_diamond_stealth64_964_vlb_device; extern const device_t s3_mirovideo_40sv_ergo_968_pci_device; +extern const device_t s3_9fx_771_pci_device; extern const device_t s3_phoenix_vision968_pci_device; extern const device_t s3_phoenix_vision968_vlb_device; extern const device_t s3_spea_mercury_p64v_pci_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 0c3befa62..b42bd21cb 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -24,7 +24,7 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c - vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c) + vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c) if(MGA) target_compile_definitions(vid PRIVATE USE_MGA) diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c new file mode 100644 index 000000000..747ffe75c --- /dev/null +++ b/src/video/vid_att2xc498_ramdac.c @@ -0,0 +1,186 @@ +/* + * 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 a AT&T 2xc498 RAMDAC. + * + * + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> + + +typedef struct +{ + int type; + int state; + int loop; + uint8_t ctrl; +} att498_ramdac_t; + +static void +att498_ramdac_control(uint8_t val, void *p, svga_t *svga) +{ + att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + ramdac->ctrl = val; + + if (val == 0xff) + return; + + switch ((ramdac->ctrl >> 4) & 0x0f) { + default: + svga->bpp = 8; + break; + case 1: + if (ramdac->ctrl & 4) + svga->bpp = 15; + else + svga->bpp = 8; + break; + case 3: + case 6: + svga->bpp = 16; + break; + case 5: + case 7: + svga->bpp = 32; + break; + case 0x0e: + svga->bpp = 24; + break; + } + + svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); + svga_recalctimings(svga); +} + +void +att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) +{ + att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + uint8_t rs = (addr & 0x03); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + ramdac->state = 0; + break; + case 0x02: + switch (ramdac->state) { + case 4: + att498_ramdac_control(val, ramdac, svga); + break; + default: + svga_out(addr, val, svga); + break; + } + break; + case 0x06: + att498_ramdac_control(val, ramdac, svga); + break; + } +} + + +uint8_t +att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) +{ + att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + temp = svga_in(addr, svga); + ramdac->state = 0; + break; + case 0x02: + switch (ramdac->state) { + case 4: + temp = ramdac->ctrl; + ramdac->state++; + break; + case 5: + temp = 0x84; + ramdac->state++; + break; + case 6: + temp = ramdac->ctrl; + ramdac->state = 0; + break; + default: + temp = svga_in(addr, svga); + ramdac->state++; + break; + } + break; + case 0x06: + temp = ramdac->ctrl; + ramdac->state = 0; + break; + } + + return temp; +} + + +static void * +att498_ramdac_init(const device_t *info) +{ + att498_ramdac_t *ramdac = (att498_ramdac_t *) malloc(sizeof(att498_ramdac_t)); + memset(ramdac, 0, sizeof(att498_ramdac_t)); + + ramdac->type = info->local; + + return ramdac; +} + + +static void +att498_ramdac_close(void *priv) +{ + att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; + + if (ramdac) + free(ramdac); +} + + +const device_t att498_ramdac_device = +{ + "AT&T 22c498 RAMDAC", + 0, 0, + att498_ramdac_init, att498_ramdac_close, + NULL, { NULL }, NULL, NULL +}; \ No newline at end of file diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 7ba2efb3c..3055de90a 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -45,13 +45,15 @@ #define BIOS_GD5402_ONBOARD_PATH "roms/machines/cbm_sl386sx25/c000.rom" #define BIOS_GD5420_PATH "roms/video/cirruslogic/5420.vbi" #define BIOS_GD5422_PATH "roms/video/cirruslogic/cl5422.bin" -#define BIOS_GD5426_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" +#define BIOS_GD5426_DIAMOND_A1_ISA_PATH "roms/video/cirruslogic/diamond5426.bin" +#define BIOS_GD5428_DIAMOND_B1_VLB_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" #define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin" #define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM" #define BIOS_GD5428_PATH "roms/video/cirruslogic/vlbusjapan.BIN" #define BIOS_GD5429_PATH "roms/video/cirruslogic/5429.vbi" -#define BIOS_GD5430_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin" -#define BIOS_GD5430_PCI_PATH "roms/video/cirruslogic/pci.bin" +#define BIOS_GD5430_DIAMOND_A8_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin" +#define BIOS_GD5430_PATH "roms/video/cirruslogic/pci.bin" +#define BIOS_GD5434_DIAMOND_A3_ISA_PATH "roms/video/cirruslogic/Diamond Multimedia SpeedStar 64 v2.02 EPROM Backup from ST M27C256B-12F1.BIN" #define BIOS_GD5434_PATH "roms/video/cirruslogic/gd5434.bin" #define BIOS_GD5436_PATH "roms/video/cirruslogic/5436.vbi" #define BIOS_GD5440_PATH "roms/video/cirruslogic/BIOS.BIN" @@ -1209,11 +1211,62 @@ gd54xx_in(uint16_t addr, void *p) ret |= 0x80; } break; + case 0x0a: /*Scratch Pad 1 (Memory size for 5402/542x)*/ + ret = svga->seqregs[0x0a] & ~0x1a; + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5402) { + ret |= 0x01; /*512K of memory*/ + } else if (svga->crtc[0x27] > CIRRUS_ID_CLGD5402) { + switch (gd54xx->vram_size >> 10) { + case 512: + ret |= 0x08; + break; + case 1024: + ret |= 0x10; + break; + case 2048: + ret |= 0x18; + break; + } + } + break; case 0x0b: case 0x0c: case 0x0d: case 0x0e: ret = gd54xx->vclk_n[svga->seqaddr-0x0b]; break; + case 0x0f: /*DRAM control*/ + ret = svga->seqregs[0x0f] & ~0x98; + switch (gd54xx->vram_size >> 10) { + case 512: + ret |= 0x08; /*16-bit DRAM data bus width*/ + break; + case 1024: + ret |= 0x10; /*32-bit DRAM data bus width for 1M of memory*/ + break; + case 2048: + ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18; /*32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width for 2M of memory*/ + break; + case 4096: + ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ + break; + } + break; + case 0x15: /*Scratch Pad 3 (Memory size for 543x)*/ + ret = svga->seqregs[0x15] & ~0x0f; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { + switch (gd54xx->vram_size >> 20) { + case 1: + ret |= 0x02; + break; + case 2: + ret |= 0x03; + break; + case 4: + ret |= 0x04; + break; + } + } + break; case 0x17: - ret = svga->gdcreg[0x17] & ~(7 << 3); + ret = svga->seqregs[0x17] & ~(7 << 3); if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { if (gd54xx->vlb) @@ -3844,17 +3897,29 @@ static void case CIRRUS_ID_CLGD5426: if (info->local & 0x200) romfn = NULL; - else - romfn = BIOS_GD5426_PATH; + else { + if (info->local & 0x100) + romfn = BIOS_GD5426_DIAMOND_A1_ISA_PATH; + else { + if (gd54xx->vlb) + romfn = BIOS_GD5428_PATH; + else + romfn = BIOS_GD5428_ISA_PATH; + } + } break; case CIRRUS_ID_CLGD5428: - if (gd54xx->vlb) - romfn = BIOS_GD5428_PATH; - else if (gd54xx->mca) - romfn = BIOS_GD5428_MCA_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; + if (info->local & 0x100) + romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH; + else { + if (gd54xx->vlb) + romfn = BIOS_GD5428_PATH; + else if (gd54xx->mca) + romfn = BIOS_GD5428_MCA_PATH; + else + romfn = BIOS_GD5428_ISA_PATH; + } break; case CIRRUS_ID_CLGD5429: @@ -3873,8 +3938,12 @@ static void if (info->local & 0x200) { romfn = NULL; gd54xx->has_bios = 0; - } else - romfn = BIOS_GD5434_PATH; + } else { + if (info->local & 0x100) + romfn = BIOS_GD5434_DIAMOND_A3_ISA_PATH; + else + romfn = BIOS_GD5434_PATH; + } break; case CIRRUS_ID_CLGD5436: @@ -3896,9 +3965,9 @@ static void romfn = NULL; gd54xx->has_bios = 0; } else if (gd54xx->pci) - romfn = BIOS_GD5430_PCI_PATH; + romfn = BIOS_GD5430_PATH; else - romfn = BIOS_GD5430_VLB_PATH; + romfn = BIOS_GD5430_DIAMOND_A8_VLB_PATH; } break; @@ -3915,23 +3984,24 @@ static void } if (info->flags & DEVICE_MCA) { - vram = 1; - gd54xx->vram_size = 1 << 20; + vram = 1024; + gd54xx->vram_size = vram << 10; } else { - if (id >= CIRRUS_ID_CLGD5420) { + if (id <= CIRRUS_ID_CLGD5428) { if ((id == CIRRUS_ID_CLGD5426) && (info->local & 0x200)) - vram = 1; + vram = 1024; + else if (id == CIRRUS_ID_CLGD5401) + vram = 256; + else if (id == CIRRUS_ID_CLGD5402) + vram = 512; else vram = device_get_config_int("memory"); - } else - vram = 0; - - if (vram) - gd54xx->vram_size = vram << 20; - else - gd54xx->vram_size = 1 << 19; + gd54xx->vram_size = vram << 10; + } else { + vram = device_get_config_int("memory"); + gd54xx->vram_size = vram << 20; + } } - gd54xx->vram_mask = gd54xx->vram_size - 1; if (romfn) @@ -3955,8 +4025,8 @@ static void } svga->vblank_start = gd54xx_vblank_start; svga->ven_write = gd54xx_write_modes45; - if (vram <= 1) - svga->decode_mask = gd54xx->vram_mask; + if ((vram == 1) || (vram >= 256 && vram <= 1024)) + svga->decode_mask = gd54xx->vram_mask; if (gd54xx->bit32) { mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); @@ -4039,6 +4109,7 @@ static void svga->crtc[0x27] = id; svga->seqregs[6] = 0x0f; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) gd54xx->unlocked = 1; @@ -4089,9 +4160,9 @@ gd5422_available(void) } static int -gd5426_available(void) +gd5426_diamond_a1_available(void) { - return rom_present(BIOS_GD5426_PATH); + return rom_present(BIOS_GD5426_DIAMOND_A1_ISA_PATH); } static int @@ -4100,6 +4171,12 @@ gd5428_available(void) return rom_present(BIOS_GD5428_PATH); } +static int +gd5428_diamond_b1_available(void) +{ + return rom_present(BIOS_GD5428_DIAMOND_B1_VLB_PATH); +} + static int gd5428_isa_available(void) { @@ -4119,15 +4196,15 @@ gd5429_available(void) } static int -gd5430_vlb_available(void) +gd5430_diamond_a8_available(void) { - return rom_present(BIOS_GD5430_VLB_PATH); + return rom_present(BIOS_GD5430_DIAMOND_A8_VLB_PATH); } static int -gd5430_pci_available(void) +gd5430_available(void) { - return rom_present(BIOS_GD5430_PCI_PATH); + return rom_present(BIOS_GD5430_PATH); } static int @@ -4136,6 +4213,12 @@ gd5434_available(void) return rom_present(BIOS_GD5434_PATH); } +static int +gd5434_diamond_a3_available(void) +{ + return rom_present(BIOS_GD5434_DIAMOND_A3_ISA_PATH); +} + static int gd5436_available(void) { @@ -4199,28 +4282,96 @@ gd54xx_force_redraw(void *p) gd54xx->svga.fullchange = changeframecount; } -static const device_config_t gd5422_config[] = +static const device_config_t gd542x_config[] = { { - "memory","Memory size",CONFIG_SELECTION,"", 1, "", { 0 }, + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = { { - "512 KB", 0 + .description = "512 KB", + .value = 512 }, { - "1 MB", 1 + .description = "1 MB", + .value = 1024 }, { - "" + .description = "" } }, + .default_int = 512 }, { - "", "", -1 + .type = -1 } }; -static const device_config_t gd5428_config[] = +static const device_config_t gd5426_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "" + } + }, + .default_int = 2048 + }, + { + .type = -1 + } +}; + +static const device_config_t gd5428_onboard_config[] = +{ + { + .name = "memory", + .description = "Onboard memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "" + } + }, + .default_int = 2048 + }, + { + .type = -1 + } +}; + +static const device_config_t gd5429_config[] = { { .name = "memory", @@ -4247,38 +4398,11 @@ static const device_config_t gd5428_config[] = } }; -static const device_config_t gd5428_onboard_config[] = -{ - { - .name = "memory", - .description = "Onboard Video RAM size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - static const device_config_t gd5440_onboard_config[] = { { .name = "memory", - .description = "Video memory size", + .description = "Onboard memory size", .type = CONFIG_SELECTION, .selection = { @@ -4302,6 +4426,68 @@ static const device_config_t gd5440_onboard_config[] = }; static const device_config_t gd5434_config[] = +{ + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; + +static const device_config_t gd5434_onboard_config[] = +{ + { + .name = "memory", + .description = "Onboard memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } +}; + +static const device_config_t gd5480_config[] = { { .name = "memory", @@ -4330,7 +4516,7 @@ static const device_config_t gd5434_config[] = const device_t gd5401_isa_device = { - "Cirrus Logic GD-5401 (ACUMOS AVGA1)", + "Cirrus Logic GD5401 (ISA) (ACUMOS AVGA1)", DEVICE_ISA, CIRRUS_ID_CLGD5401, gd54xx_init, gd54xx_close, @@ -4343,7 +4529,7 @@ const device_t gd5401_isa_device = const device_t gd5402_isa_device = { - "Cirrus Logic GD-5402 (ACUMOS AVGA2)", + "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2)", DEVICE_ISA, CIRRUS_ID_CLGD5402, gd54xx_init, gd54xx_close, @@ -4356,7 +4542,7 @@ const device_t gd5402_isa_device = const device_t gd5402_onboard_device = { - "Cirrus Logic GD-5402 (ACUMOS AVGA2) (On-Board)", + "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2) (On-Board)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5402 | 0x200, gd54xx_init, gd54xx_close, @@ -4369,7 +4555,7 @@ const device_t gd5402_onboard_device = const device_t gd5420_isa_device = { - "Cirrus Logic GD-5420", + "Cirrus Logic GD5420 (ISA)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5420, gd54xx_init, gd54xx_close, @@ -4377,11 +4563,11 @@ const device_t gd5420_isa_device = { gd5420_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5422_config, + gd542x_config, }; const device_t gd5422_isa_device = { - "Cirrus Logic GD-5422", + "Cirrus Logic GD5422 (ISA)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5422, gd54xx_init, gd54xx_close, @@ -4389,11 +4575,11 @@ const device_t gd5422_isa_device = { { gd5422_available }, /* Common BIOS between 5422 and 5424 */ gd54xx_speed_changed, gd54xx_force_redraw, - gd5422_config, + gd542x_config, }; const device_t gd5424_vlb_device = { - "Cirrus Logic GD-5424", + "Cirrus Logic GD5424 (VLB)", DEVICE_VLB, CIRRUS_ID_CLGD5424, gd54xx_init, gd54xx_close, @@ -4401,26 +4587,57 @@ const device_t gd5424_vlb_device = { { gd5422_available }, /* Common BIOS between 5422 and 5424 */ gd54xx_speed_changed, gd54xx_force_redraw, - gd5422_config, + gd542x_config, +}; + +const device_t gd5426_isa_device = +{ + "Cirrus Logic GD5426 (ISA)", + DEVICE_AT | DEVICE_ISA, + CIRRUS_ID_CLGD5426, + gd54xx_init, + gd54xx_close, + gd54xx_reset, + { gd5428_isa_available }, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd5426_config +}; + + +/*According to a Diamond bios file listing and vgamuseum*/ +const device_t gd5426_diamond_speedstar_pro_a1_isa_device = +{ + "Cirrus Logic GD5426 (ISA) (Diamond SpeedStar Pro Rev. A1)", + DEVICE_AT | DEVICE_ISA, + CIRRUS_ID_CLGD5426 | 0x100, + gd54xx_init, + gd54xx_close, + gd54xx_reset, + { gd5426_diamond_a1_available }, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd5426_config }; const device_t gd5426_vlb_device = { - "Cirrus Logic CL-GD 5426 (VLB)", + "Cirrus Logic GD5426 (VLB)", DEVICE_VLB, CIRRUS_ID_CLGD5426, gd54xx_init, gd54xx_close, gd54xx_reset, - { gd5426_available }, + { gd5428_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5426_config }; + const device_t gd5426_onboard_device = { - "Cirrus Logic CL-GD 5426 (On-board)", + "Cirrus Logic GD5426 (VLB) (On-Board)", DEVICE_VLB, CIRRUS_ID_CLGD5426 | 0x200, gd54xx_init, @@ -4434,7 +4651,7 @@ const device_t gd5426_onboard_device = const device_t gd5428_isa_device = { - "Cirrus Logic CL-GD 5428 (ISA)", + "Cirrus Logic GD5428 (ISA)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5428, gd54xx_init, @@ -4443,12 +4660,12 @@ const device_t gd5428_isa_device = { gd5428_isa_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5426_config }; const device_t gd5428_vlb_device = { - "Cirrus Logic CL-GD 5428 (VLB)", + "Cirrus Logic GD5428 (VLB)", DEVICE_VLB, CIRRUS_ID_CLGD5428, gd54xx_init, @@ -4457,12 +4674,27 @@ const device_t gd5428_vlb_device = { gd5428_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5426_config +}; + +/*According to a Diamond bios file listing and vgamuseum*/ +const device_t gd5428_diamond_speedstar_pro_b1_vlb_device = +{ + "Cirrus Logic GD5428 (VLB) (Diamond SpeedStar Pro Rev. B1)", + DEVICE_VLB, + CIRRUS_ID_CLGD5428 | 0x100, + gd54xx_init, + gd54xx_close, + gd54xx_reset, + { gd5428_diamond_b1_available }, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd5426_config }; const device_t gd5428_mca_device = { - "Cirrus Logic CL-GD 5428 (IBM SVGA Adapter/A)", + "Cirrus Logic GD5428 (MCA) (IBM SVGA Adapter/A)", DEVICE_MCA, CIRRUS_ID_CLGD5428, gd54xx_init, @@ -4476,7 +4708,7 @@ const device_t gd5428_mca_device = const device_t gd5428_onboard_device = { - "Cirrus Logic CL-GD 5428 (On-Board)", + "Cirrus Logic GD5428 (ISA) (On-Board)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5428, gd54xx_init, @@ -4490,7 +4722,7 @@ const device_t gd5428_onboard_device = const device_t gd5429_isa_device = { - "Cirrus Logic CL-GD 5429 (ISA)", + "Cirrus Logic GD5429 (ISA)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5429, gd54xx_init, @@ -4499,12 +4731,12 @@ const device_t gd5429_isa_device = { gd5429_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5429_config }; const device_t gd5429_vlb_device = { - "Cirrus Logic CL-GD 5429 (VLB)", + "Cirrus Logic GD5429 (VLB)", DEVICE_VLB, CIRRUS_ID_CLGD5429, gd54xx_init, @@ -4513,40 +4745,41 @@ const device_t gd5429_vlb_device = { gd5429_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5429_config }; -const device_t gd5430_vlb_device = +/*According to a Diamond bios file listing and vgamuseum*/ +const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device = { - "Cirrus Logic CL-GD 5430 (VLB)", + "Cirrus Logic GD5430 (VLB) (Diamond SpeedStar Pro SE Rev. A8)", DEVICE_VLB, CIRRUS_ID_CLGD5430, gd54xx_init, gd54xx_close, gd54xx_reset, - { gd5430_vlb_available }, + { gd5430_diamond_a8_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5429_config }; const device_t gd5430_pci_device = { - "Cirrus Logic CL-GD 5430 (PCI)", + "Cirrus Logic GD5430 (PCI)", DEVICE_PCI, CIRRUS_ID_CLGD5430, gd54xx_init, gd54xx_close, gd54xx_reset, - { gd5430_pci_available }, + { gd5430_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5429_config }; const device_t gd5434_isa_device = { - "Cirrus Logic CL-GD 5434 (ISA)", + "Cirrus Logic GD5434 (ISA)", DEVICE_AT | DEVICE_ISA, CIRRUS_ID_CLGD5434, gd54xx_init, @@ -4558,9 +4791,24 @@ const device_t gd5434_isa_device = gd5434_config }; +/*According to a Diamond bios file listing and vgamuseum*/ +const device_t gd5434_diamond_speedstar_64_a3_isa_device = +{ + "Cirrus Logic GD5434 (ISA) (Diamond SpeedStar 64 Rev. A3)", + DEVICE_AT | DEVICE_ISA, + CIRRUS_ID_CLGD5434 | 0x100, + gd54xx_init, + gd54xx_close, + gd54xx_reset, + { gd5434_diamond_a3_available }, + gd54xx_speed_changed, + gd54xx_force_redraw, + gd5429_config +}; + const device_t gd5434_onboard_pci_device = { - "Cirrus Logic CL-GD 5434-4 (On-Board PCI)", + "Cirrus Logic GD5434-4 (PCI) (On-Board)", DEVICE_PCI, CIRRUS_ID_CLGD5434 | 0x200, gd54xx_init, @@ -4569,12 +4817,12 @@ const device_t gd5434_onboard_pci_device = { NULL }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5434_config + gd5434_onboard_config }; const device_t gd5434_vlb_device = { - "Cirrus Logic CL-GD 5434 (VLB)", + "Cirrus Logic GD5434 (VLB)", DEVICE_VLB, CIRRUS_ID_CLGD5434, gd54xx_init, @@ -4588,7 +4836,7 @@ const device_t gd5434_vlb_device = const device_t gd5434_pci_device = { - "Cirrus Logic CL-GD 5434 (PCI)", + "Cirrus Logic GD5434 (PCI)", DEVICE_PCI, CIRRUS_ID_CLGD5434, gd54xx_init, @@ -4602,7 +4850,7 @@ const device_t gd5434_pci_device = const device_t gd5436_pci_device = { - "Cirrus Logic CL-GD 5436 (PCI)", + "Cirrus Logic GD5436 (PCI)", DEVICE_PCI, CIRRUS_ID_CLGD5436, gd54xx_init, @@ -4616,7 +4864,7 @@ const device_t gd5436_pci_device = const device_t gd5440_onboard_pci_device = { - "Cirrus Logic CL-GD 5440 (On-Board PCI)", + "Cirrus Logic GD5440 (PCI) (On-Board)", DEVICE_PCI, CIRRUS_ID_CLGD5440 | 0x600, gd54xx_init, @@ -4630,7 +4878,7 @@ const device_t gd5440_onboard_pci_device = const device_t gd5440_pci_device = { - "Cirrus Logic CL-GD 5440 (PCI)", + "Cirrus Logic GD5440 (PCI)", DEVICE_PCI, CIRRUS_ID_CLGD5440 | 0x400, gd54xx_init, @@ -4639,12 +4887,12 @@ const device_t gd5440_pci_device = { gd5440_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5428_config + gd5429_config }; const device_t gd5446_pci_device = { - "Cirrus Logic CL-GD 5446 (PCI)", + "Cirrus Logic GD5446 (PCI)", DEVICE_PCI, CIRRUS_ID_CLGD5446, gd54xx_init, @@ -4658,7 +4906,7 @@ const device_t gd5446_pci_device = const device_t gd5446_stb_pci_device = { - "STB Nitro 64V (PCI)", + "Cirrus Logic GD5446 (PCI) (STB Nitro 64V)", DEVICE_PCI, CIRRUS_ID_CLGD5446 | 0x100, gd54xx_init, @@ -4672,7 +4920,7 @@ const device_t gd5446_stb_pci_device = const device_t gd5480_pci_device = { - "Cirrus Logic CL-GD 5480 (PCI)", + "Cirrus Logic GD5480 (PCI)", DEVICE_PCI, CIRRUS_ID_CLGD5480, gd54xx_init, @@ -4681,5 +4929,5 @@ const device_t gd5480_pci_device = { gd5480_available }, gd54xx_speed_changed, gd54xx_force_redraw, - gd5434_config + gd5480_config }; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 65dced875..1c2ca794e 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -78,9 +78,9 @@ typedef struct et4000w32p_t uint8_t regs[256], pci_regs[256]; int index, vlb, pci, interleaved, - bank, blitter_busy, type; + bank, type; - uint32_t linearbase, linearbase_old; + uint32_t linearbase; uint32_t vram_mask; /* Accelerator */ @@ -97,12 +97,13 @@ typedef struct et4000w32p_t uint32_t pattern_addr, source_addr, dest_addr, mix_addr; } queued, internal; - uint8_t osr; + uint8_t suspend_terminate, osr; uint8_t status; + uint16_t x_count, y_count; int pattern_x, source_x, pattern_x_back, source_x_back, pattern_y, source_y, cpu_dat_pos, pix_pos, - cpu_input_num, queue; + cpu_input_num, fifo_queue; uint32_t pattern_addr, source_addr, dest_addr, mix_addr, pattern_back, source_back, dest_back, mix_back, @@ -115,6 +116,8 @@ typedef struct et4000w32p_t uint32_t base[3]; uint8_t ctrl; } mmu; + + volatile int busy; } et4000w32p_t; @@ -131,12 +134,13 @@ static video_timings_t timing_et4000w32_isa = {VIDEO_ISA, 4, 4, 4, 10, 10, 10 void et4000w32p_recalcmapping(et4000w32p_t *et4000); -uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); -void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); +static uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); +static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); -void et4000w32_blit_start(et4000w32p_t *et4000); -void et4000w32p_blit_start(et4000w32p_t *et4000); -void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); +static void et4000w32_blit_start(et4000w32p_t *et4000); +static void et4000w32p_blit_start(et4000w32p_t *et4000); +static void et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000); +static void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); uint8_t et4000w32p_in(uint16_t addr, void *p); @@ -213,7 +217,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) } break; case 0x3d4: - svga->crtcreg = val & 63; + svga->crtcreg = val & 0x3f; return; case 0x3d5: if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) @@ -333,12 +337,16 @@ et4000w32p_in(uint16_t addr, void *p) case 0x3d4: return svga->crtcreg; case 0x3d5: + if (et4000->type == ET4000W32) { + if (svga->crtcreg == 0x37) + return 0x09; + } return svga->crtc[svga->crtcreg]; case 0x3da: svga->attrff = 0; - /*Bit 1 of the Input Status Register is required by OS/2 ET4000W32/I drivers to be set otherwise + /*Bit 1 of the Input Status Register is required by the OS/2 and NT ET4000W32/I drivers to be set otherwise the guest will loop infinitely upon reaching the GUI*/ if (svga->cgastat & 0x01) svga->cgastat &= ~0x32; @@ -397,6 +405,24 @@ et4000w32p_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); + if (et4000->type != ET4000W32P_DIAMOND) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->gdcreg[5] & 0x40) { + switch (svga->bpp) { + case 8: + svga->clock /= 2; + break; + case 15: case 16: + svga->clock /= 3; + break; + case 24: + svga->clock /= 4; + break; + } + } + } + } + if (svga->adv_flags & FLAG_NOSKEW) { /* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */ if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ @@ -550,6 +576,7 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000) map = (svga->gdcreg[6] & 0xc) >> 2; if (svga->crtc[0x36] & 0x20) map |= 4; if (svga->crtc[0x36] & 0x08) map |= 8; + mem_mapping_disable(&et4000->linear_mapping); switch (map) { case 0x0: case 0x4: case 0x8: case 0xc: /* 128k at A0000 */ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -587,12 +614,8 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000) svga->banked_mask = 0x7fff; break; } - - mem_mapping_disable(&et4000->linear_mapping); } - et4000->linearbase_old = et4000->linearbase; - if (!et4000->interleaved && (svga->crtc[0x32] & 0x80)) mem_mapping_disable(&svga->mapping); } @@ -601,128 +624,208 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000) static void et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) { - switch (addr & 0x7fff) { - case 0x7f80: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; break; - case 0x7f81: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7f82: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break; - case 0x7f84: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; break; - case 0x7f85: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7f86: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7f87: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break; - case 0x7f88: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; break; - case 0x7f89: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7f8a: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; break; - case 0x7f8b: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); et4000->acl.queue++;break; - case 0x7f8c: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; break; - case 0x7f8d: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7f8e: - et4000->acl.queue++; - if (et4000->type >= ET4000W32P_REVC) - et4000->acl.queued.pixel_depth = val; - else - et4000->acl.queued.vbus = val; + et4000->acl.fifo_queue++; + switch (addr & 0xff) { + case 0x80: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3fff00) | val; break; - case 0x7f8f: et4000->acl.queued.xy_dir = val; et4000->acl.queue++; break; - case 0x7f90: et4000->acl.queued.pattern_wrap = val; et4000->acl.queue++; break; - case 0x7f92: et4000->acl.queued.source_wrap = val; et4000->acl.queue++; break; - case 0x7f98: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; break; - case 0x7f99: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7f9a: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; break; - case 0x7f9b: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7f9c: et4000->acl.queued.ctrl_routing = val; et4000->acl.queue++; break; - case 0x7f9d: et4000->acl.queued.ctrl_reload = val; et4000->acl.queue++; break; - case 0x7f9e: et4000->acl.queued.rop_bg = val; et4000->acl.queue++; break; - case 0x7f9f: et4000->acl.queued.rop_fg = val; et4000->acl.queue++; break; - case 0x7fa0: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; break; - case 0x7fa1: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7fa2: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7fa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24); - et4000->acl.queue++; + case 0x81: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3f00ff) | (val << 8); + break; + case 0x82: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x84: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3fff00) | val; + break; + case 0x85: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3f00ff) | (val << 8); + break; + case 0x86: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x88: + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x0f00) | val; + break; + case 0x89: + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x8a: + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x0f00) | val; + break; + case 0x8b: + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x8c: + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x0f00) | val; + break; + case 0x8d: + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x8e: + if (et4000->type >= ET4000W32P_REVC) + et4000->acl.queued.pixel_depth = val & 0x30; + else + et4000->acl.queued.vbus = val & 0x03; + break; + case 0x8f: + if (et4000->type >= ET4000W32P_REVC) + et4000->acl.queued.xy_dir = val & 0xb7; + else + et4000->acl.queued.xy_dir = val & 0x03; + break; + case 0x90: + et4000->acl.queued.pattern_wrap = val & 0x77; + break; + case 0x92: + et4000->acl.queued.source_wrap = val & 0x77; + break; + case 0x98: + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x0f00) | val; + break; + case 0x99: + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x9a: + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x0f00) | val; + break; + case 0x9b: + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x9c: + if (et4000->type >= ET4000W32P_REVC) + et4000->acl.queued.ctrl_routing = val & 0xdb; + else + et4000->acl.queued.ctrl_routing = val & 0xb7; + break; + case 0x9d: + et4000->acl.queued.ctrl_reload = val & 0x03; + break; + case 0x9e: + et4000->acl.queued.rop_bg = val; + break; + case 0x9f: + et4000->acl.queued.rop_fg = val; + break; + case 0xa0: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3fff00) | val; + break; + case 0xa1: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3f00ff) | (val << 8); + break; + case 0xa2: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0xa3: et4000->acl.internal = et4000->acl.queued; if (et4000->type >= ET4000W32P_REVC) { - if (et4000->acl.osr & 0x10) { - et4000w32p_blit_start(et4000); - if (!(et4000->acl.queued.ctrl_routing & 0x43)) { - et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) { - et4000w32p_blit(4, ~0, 0, 0, et4000); - } + et4000w32p_blit_start(et4000); + et4000w32_log("Destination Address write and start XY Block, xcnt = %i, ycnt = %i\n", et4000->acl.x_count + 1, et4000->acl.y_count + 1); + if (!(et4000->acl.queued.ctrl_routing & 0x43)) { + et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); + } + if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) { + et4000w32p_blit(4, ~0, 0, 0, et4000); } } else { et4000w32_blit_start(et4000); et4000->acl.cpu_input_num = 0; - if (!(et4000->acl.queued.ctrl_routing & 0x37)) - et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); + if (!(et4000->acl.queued.ctrl_routing & 0x37)) { + et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); + } } break; - case 0x7fa4: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; break; - case 0x7fa5: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); break; - case 0x7fa6: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); break; - case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break; - case 0x7fa8: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; break; - case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7faa: et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; break; - case 0x7fab: et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7fac: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; break; - case 0x7fad: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); et4000->acl.queue++; break; - case 0x7fae: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; break; - case 0x7faf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); et4000->acl.queue++; break; + case 0xa4: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; + break; + case 0xa5: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); + break; + case 0xa6: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); + break; + case 0xa7: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); + break; + case 0xa8: + et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; + break; + case 0xa9: + et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); + break; + case 0xaa: + et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; + break; + case 0xab: + et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); + break; + case 0xac: + et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; + break; + case 0xad: + et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); + break; + case 0xae: + et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; + break; + case 0xaf: + et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); + break; } } - static void -et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val) +et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uint8_t bank) { if (et4000->type >= ET4000W32P_REVC) { - if (!(et4000->acl.status & ACL_XYST)) + if (!(et4000->acl.status & ACL_XYST)) { + et4000w32_log("XY MMU block not started\n"); return; + } if (et4000->acl.internal.ctrl_routing & 3) { - et4000->acl.queue++; - if ((et4000->acl.internal.ctrl_routing & 3) == 2) { + et4000->acl.fifo_queue++; + if ((et4000->acl.internal.ctrl_routing & 3) == 2) /*CPU data is Mix data*/ et4000w32p_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); - } - else if ((et4000->acl.internal.ctrl_routing & 3) == 1) { + else if ((et4000->acl.internal.ctrl_routing & 3) == 1) /*CPU data is Source data*/ et4000w32p_blit(1, ~0, val, 2, et4000); - } } } else { if (!(et4000->acl.status & ACL_XYST)) { - et4000->acl.queue++; - et4000->acl.queued.dest_addr = (addr & 0x1FFF) + et4000->mmu.base[et4000->bank]; + et4000->acl.fifo_queue++; + et4000->acl.queued.dest_addr = ((addr & 0x1fff) + et4000->mmu.base[bank]); et4000->acl.internal = et4000->acl.queued; et4000w32_blit_start(et4000); - if (!(et4000->acl.internal.ctrl_routing & 0x37)) - et4000w32p_blit(0xFFFFFF, ~0, 0, 0, et4000); + et4000w32_log("Accelerated MMU aperture = %i and start XY Block (Implicit), xcnt = %i, ycnt = %i\n", bank, et4000->acl.x_count + 1, et4000->acl.y_count + 1); et4000->acl.cpu_input_num = 0; + if (!(et4000->acl.queued.ctrl_routing & 0x37)) { + et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); + } } if (et4000->acl.internal.ctrl_routing & 7) { - et4000->acl.queue++; - et4000->acl.cpu_input = (et4000->acl.cpu_input &~ (0xFF << (et4000->acl.cpu_input_num << 3))) | + et4000->acl.fifo_queue++; + et4000->acl.cpu_input = (et4000->acl.cpu_input & ~(0xff << (et4000->acl.cpu_input_num << 3))) | (val << (et4000->acl.cpu_input_num << 3)); et4000->acl.cpu_input_num++; - if (et4000->acl.cpu_input_num == et4000w32_vbus[et4000->acl.internal.vbus & 3]) { - if ((et4000->acl.internal.ctrl_routing & 7) == 2) - et4000w32p_blit(et4000->acl.cpu_input_num << 3, et4000->acl.cpu_input, 0, 1, et4000); - else if ((et4000->acl.internal.ctrl_routing & 7) == 1) - et4000w32p_blit(et4000->acl.cpu_input_num, ~0, et4000->acl.cpu_input, 2, et4000); - else if ((et4000->acl.internal.ctrl_routing & 7) == 4) - et4000w32p_blit(et4000->acl.cpu_input_num, ~0, et4000->acl.internal.count_x, 2, et4000); - else if ((et4000->acl.internal.ctrl_routing & 7) == 5) - et4000w32p_blit(et4000->acl.cpu_input_num, ~0, et4000->acl.internal.count_y, 2, et4000); + if (et4000->acl.cpu_input_num == et4000w32_vbus[et4000->acl.internal.vbus]) { + if ((et4000->acl.internal.ctrl_routing & 7) == 2) /*CPU data is Mix data*/ + et4000w32_blit(et4000->acl.cpu_input_num << 3, 2, 0, et4000->acl.cpu_input, et4000); + else if ((et4000->acl.internal.ctrl_routing & 7) == 1) /*CPU data is Source data*/ + et4000w32_blit(et4000->acl.cpu_input_num, 1, et4000->acl.cpu_input, 0xffffffff, et4000); et4000->acl.cpu_input_num = 0; } + + if ((et4000->acl.internal.ctrl_routing & 7) == 4) /*CPU data is X Count*/ + et4000w32_blit(val | (et4000->acl.queued.count_x << 8), 0, 0, 0xffffffff, et4000); + if ((et4000->acl.internal.ctrl_routing & 7) == 5) /*CPU data is Y Count*/ + et4000w32_blit(val | (et4000->acl.queued.count_y << 8), 0, 0, 0xffffffff, et4000); } } } - -void +static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; @@ -734,7 +837,7 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) case 0x4000: /* MMU 2 */ et4000->bank = (addr >> 13) & 3; if (et4000->mmu.ctrl & (1 << et4000->bank)) { - et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val); + et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val, et4000->bank); } else { if (((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) < svga->vram_max) { svga->vram[(addr & 0x1fff) + et4000->mmu.base[et4000->bank]] = val; @@ -743,43 +846,65 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) } break; case 0x6000: - if ((addr & 0x7fff) >= 0x7f80) { + if ((addr & 0xff) >= 0x80) { et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val); - } else switch (addr & 0x7fff) { - case 0x7f00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; break; - case 0x7f01: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); break; - case 0x7f02: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); break; - case 0x7f03: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); break; - case 0x7f04: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val; break; - case 0x7f05: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8); break; - case 0x7f06: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); break; - case 0x7f07: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); break; - case 0x7f08: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val; break; - case 0x7f09: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8); break; - case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break; - case 0x7f0b: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break; - case 0x7f13: et4000->mmu.ctrl = val; break; - case 0x7f31: et4000->acl.osr = val; break; + } else { + switch (addr & 0xff) { + case 0x00: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3fff00) | val; + break; + case 0x01: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3f00ff) | (val << 8); + break; + case 0x02: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x04: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3fff00) | val; + break; + case 0x05: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3f00ff) | (val << 8); + break; + case 0x06: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x08: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3fff00) | val; + break; + case 0x09: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3f00ff) | (val << 8); + break; + case 0x0a: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x13: + et4000->mmu.ctrl = val; + break; + case 0x30: + et4000->acl.suspend_terminate = val; + break; + case 0x31: + et4000->acl.osr = val; + break; + } } break; } } - -uint8_t +static uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; svga_t *svga = &et4000->svga; - int bank; uint8_t temp; switch (addr & 0x6000) { case 0x0000: /* MMU 0 */ case 0x2000: /* MMU 1 */ case 0x4000: /* MMU 2 */ - bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << bank)) { + et4000->bank = (addr >> 13) & 3; + if (et4000->mmu.ctrl & (1 << et4000->bank)) { temp = 0xff; if (et4000->acl.cpu_dat_pos) { et4000->acl.cpu_dat_pos--; @@ -793,84 +918,97 @@ et4000w32p_mmu_read(uint32_t addr, void *p) return temp; } - if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_max) + if ((addr & 0x1fff) + et4000->mmu.base[et4000->bank] >= svga->vram_max) return 0xff; - return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]]; + return svga->vram[(addr & 0x1fff) + et4000->mmu.base[et4000->bank]]; case 0x6000: - switch (addr & 0x7fff) { - case 0x7f00: return et4000->mmu.base[0]; - case 0x7f01: return et4000->mmu.base[0] >> 8; - case 0x7f02: return et4000->mmu.base[0] >> 16; - case 0x7f03: return et4000->mmu.base[0] >> 24; - case 0x7f04: return et4000->mmu.base[1]; - case 0x7f05: return et4000->mmu.base[1] >> 8; - case 0x7f06: return et4000->mmu.base[1] >> 16; - case 0x7f07: return et4000->mmu.base[1] >> 24; - case 0x7f08: return et4000->mmu.base[2]; - case 0x7f09: return et4000->mmu.base[2] >> 8; - case 0x7f0a: return et4000->mmu.base[2] >> 16; - case 0x7f0b: return et4000->mmu.base[2] >> 24; - case 0x7f13: return et4000->mmu.ctrl; + switch (addr & 0xff) { + case 0x00: + return et4000->mmu.base[0] & 0xff; + case 0x01: + return et4000->mmu.base[0] >> 8; + case 0x02: + return et4000->mmu.base[0] >> 16; + case 0x03: + return et4000->mmu.base[0] >> 24; + case 0x04: + return et4000->mmu.base[1] & 0xff; + case 0x05: + return et4000->mmu.base[1] >> 8; + case 0x06: + return et4000->mmu.base[1] >> 16; + case 0x07: + return et4000->mmu.base[1] >> 24; + case 0x08: + return et4000->mmu.base[2] & 0xff; + case 0x09: + return et4000->mmu.base[2] >> 8; + case 0x0a: + return et4000->mmu.base[2] >> 16; + case 0x0b: + return et4000->mmu.base[2] >> 24; + case 0x13: + return et4000->mmu.ctrl; - case 0x7f36: - if (et4000->type >= ET4000W32P_REVC) { - if (et4000->acl.queue) { - et4000->acl.status |= ACL_RDST; - et4000->acl.queue = 0; - } else - et4000->acl.status &= ~ACL_RDST; - - temp = et4000->acl.status; - } else { - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + case 0x36: + if (et4000->acl.fifo_queue) { + et4000->acl.status |= ACL_RDST; + et4000->acl.fifo_queue = 0; + } else + et4000->acl.status &= ~ACL_RDST; + return et4000->acl.status; - if (et4000->acl.queue) { - et4000->acl.status |= ACL_RDST; - et4000->acl.queue = 0; - } else - et4000->acl.status &= ~ACL_RDST; - - temp = et4000->acl.status; - } - return temp; - - case 0x7f80: return et4000->acl.internal.pattern_addr; - case 0x7f81: return et4000->acl.internal.pattern_addr >> 8; - case 0x7f82: return et4000->acl.internal.pattern_addr >> 16; - case 0x7f83: return et4000->acl.internal.pattern_addr >> 24; - case 0x7f84: return et4000->acl.internal.source_addr; - case 0x7f85: return et4000->acl.internal.source_addr >> 8; - case 0x7f86: return et4000->acl.internal.source_addr >> 16; - case 0x7f87: return et4000->acl.internal.source_addr >> 24; - case 0x7f88: return et4000->acl.internal.pattern_off; - case 0x7f89: return et4000->acl.internal.pattern_off >> 8; - case 0x7f8a: return et4000->acl.internal.source_off; - case 0x7f8b: return et4000->acl.internal.source_off >> 8; - case 0x7f8c: return et4000->acl.internal.dest_off; - case 0x7f8d: return et4000->acl.internal.dest_off >> 8; - case 0x7f8e: + case 0x80: + return et4000->acl.internal.pattern_addr & 0xff; + case 0x81: + return et4000->acl.internal.pattern_addr >> 8; + case 0x82: + return et4000->acl.internal.pattern_addr >> 16; + case 0x83: + return et4000->acl.internal.pattern_addr >> 24; + case 0x84: + return et4000->acl.internal.source_addr & 0xff; + case 0x85: + return et4000->acl.internal.source_addr >> 8; + case 0x86: + return et4000->acl.internal.source_addr >> 16; + case 0x87: + return et4000->acl.internal.source_addr >> 24; + case 0x88: + return et4000->acl.internal.pattern_off & 0xff; + case 0x89: + return et4000->acl.internal.pattern_off >> 8; + case 0x8a: + return et4000->acl.internal.source_off & 0xff; + case 0x8b: + return et4000->acl.internal.source_off >> 8; + case 0x8c: + return et4000->acl.internal.dest_off & 0xff; + case 0x8d: + return et4000->acl.internal.dest_off >> 8; + case 0x8e: if (et4000->type >= ET4000W32P_REVC) return et4000->acl.internal.pixel_depth; else return et4000->acl.internal.vbus; break; - case 0x7f8f: return et4000->acl.internal.xy_dir; - case 0x7f90: return et4000->acl.internal.pattern_wrap; - case 0x7f92: return et4000->acl.internal.source_wrap; - case 0x7f98: return et4000->acl.internal.count_x; - case 0x7f99: return et4000->acl.internal.count_x >> 8; - case 0x7f9a: return et4000->acl.internal.count_y; - case 0x7f9b: return et4000->acl.internal.count_y >> 8; - case 0x7f9c: return et4000->acl.internal.ctrl_routing; - case 0x7f9d: return et4000->acl.internal.ctrl_reload; - case 0x7f9e: return et4000->acl.internal.rop_bg; - case 0x7f9f: return et4000->acl.internal.rop_fg; - case 0x7fa0: return et4000->acl.internal.dest_addr; - case 0x7fa1: return et4000->acl.internal.dest_addr >> 8; - case 0x7fa2: return et4000->acl.internal.dest_addr >> 16; - case 0x7fa3: return et4000->acl.internal.dest_addr >> 24; + case 0x8f: return et4000->acl.internal.xy_dir; + case 0x90: return et4000->acl.internal.pattern_wrap; + case 0x92: return et4000->acl.internal.source_wrap; + case 0x98: return et4000->acl.internal.count_x & 0xff; + case 0x99: return et4000->acl.internal.count_x >> 8; + case 0x9a: return et4000->acl.internal.count_y & 0xff; + case 0x9b: return et4000->acl.internal.count_y >> 8; + case 0x9c: return et4000->acl.internal.ctrl_routing; + case 0x9d: return et4000->acl.internal.ctrl_reload; + case 0x9e: return et4000->acl.internal.rop_bg; + case 0x9f: return et4000->acl.internal.rop_fg; + case 0xa0: return et4000->acl.internal.dest_addr & 0xff; + case 0xa1: return et4000->acl.internal.dest_addr >> 8; + case 0xa2: return et4000->acl.internal.dest_addr >> 16; + case 0xa3: return et4000->acl.internal.dest_addr >> 24; } return 0xff; @@ -883,16 +1021,19 @@ et4000w32p_mmu_read(uint32_t addr, void *p) void et4000w32_blit_start(et4000w32p_t *et4000) { - et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; - et4000->acl.source_addr = et4000->acl.internal.source_addr; - et4000->acl.dest_addr = et4000->acl.internal.dest_addr; - et4000->acl.dest_back = et4000->acl.dest_addr; - et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; - et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; + et4000->acl.x_count = et4000->acl.internal.count_x; + et4000->acl.y_count = et4000->acl.internal.count_y; + + et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; + et4000->acl.source_addr = et4000->acl.internal.source_addr; + et4000->acl.dest_addr = et4000->acl.internal.dest_addr; + et4000->acl.dest_back = et4000->acl.dest_addr; + et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; et4000->acl.status |= ACL_XYST; + et4000->acl.status &= ~ACL_SSO; - if (!(et4000->acl.internal.ctrl_routing & 7)) + if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) et4000->acl.status |= ACL_SSO; if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { @@ -900,10 +1041,11 @@ et4000w32_blit_start(et4000w32p_t *et4000) et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; } et4000->acl.pattern_back = et4000->acl.pattern_addr; + if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) + if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ et4000->acl.pattern_y = (et4000->acl.pattern_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - else + } else et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); } @@ -913,13 +1055,12 @@ et4000w32_blit_start(et4000w32p_t *et4000) et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; } - et4000->acl.source_back = et4000->acl.source_addr; if (!(et4000->acl.internal.source_wrap & 0x40)) { - if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) + if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ et4000->acl.source_y = (et4000->acl.source_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - else + } else et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } @@ -927,9 +1068,12 @@ et4000w32_blit_start(et4000w32p_t *et4000) } -void +static void et4000w32p_blit_start(et4000w32p_t *et4000) { + et4000->acl.x_count = et4000->acl.internal.count_x; + et4000->acl.y_count = et4000->acl.internal.count_y; + if (!(et4000->acl.queued.xy_dir & 0x20)) et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; @@ -941,6 +1085,7 @@ et4000w32p_blit_start(et4000w32p_t *et4000) et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; et4000->acl.status |= ACL_XYST; + et4000w32_log("ACL status XYST set\n"); if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) et4000->acl.status |= ACL_SSO; @@ -961,13 +1106,14 @@ et4000w32p_blit_start(et4000w32p_t *et4000) et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; } et4000->acl.source_back = et4000->acl.source_addr; + if (!(et4000->acl.internal.source_wrap & 0x40)) { et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } et4000->acl.source_x_back = et4000->acl.source_x; - et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4; + et4000w32_max_x[2] = (et4000->acl.internal.pixel_depth == 0x20) ? 3 : 4; et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; et4000->acl.cpu_dat_pos = 0; @@ -1040,24 +1186,393 @@ et4000w32_decy(et4000w32p_t *et4000) et4000->acl.source_y--; if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; - et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] *(et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));; + et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] *(et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); } } -void +#define ROPMIX(R, D, P, S, out) \ + { \ + switch (R) { \ + case 0x00: out = 0; break; \ + case 0x01: out = ~(D | (P | S)); break; \ + case 0x02: out = D & ~(P | S); break; \ + case 0x03: out = ~(P | S); break; \ + case 0x04: out = S & ~(D | P); break; \ + case 0x05: out = ~(D | P); break; \ + case 0x06: out = ~(P | ~(D ^ S)); break; \ + case 0x07: out = ~(P | (D & S)); break; \ + case 0x08: out = S & (D & ~P); break; \ + case 0x09: out = ~(P | (D ^ S)); break; \ + case 0x0a: out = D & ~P; break; \ + case 0x0b: out = ~(P | (S & ~D)); break; \ + case 0x0c: out = S & ~P; break; \ + case 0x0d: out = ~(P | (D & ~S)); break; \ + case 0x0e: out = ~(P | ~(D | S)); break; \ + case 0x0f: out = ~P; break; \ + case 0x10: out = P & ~(D | S); break; \ + case 0x11: out = ~(D | S); break; \ + case 0x12: out = ~(S | ~(D ^ P)); break; \ + case 0x13: out = ~(S | (D & P)); break; \ + case 0x14: out = ~(D | ~(P ^ S)); break; \ + case 0x15: out = ~(D | (P & S)); break; \ + case 0x16: out = P ^ (S ^ (D & ~(P & S))); break; \ + case 0x17: out = ~(S ^ ((S ^ P) & (D ^ S))); break; \ + case 0x18: out = (S ^ P) & (P ^ D); break; \ + case 0x19: out = ~(S ^ (D & ~(P & S))); break; \ + case 0x1a: out = P ^ (D | (S & P)); break; \ + case 0x1b: out = ~(S ^ (D & (P ^ S))); break; \ + case 0x1c: out = P ^ (S | (D & P)); break; \ + case 0x1d: out = ~(D ^ (S & (P ^ D))); break; \ + case 0x1e: out = P ^ (D | S); break; \ + case 0x1f: out = ~(P & (D | S)); break; \ + case 0x20: out = D & (P & ~S); break; \ + case 0x21: out = ~(S | (D ^ P)); break; \ + case 0x22: out = D & ~S; break; \ + case 0x23: out = ~(S | (P & ~D)); break; \ + case 0x24: out = (S ^ P) & (D ^ S); break; \ + case 0x25: out = ~(P ^ (D & ~(S & P))); break; \ + case 0x26: out = S ^ (D | (P & S)); break; \ + case 0x27: out = S ^ (D | ~(P ^ S)); break; \ + case 0x28: out = D & (P ^ S); break; \ + case 0x29: out = ~(P ^ (S ^ (D | (P & S)))); break; \ + case 0x2a: out = D & ~(P & S); break; \ + case 0x2b: out = ~(S ^ ((S ^ P) & (P ^ D))); break; \ + case 0x2c: out = S ^ (P & (D | S)); break; \ + case 0x2d: out = P ^ (S | ~D); break; \ + case 0x2e: out = P ^ (S | (D ^ P)); break; \ + case 0x2f: out = ~(P & (S | ~D)); break; \ + case 0x30: out = P & ~S; break; \ + case 0x31: out = ~(S | (D & ~P)); break; \ + case 0x32: out = S ^ (D | (P | S)); break; \ + case 0x33: out = ~S; break; \ + case 0x34: out = S ^ (P | (D & S)); break; \ + case 0x35: out = S ^ (P | ~(D ^ S)); break; \ + case 0x36: out = S ^ (D | P); break; \ + case 0x37: out = ~(S & (D | P)); break; \ + case 0x38: out = P ^ (S & (D | P)); break; \ + case 0x39: out = S ^ (P | ~D); break; \ + case 0x3a: out = S ^ (P | (D ^ S)); break; \ + case 0x3b: out = ~(S & (P | ~D)); break; \ + case 0x3c: out = P ^ S; break; \ + case 0x3d: out = S ^ (P | ~(D | S)); break; \ + case 0x3e: out = S ^ (P | (D & ~S)); break; \ + case 0x3f: out = ~(P & S); break; \ + case 0x40: out = P & (S & ~D); break; \ + case 0x41: out = ~(D | (P ^ S)); break; \ + case 0x42: out = (S ^ D) & (P ^ D); break; \ + case 0x43: out = ~(S ^ (P & ~(D & S))); break; \ + case 0x44: out = S & ~D; break; \ + case 0x45: out = ~(D | (P & ~S)); break; \ + case 0x46: out = D ^ (S | (P & D)); break; \ + case 0x47: out = ~(P ^ (S & (D ^ P))); break; \ + case 0x48: out = S & (D ^ P); break; \ + case 0x49: out = ~(P ^ (D ^ (S | (P & D)))); break; \ + case 0x4a: out = D ^ (P & (S | D)); break; \ + case 0x4b: out = P ^ (D | ~S); break; \ + case 0x4c: out = S & ~(D & P); break; \ + case 0x4d: out = ~(S ^ ((S ^ P) | (D ^ S))); break; \ + case 0x4e: out = P ^ (D | (S ^ P)); break; \ + case 0x4f: out = ~(P & (D | ~S)); break; \ + case 0x50: out = P & ~D; break; \ + case 0x51: out = ~(D | (S & ~P)); break; \ + case 0x52: out = D ^ (P | (S & D)); break; \ + case 0x53: out = ~(S ^ (P & (D ^ S))); break; \ + case 0x54: out = ~(D | ~(P | S)); break; \ + case 0x55: out = ~D; break; \ + case 0x56: out = D ^ (P | S); break; \ + case 0x57: out = ~(D & (P | S)); break; \ + case 0x58: out = P ^ (D & (S | P)); break; \ + case 0x59: out = D ^ (P | ~S); break; \ + case 0x5a: out = D ^ P; break; \ + case 0x5b: out = D ^ (P | ~(S | D)); break; \ + case 0x5c: out = D ^ (P | (S ^ D)); break; \ + case 0x5d: out = ~(D & (P | ~S)); break; \ + case 0x5e: out = D ^ (P | (S & ~D)); break; \ + case 0x5f: out = ~(D & P); break; \ + case 0x60: out = P & (D ^ S); break; \ + case 0x61: out = ~(D ^ (S ^ (P | (D & S)))); break; \ + case 0x62: out = D ^ (S & (P | D)); break; \ + case 0x63: out = S ^ (D | ~P); break; \ + case 0x64: out = S ^ (D & (P | S)); break; \ + case 0x65: out = D ^ (S | ~P); break; \ + case 0x66: out = D ^ S; break; \ + case 0x67: out = S ^ (D | ~(P | S)); break; \ + case 0x68: out = ~(D ^ (S ^ (P | ~(D | S)))); break; \ + case 0x69: out = ~(P ^ (D ^ S)); break; \ + case 0x6a: out = D ^ (P & S); break; \ + case 0x6b: out = ~(P ^ (S ^ (D & (P | S)))); break; \ + case 0x6c: out = S ^ (D & P); break; \ + case 0x6d: out = ~(P ^ (D ^ (S & (P | D)))); break; \ + case 0x6e: out = S ^ (D & (P | ~S)); break; \ + case 0x6f: out = ~(P & ~(D ^ S)); break; \ + case 0x70: out = P & ~(D & S); break; \ + case 0x71: out = ~(S ^ ((S ^ D) & (P ^ D))); break; \ + case 0x72: out = S ^ (D | (P ^ S)); break; \ + case 0x73: out = ~(S & (D | ~P)); break; \ + case 0x74: out = D ^ (S | (P ^ D)); break; \ + case 0x75: out = ~(D & (S | ~P)); break; \ + case 0x76: out = S ^ (D | (P & ~S)); break; \ + case 0x77: out = ~(D & S); break; \ + case 0x78: out = P ^ (D & S); break; \ + case 0x79: out = ~(D ^ (S ^ (P & (D | S)))); break; \ + case 0x7a: out = D ^ (P & (S | ~D)); break; \ + case 0x7b: out = ~(S & ~(D ^ P)); break; \ + case 0x7c: out = S ^ (P & (D | ~S)); break; \ + case 0x7d: out = ~(D & ~(P ^ S)); break; \ + case 0x7e: out = (S ^ P) | (D ^ S); break; \ + case 0x7f: out = ~(D & (P & S)); break; \ + case 0x80: out = D & (P & S); break; \ + case 0x81: out = ~((S ^ P) | (D ^ S)); break; \ + case 0x82: out = D & ~(P ^ S); break; \ + case 0x83: out = ~(S ^ (P & (D | ~S))); break; \ + case 0x84: out = S & ~(D ^ P); break; \ + case 0x85: out = ~(P ^ (D & (S | ~P))); break; \ + case 0x86: out = D ^ (S ^ (P & (D | S))); break; \ + case 0x87: out = ~(P ^ (D & S)); break; \ + case 0x88: out = D & S; break; \ + case 0x89: out = ~(S ^ (D | (P & ~S))); break; \ + case 0x8a: out = D & (S | ~P); break; \ + case 0x8b: out = ~(D ^ (S | (P ^ D))); break; \ + case 0x8c: out = S & (D | ~P); break; \ + case 0x8d: out = ~(S ^ (D | (P ^ S))); break; \ + case 0x8e: out = S ^ ((S ^ D) & (P ^ D)); break; \ + case 0x8f: out = ~(P & ~(D & S)); break; \ + case 0x90: out = P & ~(D ^ S); break; \ + case 0x91: out = ~(S ^ (D & (P | ~S))); break; \ + case 0x92: out = D ^ (P ^ (S & (D | P))); break; \ + case 0x93: out = ~(S ^ (P & D)); break; \ + case 0x94: out = P ^ (S ^ (D & (P | S))); break; \ + case 0x95: out = ~(D ^ (P & S)); break; \ + case 0x96: out = D ^ (P ^ S); break; \ + case 0x97: out = P ^ (S ^ (D | ~(P | S))); break; \ + case 0x98: out = ~(S ^ (D | ~(P | S))); break; \ + case 0x99: out = ~(D ^ S); break; \ + case 0x9a: out = D ^ (P & ~S); break; \ + case 0x9b: out = ~(S ^ (D & (P | S))); break; \ + case 0x9c: out = S ^ (P & ~D); break; \ + case 0x9d: out = ~(D ^ (S & (P | D))); break; \ + case 0x9e: out = D ^ (S ^ (P | (D & S))); break; \ + case 0x9f: out = ~(P & (D ^ S)); break; \ + case 0xa0: out = D & P; break; \ + case 0xa1: out = ~(P ^ (D | (S & ~P))); break; \ + case 0xa2: out = D & (P | ~S); break; \ + case 0xa3: out = ~(D ^ (P | (S ^ D))); break; \ + case 0xa4: out = ~(P ^ (D | ~(S | P))); break; \ + case 0xa5: out = ~(P ^ D); break; \ + case 0xa6: out = D ^ (S & ~P); break; \ + case 0xa7: out = ~(P ^ (D & (S | P))); break; \ + case 0xa8: out = D & (P | S); break; \ + case 0xa9: out = ~(D ^ (P | S)); break; \ + case 0xaa: out = D; break; \ + case 0xab: out = D | ~(P | S); break; \ + case 0xac: out = S ^ (P & (D ^ S)); break; \ + case 0xad: out = ~(D ^ (P | (S & D))); break; \ + case 0xae: out = D | (S & ~P); break; \ + case 0xaf: out = D | ~P; break; \ + case 0xb0: out = P & (D | ~S); break; \ + case 0xb1: out = ~(P ^ (D | (S ^ P))); break; \ + case 0xb2: out = S ^ ((S ^ P) | (D ^ S)); break; \ + case 0xb3: out = ~(S & ~(D & P)); break; \ + case 0xb4: out = P ^ (S & ~D); break; \ + case 0xb5: out = ~(D ^ (P & (S | D))); break; \ + case 0xb6: out = D ^ (P ^ (S | (D & P))); break; \ + case 0xb7: out = ~(S & (D ^ P)); break; \ + case 0xb8: out = P ^ (S & (D ^ P)); break; \ + case 0xb9: out = ~(D ^ (S | (P & D))); break; \ + case 0xba: out = D | (P & ~S); break; \ + case 0xbb: out = D | ~S; break; \ + case 0xbc: out = S ^ (P & ~(D & S)); break; \ + case 0xbd: out = ~((S ^ D) & (P ^ D)); break; \ + case 0xbe: out = D | (P ^ S); break; \ + case 0xbf: out = D | ~(P & S); break; \ + case 0xc0: out = P & S; break; \ + case 0xc1: out = ~(S ^ (P | (D & ~S))); break; \ + case 0xc2: out = ~(S ^ (P | ~(D | S))); break; \ + case 0xc3: out = ~(P ^ S); break; \ + case 0xc4: out = S & (P | ~D); break; \ + case 0xc5: out = ~(S ^ (P | (D ^ S))); break; \ + case 0xc6: out = S ^ (D & ~P); break; \ + case 0xc7: out = ~(P ^ (S & (D | P))); break; \ + case 0xc8: out = S & (D | P); break; \ + case 0xc9: out = ~(S ^ (P | D)); break; \ + case 0xca: out = D ^ (P & (S ^ D)); break; \ + case 0xcb: out = ~(S ^ (P | (D & S))); break; \ + case 0xcc: out = S; break; \ + case 0xcd: out = S | ~(D | P); break; \ + case 0xce: out = S | (D & ~P); break; \ + case 0xcf: out = S | ~P; break; \ + case 0xd0: out = P & (S | ~D); break; \ + case 0xd1: out = ~(P ^ (S | (D ^ P))); break; \ + case 0xd2: out = P ^ (D & ~S); break; \ + case 0xd3: out = ~(S ^ (P & (D | S))); break; \ + case 0xd4: out = S ^ ((S ^ P) & (P ^ D)); break; \ + case 0xd5: out = ~(D & ~(P & S)); break; \ + case 0xd6: out = P ^ (S ^ (D | (P & S))); break; \ + case 0xd7: out = ~(D & (P ^ S)); break; \ + case 0xd8: out = P ^ (D & (S ^ P)); break; \ + case 0xd9: out = ~(S ^ (D | (P & S))); break; \ + case 0xda: out = D ^ (P & ~(S & D)); break; \ + case 0xdb: out = ~((S ^ P) & (D ^ S)); break; \ + case 0xdc: out = S | (P & ~D); break; \ + case 0xdd: out = S | ~D; break; \ + case 0xde: out = S | (D ^ P); break; \ + case 0xdf: out = S | ~(D & P); break; \ + case 0xe0: out = P & (D | S); break; \ + case 0xe1: out = ~(P ^ (D | S)); break; \ + case 0xe2: out = D ^ (S & (P ^ D)); break; \ + case 0xe3: out = ~(P ^ (S | (D & P))); break; \ + case 0xe4: out = S ^ (D & (P ^ S)); break; \ + case 0xe5: out = ~(P ^ (D | (S & P))); break; \ + case 0xe6: out = S ^ (D & ~(P & S)); break; \ + case 0xe7: out = ~((S ^ P) & (P ^ D)); break; \ + case 0xe8: out = S ^ ((S ^ P) & (D ^ S)); break; \ + case 0xe9: out = ~(D ^ (S ^ (P & ~(D & S)))); break; \ + case 0xea: out = D | (P & S); break; \ + case 0xeb: out = D | ~(P ^ S); break; \ + case 0xec: out = S | (D & P); break; \ + case 0xed: out = S | ~(D ^ P); break; \ + case 0xee: out = D | S; break; \ + case 0xef: out = S | (D | ~P); break; \ + case 0xf0: out = P; break; \ + case 0xf1: out = P | ~(D | S); break; \ + case 0xf2: out = P | (D & ~S); break; \ + case 0xf3: out = P | ~S; break; \ + case 0xf4: out = P | (S & ~D); break; \ + case 0xf5: out = P | ~D; break; \ + case 0xf6: out = P | (D ^ S); break; \ + case 0xf7: out = P | ~(D & S); break; \ + case 0xf8: out = P | (D & S); break; \ + case 0xf9: out = P | ~(D ^ S); break; \ + case 0xfa: out = D | P; break; \ + case 0xfb: out = D | (P | ~S); break; \ + case 0xfc: out = P | S; break; \ + case 0xfd: out = P | (S | ~D); break; \ + case 0xfe: out = D | (P | S); break; \ + case 0xff: out = ~0; break; \ + } \ + } + +static void +et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000) +{ + svga_t *svga = &et4000->svga; + uint8_t pattern, source, dest; + uint8_t rop; + int mixmap; + + while (count-- && et4000->acl.y_count >= 0) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; + + if (cpu_input == 1) { + source = src_dat & 0xff; + src_dat >>= 8; + } else /*The source data is from the display memory if the Control Routing register is not set to 1*/ + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + mixmap = mix_dat & 1; + + /*Now determine the Raster Operation*/ + rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + mix_dat >>= 1; + mix_dat |= 0x80000000; + + ROPMIX(rop, dest, pattern, source, dest); + + /*Write the data*/ + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = dest; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + + if (et4000->acl.internal.xy_dir & 1) { + et4000->acl.dest_addr--; + et4000->acl.pattern_x--; + et4000->acl.source_x--; + if (et4000->acl.pattern_x < 0) + et4000->acl.pattern_x += (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); + if (et4000->acl.source_x < 0) + et4000->acl.source_x += (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); + } else { + et4000->acl.dest_addr++; + et4000->acl.pattern_x++; + et4000->acl.source_x++; + if (et4000->acl.pattern_x >= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) + et4000->acl.pattern_x -= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); + if (et4000->acl.source_x >= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) + et4000->acl.source_x -= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); + } + + et4000->acl.x_count--; + if (et4000->acl.x_count == 0xffff) { + et4000->acl.x_count = et4000->acl.internal.count_x; + + if (et4000->acl.internal.xy_dir & 2) { + et4000->acl.pattern_addr -= (et4000->acl.internal.pattern_off + 1); + et4000->acl.source_addr -= (et4000->acl.internal.source_off + 1); + et4000->acl.dest_addr -= (et4000->acl.internal.dest_off + 1); + et4000->acl.pattern_y--; + if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) { + et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; + et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); + } + et4000->acl.source_y--; + if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) { + et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; + et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); + } + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000->acl.pattern_addr += (et4000->acl.internal.pattern_off + 1); + et4000->acl.source_addr += (et4000->acl.internal.source_off + 1); + et4000->acl.dest_addr += (et4000->acl.internal.dest_off + 1); + et4000->acl.pattern_y++; + if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { + et4000->acl.pattern_y = 0; + et4000->acl.pattern_addr = et4000->acl.pattern_back; + } + et4000->acl.source_y++; + if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { + et4000->acl.source_y = 0; + et4000->acl.source_addr = et4000->acl.source_back; + } + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + (et4000->acl.internal.dest_off + 1); + } + + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; + + et4000->acl.y_count--; + if (et4000->acl.y_count == 0xffff) { + et4000->acl.status &= ~ACL_XYST; + if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { + et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); + et4000->acl.status &= ~ACL_SSO; + } + et4000->acl.cpu_input_num = 0; + return; + } + + if (cpu_input) + return; + } + } +} + +static void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000) { svga_t *svga = &et4000->svga; - int c, d; uint8_t pattern, source, dest, out; uint8_t rop; int mixdat; - if (!(et4000->acl.status & ACL_XYST) && (et4000->type >= ET4000W32P_REVC)) - return; + if (!(et4000->acl.status & ACL_XYST)) { + et4000w32_log("XY Block not started\n"); + return; + } if (et4000->acl.internal.xy_dir & 0x80) { /* Line draw */ + et4000w32_log("Line draw\n"); while (count--) { et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; @@ -1080,12 +1595,9 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 } et4000->acl.mix_addr++; rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - for (c = 0; c < 8; c++) { - d = (dest & (1 << c)) ? 1 : 0; - if (source & (1 << c)) d |= 2; - if (pattern & (1 << c)) d |= 4; - if (rop & (1 << d)) out |= (1 << c); - } + + ROPMIX(rop, dest, pattern, source, out); + et4000w32_log("%06X = %02X\n", et4000->acl.dest_addr & et4000->vram_mask, out); if (!(et4000->acl.internal.ctrl_routing & 0x40)) { svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; @@ -1157,80 +1669,77 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 } } } else { - while (count--) { - et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); + et4000w32_log("BitBLT: count = %i\n", count); + while (count-- && et4000->acl.y_count >= 0) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - et4000w32_log("%i %06X %06X %02X %02X ", et4000->acl.pattern_y, (et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask, (et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask, pattern, source); - - if (cpu_input == 2) { - source = sdat & 0xff; - sdat >>= 8; - } - dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - out = 0; - et4000w32_log("%06X %02X %i %08X %08X ", dest, et4000->acl.dest_addr, mix & 1, mix, et4000->acl.mix_addr); - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); - et4000w32_log("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask]); - } else { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } - - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - for (c = 0; c < 8; c++) { - d = (dest & (1 << c)) ? 1 : 0; - if (source & (1 << c)) d |= 2; - if (pattern & (1 << c)) d |= 4; - if (rop & (1 << d)) out |= (1 << c); - } - et4000w32_log("%06X = %02X\n", et4000->acl.dest_addr & et4000->vram_mask, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; - svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; - } else { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } - - if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000); - else et4000w32_incx(1, et4000); - - et4000->acl.internal.pos_x++; - if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x) { - if (et4000->acl.internal.xy_dir & 2) { - et4000w32_decy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + if (cpu_input == 2) { + source = sdat & 0xff; + sdat >>= 8; + } else + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + out = 0; + + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); } else { - et4000w32_incy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; + mixdat = mix & 1; + mix >>= 1; + mix |= 0x80000000; } - et4000->acl.pattern_x = et4000->acl.pattern_x_back; - et4000->acl.source_x = et4000->acl.source_x_back; + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x = 0; - if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); - return; + ROPMIX(rop, dest, pattern, source, out); + + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + } else { + et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; } - if (cpu_input) - return; + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); + + et4000->acl.x_count--; + if (et4000->acl.x_count == 0xffff) { + if (et4000->acl.internal.xy_dir & 2) { + et4000w32_decy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000w32_incy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; + } - if (et4000->acl.internal.ctrl_routing & 0x40) { - if (et4000->acl.cpu_dat_pos & 3) - et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); - return; + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; + + et4000->acl.y_count--; + et4000->acl.x_count = et4000->acl.internal.count_x; + if (et4000->acl.y_count == 0xffff) { + et4000w32_log("BitBLT end\n"); + et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + return; + } + + if (cpu_input) + return; + + if (et4000->acl.internal.ctrl_routing & 0x40) { + if (et4000->acl.cpu_dat_pos & 3) + et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); + return; + } } } - } } } diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 107a1773f..d32871c22 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -40,7 +40,7 @@ typedef struct paradise_t rom_t bios_rom; - uint8_t pr0a, pr0b, pr1, pr5, bank_mask; + uint8_t bank_mask; enum { @@ -54,7 +54,7 @@ typedef struct paradise_t uint32_t read_bank[4], write_bank[4]; int interlace; - int check; + int check, check2; struct { uint8_t reg_block_ptr; @@ -81,7 +81,7 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; svga_t *svga = ¶dise->svga; - uint8_t old, o; + uint8_t old; if (paradise->vram_mask <= ((512 << 10) - 1)) paradise->bank_mask = 0x7f; @@ -94,15 +94,14 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3c5: - if (svga->seqaddr > 7) - { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return; - svga->seqregs[svga->seqaddr & 0x1f] = val; - if (svga->seqaddr == 0x11) { - paradise_remap(paradise); - } - return; + if (svga->seqaddr > 7) { + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) + return; + svga->seqregs[svga->seqaddr & 0x1f] = val; + if (svga->seqaddr == 0x11) { + paradise_remap(paradise); + } + return; } break; @@ -115,53 +114,45 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) case 0x3cf: if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { - if ((paradise->pr5 & 7) != 5) + if ((svga->gdcreg[0x0f] & 7) != 5) return; } + switch (svga->gdcaddr) { case 6: - if (val & 8) - svga->banked_mask = 0x7fff; - else - svga->banked_mask = 0xffff; - if (svga->gdcreg[6] != val) - svga->gdcreg[6] = val; + if ((svga->gdcreg[6] & 0x0c) != (val & 0x0c)) { + switch (val & 0x0c) { + case 0x00: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x04: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x08: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0x0c: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + svga->gdcreg[6] = val; paradise_remap(paradise); - break; + return; case 9: - paradise->pr0a = val & paradise->bank_mask; - paradise_remap(paradise); - break; case 0x0a: - paradise->pr0b = val & paradise->bank_mask; + svga->gdcreg[svga->gdcaddr] = val & paradise->bank_mask; paradise_remap(paradise); - break; + return; case 0x0b: - paradise->pr1 = val; + svga->gdcreg[0x0b] = val; paradise_remap(paradise); - break; - case 0x0d: - o = svga->gdcreg[0x0d]; - svga->gdcreg[0x0d] = val; - if ((o ^ val) & 0x18) - svga_recalctimings(svga); - break; - case 0x0e: - o = svga->gdcreg[0x0e]; - svga->gdcreg[0x0e] = val; - if ((o ^ val) & 0x01) - svga_recalctimings(svga); - break; - case 0x0c: - svga->gdcreg[0x0c] = val; - break; - case 0x0f: - paradise->pr5 = val; - break; - default: - svga->gdcreg[svga->gdcaddr] = val; - break; + return; } break; @@ -216,10 +207,8 @@ uint8_t paradise_in(uint16_t addr, void *p) { if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) return 0xff; - if (paradise->type < WD90C30) { - if (svga->seqaddr > 0x12) + if (svga->seqaddr > 0x12) return 0xff; - } return svga->seqregs[svga->seqaddr & 0x1f]; } break; @@ -231,36 +220,21 @@ uint8_t paradise_in(uint16_t addr, void *p) case 0x3cf: if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { - if (paradise->pr5 & 0x10) + if (svga->gdcreg[0x0f] & 0x10) return 0xff; } switch (svga->gdcaddr) { - case 9: - return paradise->pr0a; - case 0x0a: - return paradise->pr0b; case 0x0b: - if (paradise->vram_mask == (512 << 10) - 1) { - paradise->pr1 |= 0xc0; - paradise->pr1 &= ~0x40; - } else if (paradise->vram_mask == (1024 << 10) - 1) { - paradise->pr1 |= 0xc0; - /*The following is a horrible tweak, but needed to get around black corruption in 1M mode*/ - if (svga->bpp >= 8 && (svga->gdcreg[0x0e] & 0x01) && paradise->check) - paradise->pr1 &= ~0x40; - else if (!(svga->gdcreg[0x0e] & 0x01) && !(svga->crtc[0x14] & 0x40) && paradise->check) - paradise->check = 0; + if (paradise->type == WD90C30) { + if (paradise->vram_mask == ((512 << 10) - 1)) { + svga->gdcreg[0x0b] |= 0xc0; + svga->gdcreg[0x0b] &= ~0x40; + } } - return paradise->pr1; - case 6: - case 0x0c: - case 0x0d: - case 0x0e: - return svga->gdcreg[svga->gdcaddr]; + return svga->gdcreg[0x0b]; + case 0x0f: - return (paradise->pr5 & 0x17) | 0x80; - default: - return svga->gdcreg[svga->gdcaddr]; + return (svga->gdcreg[0x0f] & 0x17) | 0x80; } break; @@ -278,61 +252,46 @@ uint8_t paradise_in(uint16_t addr, void *p) void paradise_remap(paradise_t *paradise) { - svga_t *svga = ¶dise->svga; + svga_t *svga = ¶dise->svga; + paradise->check = 0; - if (svga->seqregs[0x11] & 0x80) { - paradise->read_bank[0] = (paradise->pr0a) << 12; - paradise->read_bank[1] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->read_bank[0]; - paradise->read_bank[3] = paradise->read_bank[1]; - paradise->write_bank[0] = (paradise->pr0b) << 12; - paradise->write_bank[1] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->write_bank[2] = paradise->write_bank[0]; - paradise->write_bank[3] = paradise->write_bank[1]; - } else if (paradise->pr1 & 8) { - if (svga->gdcreg[6] & 0x0c) { - paradise->read_bank[0] = (paradise->pr0b) << 12; - paradise->read_bank[1] = ((paradise->pr0a) << 12) + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->read_bank[0]; - paradise->read_bank[3] = paradise->read_bank[1]; - paradise->write_bank[0] = (paradise->pr0b) << 12; - paradise->write_bank[1] = ((paradise->pr0a) << 12) + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->write_bank[2] = paradise->write_bank[0]; - paradise->write_bank[3] = paradise->write_bank[1]; - } else { - paradise->read_bank[0] = (paradise->pr0b) << 12; - paradise->read_bank[1] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->read_bank[2] = (paradise->pr0a) << 12; - paradise->read_bank[3] = paradise->read_bank[2] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->write_bank[0] = (paradise->pr0b) << 12; - paradise->write_bank[1] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->write_bank[2] = (paradise->pr0a) << 12; - paradise->write_bank[3] = paradise->write_bank[2] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - } - } else { - paradise->read_bank[0] = (paradise->pr0a) << 12; - paradise->write_bank[0] = (paradise->pr0a) << 12; - paradise->read_bank[1] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->write_bank[1] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->read_bank[0]; - paradise->write_bank[2] = paradise->write_bank[0]; - paradise->read_bank[3] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - paradise->write_bank[3] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000); - } - - if (paradise->bank_mask == 0x7f) { - paradise->read_bank[1] &= 0x7ffff; - paradise->write_bank[1] &= 0x7ffff; + if (svga->seqregs[0x11] & 0x80) { + paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[0x0a] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } else if (svga->gdcreg[0x0b] & 0x08) { + if (svga->gdcreg[6] & 0x0c) { + paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } else { + paradise->read_bank[0] = paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = paradise->write_bank[1] = (svga->gdcreg[0xa] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[2] = paradise->write_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[3] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } + } else { + paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[9] << 12; + paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } + + if ((((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4 && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[6] >> 2) & 3) == 1)) + paradise->check = 1; + + if (paradise->bank_mask == 0x7f) { + paradise->read_bank[1] &= 0x7ffff; + paradise->write_bank[1] &= 0x7ffff; + } } void paradise_recalctimings(svga_t *svga) { paradise_t *paradise = (paradise_t *) svga->p; - if (svga->gdcreg[0x0d] & 0x08) svga->ma_latch |= 0x10000; - if (svga->gdcreg[0x0d] & 0x10) svga->ma_latch |= 0x20000; - svga->lowres = !(svga->gdcreg[0x0e] & 0x01); if (paradise->type == WD90C30) { @@ -355,8 +314,6 @@ void paradise_recalctimings(svga_t *svga) if (paradise->type < WD90C30) { if (svga->bpp >= 8 && !svga->lowres) { - if ((svga->crtc[0x17] == 0xc2) && (svga->crtc[0x14] & 0x40)) - paradise->check = 1; svga->render = svga_render_8bpp_highres; } } else { @@ -368,8 +325,6 @@ void paradise_recalctimings(svga_t *svga) svga->render = svga_render_15bpp_highres; svga->hdisp >>= 1; } else { - if ((svga->crtc[0x17] == 0xc2) && (svga->crtc[0x14] & 0x40)) - paradise->check = 1; svga->render = svga_render_8bpp_highres; } } @@ -380,20 +335,94 @@ static void paradise_write(uint32_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; svga_t *svga = ¶dise->svga; + uint32_t prev_addr, prev_addr2; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } + svga_write_linear(addr, val, svga); } static void paradise_writew(uint32_t addr, uint16_t val, void *p) { paradise_t *paradise = (paradise_t *)p; svga_t *svga = ¶dise->svga; + uint32_t prev_addr, prev_addr2; - addr &= svga->banked_mask; addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - + + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } + svga_writew_linear(addr, val, svga); } @@ -401,9 +430,46 @@ static uint8_t paradise_read(uint32_t addr, void *p) { paradise_t *paradise = (paradise_t *)p; svga_t *svga = ¶dise->svga; - - addr &= svga->banked_mask; + uint32_t prev_addr, prev_addr2; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } return svga_read_linear(addr, svga); } @@ -411,11 +477,48 @@ static uint16_t paradise_readw(uint32_t addr, void *p) { paradise_t *paradise = (paradise_t *)p; svga_t *svga = ¶dise->svga; - - addr &= svga->banked_mask; + uint32_t prev_addr, prev_addr2; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } - return svga_readw_linear(addr, svga); + return svga_readw_linear(addr, svga); } void *paradise_init(const device_t *info, uint32_t memsize) @@ -653,9 +756,6 @@ static const device_config_t paradise_pvga1a_config[] = { "512 kB", 512 }, - { - "1 MB", 1024 - }, { "" } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 7dff04e4a..30c0df216 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -62,9 +62,11 @@ #define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" #define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" #define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" +#define ROM_NUMBER9_9FX_531 "roms/video/s3/numbernine.BIN" #define ROM_PHOENIX_VISION868 "roms/video/s3/1-DSV3868.BIN" #define ROM_MIROVIDEO40SV_ERGO_968_PCI "roms/video/s3/S3_968PCI_TVP3026_miroVideo40SV_PCI_1.04.BIN" #define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN" +#define ROM_NUMBER9_9FX_771 "roms/video/s3/no9motionfx771.BIN" #define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN" enum @@ -100,7 +102,9 @@ enum S3_MIROCRYSTAL20SV_964, S3_MIROCRYSTAL20SD_864, S3_PHOENIX_VISION968, - S3_MIROCRYSTAL8S_805 + S3_MIROCRYSTAL8S_805, + S3_NUMBER9_9FX_531, + S3_NUMBER9_9FX_771 }; @@ -1140,18 +1144,30 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; s3->accel.pix_trans[0] = val; if (s3->accel.cmd & 0x100) { - if (!(s3->accel.cmd & 0x600)) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else { + if (s3->color_16bit) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); + } else { + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); + } + break; } } break; @@ -2442,7 +2458,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) rs3 = 0; bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || - s3->card_type == S3_PHOENIX_VISION968))) + s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { rs3 = !!(svga->crtc[0x55] & 0x02); @@ -2451,7 +2467,9 @@ s3_out(uint16_t addr, uint8_t val, void *p) att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); else if (s3->chip <= S3_86C924) { sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - } else + } else if (s3->card_type == S3_NUMBER9_9FX_531) + att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + else sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); return; @@ -2728,7 +2746,7 @@ s3_in(uint16_t addr, void *p) rs3 = !!(svga->crtc[0x55] & 0x02); return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || - s3->card_type == S3_PHOENIX_VISION968))) + s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { rs3 = !!(svga->crtc[0x55] & 0x02); @@ -2737,6 +2755,8 @@ s3_in(uint16_t addr, void *p) return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->chip <= S3_86C924) return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + else if (s3->card_type == S3_NUMBER9_9FX_531) + return att498_ramdac_in(addr, rs2, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); break; @@ -2839,7 +2859,7 @@ static void s3_recalctimings(svga_t *svga) else ibm_rgb528_recalctimings(svga->ramdac, svga); } else - svga->interlace = svga->crtc[0x42] & 0x20; + svga->interlace = !!(svga->crtc[0x42] & 0x20); if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32) clk_sel = svga->crtc[0x42] & 0x0f; @@ -2856,10 +2876,25 @@ static void s3_recalctimings(svga_t *svga) if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || - s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805) { + s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || + s3->card_type == S3_NUMBER9_9FX_531) { + if (!(svga->crtc[0x5e] & 0x04)) + svga->vblankstart = svga->dispend; if (svga->bpp != 32) { if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ s3->width = 2048; + else { + if (s3->card_type == S3_MIROCRYSTAL10SD_805) { + if (svga->hdisp == 1280 && s3->width == 1024) { + s3->width = 1280; + } + } + } + } else { + if (s3->card_type == S3_NUMBER9_9FX_531) { + if (svga->hdisp == 1600 && s3->width == 1600) + s3->width = 800; + } } } else if (s3->chip == S3_86C928) { if (svga->bpp == 15) { @@ -2889,15 +2924,16 @@ static void s3_recalctimings(svga_t *svga) if (s3->chip != S3_VISION868) { if (s3->chip == S3_86C928) { if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) - svga->hdisp *= 2; + svga->hdisp <<= 1; } else if ((s3->chip != S3_86C801) && (s3->chip != S3_86C805) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968)) { if (s3->width == 1280 || s3->width == 1600) - svga->hdisp *= 2; + svga->hdisp <<= 1; } else if (s3->card_type == S3_SPEA_MERCURY_P64V) { if (s3->width == 1280 || s3->width == 1600) - svga->hdisp *= 2; - } + svga->hdisp <<= 1; + } else if (s3->card_type == S3_NUMBER9_9FX_771) + svga->hdisp <<= 1; if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { @@ -2948,19 +2984,21 @@ static void s3_recalctimings(svga_t *svga) if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) - svga->hdisp *= 2; + svga->hdisp <<= 1; else if (s3->chip != S3_VISION968) - svga->hdisp /= 2; + svga->hdisp >>= 1; } if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { if (s3->width == 1280 || s3->width == 1600) - svga->hdisp *= 2; + svga->hdisp <<= 1; + else if (s3->card_type == S3_NUMBER9_9FX_771) + svga->hdisp <<= 1; } if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { if (svga->hdisp == (1408*2)) - svga->hdisp /= 2; + svga->hdisp >>= 1; else svga->hdisp = s3->width; } @@ -2973,21 +3011,22 @@ static void s3_recalctimings(svga_t *svga) if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { if (s3->chip == S3_86C928) - svga->hdisp *= 2; + svga->hdisp <<= 1; else if (s3->chip != S3_VISION968) - svga->hdisp /= 2; - } else if ((s3->card_type == S3_SPEA_MIRAGE_86C801) || (s3->card_type == S3_SPEA_MIRAGE_86C805)) { - svga->hdisp /= 2; - } + svga->hdisp >>= 1; + } else if ((s3->card_type == S3_SPEA_MIRAGE_86C801) || (s3->card_type == S3_SPEA_MIRAGE_86C805)) + svga->hdisp >>= 1; if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { if (s3->width == 1280 || s3->width == 1600) - svga->hdisp *= 2; + svga->hdisp <<= 1; + else if (s3->card_type == S3_NUMBER9_9FX_771) + svga->hdisp <<= 1; } if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { if (svga->hdisp == (1408*2)) - svga->hdisp /= 2; + svga->hdisp >>= 1; else svga->hdisp = s3->width; } @@ -3013,12 +3052,13 @@ static void s3_recalctimings(svga_t *svga) if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { if (s3->chip == S3_VISION868) - svga->hdisp /= 2; + svga->hdisp >>= 1; else - svga->hdisp /= 4; + svga->hdisp >>= 2; } - if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V)) - svga->hdisp *= 2; + if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V || + s3->card_type == S3_NUMBER9_9FX_771)) + svga->hdisp <<= 1; if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { @@ -3110,11 +3150,11 @@ static void s3_trio64v_recalctimings(svga_t *svga) break; case 15: svga->render = svga_render_15bpp_highres; - svga->hdisp /= 2; + svga->hdisp >>= 1; break; case 16: svga->render = svga_render_16bpp_highres; - svga->hdisp /= 2; + svga->hdisp >>= 1; break; case 24: svga->render = svga_render_24bpp_highres; @@ -6530,6 +6570,7 @@ static void s3_reset(void *priv) case S3_ELSAWIN2KPROX: case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: + case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: if (s3->pci) { svga->crtc[0x53] = 0x18; @@ -6544,6 +6585,7 @@ static void s3_reset(void *priv) } break; + case S3_NUMBER9_9FX_531: case S3_PHOENIX_VISION868: if (s3->pci) { svga->crtc[0x53] = 0x18; @@ -6679,6 +6721,11 @@ static void *s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); break; + case S3_NUMBER9_9FX_531: + bios_fn = ROM_NUMBER9_9FX_531; + chip = S3_VISION868; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); + break; case S3_PHOENIX_VISION868: bios_fn = ROM_PHOENIX_VISION868; chip = S3_VISION868; @@ -6710,6 +6757,11 @@ static void *s3_init(const device_t *info) chip = S3_VISION968; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); break; + case S3_NUMBER9_9FX_771: + bios_fn = ROM_NUMBER9_9FX_771; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; case S3_PHOENIX_VISION968: bios_fn = ROM_PHOENIX_VISION968; chip = S3_VISION968; @@ -6887,7 +6939,7 @@ static void *s3_init(const device_t *info) if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) svga->dac_hwcursor_draw = bt48x_hwcursor_draw; else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && (info->local == S3_ELSAWIN2KPROX || - info->local == S3_PHOENIX_VISION968))) + info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771))) svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; else if (chip == S3_VISION968 && (info->local == S3_SPEA_MERCURY_P64V || info->local == S3_MIROVIDEO40SV_ERGO_968)) svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; @@ -7048,7 +7100,7 @@ static void *s3_init(const device_t *info) case S3_PARADISE_BAHAMAS64: case S3_PHOENIX_VISION864: - case S3_MIROCRYSTAL20SD_864: + case S3_MIROCRYSTAL20SD_864: /*BIOS 3.xx has a SDAC ramdac.*/ svga->decode_mask = (8 << 20) - 1; if (info->local == S3_PARADISE_BAHAMAS64 || info->local == S3_MIROCRYSTAL20SD_864) stepping = 0xc0; /*Vision864*/ @@ -7085,6 +7137,7 @@ static void *s3_init(const device_t *info) case S3_ELSAWIN2KPROX: case S3_SPEA_MERCURY_P64V: case S3_MIROVIDEO40SV_ERGO_968: + case S3_NUMBER9_9FX_771: case S3_PHOENIX_VISION968: svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision968*/ @@ -7102,7 +7155,8 @@ static void *s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; } - if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968) + if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || + info->local == S3_NUMBER9_9FX_771) svga->ramdac = device_add(&ibm_rgb528_ramdac_device); else svga->ramdac = device_add(&tvp3026_ramdac_device); @@ -7111,6 +7165,7 @@ static void *s3_init(const device_t *info) svga->getclock = icd2061_getclock; break; + case S3_NUMBER9_9FX_531: case S3_PHOENIX_VISION868: svga->decode_mask = (8 << 20) - 1; s3->id = 0xe1; /*Vision868*/ @@ -7128,10 +7183,16 @@ static void *s3_init(const device_t *info) svga->crtc[0x59] = 0x00; svga->crtc[0x5a] = 0x0a; } - - svga->ramdac = device_add(&sdac_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = sdac_getclock; + + if (info->local == S3_NUMBER9_9FX_531) { + svga->ramdac = device_add(&att498_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + } else { + svga->ramdac = device_add(&sdac_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; + } break; case S3_PHOENIX_TRIO32: @@ -7261,6 +7322,11 @@ static int s3_phoenix_vision864_available(void) return rom_present(ROM_PHOENIX_VISION864); } +static int s3_9fx_531_available(void) +{ + return rom_present(ROM_NUMBER9_9FX_531); +} + static int s3_phoenix_vision868_available(void) { return rom_present(ROM_PHOENIX_VISION868); @@ -7286,6 +7352,11 @@ static int s3_mirovideo_40sv_ergo_968_pci_available(void) return rom_present(ROM_MIROVIDEO40SV_ERGO_968_PCI); } +static int s3_9fx_771_available(void) +{ + return rom_present(ROM_NUMBER9_9FX_771); +} + static int s3_phoenix_vision968_available(void) { return rom_present(ROM_PHOENIX_VISION968); @@ -7448,7 +7519,7 @@ static const device_config_t s3_phoenix_trio32_config[] = static const device_config_t s3_standard_config[] = { { - "memory", "Video memory size", CONFIG_SELECTION, "", 4, "", { 0 }, + "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 }, { { "1 MB", 1 @@ -7750,6 +7821,20 @@ const device_t s3_diamond_stealth64_964_pci_device = s3_standard_config }; +const device_t s3_9fx_771_pci_device = +{ + "S3 Vision968 PCI (Number 9 9FX 771)", + DEVICE_PCI, + S3_NUMBER9_9FX_771, + s3_init, + s3_close, + s3_reset, + { s3_9fx_771_available }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + const device_t s3_phoenix_vision968_pci_device = { "S3 Vision968 PCI (Phoenix)", @@ -7989,6 +8074,20 @@ const device_t s3_phoenix_vision864_pci_device = s3_standard_config }; +const device_t s3_9fx_531_pci_device = +{ + "S3 Vision868 PCI (Number 9 9FX 531)", + DEVICE_PCI, + S3_NUMBER9_9FX_531, + s3_init, + s3_close, + s3_reset, + { s3_9fx_531_available }, + s3_speed_changed, + s3_force_redraw, + s3_9fx_config +}; + const device_t s3_phoenix_vision868_vlb_device = { "S3 Vision868 VLB (Phoenix)", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 32865df01..f1752d611 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -72,9 +72,12 @@ video_cards[] = { { "cl_gd5402_isa", &gd5402_isa_device }, { "cl_gd5420_isa", &gd5420_isa_device }, { "cl_gd5422_isa", &gd5422_isa_device }, + { "cl_gd5426_isa", &gd5426_isa_device }, + { "cl_gd5426_diamond_a1_isa", &gd5426_diamond_speedstar_pro_a1_isa_device }, { "cl_gd5428_isa", &gd5428_isa_device }, { "cl_gd5429_isa", &gd5429_isa_device }, { "cl_gd5434_isa", &gd5434_isa_device }, + { "cl_gd5434_diamond_a3_isa", &gd5434_diamond_speedstar_64_a3_isa_device }, { "compaq_cga", &compaq_cga_device }, { "compaq_cga_2", &compaq_cga_2_device }, { "compaq_ega", &cpqega_device }, @@ -123,14 +126,15 @@ video_cards[] = { { "radius_mc", &radius_svga_multiview_mca_device }, { "mach64gx_pci", &mach64gx_pci_device }, { "mach64vt2", &mach64vt2_device }, + { "et4000w32p_revc_pci", &et4000w32p_revc_pci_device }, { "et4000w32p_pci", &et4000w32p_cardex_pci_device }, { "et4000w32p_nc_pci", &et4000w32p_noncardex_pci_device }, - { "et4000w32p_revc_pci", &et4000w32p_revc_pci_device }, { "cl_gd5430_pci", &gd5430_pci_device, }, { "cl_gd5434_pci", &gd5434_pci_device }, { "cl_gd5436_pci", &gd5436_pci_device }, { "cl_gd5440_pci", &gd5440_pci_device }, { "cl_gd5446_pci", &gd5446_pci_device }, + { "cl_gd5446_stb_pci", &gd5446_stb_pci_device }, { "cl_gd5480_pci", &gd5480_pci_device }, { "ctl3d_banshee_pci", &creative_voodoo_banshee_device }, { "stealth32_pci", &et4000w32p_pci_device }, @@ -146,8 +150,10 @@ video_cards[] = { { "px_trio64_pci", &s3_phoenix_trio64_pci_device }, { "elsawin2kprox_pci", &s3_elsa_winner2000_pro_x_pci_device }, { "mirovideo40sv_pci", &s3_mirovideo_40sv_ergo_968_pci_device }, + { "n9_9fx_771_pci", &s3_9fx_771_pci_device }, { "px_vision968_pci", &s3_phoenix_vision968_pci_device }, { "spea_mercury64p_pci", &s3_spea_mercury_p64v_pci_device }, + { "n9_9fx_531_pci", &s3_9fx_531_pci_device }, { "px_vision868_pci", &s3_phoenix_vision868_pci_device }, { "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device }, { "trio64v2dx_pci", &s3_trio64v2_dx_pci_device }, @@ -164,7 +170,6 @@ video_cards[] = { { "mystique", &mystique_device }, { "mystique_220", &mystique_220_device }, #endif - { "cl_gd5446_stb_pci", &gd5446_stb_pci_device }, { "tgui9440_pci", &tgui9440_pci_device }, { "tgui9660_pci", &tgui9660_pci_device }, { "tgui9680_pci", &tgui9680_pci_device }, @@ -173,16 +178,17 @@ video_cards[] = { { "voodoo3_3k_pci", &voodoo_3_3000_device }, { "mach64gx_vlb", &mach64gx_vlb_device }, { "et4000w32i_vlb", &et4000w32i_vlb_device }, - { "et4000w32p_vlb", &et4000w32p_cardex_vlb_device }, - { "et4000w32p_nc_vlb", &et4000w32p_noncardex_vlb_device }, { "et4000w32p_revc_vlb", &et4000w32p_revc_vlb_device }, - { "cl_gd5424_vlb", &gd5424_vlb_device }, - { "cl_gd5428_vlb", &gd5428_vlb_device }, - { "cl_gd5429_vlb", &gd5429_vlb_device }, - { "cl_gd5434_vlb", &gd5434_vlb_device }, + { "et4000w32p_vlb", &et4000w32p_cardex_vlb_device }, { "stealth32_vlb", &et4000w32p_vlb_device }, + { "et4000w32p_nc_vlb", &et4000w32p_noncardex_vlb_device }, + { "cl_gd5424_vlb", &gd5424_vlb_device }, { "cl_gd5426_vlb", &gd5426_vlb_device }, - { "cl_gd5430_vlb", &gd5430_vlb_device }, + { "cl_gd5428_vlb", &gd5428_vlb_device }, + { "cl_gd5428_diamond_b1_vlb", &gd5428_diamond_speedstar_pro_b1_vlb_device }, + { "cl_gd5429_vlb", &gd5429_vlb_device }, + { "cl_gd5430_vlb", &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, + { "cl_gd5434_vlb", &gd5434_vlb_device }, { "metheus928_vlb", &s3_metheus_86c928_vlb_device }, { "mirocrystal8s_vlb", &s3_mirocrystal_8s_805_vlb_device }, { "mirocrystal10sd_vlb", &s3_mirocrystal_10sd_805_vlb_device }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index d678e2699..2d2ad272f 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -730,6 +730,7 @@ VIDOBJ := agpgart.o video.o \ vid_tvga.o \ vid_tgui9440.o vid_tkd8001_ramdac.o \ vid_att20c49x_ramdac.o \ + vid_att2xc498_ramdac.o \ vid_s3.o vid_s3_virge.o \ vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ vid_ogc.o \ From 93e4e94c7c9ca6b11ea16e60dcaacb55df9ab092 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 18 Nov 2021 20:28:46 -0300 Subject: [PATCH 15/19] Jenkins: Commit new Jenkinsfile --- .ci/Jenkinsfile | 259 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 173 insertions(+), 86 deletions(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 360b5e1b7..0d9e722a4 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -15,48 +15,92 @@ * Copyright 2021 RichardG. */ -/* Run this on /script to get all approvals required to sync build numbers across jobs: +def osArchs = [ + 'Windows': ['32', '64'], + 'Linux': ['x86', 'x86_64', 'arm32', 'arm64'] +] -def approval = org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval.get() -approval.approveSignature('staticMethod jenkins.model.Jenkins getInstance') -approval.approveSignature('method hudson.model.ItemGroup getItem java.lang.String') -approval.approveSignature('field hudson.model.Job nextBuildNumber') -approval.approveSignature('method hudson.model.Job saveNextBuildNumber') +def archNames = [ + '32': 'x86 (32-bit)', + 'x86': 'x86 (32-bit)', + '64': 'x64 (64-bit)', + 'x86_64': 'x64 (64-bit)', + 'arm32': 'ARM (32-bit)', + 'arm64': 'ARM (64-bit)' +] -*/ +def dynarecNames = [ + 'ODR': 'Old Recompiler (recommended)', + 'NDR': 'New Recompiler (beta)', + 'NoDR': 'No Dynamic Recompiler' +] + +def dynarecArchs = [ + '32': ['ODR', 'NDR'], + 'x86': ['ODR', 'NDR'], + '64': ['ODR', 'NDR'], + 'x86_64': ['ODR', 'NDR'], + 'arm32': ['NDR'], + 'ARM32': ['NDR'], + 'arm64': ['NDR'], + 'ARM64': ['NDR'] +] + +def dynarecFlags = [ + 'ODR': '-D NEW_DYNAREC=OFF', + 'NDR': '-D NEW_DYNAREC=ON', + 'NoDR': '-D DYNAREC=OFF' +] + +def dynarecSlugs = [ + 'ODR': '', + 'NDR': '-NDR', + 'NoDR': '' +] + +def presets = [ + 'Regular', + 'Debug' +] + +def presetSlugs = [ + 'Regular': '', + 'Debug': '-Debug', + 'Dev': '-Dev' +] + +def presetFlags = [ + 'Regular': '--preset=regular', + 'Debug': '--preset=debug', + 'Dev': '--preset=experimental -D VNC=OFF' +] + +def anyFailure = false def gitClone() { - cleanWs() if (env.GIT_COMMIT == null) - env.GIT_COMMIT = BRANCH - println "[-] Building git tag [${env.GIT_COMMIT}]" + env.GIT_COMMIT = 'master' + println "[-] Using git tag [${env.GIT_COMMIT}]" def scmVars = checkout scm: [$class: 'GitSCM', branches: [[name: env.GIT_COMMIT]], userRemoteConfigs: [[url: 'https://github.com/86Box/86Box.git']]] env.GIT_COMMIT = scmVars.GIT_COMMIT } -def windowsBuild() { - bat 'C:\\msys64\\msys2_shell.cmd -msys2 -defterm -here -no-start -c "exec .ci/build.sh"' +def removeDir(dir) { + if (isUnix()) + sh "rm -rf \"$dir\" || exit 0" + else + bat "if exist \"$dir\" rd /s /q \"$dir\" & exit /b 0" } -def unixBuild() { - sh 'chmod u+x .ci/build.sh && exec .ci/build.sh' +def runBuild(args) { + if (isUnix()) + sh "chmod u+x \"$WORKSPACE/.ci/build.sh\" && exec \"$WORKSPACE/.ci/build.sh\" $args" + else + bat "C:\\msys64\\msys2_shell.cmd -msys2 -defterm -here -no-start -c 'exec \"\$(cygpath -u \\'%WORKSPACE%\\')\"/.ci/build.sh $args'" } -def saveArtifacts() { - archiveArtifacts artifacts: "${env.JOB_BASE_NAME}-*" -} - -def successCount = 0 - -def buildChain = [ - '86Box': '86Box-Dev', - '86Box-Dev': '86Box-DevODR', - '86Box-DevODR': '86Box-Debug', - '86Box-TestBuildPleaseIgnore': '86Box-TestBuildPleaseIgnore2' -] - pipeline { agent none @@ -64,9 +108,6 @@ pipeline { string(name: 'BUILD_TYPE', defaultValue: 'beta', /* !!! CHANGE HERE !!! for build type */ description: "Build type to pass on to CMake. Don't change this, you should instead change the default value on .ci/Jenkinsfile") - string(name: 'BRANCH', - defaultValue: 'master', - description: "Used internally to make sure all downstream builds use the same commit. Don't change this.") } environment { @@ -74,41 +115,105 @@ pipeline { } stages { - stage('Build Windows') { - agent { - node { - label 'windows' - } - } + stage('Source Tarball') { + agent none steps { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - gitClone() - windowsBuild() - saveArtifacts() - - script { - successCount += 1 + script { + /* Run a dummy git clone on any node to try and save the latest commit regardless of executor status. + This avoids a timing issue where HEAD changes between polling and the nodes being available below. + I talked to a few people, and we reached the conclusion that reading the polled commit from within + the pipeline is not really possible (maybe short of switching to a multi-branch pipeline), so we + have to live with this hack, which shortens but doesn't fully eliminate the timing issue's window. */ + node { + /* Ignore exceptions as this is not really critical. */ + try { + gitClone() + } catch (e) {} + try { + cleanWs() + } catch (e) {} } - } - } - } - stage('Build Linux') { - agent { - node { - label 'debian' - } - } + /* Create source tarball. */ + node('Linux') { + try { + /* Run git clone. */ + gitClone() - steps { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - gitClone() - unixBuild() - saveArtifacts() + /* Switch to temp directory. */ + dir(WORKSPACE_TMP) { + /* Clean output directory of potential stale old builds. */ + removeDir('output') - script { - successCount += 1 + /* Switch to output directory. */ + dir('output') { + /* Run source tarball creation process. */ + def packageName = "${env.JOB_BASE_NAME}-Source-b${env.BUILD_NUMBER}" + runBuild("-s \"$packageName\"") + + /* Archive resulting artifacts. */ + archiveArtifacts artifacts: "$packageName*" + } + } + } catch (e) { + /* Mark that a failure occurred. */ + anyFailure = true + + /* Force this stage to fail. */ + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + throw e; + } + } + } + + /* Build here to avoid creating a redundant parent stage on the stage view. */ + osArchs.each { os, thisOsArchs -> + thisOsArchs.each { arch -> + def thisArchDynarecs = dynarecArchs[arch] + if (!thisArchDynarecs) + thisArchDynarecs = ['NoDR'] + thisArchDynarecs.each { dynarec -> + presets.each { preset -> + node(os) { + stage("$os $arch $dynarec $preset") { + try { + /* Run git clone. */ + gitClone() + + /* Switch to temp directory. */ + dir(WORKSPACE_TMP) { + /* Clean output directory of potential stale old builds. */ + removeDir('output') + + /* Switch to output directory. */ + dir('output') { + def packageName = "${env.JOB_BASE_NAME}${dynarecSlugs[dynarec]}${presetSlugs[preset]}-$os-$arch-b${env.BUILD_NUMBER}" + dir(dynarecNames[dynarec]) { + dir("$os - ${archNames[arch]}") { + /* Run build process. */ + runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} -D \"BUILD_TYPE=$BUILD_TYPE\" -D \"EMU_BUILD=build ${env.BUILD_NUMBER}\" -D \"EMU_BUILD_NUMBER=${env.BUILD_NUMBER}\"") + } + } + + /* Archive resulting artifacts. */ + archiveArtifacts artifacts: "**/**/$packageName*" + } + } + } catch (e) { + /* Mark that a failure occurred. */ + anyFailure = true + + /* Force this stage to fail. */ + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { + throw e; + } + } + } + } + } + } + } } } } @@ -118,36 +223,14 @@ pipeline { post { always { script { - /* Trigger next job is applicable. */ - if (buildChain[env.JOB_BASE_NAME]) { - def nextJob = buildChain[env.JOB_BASE_NAME] - - /* Set next build number for the next job. */ - try { - def job = Jenkins.instance.getItem(nextJob) - job.nextBuildNumber = env.BUILD_NUMBER as Integer - job.saveNextBuildNumber() - } catch (Exception e) { - println "[!] Could not set next build number for [$nextJob], make sure all required script approvals are in place" - } - - /* Trigger next job. */ - build propagate: false, - wait: false, - job: nextJob, - parameters: [ - string(name: 'BUILD_TYPE', value: BUILD_TYPE), - string(name: 'BRANCH', value: env.GIT_COMMIT) - ] - } - - if (successCount < 2) { + if (anyFailure) { println "[!] Failing build because a build stage failed" currentBuild.result = 'FAILURE' } if (!env.JOB_BASE_NAME.contains("TestBuildPleaseIgnore")) { try { + /* Notify Discord. */ def result = currentBuild.currentResult.toLowerCase() discordSend webhookURL: DISCORD_WEBHOOK_URL, title: "${env.JOB_BASE_NAME} #${env.BUILD_NUMBER}", @@ -157,11 +240,15 @@ pipeline { enableArtifactsList: false, showChangeset: true - node { /* IRC notifications need a node for whatever reason */ + /* Notify IRC, which needs a node for whatever reason. */ + node { ircNotify() } - } catch (Exception e) { - e.printStackTrace() + } catch (e) { + /* Force this stage to fail. */ + catchError(buildResult: currentBuild.result, stageResult: 'FAILURE') { + throw e; + } } } } From 065366b35be3f8bd997272d52422f24683fbeabb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 18 Nov 2021 20:32:23 -0300 Subject: [PATCH 16/19] Jenkins: Fix build number passing in pipeline --- .ci/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 0d9e722a4..28ef5e005 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -192,7 +192,7 @@ pipeline { dir(dynarecNames[dynarec]) { dir("$os - ${archNames[arch]}") { /* Run build process. */ - runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} -D \"BUILD_TYPE=$BUILD_TYPE\" -D \"EMU_BUILD=build ${env.BUILD_NUMBER}\" -D \"EMU_BUILD_NUMBER=${env.BUILD_NUMBER}\"") + runBuild("-b \"$packageName\" \"$arch\" ${presetFlags[preset]} ${dynarecFlags[dynarec]} -D \"BUILD_TYPE=$BUILD_TYPE\" -D \"EMU_BUILD=build ${env.BUILD_NUMBER}\" -D \"EMU_BUILD_NUM=${env.BUILD_NUMBER}\"") } } From 43039331fc2c74c0c0cbf8c80956dcc510a0a5c2 Mon Sep 17 00:00:00 2001 From: jvernet Date: Fri, 19 Nov 2021 12:22:36 +0100 Subject: [PATCH 17/19] Update fr-FR.rc --- src/win/languages/fr-FR.rc | 72 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index 76060ce8b..e107cf109 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -135,10 +135,10 @@ BEGIN MENUITEM "Activer journaux de IDE\tCtrl+F8", IDM_LOG_IDE # endif # ifdef ENABLE_SERIAL_LOG - MENUITEM "Activer journaux de porte sériel\tCtrl+F3", IDM_LOG_SERIAL + MENUITEM "Activer journaux de port série\tCtrl+F3", IDM_LOG_SERIAL # endif # ifdef ENABLE_NIC_LOG - MENUITEM "Activer journaux de réseau\tCtrl+F9", IDM_LOG_NIC + MENUITEM "Activer journaux du réseau\tCtrl+F9", IDM_LOG_NIC # endif # ifdef ENABLE_LOG_COMMANDS # ifdef ENABLE_LOG_TOGGLES @@ -172,7 +172,7 @@ BEGIN MENUITEM "&Nouvelle image...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "Image &Existante...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "Image Exsistane(&Lecture seule)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "En®istrer", IDM_CASSETTE_RECORD MENUITEM "&Jouer", IDM_CASSETTE_PLAY @@ -200,7 +200,7 @@ BEGIN MENUITEM "&Nouvelle image...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "Image &Existante...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "Image Existante(&Lecture seule)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "E&xport vers 86F...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR @@ -212,7 +212,7 @@ CdromSubmenu MENU DISCARDABLE BEGIN POPUP "" BEGIN - MENUITEM "&Mute", IDM_CDROM_MUTE + MENUITEM "&Couper", IDM_CDROM_MUTE MENUITEM SEPARATOR MENUITEM "E&jecter", IDM_CDROM_EMPTY MENUITEM "&Recharger image précedente", IDM_CDROM_RELOAD @@ -228,7 +228,7 @@ BEGIN MENUITEM "&Nouvelle image...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "Image &Existante...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "Existing image (&Write-protected)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "Image Existante (&Lecture Seule)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "E&jecter", IDM_ZIP_EJECT MENUITEM "&Recharger image précédente", IDM_ZIP_RELOAD @@ -242,7 +242,7 @@ BEGIN MENUITEM "&Nouvelle image...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "Image &Existante...", IDM_MO_IMAGE_EXISTING - MENUITEM "Image Existante (&Write-protected)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "Image Existante (&Lecture Seule)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "E&jecter", IDM_MO_EJECT MENUITEM "&Recharger image précédente", IDM_MO_RELOAD @@ -281,7 +281,7 @@ END #define STR_OK "OK" #define STR_CANCEL "Annuler" -#define STR_GLOBAL "Salve ces paramètres comme valeurs par défaut &globales" +#define STR_GLOBAL "Sauver ces paramètres comme valeurs par défaut &globales" #define STR_DEFAULT "&Défaut" #define STR_LANGUAGE "Langue:" #define STR_ICONSET "Ensemble d'icônes:" @@ -297,10 +297,10 @@ END #define STR_HEIGHT "Hauteur:" #define STR_LOCK_TO_SIZE "Verrouiller à cette taille" -#define STR_MACHINE_TYPE "Type de la machine:" +#define STR_MACHINE_TYPE "Type de machine:" #define STR_MACHINE "Machine:" #define STR_CONFIGURE "Configurer" -#define STR_CPU_TYPE "Typ du processeur:" +#define STR_CPU_TYPE "Type du processeur:" #define STR_SPEED "Vitesse:" #define STR_FPU "FPU:" #define STR_WAIT_STATES "États d'attente:" @@ -338,10 +338,10 @@ END #define STR_LPT1 "Dispositif LPT1:" #define STR_LPT2 "Dispositif LPT2:" #define STR_LPT3 "Dispositif LPT3:" -#define STR_SERIAL1 "Port sériel 1" -#define STR_SERIAL2 "Port sériel 2" -#define STR_SERIAL3 "Port sériel 3" -#define STR_SERIAL4 "Port sériel 4" +#define STR_SERIAL1 "Port série 1" +#define STR_SERIAL2 "Port série 2" +#define STR_SERIAL3 "Port série 3" +#define STR_SERIAL4 "Port série 4" #define STR_PARALLEL1 "Port parallèle 1" #define STR_PARALLEL2 "Port parallèle 2" #define STR_PARALLEL3 "Port parallèle 3" @@ -375,12 +375,12 @@ END #define STR_BLOCK_SIZE "Taille du bloc:" #define STR_FLOPPY_DRIVES "Lecteurs de disquettes:" -#define STR_TURBO "Temps de turbo" +#define STR_TURBO "Turbo" #define STR_CHECKBPB "Vérifier BPB" #define STR_CDROM_DRIVES "Lecterus CD-ROM:" #define STR_MO_DRIVES "Lecteurs magnéto-optiques:" -#define STR_ZIP_DRIVES "Lecterus ZIP:" +#define STR_ZIP_DRIVES "Lecteurs ZIP:" #define STR_250 "ZIP 250" #define STR_ISARTC "Horloge temps réel ISA:" @@ -406,7 +406,7 @@ STRINGTABLE DISCARDABLE BEGIN 2048 "86Box" IDS_2049 "Erreur" - IDS_2050 "Erreur fatal" + IDS_2050 "Erreur fatale" IDS_2051 "" IDS_2052 "Appuyez sur CTRL+ALT+PAGE ↓ pour revenir au mode fenêtré." IDS_2053 "Vitesse" @@ -419,12 +419,12 @@ BEGIN IDS_2060 "Activé" IDS_2061 "Désactivé" IDS_2062 "Tous les images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Images basiques du secteur (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Images de la surface (*.86F)\0*.86F\0" - IDS_2063 "La machine ""%hs"" n'est pas disponible en raison de l'absence de ROMs en le répertoire roms/machines. Basculer vers une machine disponible." + IDS_2063 "La machine ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/machines. Basculer vers une machine disponible." END STRINGTABLE DISCARDABLE BEGIN - IDS_2064 "La carte vidéo ""%hs"" n'est pas disponible en raison de l'absence de ROMs en le répertoire roms/video. Basculer vers une carte vidéo disponible." + IDS_2064 "La carte vidéo ""%hs"" n'est pas disponible en raison de l'absence de ROMs dans le répertoire roms/video. Basculer vers une carte vidéo disponible." IDS_2065 "Machine" IDS_2066 "Affichage" IDS_2067 "Dispositifs d'entrée" @@ -460,10 +460,10 @@ BEGIN IDS_2093 "Impossible d'initialiser PCap" IDS_2094 "Aucun dispositif PCap trouvé" IDS_2095 "Dispositif PCap non valide" - IDS_2096 "Manette(s) de command standard avec 2 boutons" - IDS_2097 "Manette de command standard avec 4 boutons" - IDS_2098 "Manette de command standard avec 6 boutons" - IDS_2099 "Manette de command standard avec 6 boutons" + IDS_2096 "Manette(s) standard avec 2 boutons" + IDS_2097 "Manette standard avec 4 boutons" + IDS_2098 "Manette standard avec 6 boutons" + IDS_2099 "Manette standard avec 6 boutons" IDS_2100 "CH Flightstick Pro" IDS_2101 "Microsoft SideWinder Pad" IDS_2102 "Système de contrôle de vol Thrustmaster" @@ -477,16 +477,16 @@ BEGIN IDS_2110 "Impossible d'initialiser FreeType" IDS_2111 "Impossible d'initialiser SDL, SDL2.dll est nécessaire" IDS_2112 "Etes-vous sûr de vouloir réinitialiser la machine émulée ?" - IDS_2113 "Etes-vous sûr de vouloir sortir du86Box?" + IDS_2113 "Etes-vous sûr de vouloir quitter 86Box?" IDS_2114 "Impossible d'initialiser Ghostscript" IDS_2115 "Magnéto-optique %i (%ls): %ls" IDS_2116 "Images magnéto-optiques (*.IM?;*.MDI)\0*.IM?;*.MDI\0Tous les fichiers (*.*)\0*.*\0" - IDS_2117 "Bienvenues dans 86Box !" + IDS_2117 "Bienvenue dans 86Box !" IDS_2118 "Côntrolleur interne" IDS_2119 "Sortir" IDS_2120 "Pas de ROMs trouvées" IDS_2121 "Voulez-vous sauver les paramètres ?" - IDS_2122 "Ce entraînera la réinitialisation complète de la machine émulée." + IDS_2122 "Cela entraînera la réinitialisation complète de la machine émulée." IDS_2123 "Sauver" IDS_2124 "À propos de 86Box" IDS_2125 "86Box v" EMU_VERSION @@ -499,7 +499,7 @@ BEGIN #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "Assurez-vous que " LIB_NAME_PCAP " est installé e que vou utilizes une connexion de réseau compatible avec " LIB_NAME_PCAP "." + IDS_2129 "Assurez-vous que " LIB_NAME_PCAP " est installé et que vou utilisez une connexion réseau compatible avec " LIB_NAME_PCAP "." IDS_2130 "Configuration non valide" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" @@ -549,22 +549,22 @@ BEGIN IDS_4101 "Personnalisé (grand)..." IDS_4102 "Ajouter un nouveau disque dur" IDS_4103 "Ajouter un disque dur existant" - IDS_4104 "Les images de disque HDI ne peuvent pas être plus grandes de 4 Go." - IDS_4105 "Les images de disque ne peuvent pas être plus grandes de 127 Go." + IDS_4104 "Les images de disque HDI ne peuvent pas avoir une taille supériure à Go." + IDS_4105 "Les images de disque ne peuvent pas avoir un taille supérieure à 127 Go." IDS_4106 "Images de dique dur (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0Tous les fichiers (*.*)\0*.*\0" IDS_4107 "Impossible de lire le fichier" IDS_4108 "Impossible d'écrire le fichier" - IDS_4109 "Les images HDI ou HDX avec une taille de secteur que non est 512 non sont pas prises en charge." - IDS_4110 "USB n'est pas encore pris en charge" - IDS_4111 "Le fichier de la image du sique déjà existe" + IDS_4109 "Les images HDI ou HDX avec une taille de secteur différente de 512 non sont pas prises en charge." + IDS_4110 "USB n'est pas encore pris en charge." + IDS_4111 "Le fichier de l'image disque existe déjà." IDS_4112 "Veuillez spécifier un nom de fichier valide." IDS_4113 "Image de disque créée" IDS_4114 "Assurez-vous que le fichier existe et est lisible." - IDS_4115 "Assurez-vous que est en train d'être sauvé dans une répertoire accessible en écriture." - IDS_4116 "Image de disque trop grande" + IDS_4115 "Assurez-vous que le fichier en cours d'enregistrement se trouve dans un répertoire accessible en écriture." + IDS_4116 "Image disque trop grande" IDS_4117 "N'oubliez pas de partitionner et de formater le nouveau disque créé." IDS_4118 "Le fichier sélectionné sera écrasé. Etes-vous sûr de vouloir l'utiliser?" - IDS_4119 "Image de sique non prise en charge" + IDS_4119 "Image disque non prise en charge" IDS_4120 "Écraser" IDS_4121 "Ne pas écraser" IDS_4122 "Image brute (.img)" @@ -577,7 +577,7 @@ BEGIN IDS_4129 "Blocs petits (512 KB)" IDS_4130 "Fichiers VHD (*.VHD)\0*.VHD\0Tous les fichiers (*.*)\0*.*\0" IDS_4131 "Sélectionnez le VHD parent" - IDS_4132 "Est possible que la image parente a été modifié après la création de la image à différenciation.\n\nEst même possible que les fichiers de la image ont été déplacés ou copiés ou il était une bogue dans le programme que a créé ce disque.\n\nVoulez-vous Do you want to réparer l'horodatage?" + IDS_4132 "Il est possible que l'image parente a été modifié après la création de l'image à différenciation.\n\nIl est même possible que les fichiers de l'mage ont été déplacés ou copiés ou il existe un bogue dans le programme que a créé ce disque.\n\nVoulez-vous réparer l'horodatage?" IDS_4133 "Les horodatages des disques parent et enfant ne correspondent pas" IDS_4134 "Impossible de réparer l'horodatage du VHD." IDS_4135 "%01i:%02i" From 8820a60e019e809411e999c7d6b36e07e970a112 Mon Sep 17 00:00:00 2001 From: dob205 Date: Fri, 19 Nov 2021 13:40:35 +0100 Subject: [PATCH 18/19] Loading macOSXglue.m and macOSXglue.h Enables to store the ROMs in "Application Support" on macOS, can be extended later into storage of global configuration files --- src/86box.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/86box.c b/src/86box.c index 908bef06f..89ff01e25 100644 --- a/src/86box.c +++ b/src/86box.c @@ -33,6 +33,7 @@ #ifdef __APPLE__ #include #include +#include "mac/macOSXGlue.h" #ifdef __aarch64__ #include #endif @@ -393,6 +394,7 @@ pc_init(int argc, char *argv[]) { char path[2048], path2[2048]; char *cfg = NULL, *p; + char mac_rom_path[2048]; char temp[128]; struct tm *info; time_t now; @@ -585,14 +587,14 @@ usage: plat_dir_create(usr_path); } + #ifdef __APPLE__ + getDefaultROMPath(mac_rom_path); + strcpy(path2, mac_rom_path); + #endif if (vmrp && (path2[0] == '\0')) { -#ifdef __APPLE__ - sprintf("%s/Library/Application Support/86Box/roms", getenv("HOME") ? getenv("HOME") : getpwuid(getuid())->pw_dir); -#else strcpy(path2, usr_path); plat_path_slash(path2); strcat(path2, "roms"); -#endif plat_path_slash(path2); } From 469a9d0b7a5a9ad4f5140761868b5867a5dc6df6 Mon Sep 17 00:00:00 2001 From: dob205 Date: Fri, 19 Nov 2021 13:44:53 +0100 Subject: [PATCH 19/19] Adds the macOSXglue.m into the compilation process Enables to get the macOSXglue up and running while compiling 86Box on macOS, also executes some functions related to macOS now not on Windows and Linux anymore --- src/CMakeLists.txt | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fde99e3f0..1acfa8260 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,24 +16,33 @@ # # Prepare the macOS app bundle icon depending on the release channel -if(RELEASE_BUILD) - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/release/86Box.icns) -elseif(BETA_BUILD) - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/beta/86Box.icns) -elseif(ALPHA_BUILD) - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/dev/86Box.icns) -else() - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/branch/86Box.icns) -endif() +set(APP_ICON_MACOSX) +if (APPLE) + if(RELEASE_BUILD) + set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/release/86Box.icns) + elseif(BETA_BUILD) + set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/beta/86Box.icns) + elseif(ALPHA_BUILD) + set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/dev/86Box.icns) + else() + set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/branch/86Box.icns) + endif() set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") +endif() + +#Adding the macOS glue for ROM paths +set(MAC_GLUE) +if (APPLE) + set(MAC_GLUE ${CMAKE_CURRENT_SOURCE_DIR}/mac/macOSXGlue.m) +endif() # WIN32 marks us as a GUI app on Windows # MACOSX_BUNDLE prepares a macOS application bundle including with the app icon add_executable(86Box WIN32 MACOSX_BUNDLE 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 port_6x.c port_92.c ppi.c pci.c mca.c usb.c - device.c nvr.c nvr_at.c nvr_ps2.c ${APP_ICON_MACOSX}) + device.c nvr.c nvr_at.c nvr_ps2.c ${APP_ICON_MACOSX} ${MAC_GLUE}) if(NEW_DYNAREC) add_compile_definitions(USE_NEW_DYNAREC) @@ -184,7 +193,6 @@ endif() if(APPLE) set(APPS ${CMAKE_CURRENT_BINARY_DIR}/86Box.app) install(CODE " - include(InstallRequiredSystemLibraries) include(BundleUtilities) fixup_bundle(\"${APPS}\" \"\" \"\")" COMPONENT Runtime)