diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index f60bf06d8..28ef5e005 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 anySuccess = false - -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,33 +115,105 @@ pipeline { } stages { - stage('Build Windows') { + stage('Source Tarball') { + agent none + steps { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - node('windows') { - gitClone() - windowsBuild() - saveArtifacts() + 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) {} } - script { - anySuccess = true - } - } - } - } + /* Create source tarball. */ + node('Linux') { + try { + /* Run git clone. */ + gitClone() - stage('Build Linux') { - steps { - catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') { - node('debian') { - gitClone() - unixBuild() - saveArtifacts() + /* Switch to temp directory. */ + dir(WORKSPACE_TMP) { + /* Clean output directory of potential stale old builds. */ + removeDir('output') + + /* 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; + } + } } - script { - anySuccess = true + /* 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_NUM=${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; + } + } + } + } + } + } + } } } } @@ -110,35 +223,14 @@ pipeline { post { always { script { - if (buildChain[env.JOB_BASE_NAME]) { - def nextJob = buildChain[env.JOB_BASE_NAME] - - try { - /* Set next build number for this job. */ - 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 this job. */ - build propagate: false, - wait: false, - job: nextJob, - parameters: [ - string(name: 'BUILD_TYPE', value: BUILD_TYPE), - string(name: 'BRANCH', value: env.GIT_COMMIT) - ] - } - - if (!anySuccess) { - println "[!] Failing build because all build stages failed" + 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}", @@ -148,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; + } } } } diff --git a/.ci/build.sh b/.ci/build.sh index 63a758542..690565a56 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,96 +105,155 @@ 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= +cmake_flags= +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" ] - then - echo [!] Missing environment variables: received JOB_BASE_NAME=[$JOB_BASE_NAME] BUILD_TYPE=[$BUILD_TYPE] BUILD_NUMBER=[$BUILD_NUMBER] GIT_COMMIT=[$GIT_COMMIT] - return 1 - fi + -s) + shift + tarball_name="$1" + shift + ;; - 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" ] + *) + if echo $1 | grep -q " " 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" && job_status=0 # make sure the main script exits cleanly on any success - return $? + cmake_flag="\"$1\"" + else + cmake_flag="$1" fi - else - echo [!] No MSYSTEM for architecture [$arch] - return 2 - fi - echo [-] Using MSYSTEM [$MSYSTEM] - elif is_mac + if [ -z "$cmake_flags" ] + then + cmake_flags="$cmake_flag" + else + cmake_flags="$cmake_flags $cmake_flag" + fi + shift + ;; + esac +done +cmake_flags_extra= + +# Check if mandatory arguments were specified. +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 repository root directory. +cd "$(dirname "$0")/.." + +# 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 + + # 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. + make_tar "$cwd/$tarball_name.tar" + status=$? + + # Check if the archival succeeded. + if [ $status -ne 0 ] 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) @@ -211,374 +271,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] - return 3 - fi - - # Run actual build. - echo [-] Running build - try_make - local status=$? - if [ $status -gt 0 ] - then - echo [!] Make failed with status [$status] - 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 - 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] - 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] - 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() { - # 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] - 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] - return 2 - fi - - echo [-] Source tarball for [$job_name] created successfully -} - -# Set common variables. -project=86Box -cwd=$(pwd) -first_build=1 -job_status=1 - -# 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 "$(cygpath -w "$cwd")\\$package_name.zip" * + status=$? +elif is_mac +then + # TBD + : +else + # Create binary tarball. + VERBOSE=1 make_tar "$cwd/$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 diff --git a/.gitignore b/.gitignore index 43b1a1037..eb01732fb 100644 --- a/.gitignore +++ b/.gitignore @@ -29,10 +29,10 @@ Makefile # Build scripts /archive_tmp /static2dll.* -/*.zip -/*.tar -/*.tar.* /VERSION +*.zip +*.tar +*.tar.* # Visual Studio Code /.vs 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); } 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) 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 \ 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" diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 41942ba61..c0f9b4488 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); } @@ -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); } @@ -74,6 +74,7 @@ dynld_module(const char *name, dllimp_t *table) } /* All good. */ + pclog("loaded %s\n", name); return((void *)h); }