diff --git a/.ci/build.sh b/.ci/build.sh index 278e252d8..3ac28eb8a 100644 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -107,6 +107,19 @@ make_tar() { return $? } +cache_dir="$HOME/86box-build-cache" +[ ! -d "$cache_dir" ] && mkdir -p "$cache_dir" +check_buildtag() { + [ -z "$BUILD_TAG" -o "$BUILD_TAG" != "$(cat "$cache_dir/buildtag.$1" 2> /dev/null)" ] + return $? +} +save_buildtag() { + local contents="$BUILD_TAG" + [ -n "$2" ] && local contents="$2" + echo "$contents" > "$cache_dir/buildtag.$1" + return $? +} + # Set common variables. project=86Box cwd=$(pwd) @@ -244,105 +257,128 @@ then fi echo [-] Using MSYSTEM [$MSYSTEM] - # Update keyring, as the package signing keys sometimes change. - echo [-] Updating package databases and keyring - yes | pacman -Sy --needed msys2-keyring - - # Query installed packages. - pacman -Qe > pacman.txt - - # Download the specified versions of architecture-specific dependencies. - echo -n [-] Downloading dependencies: - pkg_dir="/var/cache/pacman/pkg" - repo_base="https://repo.msys2.org/mingw/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')" - cat .ci/dependencies_msys.txt | tr -d '\r' > deps.txt - pkgs="" - while IFS=" " read pkg version - do - prefixed_pkg="$MINGW_PACKAGE_PREFIX-$pkg" - installed_version=$(grep -E "^$prefixed_pkg " pacman.txt | cut -d " " -f 2) - if [ "$installed_version" != "$version" ] # installed_version will be empty if not installed + # Install dependencies only if we're in a new build and/or architecture. + freetype_dll="$cache_dir/freetype.$MSYSTEM.dll" + if check_buildtag "$MSYSTEM" + then + # Update databases and keyring only if we're in a new build. + if check_buildtag pacmansync then - echo -n " [$pkg" + # Update keyring as well, since the package signing keys sometimes change. + echo [-] Updating package databases and keyring + yes | pacman -Sy --needed msys2-keyring - # Download package if not already present in the local cache. - pkg_tar="$prefixed_pkg-$version-any.pkg.tar" - if [ -s "$pkg_dir/$pkg_tar.xz" ] + # Save build tag to skip pacman sync/keyring later. + save_buildtag pacmansync + else + echo [-] Not updating package databases and keyring again + fi + + # Query installed packages. + pacman -Qe > "$cache_dir/pacman.txt" + + # Download the specified versions of architecture-specific dependencies. + echo -n [-] Downloading dependencies: + pkg_dir="/var/cache/pacman/pkg" + repo_base="https://repo.msys2.org/mingw/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')" + cat .ci/dependencies_msys.txt | tr -d '\r' > "$cache_dir/deps.txt" + pkgs="" + while IFS=" " read pkg version + do + prefixed_pkg="$MINGW_PACKAGE_PREFIX-$pkg" + installed_version=$(grep -E "^$prefixed_pkg " "$cache_dir/pacman.txt" | cut -d " " -f 2) + if [ "$installed_version" != "$version" ] # installed_version will be empty if not installed then - pkg_fn="$pkg_tar.xz" - pkg_dest="$pkg_dir/$pkg_fn" - else - pkg_fn="$pkg_tar.zst" - pkg_dest="$pkg_dir/$pkg_fn" - if [ ! -s "$pkg_dest" ] + echo -n " [$pkg" + + # Download package if not already present in the local cache. + pkg_tar="$prefixed_pkg-$version-any.pkg.tar" + if [ -s "$pkg_dir/$pkg_tar.xz" ] then - if ! wget -qO "$pkg_dest" "$repo_base/$pkg_fn" + pkg_fn="$pkg_tar.xz" + pkg_dest="$pkg_dir/$pkg_fn" + else + pkg_fn="$pkg_tar.zst" + pkg_dest="$pkg_dir/$pkg_fn" + if [ ! -s "$pkg_dest" ] then - rm -f "$pkg_dest" - pkg_fn="$pkg_tar.xz" - pkg_dest="$pkg_dir/$pkg_fn" - wget -qO "$pkg_dest" "$repo_base/$pkg_fn" || rm -f "$pkg_dest" - fi - if [ -s "$pkg_dest" ] - then - wget -qO "$pkg_dest.sig" "$repo_base/$pkg_fn.sig" || rm -f "$pkg_dest.sig" - [ ! -s "$pkg_dest.sig" ] && rm -f "$pkg_dest.sig" + if ! wget -qO "$pkg_dest" "$repo_base/$pkg_fn" + then + rm -f "$pkg_dest" + pkg_fn="$pkg_tar.xz" + pkg_dest="$pkg_dir/$pkg_fn" + wget -qO "$pkg_dest" "$repo_base/$pkg_fn" || rm -f "$pkg_dest" + fi + if [ -s "$pkg_dest" ] + then + wget -qO "$pkg_dest.sig" "$repo_base/$pkg_fn.sig" || rm -f "$pkg_dest.sig" + [ ! -s "$pkg_dest.sig" ] && rm -f "$pkg_dest.sig" + fi fi fi - fi - # Check if the cached package is valid. - if [ -s "$pkg_dest" ] + # Check if the cached package is valid. + if [ -s "$pkg_dest" ] + then + # Add cached zst package. + pkgs="$pkgs $pkg_fn" + else + # Not valid, remove if it exists. + rm -f "$pkg_dest" "$pkg_dest.sig" + echo -n " FAIL" + fi + echo -n "]" + fi + done < "$cache_dir/deps.txt" + [ -z "$pkgs" ] && echo -n ' none required' + echo + + # Install the downloaded architecture-specific dependencies. + echo [-] Installing dependencies through pacman + if [ -n "$pkgs" ] + then + pushd "$pkg_dir" + yes | pacman -U --needed $pkgs + if [ $? -ne 0 ] then - # Add cached zst package. - pkgs="$pkgs $pkg_fn" - else - # Not valid, remove if it exists. - rm -f "$pkg_dest" "$pkg_dest.sig" - echo -n " FAIL" + # Install packages individually if installing them all together failed. + for pkg in $pkgs + do + yes | pacman -U --needed "$pkg" + done fi - echo -n "]" - fi - done < deps.txt - [ -z "$pkgs" ] && echo -n ' none required' - echo + popd - # Install the downloaded architecture-specific dependencies. - echo [-] Installing dependencies through pacman - if [ -n "$pkgs" ] - then - pushd "$pkg_dir" - yes | pacman -U --needed $pkgs + # Query installed packages again. + pacman -Qe > "$cache_dir/pacman.txt" + fi + + # Install the latest versions for any missing packages (if the specified version couldn't be installed). + pkgs="git" + while IFS=" " read pkg version + do + prefixed_pkg="$MINGW_PACKAGE_PREFIX-$pkg" + grep -qE "^$prefixed_pkg " "$cache_dir/pacman.txt" || pkgs="$pkgs $prefixed_pkg" + done < "$cache_dir/deps.txt" + rm -f "$cache_dir/pacman.txt" "$cache_dir/deps.txt" + yes | pacman -S --needed $pkgs if [ $? -ne 0 ] then # Install packages individually if installing them all together failed. for pkg in $pkgs do - yes | pacman -U --needed "$pkg" + yes | pacman -S --needed "$pkg" done fi - popd - # Query installed packages again. - pacman -Qe > pacman.txt - fi + # Generate a new freetype DLL for this architecture. + rm -f "$freetype_dll" - # Install the latest versions for any missing packages (if the specified version couldn't be installed). - pkgs="git" - while IFS=" " read pkg version - do - prefixed_pkg="$MINGW_PACKAGE_PREFIX-$pkg" - grep -qE "^$prefixed_pkg " pacman.txt || pkgs="$pkgs $prefixed_pkg" - done < deps.txt - rm -f pacman.txt deps.txt - yes | pacman -S --needed $pkgs - if [ $? -ne 0 ] - then - # Install packages individually if installing them all together failed. - for pkg in $pkgs - do - yes | pacman -S --needed "$pkg" - done + # Save build tag to skip this later. Doing it here (once everything is + # in place) is important to avoid potential issues with retried builds. + save_buildtag "$MSYSTEM" + else + echo [-] Not installing dependencies again fi # Point CMake to the toolchain file. @@ -352,7 +388,7 @@ then # macOS lacks nproc, but sysctl can do the same job. alias nproc='sysctl -n hw.logicalcpu' - # Handle universal build. + # Handle universal building. if echo "$arch" | grep -q '+' then # Create temporary directory for merging app bundles. @@ -391,18 +427,18 @@ then echo [-] Merging app bundles [$merge_src] and [$arch_universal] into [$merge_dest] # Merge directory structures. - (cd "archive_tmp_universal/$merge_src.app" && find . -type d && cd "../../archive_tmp_universal/$arch_universal.app" && find . -type d && cd ../..) | sort > universal_listing.txt - cat universal_listing.txt | uniq | while IFS= read line + (cd "archive_tmp_universal/$merge_src.app" && find . -type d && cd "../../archive_tmp_universal/$arch_universal.app" && find . -type d && cd ../..) | sort > "$cache_dir/universal_listing.txt" + cat "$cache_dir/universal_listing.txt" | uniq | while IFS= read line do echo "> Directory: $line" mkdir -p "archive_tmp_universal/$merge_dest.app/$line" done # Create merged file listing. - (cd "archive_tmp_universal/$merge_src.app" && find . -type f && cd "../../archive_tmp_universal/$arch_universal.app" && find . -type f && cd ../..) | sort > universal_listing.txt + (cd "archive_tmp_universal/$merge_src.app" && find . -type f && cd "../../archive_tmp_universal/$arch_universal.app" && find . -type f && cd ../..) | sort > "$cache_dir/universal_listing.txt" # Copy files that only exist on one bundle. - cat universal_listing.txt | uniq -u | while IFS= read line + cat "$cache_dir/universal_listing.txt" | uniq -u | while IFS= read line do if [ -e "archive_tmp_universal/$merge_src.app/$line" ] then @@ -415,7 +451,7 @@ then done # Copy or lipo files that exist on both bundles. - cat universal_listing.txt | uniq -d | while IFS= read line + cat "$cache_dir/universal_listing.txt" | uniq -d | while IFS= read line do if cmp -s "archive_tmp_universal/$merge_src.app/$line" "archive_tmp_universal/$arch_universal.app/$line" then @@ -431,8 +467,8 @@ then done # Merge symlinks. - (cd "archive_tmp_universal/$merge_src.app" && find . -type l && cd "../../archive_tmp_universal/$arch_universal.app" && find . -type l && cd ../..) | sort > universal_listing.txt - cat universal_listing.txt | uniq | while IFS= read line + (cd "archive_tmp_universal/$merge_src.app" && find . -type l && cd "../../archive_tmp_universal/$arch_universal.app" && find . -type l && cd ../..) | sort > "$cache_dir/universal_listing.txt" + cat "$cache_dir/universal_listing.txt" | uniq | while IFS= read line do # Get symlink destinations. other_link_dest= @@ -526,10 +562,21 @@ then [ "$arch" = "x86_64" -a -e "/opt/intel/bin/port" ] && macports="/opt/intel" export PATH="$macports/bin:$macports/sbin:$macports/libexec/qt5/bin:$PATH" - # Install dependencies. - echo [-] Installing dependencies through MacPorts - sudo "$macports/bin/port" selfupdate - sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) + # Install dependencies only if we're in a new build and/or architecture. + if check_buildtag "$(arch)" + then + # Install dependencies. + echo [-] Installing dependencies through MacPorts + sudo "$macports/bin/port" selfupdate + sudo "$macports/bin/port" install $(cat .ci/dependencies_macports.txt) + + # Save build tag to skip this later. Doing it here (once everything is + # in place) is important to avoid potential issues with retried builds. + save_buildtag "$(arch)" + else + echo [-] Not installing dependencies again + + fi # Point CMake to the toolchain file. [ -e "cmake/$toolchain.cmake" ] && cmake_flags_extra="$cmake_flags_extra -D \"CMAKE_TOOLCHAIN_FILE=cmake/$toolchain.cmake\"" @@ -548,7 +595,15 @@ else then pkgs="$pkgs build-essential" else - sudo dpkg --add-architecture "$arch_deb" + # Add foreign architecture if required. + if ! dpkg --print-foreign-architectures | grep -qE '^'"$arch_deb"'$' + then + sudo dpkg --add-architecture "$arch_deb" + + # Force an apt-get update. + save_buildtag aptupdate "arch_$arch_deb" + fi + pkgs="$pkgs crossbuild-essential-$arch_deb" fi @@ -606,11 +661,28 @@ EOF cmake_flags_extra="$cmake_flags_extra -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake" strip_binary="$arch_triplet-strip" - # 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 + # Install dependencies only if we're in a new build and/or architecture. + if check_buildtag "$arch_deb" + then + # Install or update dependencies. + echo [-] Installing dependencies through apt + if check_buildtag aptupdate + then + sudo apt-get update + + # Save build tag to skip apt-get update later, unless a new architecture + # is added to dpkg, in which case, this saved tag file gets replaced. + save_buildtag aptupdate + fi + DEBIAN_FRONTEND=noninteractive sudo apt-get -y install $pkgs $libpkgs + sudo apt-get clean + + # Save build tag to skip this later. Doing it here (once everything is + # in place) is important to avoid potential issues with retried builds. + save_buildtag "$arch_deb" + else + echo [-] Not installing dependencies again + fi # Link against the system libslirp instead of compiling ours. cmake_flags_extra="$cmake_flags_extra -D SLIRP_EXTERNAL=ON" @@ -618,12 +690,7 @@ fi # Clean workspace. echo [-] Cleaning workspace -if [ -d "build" ] -then - cmake --build build -j$(nproc) --target clean 2> /dev/null - rm -rf build -fi -find . \( -name Makefile -o -name CMakeCache.txt -o -name CMakeFiles \) -exec rm -rf "{}" \; 2> /dev/null +rm -rf build # Add ARCH to skip the arch_detect process. case $arch in @@ -671,17 +738,25 @@ then exit 4 fi -# Download Discord Game SDK from their CDN if necessary. -if [ ! -e "discord_game_sdk.zip" ] +# Download Discord Game SDK from their CDN if we're in a new build. +discord_zip="$cache_dir/discord_game_sdk.zip" +if check_buildtag discord then + # Download file. echo [-] Downloading Discord Game SDK - wget -qO discord_game_sdk.zip "https://dl-game-sdk.discordapp.net/latest/discord_game_sdk.zip" + wget -qO "$discord_zip" "https://dl-game-sdk.discordapp.net/latest/discord_game_sdk.zip" status=$? if [ $status -ne 0 ] then echo [!] Discord Game SDK download failed with status [$status] - rm -f discord_game_sdk.zip + rm -f "$discord_zip" + else + # Save build tag to skip this later. Doing it here (once everything is + # in place) is important to avoid potential issues with retried builds. + save_buildtag discord fi +else + echo [-] Not downloading Discord Game SDK again fi # Determine Discord Game SDK architecture. @@ -713,8 +788,9 @@ then 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 freetype from cache or generate it from local MSYS installation. + [ ! -e "$freetype_dll" ] && .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a "$freetype_dll" + cp -p "$freetype_dll" archive_tmp/freetype.dll # Archive Ghostscript DLL from local official distribution installation. for gs in "$pf"/gs/gs*.*.* @@ -723,7 +799,7 @@ then done # Archive Discord Game SDK DLL. - "$sevenzip" e -y -o"archive_tmp" discord_game_sdk.zip "lib/$arch_discord/discord_game_sdk.dll" + "$sevenzip" e -y -o"archive_tmp" "$discord_zip" "lib/$arch_discord/discord_game_sdk.dll" [ ! -e "archive_tmp/discord_game_sdk.dll" ] && echo [!] No Discord Game SDK for architecture [$arch_discord] # Archive other DLLs from local directory. @@ -749,31 +825,29 @@ then if [ $status -eq 0 ] then # Archive Discord Game SDK library. - unzip -j discord_game_sdk.zip "lib/$arch_discord/discord_game_sdk.dylib" -d "archive_tmp/"*".app/Contents/Frameworks" + unzip -j "$discord_zip" "lib/$arch_discord/discord_game_sdk.dylib" -d "archive_tmp/"*".app/Contents/Frameworks" [ ! -e "archive_tmp/"*".app/Contents/Frameworks/discord_game_sdk.dylib" ] && echo [!] No Discord Game SDK for architecture [$arch_discord] # Sign app bundle, unless we're in an universal build. [ $skip_archive -eq 0 ] && codesign --force --deep -s - "archive_tmp/"*".app" fi else - cwd_root=$(pwd) - cache_dir="$HOME/86box-build-cache" - [ ! -d "$cache_dir" ] && mkdir -p "$cache_dir" + cwd_root="$(pwd)" + check_buildtag "libs.$arch_deb" if grep -q "OPENAL:BOOL=ON" build/CMakeCache.txt then # Build openal-soft 1.21.1 manually to fix audio issues. This is a temporary # workaround until a newer version of openal-soft trickles down to Debian repos. prefix="$cache_dir/openal-soft-1.21.1" - if [ -d "$prefix" ] + if [ ! -d "$prefix" ] then - rm -rf "$prefix/build" - else wget -qO - https://github.com/kcat/openal-soft/archive/refs/tags/1.21.1.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi - cmake -G Ninja -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix/build" || exit 99 - cmake --build "$prefix/build" -j$(nproc) || exit 99 - cmake --install "$prefix/build" || exit 99 + prefix_build="$prefix/build-$arch_deb" + cmake -G Ninja -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix_build" || exit 99 + cmake --build "$prefix_build" -j$(nproc) || exit 99 + cmake --install "$prefix_build" || exit 99 # Build SDL2 without sound systems. sdl_ss=OFF @@ -781,15 +855,14 @@ else # Build FAudio 22.03 manually to remove the dependency on GStreamer. This is a temporary # workaround until a newer version of FAudio trickles down to Debian repos. prefix="$cache_dir/FAudio-22.03" - if [ -d "$prefix" ] + if [ ! -d "$prefix" ] then - rm -rf "$prefix/build" - else wget -qO - https://github.com/FNA-XNA/FAudio/archive/refs/tags/22.03.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi - cmake -G Ninja -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix/build" || exit 99 - cmake --build "$prefix/build" -j$(nproc) || exit 99 - cmake --install "$prefix/build" || exit 99 + prefix_build="$prefix/build-$arch_deb" + cmake -G Ninja -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix_build" || exit 99 + cmake --build "$prefix_build" -j$(nproc) || exit 99 + cmake --install "$prefix_build" || exit 99 # Build SDL2 with sound systems. sdl_ss=ON @@ -801,15 +874,14 @@ else # Build rtmidi without JACK support to remove the dependency on libjack. prefix="$cache_dir/rtmidi-4.0.0" - if [ -d "$prefix" ] + if [ ! -d "$prefix" ] then - rm -rf "$prefix/build" - else wget -qO - https://github.com/thestk/rtmidi/archive/refs/tags/4.0.0.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi - cmake -G Ninja -D RTMIDI_API_JACK=OFF -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix/build" || exit 99 - cmake --build "$prefix/build" -j$(nproc) || exit 99 - cmake --install "$prefix/build" || exit 99 + prefix_build="$prefix/build-$arch_deb" + cmake -G Ninja -D RTMIDI_API_JACK=OFF -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" -S "$prefix" -B "$prefix_build" || exit 99 + cmake --build "$prefix_build" -j$(nproc) || exit 99 + cmake --install "$prefix_build" || exit 99 # Build SDL2 for joystick and FAudio support, with most components # disabled to remove the dependencies on PulseAudio and libdrm. @@ -818,7 +890,7 @@ else then wget -qO - https://www.libsdl.org/release/SDL2-2.0.20.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi - rm -rf "$cache_dir/sdlbuild" + prefix_build="$cache_dir/SDL2-2.0.20-build-$arch_deb" cmake -G Ninja -D SDL_SHARED=ON -D SDL_STATIC=OFF \ \ -D SDL_AUDIO=$sdl_ss -D SDL_DUMMYAUDIO=$sdl_ss -D SDL_DISKAUDIO=OFF -D SDL_OSS=OFF -D SDL_ALSA=$sdl_ss -D SDL_ALSA_SHARED=$sdl_ss \ @@ -837,12 +909,12 @@ else -D SDL_LOADSO=ON -D SDL_CPUINFO=ON -D SDL_FILESYSTEM=$sdl_ui -D SDL_DLOPEN=OFF -D SDL_SENSOR=OFF -D SDL_LOCALE=OFF \ \ -D "CMAKE_TOOLCHAIN_FILE=$cwd_root/toolchain.cmake" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" \ - -S "$prefix" -B "$cache_dir/sdlbuild" || exit 99 - cmake --build "$cache_dir/sdlbuild" -j$(nproc) || exit 99 - cmake --install "$cache_dir/sdlbuild" || exit 99 + -S "$prefix" -B "$prefix_build" || exit 99 + cmake --build "$prefix_build" -j$(nproc) || exit 99 + cmake --install "$prefix_build" || exit 99 # Archive Discord Game SDK library. - 7z e -y -o"archive_tmp/usr/lib" discord_game_sdk.zip "lib/$arch_discord/discord_game_sdk.so" + 7z e -y -o"archive_tmp/usr/lib" "$discord_zip" "lib/$arch_discord/discord_game_sdk.so" [ ! -e "archive_tmp/usr/lib/discord_game_sdk.so" ] && echo [!] No Discord Game SDK for architecture [$arch_discord] # Archive readme with library package versions. diff --git a/.gitignore b/.gitignore index 5b1c5bbd1..267f3d766 100644 --- a/.gitignore +++ b/.gitignore @@ -28,9 +28,6 @@ Makefile /archive_tmp /archive_tmp_universal /static2dll.* -/pacman.txt -/deps.txt -/universal_listing.txt /VERSION *.zip *.tar diff --git a/src/86box.c b/src/86box.c index 805cc60bf..cb9fa52a7 100644 --- a/src/86box.c +++ b/src/86box.c @@ -182,6 +182,7 @@ int confirm_reset = 1; /* (C) enable reset confirmation */ int confirm_exit = 1; /* (C) enable exit confirmation */ int confirm_save = 1; /* (C) enable save confirmation */ int enable_discord = 0; /* (C) enable Discord integration */ +int pit_mode = -1; /* (C) force setting PIT mode */ /* Statistics. */ extern int mmuflush; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d1da45172..1420aaa89 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,7 +16,7 @@ # add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c - dma.c ddma.c discord.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c + dma.c ddma.c discord.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c machine_status.c) if(CMAKE_SYSTEM_NAME MATCHES "Linux") diff --git a/src/acpi.c b/src/acpi.c index 470e24c41..db181cee8 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1458,7 +1458,7 @@ acpi_apm_out(uint16_t port, uint8_t val, void *p) dev->apm->cmd = val; if (dev->vendor == VEN_INTEL) dev->regs.glbsts |= 0x20; - acpi_raise_smi(dev, dev->apm->do_smi); + acpi_raise_smi(dev, dev->apm->do_smi); } else dev->apm->stat = val; } diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 9811b198c..bbbf7d705 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -30,18 +30,15 @@ #include <86box/apm.h> #include <86box/dma.h> #include <86box/ddma.h> -#include <86box/fdd.h> -#include <86box/fdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/keyboard.h> -#include <86box/lpt.h> #include <86box/mem.h> #include <86box/nvr.h> #include <86box/pci.h> #include <86box/pic.h> #include <86box/port_92.h> -#include <86box/serial.h> +#include <86box/sio.h> #include <86box/smbus.h> #include <86box/usb.h> @@ -53,17 +50,15 @@ typedef struct ali1543_t { uint8_t pci_conf[256], pmu_conf[256], usb_conf[256], ide_conf[256], - sio_regs[256], device_regs[8][256], sio_index, in_configuration_mode, pci_slot, ide_slot, usb_slot, pmu_slot, usb_dev_enable, ide_dev_enable, pmu_dev_enable, type; + int offset; apm_t * apm; acpi_t * acpi; ddma_t * ddma; - fdc_t * fdc_controller; nvr_t * nvr; port_92_t * port_92; - serial_t * uart[2]; sff8038i_t * ide_controller[2]; smbus_ali7101_t * smbus; usb_t * usb; @@ -274,8 +269,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[addr] = val & 0xe0; break; - /* IDE interface control - TODO: What is IDSEL address? */ + /* IDE interface control */ case 0x58: dev->pci_conf[addr] = val & 0x7f; ali1543_log("PCI58: %02X\n", val); @@ -294,7 +288,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) dev->ide_slot = 0x0d; /* A24 = slot 13 */ break; } - ali1543_log("IDE slot = %02X (A%0i)\n", dev->ide_slot/* - 5*/, dev->ide_slot + 11); + pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_IDE, ((int) dev->ide_slot) + dev->offset); + ali1543_log("IDE slot = %02X (A%0i)\n", ((int) dev->ide_slot) + dev->offset, dev->ide_slot + 11); ali5229_ide_irq_handler(dev); break; @@ -363,7 +358,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) dev->pmu_slot = 0x04; /* A15 = slot 04 */ break; } - ali1543_log("PMU slot = %02X (A%0i)\n", dev->pmu_slot/* - 5*/, dev->pmu_slot + 11); + pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_PMU, ((int) dev->pmu_slot) + dev->offset); + ali1543_log("PMU slot = %02X (A%0i)\n", ((int) dev->pmu_slot) + dev->offset, dev->pmu_slot + 11); switch (val & 0x03) { case 0x00: dev->usb_slot = 0x14; /* A31 = slot 20 */ @@ -378,7 +374,8 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) dev->usb_slot = 0x01; /* A12 = slot 01 */ break; } - ali1543_log("USB slot = %02X (A%0i)\n", dev->usb_slot/* - 5*/, dev->usb_slot + 11); + pci_relocate_slot(PCI_CARD_SOUTHBRIDGE_USB, ((int) dev->usb_slot) + dev->offset); + ali1543_log("USB slot = %02X (A%0i)\n", ((int) dev->usb_slot) + dev->offset, dev->usb_slot + 11); break; case 0x73: /* DDMA Base Address */ @@ -1400,134 +1397,10 @@ ali7101_read(int func, int addr, void *priv) } -static void -ali1533_sio_fdc_handler(ali1543_t *dev) -{ - fdc_remove(dev->fdc_controller); - - if (dev->device_regs[0][0x30] & 1) { - ali1543_log("New FDC base address: %04X\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8)); - fdc_set_base(dev->fdc_controller, dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8)); - fdc_set_irq(dev->fdc_controller, dev->device_regs[0][0x70] & 0xf); - fdc_set_dma_ch(dev->fdc_controller, dev->device_regs[0][0x74] & 0x07); - ali1543_log("M1543-SIO FDC: ADDR %04x IRQ %02x DMA %02x\n", dev->device_regs[0][0x61] | (dev->device_regs[0][0x60] << 8), dev->device_regs[0][0x70] & 0xf, dev->device_regs[0][0x74] & 0x07); - } -} - - -static void -ali1533_sio_uart_handler(int num, ali1543_t *dev) -{ - serial_remove(dev->uart[num]); - - if (dev->device_regs[num + 4][0x30] & 1) { - serial_setup(dev->uart[num], dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); - ali1543_log("M1543-SIO UART%d: ADDR %04x IRQ %02x\n", num, dev->device_regs[num + 4][0x61] | (dev->device_regs[num + 4][0x60] << 8), dev->device_regs[num + 4][0x70] & 0xf); - } -} - - -void -ali1533_sio_lpt_handler(ali1543_t *dev) -{ - lpt1_remove(); - - if (dev->device_regs[3][0x30] & 1) { - lpt1_init(dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8)); - lpt1_irq(dev->device_regs[3][0x70] & 0xf); - ali1543_log("M1543-SIO LPT: ADDR %04x IRQ %02x\n", dev->device_regs[3][0x61] | (dev->device_regs[3][0x60] << 8), dev->device_regs[3][0x70] & 0xf); - } -} - - -void -ali1533_sio_ldn(uint16_t ldn, ali1543_t *dev) -{ - /* We don't include all LDN's */ - switch (ldn) { - case 0: /* FDC */ - ali1533_sio_fdc_handler(dev); - break; - case 3: /* LPT */ - ali1533_sio_lpt_handler(dev); - break; - /* UART */ - case 4: case 5: - ali1533_sio_uart_handler(ldn - 4, dev); - break; - } -} - - -static void -ali1533_sio_write(uint16_t addr, uint8_t val, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - - switch (addr) { - case FDC_PRIMARY_ADDR: - dev->sio_index = val; - if (dev->sio_index == 0x51) - dev->in_configuration_mode = 1; - else if ((dev->sio_index == 0x23) && (dev->in_configuration_mode == 1)) - dev->in_configuration_mode = 2; - else if (dev->sio_index == 0xbb) - dev->in_configuration_mode = 0; - break; - - case 0x3f1: - if (dev->in_configuration_mode == 2) { - switch (dev->sio_index) { - case 0x07: - dev->sio_regs[dev->sio_index] = val & 0x7; - break; - - case 0x22: - dev->sio_regs[dev->sio_index] = val & 0x39; - break; - - case 0x23: - dev->sio_regs[dev->sio_index] = val & 0x38; - break; - - default: - if ((dev->sio_index < 0x30) || (dev->sio_index == 0x51) || (dev->sio_index == 0xbb)) - dev->sio_regs[dev->sio_index] = val; - else if (dev->sio_regs[0x07] <= 7) - dev->device_regs[dev->sio_regs[0x07]][dev->sio_index] = val; - break; - } - } - break; - } - - if ((!dev->in_configuration_mode) && (dev->sio_regs[0x07] <= 7) && (addr == FDC_PRIMARY_ADDR)) - ali1533_sio_ldn(dev->sio_regs[0x07], dev); -} - - -static uint8_t -ali1533_sio_read(uint16_t addr, void *priv) -{ - ali1543_t *dev = (ali1543_t *)priv; - uint8_t ret = 0xff; - - if (addr == 0x03f1) { - if (dev->sio_index >= 0x30) - ret = dev->device_regs[dev->sio_regs[0x07]][dev->sio_index]; - else - ret = dev->sio_regs[dev->sio_index]; - } - - return ret; -} - - static void ali1543_reset(void *priv) { ali1543_t *dev = (ali1543_t *)priv; - int i; /* Temporarily enable everything. Register writes will disable the devices. */ dev->ide_dev_enable = 1; @@ -1616,44 +1489,6 @@ ali1543_reset(void *priv) ali1533_write(0, 0x75, 0x00, dev); ali1533_write(0, 0x76, 0x00, dev); - /* M1543 Super I/O */ - memset(dev->sio_regs, 0x00, sizeof(dev->sio_regs)); - for (i = 0; i < 8; i++) - memset(dev->device_regs[i], 0x00, sizeof(dev->device_regs[i])); - - dev->device_regs[0][0x60] = 0x03; - dev->device_regs[0][0x61] = 0xf0; - dev->device_regs[0][0x70] = 0x06; - dev->device_regs[0][0x74] = 0x02; - dev->device_regs[0][0xf0] = 0x08; - dev->device_regs[0][0xf2] = 0xff; - - dev->device_regs[3][0x60] = 0x03; - dev->device_regs[3][0x61] = 0x78; - dev->device_regs[3][0x70] = 0x05; - dev->device_regs[3][0x74] = 0x04; - dev->device_regs[3][0xf0] = 0x0c; - dev->device_regs[3][0xf1] = 0x05; - - dev->device_regs[4][0x60] = 0x03; - dev->device_regs[4][0x61] = 0xf8; - dev->device_regs[4][0x70] = 0x04; - dev->device_regs[4][0xf1] = 0x02; - dev->device_regs[4][0xf2] = 0x0c; - - dev->device_regs[5][0x60] = 0x02; - dev->device_regs[5][0x61] = 0xf8; - dev->device_regs[5][0x70] = 0x03; - dev->device_regs[5][0xf1] = 0x02; - dev->device_regs[5][0xf2] = 0x0c; - - dev->device_regs[7][0x70] = 0x01; - - ali1533_sio_fdc_handler(dev); - ali1533_sio_uart_handler(0, dev); - ali1533_sio_uart_handler(1, dev); - ali1533_sio_lpt_handler(dev); - unmask_a20_in_smm = 1; } @@ -1677,16 +1512,13 @@ ali1543_init(const device_t *info) dev->pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali1533_read, ali1533_write, dev); /* Device 0B: M5229 IDE Controller*/ - dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali5229_read, ali5229_write, dev); + dev->ide_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_IDE, ali5229_read, ali5229_write, dev); /* Device 0C: M7101 Power Managment Controller */ - dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali7101_read, ali7101_write, dev); + dev->pmu_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_PMU, ali7101_read, ali7101_write, dev); /* Device 0F: M5237 USB */ - dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, ali5237_read, ali5237_write, dev); - - /* Ports 3F0-1h: M1543 Super I/O */ - io_sethandler(FDC_PRIMARY_ADDR, 0x0002, ali1533_sio_read, NULL, NULL, ali1533_sio_write, NULL, NULL, dev); + dev->usb_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE_USB, ali5237_read, ali5237_write, dev); /* ACPI */ dev->acpi = device_add(&acpi_ali_device); @@ -1703,9 +1535,6 @@ ali1543_init(const device_t *info) /* DDMA */ dev->ddma = device_add(&ddma_device); - /* Floppy Disk Controller */ - dev->fdc_controller = device_add(&fdc_at_smc_device); - /* IDE Controllers */ dev->ide_controller[0] = device_add_inst(&sff8038i_device, 1); dev->ide_controller[1] = device_add_inst(&sff8038i_device, 2); @@ -1713,20 +1542,17 @@ ali1543_init(const device_t *info) /* Port 92h */ dev->port_92 = device_add(&port_92_pci_device); - /* Serial NS16500 */ - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - /* Standard SMBus */ dev->smbus = device_add(&ali7101_smbus_device); - /* Super I/O Configuration Mechanism */ - dev->in_configuration_mode = 0; - /* USB */ dev->usb = device_add(&usb_device); - dev->type = info->local; + dev->type = info->local & 0xff; + dev->offset = (info->local >> 8) & 0x7f; + if (info->local & 0x8000) + dev->offset = -dev->offset; + pclog("Offset = %i\n", dev->offset); pci_enable_mirq(0); pci_enable_mirq(1); @@ -1736,6 +1562,9 @@ ali1543_init(const device_t *info) pci_enable_mirq(5); pci_enable_mirq(6); + /* Super I/O chip */ + device_add(&ali5123_device); + ali1543_reset(dev); return dev; @@ -1745,7 +1574,8 @@ const device_t ali1543_device = { .name = "ALi M1543 Desktop South Bridge", .internal_name = "ali1543", .flags = DEVICE_PCI, - .local = 0, + .local = 0x8500, /* -5 slot offset, we can do this because we currently + have no case of M1543 non-C with a different offset */ .init = ali1543_init, .close = ali1543_close, .reset = ali1543_reset, diff --git a/src/chipset/ali6117.c b/src/chipset/ali6117.c index 224d448a2..612970e45 100644 --- a/src/chipset/ali6117.c +++ b/src/chipset/ali6117.c @@ -219,12 +219,14 @@ ali6117_reg_write(uint16_t addr, uint8_t val, void *priv) refresh_at_enable = !(val & 0x02) || !!(dev->regs[0x20] & 0x80); dev->regs[dev->reg_offset] = val; - if (val & 0x04) - mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - else - mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (dev->local != 0x8) { + if (val & 0x04) + mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + else + mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - ali6117_bank_recalc(dev); + ali6117_bank_recalc(dev); + } break; case 0x12: @@ -417,9 +419,11 @@ ali6117_reset(void *priv) refresh_at_enable = 1; - /* On-board memory 15-16M is enabled by default. */ - mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - ali6117_bank_recalc(dev); + if (dev->local != 0x8) { + /* On-board memory 15-16M is enabled by default. */ + mem_set_mem_state_both(0x00f00000, 0x00100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + ali6117_bank_recalc(dev); + } } diff --git a/src/chipset/wd76c10.c b/src/chipset/wd76c10.c index 138349955..12b7e19a0 100644 --- a/src/chipset/wd76c10.c +++ b/src/chipset/wd76c10.c @@ -45,8 +45,6 @@ #define LOCK dev->lock #define UNLOCKED !dev->lock -#define ENABLE_WD76C10_LOG 1 - #ifdef ENABLE_WD76C10_LOG int wd76c10_do_log = ENABLE_WD76C10_LOG; static void diff --git a/src/config.c b/src/config.c index 723691157..8554dcc7a 100644 --- a/src/config.c +++ b/src/config.c @@ -1,30 +1,31 @@ /* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. * - * This file is part of the 86Box distribution. + * This file is part of the 86Box distribution. * - * Configuration file handler. + * Configuration file handler. * * * - * Authors: Sarah Walker, - * Miran Grca, - * Fred N. van Kempen, - * Overdoze, - * David Hrdlička, + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Overdoze, + * David Hrdlička, * - * Copyright 2008-2019 Sarah Walker. - * Copyright 2016-2019 Miran Grca. - * Copyright 2017-2019 Fred N. van Kempen. - * Copyright 2018,2019 David Hrdlička. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. + * Copyright 2018,2019 David Hrdlička. * - * NOTE: Forcing config files to be in Unicode encoding breaks - * it on Windows XP, and possibly also Vista. Use the - * -DANSI_CFG for use on these systems. + * NOTE: Forcing config files to be in Unicode encoding breaks + * it on Windows XP, and possibly also Vista. Use the + * -DANSI_CFG for use on these systems. */ + #include #include #include @@ -74,99 +75,95 @@ typedef struct _list_ { } list_t; typedef struct { - list_t list; + list_t list; - char name[128]; + char name[128]; - list_t entry_head; + list_t entry_head; } section_t; typedef struct { - list_t list; + list_t list; - char name[128]; - char data[512]; - wchar_t wdata[512]; + char name[128]; + char data[512]; + wchar_t wdata[512]; } entry_t; -#define list_add(new, head) { \ - list_t *next = head; \ - \ - while (next->next != NULL) \ - next = next->next; \ - \ - (next)->next = new; \ - (new)->next = NULL; \ -} +#define list_add(new, head) \ + { \ + list_t *next = head; \ + \ + while (next->next != NULL) \ + next = next->next; \ + \ + (next)->next = new; \ + (new)->next = NULL; \ + } -#define list_delete(old, head) { \ - list_t *next = head; \ - \ - while ((next)->next != old) { \ - next = (next)->next; \ - } \ - \ - (next)->next = (old)->next; \ - if ((next) == (head)) \ - (head)->next = (old)->next; \ -} +#define list_delete(old, head) \ + { \ + list_t *next = head; \ + \ + while ((next)->next != old) { \ + next = (next)->next; \ + } \ + \ + (next)->next = (old)->next; \ + if ((next) == (head)) \ + (head)->next = (old)->next; \ + } - -static list_t config_head; +static list_t config_head; /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ -static int backwards_compat = 0; -static int backwards_compat2 = 0; - +static int backwards_compat = 0; +static int backwards_compat2 = 0; #ifdef ENABLE_CONFIG_LOG int config_do_log = ENABLE_CONFIG_LOG; - static void config_log(const char *fmt, ...) { va_list ap; if (config_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define config_log(fmt, ...) +# define config_log(fmt, ...) #endif - static section_t * find_section(char *name) { section_t *sec; - char blank[] = ""; + char blank[] = ""; - sec = (section_t *)config_head.next; + sec = (section_t *) config_head.next; if (name == NULL) - name = blank; + name = blank; while (sec != NULL) { - if (! strncmp(sec->name, name, sizeof(sec->name))) - return(sec); + if (!strncmp(sec->name, name, sizeof(sec->name))) + return (sec); - sec = (section_t *)sec->list.next; + sec = (section_t *) sec->list.next; } - return(NULL); + return (NULL); } - void * config_find_section(char *name) { return (void *) find_section(name); } - void config_rename_section(void *priv, char *name) { @@ -176,58 +173,56 @@ config_rename_section(void *priv, char *name) memcpy(sec->name, name, MIN(128, strlen(name) + 1)); } - static entry_t * find_entry(section_t *section, char *name) { entry_t *ent; - ent = (entry_t *)section->entry_head.next; + ent = (entry_t *) section->entry_head.next; while (ent != NULL) { - if (! strncmp(ent->name, name, sizeof(ent->name))) - return(ent); + if (!strncmp(ent->name, name, sizeof(ent->name))) + return (ent); - ent = (entry_t *)ent->list.next; + ent = (entry_t *) ent->list.next; } - return(NULL); + return (NULL); } - static int entries_num(section_t *section) { entry_t *ent; - int i = 0; + int i = 0; - ent = (entry_t *)section->entry_head.next; + ent = (entry_t *) section->entry_head.next; while (ent != NULL) { - if (strlen(ent->name) > 0) i++; + if (strlen(ent->name) > 0) + i++; - ent = (entry_t *)ent->list.next; + ent = (entry_t *) ent->list.next; } - return(i); + return (i); } - static void delete_section_if_empty(char *head) { section_t *section; section = find_section(head); - if (section == NULL) return; + if (section == NULL) + return; if (entries_num(section) == 0) { - list_delete(§ion->list, &config_head); - free(section); + list_delete(§ion->list, &config_head); + free(section); } } - static section_t * create_section(char *name) { @@ -237,10 +232,9 @@ create_section(char *name) memcpy(ns->name, name, strlen(name) + 1); list_add(&ns->list, &config_head); - return(ns); + return (ns); } - static entry_t * create_entry(section_t *section, char *name) { @@ -250,10 +244,9 @@ create_entry(section_t *section, char *name) memcpy(ne->name, name, strlen(name) + 1); list_add(&ne->list, §ion->entry_head); - return(ne); + return (ne); } - #if 0 static void config_free(void) @@ -263,18 +256,18 @@ config_free(void) sec = (section_t *)config_head.next; while (sec != NULL) { - ns = (section_t *)sec->list.next; - ent = (entry_t *)sec->entry_head.next; + ns = (section_t *)sec->list.next; + ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - entry_t *nent = (entry_t *)ent->list.next; + while (ent != NULL) { + entry_t *nent = (entry_t *)ent->list.next; - free(ent); - ent = nent; - } + free(ent); + ent = nent; + } - free(sec); - sec = ns; + free(sec); + sec = ns; } } #endif @@ -282,42 +275,46 @@ config_free(void) static int config_detect_bom(char *fn) { - FILE *f; - unsigned char bom[4] = { 0, 0, 0, 0 }; + FILE *f; + unsigned char bom[4] = { 0, 0, 0, 0 }; #if defined(ANSI_CFG) || !defined(_WIN32) f = plat_fopen(fn, "rt"); #else f = plat_fopen(fn, "rt, ccs=UTF-8"); #endif - if (f == NULL) return(0); - fread(bom, 1, 3, f); - if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) - { - fclose(f); - return 1; - } - fclose(f); - return 0; + if (f == NULL) + return (0); + fread(bom, 1, 3, f); + if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) { + fclose(f); + return 1; + } + fclose(f); + return 0; } #ifdef __HAIKU__ /* Local version of fgetws to avoid a crash */ -static wchar_t* -config_fgetws(wchar_t *str, int count, FILE* stream) +static wchar_t * +config_fgetws(wchar_t *str, int count, FILE *stream) { int i = 0; - if (feof(stream)) return NULL; + if (feof(stream)) + return NULL; for (i = 0; i < count; i++) { wint_t curChar = fgetwc(stream); if (curChar == WEOF) { - if (i + 1 < count) str[i + 1] = 0; + if (i + 1 < count) + str[i + 1] = 0; return feof(stream) ? str : NULL; } str[i] = curChar; - if (curChar == '\n') break; + if (curChar == '\n') + break; } - if (i + 1 < count) str[i + 1] = 0; + if (i + 1 < count) + str[i + 1] = 0; return str; } #endif @@ -326,120 +323,128 @@ config_fgetws(wchar_t *str, int count, FILE* stream) static int config_read(char *fn) { - char sname[128], ename[128]; - wchar_t buff[1024]; + char sname[128], ename[128]; + wchar_t buff[1024]; section_t *sec, *ns; - entry_t *ne; - int c, d, bom; - FILE *f; + entry_t *ne; + int c, d, bom; + FILE *f; - bom = config_detect_bom(fn); + bom = config_detect_bom(fn); #if defined(ANSI_CFG) || !defined(_WIN32) f = plat_fopen(fn, "rt"); #else f = plat_fopen(fn, "rt, ccs=UTF-8"); #endif - if (f == NULL) return(0); + if (f == NULL) + return (0); sec = malloc(sizeof(section_t)); memset(sec, 0x00, sizeof(section_t)); memset(&config_head, 0x00, sizeof(list_t)); list_add(&sec->list, &config_head); - if (bom) - fseek(f, 3, SEEK_SET); + if (bom) + fseek(f, 3, SEEK_SET); while (1) { - memset(buff, 0x00, sizeof(buff)); + memset(buff, 0x00, sizeof(buff)); #ifdef __HAIKU__ - config_fgetws(buff, sizeof_w(buff), f); + config_fgetws(buff, sizeof_w(buff), f); #else - fgetws(buff, sizeof_w(buff), f); + fgetws(buff, sizeof_w(buff), f); #endif - if (feof(f)) break; + if (feof(f)) + break; - /* Make sure there are no stray newlines or hard-returns in there. */ - if (wcslen(buff) > 0) - if (buff[wcslen(buff)-1] == L'\n') buff[wcslen(buff)-1] = L'\0'; - if (wcslen(buff) > 0) - if (buff[wcslen(buff)-1] == L'\r') buff[wcslen(buff)-1] = L'\0'; + /* Make sure there are no stray newlines or hard-returns in there. */ + if (wcslen(buff) > 0) + if (buff[wcslen(buff) - 1] == L'\n') + buff[wcslen(buff) - 1] = L'\0'; + if (wcslen(buff) > 0) + if (buff[wcslen(buff) - 1] == L'\r') + buff[wcslen(buff) - 1] = L'\0'; - /* Skip any leading whitespace. */ - c = 0; - while ((buff[c] == L' ') || (buff[c] == L'\t')) - c++; + /* Skip any leading whitespace. */ + c = 0; + while ((buff[c] == L' ') || (buff[c] == L'\t')) + c++; - /* Skip empty lines. */ - if (buff[c] == L'\0') continue; + /* Skip empty lines. */ + if (buff[c] == L'\0') + continue; - /* Skip lines that (only) have a comment. */ - if ((buff[c] == L'#') || (buff[c] == L';')) continue; + /* Skip lines that (only) have a comment. */ + if ((buff[c] == L'#') || (buff[c] == L';')) + continue; - if (buff[c] == L'[') { /*Section*/ - c++; - d = 0; - while (buff[c] != L']' && buff[c]) - wctomb(&(sname[d++]), buff[c++]); - sname[d] = L'\0'; + if (buff[c] == L'[') { /*Section*/ + c++; + d = 0; + while (buff[c] != L']' && buff[c]) + wctomb(&(sname[d++]), buff[c++]); + sname[d] = L'\0'; - /* Is the section name properly terminated? */ - if (buff[c] != L']') continue; + /* Is the section name properly terminated? */ + if (buff[c] != L']') + continue; - /* Create a new section and insert it. */ - ns = malloc(sizeof(section_t)); - memset(ns, 0x00, sizeof(section_t)); - memcpy(ns->name, sname, 128); - list_add(&ns->list, &config_head); + /* Create a new section and insert it. */ + ns = malloc(sizeof(section_t)); + memset(ns, 0x00, sizeof(section_t)); + memcpy(ns->name, sname, 128); + list_add(&ns->list, &config_head); - /* New section is now the current one. */ - sec = ns; - continue; - } + /* New section is now the current one. */ + sec = ns; + continue; + } - /* Get the variable name. */ - d = 0; - while ((buff[c] != L'=') && (buff[c] != L' ') && buff[c]) - wctomb(&(ename[d++]), buff[c++]); - ename[d] = L'\0'; + /* Get the variable name. */ + d = 0; + while ((buff[c] != L'=') && (buff[c] != L' ') && buff[c]) + wctomb(&(ename[d++]), buff[c++]); + ename[d] = L'\0'; - /* Skip incomplete lines. */ - if (buff[c] == L'\0') continue; + /* Skip incomplete lines. */ + if (buff[c] == L'\0') + continue; - /* Look for =, skip whitespace. */ - while ((buff[c] == L'=' || buff[c] == L' ') && buff[c]) - c++; + /* Look for =, skip whitespace. */ + while ((buff[c] == L'=' || buff[c] == L' ') && buff[c]) + c++; - /* Skip incomplete lines. */ - if (buff[c] == L'\0') continue; + /* Skip incomplete lines. */ + if (buff[c] == L'\0') + continue; - /* This is where the value part starts. */ - d = c; + /* This is where the value part starts. */ + d = c; - /* Allocate a new variable entry.. */ - ne = malloc(sizeof(entry_t)); - memset(ne, 0x00, sizeof(entry_t)); - memcpy(ne->name, ename, 128); - wcsncpy(ne->wdata, &buff[d], sizeof_w(ne->wdata)-1); - ne->wdata[sizeof_w(ne->wdata)-1] = L'\0'; -#ifdef _WIN32 /* Make sure the string is converted to UTF-8 rather than a legacy codepage */ - c16stombs(ne->data, ne->wdata, sizeof(ne->data)); + /* Allocate a new variable entry.. */ + ne = malloc(sizeof(entry_t)); + memset(ne, 0x00, sizeof(entry_t)); + memcpy(ne->name, ename, 128); + wcsncpy(ne->wdata, &buff[d], sizeof_w(ne->wdata) - 1); + ne->wdata[sizeof_w(ne->wdata) - 1] = L'\0'; +#ifdef _WIN32 /* Make sure the string is converted to UTF-8 rather than a legacy codepage */ + c16stombs(ne->data, ne->wdata, sizeof(ne->data)); #else - wcstombs(ne->data, ne->wdata, sizeof(ne->data)); + wcstombs(ne->data, ne->wdata, sizeof(ne->data)); #endif - ne->data[sizeof(ne->data)-1] = '\0'; + ne->data[sizeof(ne->data) - 1] = '\0'; - /* .. and insert it. */ - list_add(&ne->list, &sec->entry_head); + /* .. and insert it. */ + list_add(&ne->list, &sec->entry_head); } - (void)fclose(f); + (void) fclose(f); if (do_dump_config) - config_dump(); + config_dump(); - return(1); + return (1); } - /* * Write the in-memory configuration to disk. * This is a public function, because the Settings UI @@ -449,82 +454,81 @@ config_read(char *fn) void config_write(char *fn) { - wchar_t wtemp[512]; + wchar_t wtemp[512]; section_t *sec; - FILE *f; - int fl = 0; + FILE *f; + int fl = 0; #if defined(ANSI_CFG) || !defined(_WIN32) f = plat_fopen(fn, "wt"); #else f = plat_fopen(fn, "wt, ccs=UTF-8"); #endif - if (f == NULL) return; + if (f == NULL) + return; - sec = (section_t *)config_head.next; + sec = (section_t *) config_head.next; while (sec != NULL) { - entry_t *ent; + entry_t *ent; - if (sec->name[0]) { - mbstowcs(wtemp, sec->name, strlen(sec->name)+1); - if (fl) - fwprintf(f, L"\n[%ls]\n", wtemp); - else - fwprintf(f, L"[%ls]\n", wtemp); - fl++; - } + if (sec->name[0]) { + mbstowcs(wtemp, sec->name, strlen(sec->name) + 1); + if (fl) + fwprintf(f, L"\n[%ls]\n", wtemp); + else + fwprintf(f, L"[%ls]\n", wtemp); + fl++; + } - ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - if (ent->name[0] != '\0') { - mbstowcs(wtemp, ent->name, 128); - if (ent->wdata[0] == L'\0') - fwprintf(f, L"%ls = \n", wtemp); - else - fwprintf(f, L"%ls = %ls\n", wtemp, ent->wdata); - fl++; - } + ent = (entry_t *) sec->entry_head.next; + while (ent != NULL) { + if (ent->name[0] != '\0') { + mbstowcs(wtemp, ent->name, 128); + if (ent->wdata[0] == L'\0') + fwprintf(f, L"%ls = \n", wtemp); + else + fwprintf(f, L"%ls = %ls\n", wtemp, ent->wdata); + fl++; + } - ent = (entry_t *)ent->list.next; - } + ent = (entry_t *) ent->list.next; + } - sec = (section_t *)sec->list.next; + sec = (section_t *) sec->list.next; } - (void)fclose(f); + (void) fclose(f); } - #if NOT_USED static void config_new(void) { -#if defined(ANSI_CFG) || !defined(_WIN32) +# if defined(ANSI_CFG) || !defined(_WIN32) FILE *f = _wfopen(config_file, L"wt"); -#else +# else FILE *f = _wfopen(config_file, L"wt, ccs=UTF-8"); -#endif +# endif if (file != NULL) - (void)fclose(f); + (void) fclose(f); } #endif - /* Load "General" section. */ static void load_general(void) { char *cat = "General"; - char temp[512]; + char temp[512]; char *p; vid_resize = config_get_int(cat, "vid_resize", 0); if (vid_resize & ~3) - vid_resize &= 3; + vid_resize &= 3; memset(temp, '\0', sizeof(temp)); - p = config_get_string(cat, "vid_renderer", "default"); + p = config_get_string(cat, "vid_renderer", "default"); vid_api = plat_vidapi(p); config_delete_var(cat, "vid_api"); @@ -535,580 +539,579 @@ load_general(void) video_filter_method = config_get_int(cat, "video_filter_method", 1); force_43 = !!config_get_int(cat, "force_43", 0); - scale = config_get_int(cat, "scale", 1); + scale = config_get_int(cat, "scale", 1); if (scale > 3) scale = 3; dpi_scale = config_get_int(cat, "dpi_scale", 1); - enable_overscan = !!config_get_int(cat, "enable_overscan", 0); + enable_overscan = !!config_get_int(cat, "enable_overscan", 0); vid_cga_contrast = !!config_get_int(cat, "vid_cga_contrast", 0); - video_grayscale = config_get_int(cat, "video_grayscale", 0); - video_graytype = config_get_int(cat, "video_graytype", 0); + video_grayscale = config_get_int(cat, "video_grayscale", 0); + video_graytype = config_get_int(cat, "video_graytype", 0); rctrl_is_lalt = config_get_int(cat, "rctrl_is_lalt", 0); - update_icons = config_get_int(cat, "update_icons", 1); + update_icons = config_get_int(cat, "update_icons", 1); window_remember = config_get_int(cat, "window_remember", 0); if (window_remember || (vid_resize & 2)) { - if (!window_remember) - config_delete_var(cat, "window_remember"); + if (!window_remember) + config_delete_var(cat, "window_remember"); } else { - config_delete_var(cat, "window_remember"); + config_delete_var(cat, "window_remember"); - window_w = window_h = window_x = window_y = 0; + window_w = window_h = window_x = window_y = 0; } if (vid_resize & 2) { - p = config_get_string(cat, "window_fixed_res", NULL); - if (p == NULL) - p = "120x120"; - sscanf(p, "%ix%i", &fixed_size_x, &fixed_size_y); - if (fixed_size_x < 120) - fixed_size_x = 120; - if (fixed_size_x > 2048) - fixed_size_x = 2048; - if (fixed_size_y < 120) - fixed_size_y = 120; - if (fixed_size_y > 2048) - fixed_size_y = 2048; + p = config_get_string(cat, "window_fixed_res", NULL); + if (p == NULL) + p = "120x120"; + sscanf(p, "%ix%i", &fixed_size_x, &fixed_size_y); + if (fixed_size_x < 120) + fixed_size_x = 120; + if (fixed_size_x > 2048) + fixed_size_x = 2048; + if (fixed_size_y < 120) + fixed_size_y = 120; + if (fixed_size_y > 2048) + fixed_size_y = 2048; } else { - config_delete_var(cat, "window_fixed_res"); + config_delete_var(cat, "window_fixed_res"); - fixed_size_x = fixed_size_y = 120; + fixed_size_x = fixed_size_y = 120; } sound_gain = config_get_int(cat, "sound_gain", 0); kbd_req_capture = config_get_int(cat, "kbd_req_capture", 0); hide_status_bar = config_get_int(cat, "hide_status_bar", 0); - hide_tool_bar = config_get_int(cat, "hide_tool_bar", 0); + hide_tool_bar = config_get_int(cat, "hide_tool_bar", 0); confirm_reset = config_get_int(cat, "confirm_reset", 1); - confirm_exit = config_get_int(cat, "confirm_exit", 1); - confirm_save = config_get_int(cat, "confirm_save", 1); + confirm_exit = config_get_int(cat, "confirm_exit", 1); + confirm_save = config_get_int(cat, "confirm_save", 1); p = config_get_string(cat, "language", NULL); if (p != NULL) - lang_id = plat_language_code(p); + lang_id = plat_language_code(p); mouse_sensitivity = config_get_double(cat, "mouse_sensitivity", 1.0); if (mouse_sensitivity < 0.5) - mouse_sensitivity = 0.5; + mouse_sensitivity = 0.5; else if (mouse_sensitivity > 2.0) - mouse_sensitivity = 2.0; + mouse_sensitivity = 2.0; p = config_get_string(cat, "iconset", NULL); if (p != NULL) - strcpy(icon_set, p); + strcpy(icon_set, p); else - strcpy(icon_set, ""); + strcpy(icon_set, ""); enable_discord = !!config_get_int(cat, "enable_discord", 0); video_framerate = config_get_int(cat, "video_gl_framerate", -1); - video_vsync = config_get_int(cat, "video_gl_vsync", 0); + video_vsync = config_get_int(cat, "video_gl_vsync", 0); strncpy(video_shader, config_get_string(cat, "video_gl_shader", ""), sizeof(video_shader)); } - /* Load "Machine" section. */ static void load_machine(void) { - char *cat = "Machine"; - char *p, *migrate_from = NULL; - int c, i, j, speed, legacy_mfg, legacy_cpu; + char *cat = "Machine"; + char *p, *migrate_from = NULL; + int c, i, j, speed, legacy_mfg, legacy_cpu; double multi; p = config_get_string(cat, "machine", NULL); if (p != NULL) { - migrate_from = p; - if (! strcmp(p, "8500ttc")) /* migrate typo... */ - machine = machine_get_machine_from_internal_name("8600ttc"); - else if (! strcmp(p, "eagle_pcspirit")) /* ...legacy names... */ - machine = machine_get_machine_from_internal_name("pcspirit"); - else if (! strcmp(p, "multitech_pc700")) - machine = machine_get_machine_from_internal_name("pc700"); - else if (! strcmp(p, "ncr_pc4i")) - machine = machine_get_machine_from_internal_name("pc4i"); - else if (! strcmp(p, "olivetti_m19")) - machine = machine_get_machine_from_internal_name("m19"); - else if (! strcmp(p, "open_xt")) - machine = machine_get_machine_from_internal_name("openxt"); - else if (! strcmp(p, "open_at")) - machine = machine_get_machine_from_internal_name("openat"); - else if (! strcmp(p, "philips_p3105")) - machine = machine_get_machine_from_internal_name("p3105"); - else if (! strcmp(p, "philips_p3120")) - machine = machine_get_machine_from_internal_name("p3120"); - else if (! strcmp(p, "olivetti_m24")) - machine = machine_get_machine_from_internal_name("m24"); - else if (! strcmp(p, "olivetti_m240")) - machine = machine_get_machine_from_internal_name("m240"); - else if (! strcmp(p, "ncr_pc8")) - machine = machine_get_machine_from_internal_name("pc8"); - else if (! strcmp(p, "olivetti_m290")) - machine = machine_get_machine_from_internal_name("m290"); - else if (! strcmp(p, "ncr_3302")) - machine = machine_get_machine_from_internal_name("3302"); - else if (! strcmp(p, "ncr_pc916sx")) - machine = machine_get_machine_from_internal_name("pc916sx"); - else if (! strcmp(p, "cbm_sl386sx16")) - machine = machine_get_machine_from_internal_name("cmdsl386sx16"); - else if (! strcmp(p, "cbm_sl386sx25")) - machine = machine_get_machine_from_internal_name("cmdsl386sx25"); - else if (! strcmp(p, "mr586")) - machine = machine_get_machine_from_internal_name("p54tp4xe_mr"); - else if (! strcmp(p, "pcv240")) - machine = machine_get_machine_from_internal_name("pcv90"); - else if (! strcmp(p, "v60n")) - machine = machine_get_machine_from_internal_name("acerv60n"); - else if (! strcmp(p, "tsunamiatx")) - machine = machine_get_machine_from_internal_name("s1846"); - else if (! strcmp(p, "trinity371")) - machine = machine_get_machine_from_internal_name("s1857"); - else if (! strcmp(p, "63a")) - machine = machine_get_machine_from_internal_name("63a1"); - else if (! strcmp(p, "4sa2")) - machine = machine_get_machine_from_internal_name("4saw2"); - else if (! strcmp(p, "award386dx")) /* ...merged machines... */ - machine = machine_get_machine_from_internal_name("award495"); - else if (! strcmp(p, "ami386dx")) - machine = machine_get_machine_from_internal_name("ami495"); - else if (! strcmp(p, "mr386dx")) - machine = machine_get_machine_from_internal_name("mr495"); - else if (! strcmp(p, "award486")) - machine = machine_get_machine_from_internal_name("award495"); - else if (! strcmp(p, "ami486")) - machine = machine_get_machine_from_internal_name("ami495"); - else if (! strcmp(p, "mr486")) - machine = machine_get_machine_from_internal_name("mr495"); - else if (! strcmp(p, "ibmps1_2121_isa")) - machine = machine_get_machine_from_internal_name("ibmps1_2121"); - else if (! strcmp(p, "fw6400gx_s1")) - machine = machine_get_machine_from_internal_name("fw6400gx"); - else if (! strcmp(p, "p54vl")) - machine = machine_get_machine_from_internal_name("p5vl"); - else if (! strcmp(p, "chariot")) - machine = machine_get_machine_from_internal_name("fmb"); - else if (! strcmp(p, "president")) { /* ...and removed machines */ - machine = machine_get_machine_from_internal_name("mb500n"); - migrate_from = NULL; - } else if (! strcmp(p, "j656vxd")) { - machine = machine_get_machine_from_internal_name("p55va"); - migrate_from = NULL; - } else { - machine = machine_get_machine_from_internal_name(p); - migrate_from = NULL; - } + migrate_from = p; + if (!strcmp(p, "8500ttc")) /* migrate typo... */ + machine = machine_get_machine_from_internal_name("8600ttc"); + else if (!strcmp(p, "eagle_pcspirit")) /* ...legacy names... */ + machine = machine_get_machine_from_internal_name("pcspirit"); + else if (!strcmp(p, "multitech_pc700")) + machine = machine_get_machine_from_internal_name("pc700"); + else if (!strcmp(p, "ncr_pc4i")) + machine = machine_get_machine_from_internal_name("pc4i"); + else if (!strcmp(p, "olivetti_m19")) + machine = machine_get_machine_from_internal_name("m19"); + else if (!strcmp(p, "open_xt")) + machine = machine_get_machine_from_internal_name("openxt"); + else if (!strcmp(p, "open_at")) + machine = machine_get_machine_from_internal_name("openat"); + else if (!strcmp(p, "philips_p3105")) + machine = machine_get_machine_from_internal_name("p3105"); + else if (!strcmp(p, "philips_p3120")) + machine = machine_get_machine_from_internal_name("p3120"); + else if (!strcmp(p, "olivetti_m24")) + machine = machine_get_machine_from_internal_name("m24"); + else if (!strcmp(p, "olivetti_m240")) + machine = machine_get_machine_from_internal_name("m240"); + else if (!strcmp(p, "ncr_pc8")) + machine = machine_get_machine_from_internal_name("pc8"); + else if (!strcmp(p, "olivetti_m290")) + machine = machine_get_machine_from_internal_name("m290"); + else if (!strcmp(p, "ncr_3302")) + machine = machine_get_machine_from_internal_name("3302"); + else if (!strcmp(p, "ncr_pc916sx")) + machine = machine_get_machine_from_internal_name("pc916sx"); + else if (!strcmp(p, "cbm_sl386sx16")) + machine = machine_get_machine_from_internal_name("cmdsl386sx16"); + else if (!strcmp(p, "cbm_sl386sx25")) + machine = machine_get_machine_from_internal_name("cmdsl386sx25"); + else if (!strcmp(p, "mr586")) + machine = machine_get_machine_from_internal_name("p54tp4xe_mr"); + else if (!strcmp(p, "pcv240")) + machine = machine_get_machine_from_internal_name("pcv90"); + else if (!strcmp(p, "v60n")) + machine = machine_get_machine_from_internal_name("acerv60n"); + else if (!strcmp(p, "tsunamiatx")) + machine = machine_get_machine_from_internal_name("s1846"); + else if (!strcmp(p, "trinity371")) + machine = machine_get_machine_from_internal_name("s1857"); + else if (!strcmp(p, "63a")) + machine = machine_get_machine_from_internal_name("63a1"); + else if (!strcmp(p, "4sa2")) + machine = machine_get_machine_from_internal_name("4saw2"); + else if (!strcmp(p, "award386dx")) /* ...merged machines... */ + machine = machine_get_machine_from_internal_name("award495"); + else if (!strcmp(p, "ami386dx")) + machine = machine_get_machine_from_internal_name("ami495"); + else if (!strcmp(p, "mr386dx")) + machine = machine_get_machine_from_internal_name("mr495"); + else if (!strcmp(p, "award486")) + machine = machine_get_machine_from_internal_name("award495"); + else if (!strcmp(p, "ami486")) + machine = machine_get_machine_from_internal_name("ami495"); + else if (!strcmp(p, "mr486")) + machine = machine_get_machine_from_internal_name("mr495"); + else if (!strcmp(p, "ibmps1_2121_isa")) + machine = machine_get_machine_from_internal_name("ibmps1_2121"); + else if (!strcmp(p, "fw6400gx_s1")) + machine = machine_get_machine_from_internal_name("fw6400gx"); + else if (!strcmp(p, "p54vl")) + machine = machine_get_machine_from_internal_name("p5vl"); + else if (!strcmp(p, "chariot")) + machine = machine_get_machine_from_internal_name("fmb"); + else if (!strcmp(p, "president")) { /* ...and removed machines */ + machine = machine_get_machine_from_internal_name("mb500n"); + migrate_from = NULL; + } else if (!strcmp(p, "j656vxd")) { + machine = machine_get_machine_from_internal_name("p55va"); + migrate_from = NULL; + } else { + machine = machine_get_machine_from_internal_name(p); + migrate_from = NULL; + } } else - machine = 0; + machine = 0; /* This is for backwards compatibility. */ p = config_get_string(cat, "model", NULL); if (p != NULL) { - migrate_from = p; - if (! strcmp(p, "p55r2p4")) /* migrate typo */ - machine = machine_get_machine_from_internal_name("p55t2p4"); - else { - machine = machine_get_machine_from_internal_name(p); - migrate_from = NULL; - } - config_delete_var(cat, "model"); + migrate_from = p; + if (!strcmp(p, "p55r2p4")) /* migrate typo */ + machine = machine_get_machine_from_internal_name("p55t2p4"); + else { + machine = machine_get_machine_from_internal_name(p); + migrate_from = NULL; + } + config_delete_var(cat, "model"); } if (machine >= machine_count()) - machine = machine_count() - 1; + machine = machine_count() - 1; /* Copy NVR files when migrating a machine to a new internal name. */ if (migrate_from) { - char old_fn[256]; - strcpy(old_fn, migrate_from); - strcat(old_fn, "."); - c = strlen(old_fn); - char new_fn[256]; - strcpy(new_fn, machines[machine].internal_name); - strcat(new_fn, "."); - i = strlen(new_fn); + char old_fn[256]; + strcpy(old_fn, migrate_from); + strcat(old_fn, "."); + c = strlen(old_fn); + char new_fn[256]; + strcpy(new_fn, machines[machine].internal_name); + strcat(new_fn, "."); + i = strlen(new_fn); - /* Iterate through NVR files. */ - DIR *dirp = opendir(nvr_path(".")); - if (dirp) { - struct dirent *entry; - while ((entry = readdir(dirp))) { - /* Check if this file corresponds to the old name. */ - if (strncmp(entry->d_name, old_fn, c)) - continue; + /* Iterate through NVR files. */ + DIR *dirp = opendir(nvr_path(".")); + if (dirp) { + struct dirent *entry; + while ((entry = readdir(dirp))) { + /* Check if this file corresponds to the old name. */ + if (strncmp(entry->d_name, old_fn, c)) + continue; - /* Add extension to the new name. */ - strcpy(&new_fn[i], &entry->d_name[c]); + /* Add extension to the new name. */ + strcpy(&new_fn[i], &entry->d_name[c]); - /* Only copy if a file with the new name doesn't already exist. */ - FILE *g = nvr_fopen(new_fn, "rb"); - if (!g) { - FILE *f = nvr_fopen(entry->d_name, "rb"); - g = nvr_fopen(new_fn, "wb"); + /* Only copy if a file with the new name doesn't already exist. */ + FILE *g = nvr_fopen(new_fn, "rb"); + if (!g) { + FILE *f = nvr_fopen(entry->d_name, "rb"); + g = nvr_fopen(new_fn, "wb"); - uint8_t buf[4096]; - while ((j = fread(buf, 1, sizeof(buf), f))) - fwrite(buf, 1, j, g); + uint8_t buf[4096]; + while ((j = fread(buf, 1, sizeof(buf), f))) + fwrite(buf, 1, j, g); - fclose(f); - } - fclose(g); - } - } + fclose(f); + } + fclose(g); + } + } } cpu_override = config_get_int(cat, "cpu_override", 0); - cpu_f = NULL; - p = config_get_string(cat, "cpu_family", NULL); + cpu_f = NULL; + p = config_get_string(cat, "cpu_family", NULL); if (p) { - if (! strcmp(p, "enh_am486dx2")) /* migrate modified names */ - cpu_f = cpu_get_family("am486dx2_slenh"); - else if (! strcmp(p, "enh_am486dx4")) - cpu_f = cpu_get_family("am486dx4_slenh"); - else - cpu_f = cpu_get_family(p); + if (!strcmp(p, "enh_am486dx2")) /* migrate modified names */ + cpu_f = cpu_get_family("am486dx2_slenh"); + else if (!strcmp(p, "enh_am486dx4")) + cpu_f = cpu_get_family("am486dx4_slenh"); + else + cpu_f = cpu_get_family(p); - if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */ - cpu_f = NULL; + if (cpu_f && !cpu_family_is_eligible(cpu_f, machine)) /* only honor eligible families */ + cpu_f = NULL; } else { - /* Backwards compatibility with the previous CPU model system. */ - legacy_mfg = config_get_int(cat, "cpu_manufacturer", 0); - legacy_cpu = config_get_int(cat, "cpu", 0); + /* Backwards compatibility with the previous CPU model system. */ + legacy_mfg = config_get_int(cat, "cpu_manufacturer", 0); + legacy_cpu = config_get_int(cat, "cpu", 0); - /* Check if either legacy ID is present, and if they are within bounds. */ - if (((legacy_mfg > 0) || (legacy_cpu > 0)) && (legacy_mfg >= 0) && (legacy_mfg < 4) && (legacy_cpu >= 0)) { - /* Look for a machine entry on the legacy table. */ - p = machine_get_internal_name(); - c = 0; - while (cpu_legacy_table[c].machine) { - if (!strcmp(p, cpu_legacy_table[c].machine)) - break; - c++; - } - if (cpu_legacy_table[c].machine) { - /* Determine the amount of CPU entries on the table. */ - i = -1; - while (cpu_legacy_table[c].tables[legacy_mfg][++i].family); + /* Check if either legacy ID is present, and if they are within bounds. */ + if (((legacy_mfg > 0) || (legacy_cpu > 0)) && (legacy_mfg >= 0) && (legacy_mfg < 4) && (legacy_cpu >= 0)) { + /* Look for a machine entry on the legacy table. */ + p = machine_get_internal_name(); + c = 0; + while (cpu_legacy_table[c].machine) { + if (!strcmp(p, cpu_legacy_table[c].machine)) + break; + c++; + } + if (cpu_legacy_table[c].machine) { + /* Determine the amount of CPU entries on the table. */ + i = -1; + while (cpu_legacy_table[c].tables[legacy_mfg][++i].family) + ; - /* If the CPU ID is out of bounds, reset to the last known ID. */ - if (legacy_cpu >= i) - legacy_cpu = i - 1; + /* If the CPU ID is out of bounds, reset to the last known ID. */ + if (legacy_cpu >= i) + legacy_cpu = i - 1; - const cpu_legacy_table_t *legacy_table_entry = &cpu_legacy_table[c].tables[legacy_mfg][legacy_cpu]; + const cpu_legacy_table_t *legacy_table_entry = &cpu_legacy_table[c].tables[legacy_mfg][legacy_cpu]; - /* Check if the referenced family exists. */ - cpu_f = cpu_get_family(legacy_table_entry->family); - if (cpu_f) { - /* Save the new values. */ - config_set_string(cat, "cpu_family", (char *) legacy_table_entry->family); - config_set_int(cat, "cpu_speed", legacy_table_entry->rspeed); - config_set_double(cat, "cpu_multi", legacy_table_entry->multi); - } - } - } + /* Check if the referenced family exists. */ + cpu_f = cpu_get_family(legacy_table_entry->family); + if (cpu_f) { + /* Save the new values. */ + config_set_string(cat, "cpu_family", (char *) legacy_table_entry->family); + config_set_int(cat, "cpu_speed", legacy_table_entry->rspeed); + config_set_double(cat, "cpu_multi", legacy_table_entry->multi); + } + } + } } if (cpu_f) { - speed = config_get_int(cat, "cpu_speed", 0); - multi = config_get_double(cat, "cpu_multi", 0); + speed = config_get_int(cat, "cpu_speed", 0); + multi = config_get_double(cat, "cpu_multi", 0); - /* Find the configured CPU. */ - cpu = 0; - c = 0; - i = 256; - while (cpu_f->cpus[cpu].cpu_type) { - if (cpu_is_eligible(cpu_f, cpu, machine)) { /* skip ineligible CPUs */ - if ((cpu_f->cpus[cpu].rspeed == speed) && (cpu_f->cpus[cpu].multi == multi)) /* exact speed/multiplier match */ - break; - else if ((cpu_f->cpus[cpu].rspeed >= speed) && (i == 256)) /* closest speed match */ - i = cpu; - c = cpu; /* store fastest eligible CPU */ - } - cpu++; - } - if (!cpu_f->cpus[cpu].cpu_type) /* if no exact match was found, use closest matching faster CPU, or fastest eligible CPU */ - cpu = MIN(i, c); + /* Find the configured CPU. */ + cpu = 0; + c = 0; + i = 256; + while (cpu_f->cpus[cpu].cpu_type) { + if (cpu_is_eligible(cpu_f, cpu, machine)) { /* skip ineligible CPUs */ + if ((cpu_f->cpus[cpu].rspeed == speed) && (cpu_f->cpus[cpu].multi == multi)) /* exact speed/multiplier match */ + break; + else if ((cpu_f->cpus[cpu].rspeed >= speed) && (i == 256)) /* closest speed match */ + i = cpu; + c = cpu; /* store fastest eligible CPU */ + } + cpu++; + } + if (!cpu_f->cpus[cpu].cpu_type) /* if no exact match was found, use closest matching faster CPU, or fastest eligible CPU */ + cpu = MIN(i, c); } else { /* default */ - /* Find first eligible family. */ - c = 0; - while (!cpu_family_is_eligible(&cpu_families[c], machine)) { - if (cpu_families[c++].package == 0) { /* end of list */ - fatal("No eligible CPU families for the selected machine\n"); - return; - } - } - cpu_f = (cpu_family_t *) &cpu_families[c]; + /* Find first eligible family. */ + c = 0; + while (!cpu_family_is_eligible(&cpu_families[c], machine)) { + if (cpu_families[c++].package == 0) { /* end of list */ + fatal("No eligible CPU families for the selected machine\n"); + return; + } + } + cpu_f = (cpu_family_t *) &cpu_families[c]; - /* Find first eligible CPU in that family. */ - cpu = 0; - while (!cpu_is_eligible(cpu_f, cpu, machine)) { - if (cpu_f->cpus[cpu++].cpu_type == 0) { /* end of list */ - cpu = 0; - break; - } - } + /* Find first eligible CPU in that family. */ + cpu = 0; + while (!cpu_is_eligible(cpu_f, cpu, machine)) { + if (cpu_f->cpus[cpu++].cpu_type == 0) { /* end of list */ + cpu = 0; + break; + } + } } cpu_s = (CPU *) &cpu_f->cpus[cpu]; cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); - p = (char *)config_get_string(cat, "fpu_type", "none"); + p = (char *) config_get_string(cat, "fpu_type", "none"); fpu_type = fpu_get_type(cpu_f, cpu, p); mem_size = config_get_int(cat, "mem_size", 64); #if 0 if (mem_size < ((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) - mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); + mem_size = (((machine_has_bus(machine, MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); #endif if (mem_size > 2097152) - mem_size = 2097152; + mem_size = 2097152; cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); p = config_get_string(cat, "time_sync", NULL); if (p != NULL) { - if (!strcmp(p, "disabled")) - time_sync = TIME_SYNC_DISABLED; - else - if (!strcmp(p, "local")) - time_sync = TIME_SYNC_ENABLED; - else - if (!strcmp(p, "utc") || !strcmp(p, "gmt")) - time_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; - else - time_sync = TIME_SYNC_ENABLED; + if (!strcmp(p, "disabled")) + time_sync = TIME_SYNC_DISABLED; + else if (!strcmp(p, "local")) + time_sync = TIME_SYNC_ENABLED; + else if (!strcmp(p, "utc") || !strcmp(p, "gmt")) + time_sync = TIME_SYNC_ENABLED | TIME_SYNC_UTC; + else + time_sync = TIME_SYNC_ENABLED; } else - time_sync = !!config_get_int(cat, "enable_sync", 1); + time_sync = !!config_get_int(cat, "enable_sync", 1); + + pit_mode = config_get_int(cat, "pit_mode", -1); /* Remove this after a while.. */ config_delete_var(cat, "nvr_path"); config_delete_var(cat, "enable_sync"); } - /* Load "Video" section. */ static void load_video(void) { char *cat = "Video"; char *p; - int free_p = 0; + int free_p = 0; if (machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { - config_delete_var(cat, "gfxcard"); - gfxcard = VID_INTERNAL; + config_delete_var(cat, "gfxcard"); + gfxcard = VID_INTERNAL; } else { - p = config_get_string(cat, "gfxcard", NULL); - if (p == NULL) { - if (machine_has_flags(machine, MACHINE_VIDEO)) { - p = (char *)malloc((strlen("internal")+1)*sizeof(char)); - strcpy(p, "internal"); - } else { - p = (char *)malloc((strlen("none")+1)*sizeof(char)); - strcpy(p, "none"); - } - free_p = 1; - } - if (!strcmp(p, "virge375_vbe20_pci")) /* migrate renamed cards */ - gfxcard = video_get_video_from_internal_name("virge385_pci"); - else - gfxcard = video_get_video_from_internal_name(p); - if (free_p) - free(p); + p = config_get_string(cat, "gfxcard", NULL); + if (p == NULL) { + if (machine_has_flags(machine, MACHINE_VIDEO)) { + p = (char *) malloc((strlen("internal") + 1) * sizeof(char)); + strcpy(p, "internal"); + } else { + p = (char *) malloc((strlen("none") + 1) * sizeof(char)); + strcpy(p, "none"); + } + free_p = 1; + } + if (!strcmp(p, "virge375_vbe20_pci")) /* migrate renamed cards */ + gfxcard = video_get_video_from_internal_name("virge385_pci"); + else + gfxcard = video_get_video_from_internal_name(p); + if (free_p) + free(p); } - voodoo_enabled = !!config_get_int(cat, "voodoo", 0); - ibm8514_enabled = !!config_get_int(cat, "8514a", 0); - xga_enabled = !!config_get_int(cat, "xga", 0); + voodoo_enabled = !!config_get_int(cat, "voodoo", 0); + ibm8514_enabled = !!config_get_int(cat, "8514a", 0); + xga_enabled = !!config_get_int(cat, "xga", 0); show_second_monitors = !!config_get_int(cat, "show_second_monitors", 1); - p = config_get_string(cat, "gfxcard_2", NULL); - if (!p) p = "none"; + p = config_get_string(cat, "gfxcard_2", NULL); + if (!p) + p = "none"; gfxcard_2 = video_get_video_from_internal_name(p); } - static void load_monitor(int monitor_index) { - char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 }; - char* ptr = NULL; + char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 }; + char *ptr = NULL; - if (monitor_index == 0) { - /* Migrate configs */ + if (monitor_index == 0) { + /* Migrate configs */ ptr = config_get_string("General", "window_coordinates", NULL); - - config_delete_var("General", "window_coordinates"); - } + + config_delete_var("General", "window_coordinates"); + } snprintf(monitor_config_name, sizeof(monitor_config_name), "Monitor #%i", monitor_index + 1); - if (!ptr) ptr = config_get_string(monitor_config_name, "window_coordinates", "0, 0, 0, 0"); - if (window_remember || (vid_resize & 2)) sscanf(ptr, "%i, %i, %i, %i", - &monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y, - &monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h); + if (!ptr) + ptr = config_get_string(monitor_config_name, "window_coordinates", "0, 0, 0, 0"); + if (window_remember || (vid_resize & 2)) + sscanf(ptr, "%i, %i, %i, %i", + &monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y, + &monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h); } static void save_monitor(int monitor_index) { char monitor_config_name[sizeof("Monitor #") + 12] = { [0] = 0 }; - char saved_coordinates[12 * 4 + 8 + 1] = { [0] = 0 }; + char saved_coordinates[12 * 4 + 8 + 1] = { [0] = 0 }; snprintf(monitor_config_name, sizeof(monitor_config_name), "Monitor #%i", monitor_index + 1); if (!(monitor_settings[monitor_index].mon_window_x == 0 - && monitor_settings[monitor_index].mon_window_y == 0 - && monitor_settings[monitor_index].mon_window_w == 0 - && monitor_settings[monitor_index].mon_window_h == 0) && (window_remember || (vid_resize & 2))) { + && monitor_settings[monitor_index].mon_window_y == 0 + && monitor_settings[monitor_index].mon_window_w == 0 + && monitor_settings[monitor_index].mon_window_h == 0) + && (window_remember || (vid_resize & 2))) { snprintf(saved_coordinates, sizeof(saved_coordinates), "%i, %i, %i, %i", monitor_settings[monitor_index].mon_window_x, monitor_settings[monitor_index].mon_window_y, - monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h); + monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h); config_set_string(monitor_config_name, "window_coordinates", saved_coordinates); - } - else config_delete_var(monitor_config_name, "window_coordinates"); + } else + config_delete_var(monitor_config_name, "window_coordinates"); } - /* Load "Input Devices" section. */ static void load_input_devices(void) { char *cat = "Input devices"; - char temp[512]; - int c, d; + char temp[512]; + int c, d; char *p; p = config_get_string(cat, "mouse_type", NULL); if (p != NULL) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; + mouse_type = mouse_get_from_internal_name(p); + else + mouse_type = 0; p = config_get_string(cat, "joystick_type", NULL); if (p != NULL) { - if (!strcmp(p, "standard_2button")) /* migrate renamed types */ - joystick_type = joystick_get_from_internal_name("2axis_2button"); - else if (!strcmp(p, "standard_4button")) - joystick_type = joystick_get_from_internal_name("2axis_4button"); - else if (!strcmp(p, "standard_6button")) - joystick_type = joystick_get_from_internal_name("2axis_6button"); - else if (!strcmp(p, "standard_8button")) - joystick_type = joystick_get_from_internal_name("2axis_8button"); - else if (!strcmp(p, "ch_flighstick_pro")) /* fix typo */ - joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); - else - joystick_type = joystick_get_from_internal_name(p); + if (!strcmp(p, "standard_2button")) /* migrate renamed types */ + joystick_type = joystick_get_from_internal_name("2axis_2button"); + else if (!strcmp(p, "standard_4button")) + joystick_type = joystick_get_from_internal_name("2axis_4button"); + else if (!strcmp(p, "standard_6button")) + joystick_type = joystick_get_from_internal_name("2axis_6button"); + else if (!strcmp(p, "standard_8button")) + joystick_type = joystick_get_from_internal_name("2axis_8button"); + else if (!strcmp(p, "ch_flighstick_pro")) /* fix typo */ + joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); + else + joystick_type = joystick_get_from_internal_name(p); - if (!joystick_type) { - /* Try to read an integer for backwards compatibility with old configs */ - if (!strcmp(p, "0")) /* workaround for config_get_int returning 0 on non-integer data */ - joystick_type = joystick_get_from_internal_name("2axis_2button"); - else { - c = config_get_int(cat, "joystick_type", 8); - switch (c) { - case 1: - joystick_type = joystick_get_from_internal_name("2axis_4button"); - break; - case 2: - joystick_type = joystick_get_from_internal_name("2axis_6button"); - break; - case 3: - joystick_type = joystick_get_from_internal_name("2axis_8button"); - break; - case 4: - joystick_type = joystick_get_from_internal_name("4axis_4button"); - break; - case 5: - joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); - break; - case 6: - joystick_type = joystick_get_from_internal_name("sidewinder_pad"); - break; - case 7: - joystick_type = joystick_get_from_internal_name("thrustmaster_fcs"); - break; - default: - joystick_type = 0; - break; - } - } - } + if (!joystick_type) { + /* Try to read an integer for backwards compatibility with old configs */ + if (!strcmp(p, "0")) /* workaround for config_get_int returning 0 on non-integer data */ + joystick_type = joystick_get_from_internal_name("2axis_2button"); + else { + c = config_get_int(cat, "joystick_type", 8); + switch (c) { + case 1: + joystick_type = joystick_get_from_internal_name("2axis_4button"); + break; + case 2: + joystick_type = joystick_get_from_internal_name("2axis_6button"); + break; + case 3: + joystick_type = joystick_get_from_internal_name("2axis_8button"); + break; + case 4: + joystick_type = joystick_get_from_internal_name("4axis_4button"); + break; + case 5: + joystick_type = joystick_get_from_internal_name("ch_flightstick_pro"); + break; + case 6: + joystick_type = joystick_get_from_internal_name("sidewinder_pad"); + break; + case 7: + joystick_type = joystick_get_from_internal_name("thrustmaster_fcs"); + break; + default: + joystick_type = 0; + break; + } + } + } } else - joystick_type = 0; + joystick_type = 0; - for (c=0; c 511) - fatal("load_sound(): strlen(p) > 511\n"); + fatal("load_sound(): strlen(p) > 511\n"); else - strncpy(temp, p, strlen(p) + 1); + strncpy(temp, p, strlen(p) + 1); if (!strcmp(temp, "float") || !strcmp(temp, "1")) - sound_is_float = 1; - else - sound_is_float = 0; + sound_is_float = 1; + else + sound_is_float = 0; } - /* Load "Network" section. */ static void load_network(void) @@ -1118,93 +1121,90 @@ load_network(void) p = config_get_string(cat, "net_type", NULL); if (p != NULL) { - if (!strcmp(p, "pcap") || !strcmp(p, "1")) - network_type = NET_TYPE_PCAP; - else - if (!strcmp(p, "slirp") || !strcmp(p, "2")) - network_type = NET_TYPE_SLIRP; - else - network_type = NET_TYPE_NONE; + if (!strcmp(p, "pcap") || !strcmp(p, "1")) + network_type = NET_TYPE_PCAP; + else if (!strcmp(p, "slirp") || !strcmp(p, "2")) + network_type = NET_TYPE_SLIRP; + else + network_type = NET_TYPE_NONE; } else - network_type = NET_TYPE_NONE; + network_type = NET_TYPE_NONE; memset(network_host, '\0', sizeof(network_host)); p = config_get_string(cat, "net_host_device", NULL); if (p == NULL) { - p = config_get_string(cat, "net_host_device", NULL); - if (p != NULL) - config_delete_var(cat, "net_host_device"); + p = config_get_string(cat, "net_host_device", NULL); + if (p != NULL) + config_delete_var(cat, "net_host_device"); } if (p != NULL) { - if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { - if ((network_ndev == 1) && strcmp(network_host, "none")) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2094, (wchar_t *) IDS_2129); - } else if (network_dev_to_id(p) == -1) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2129); - } + if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { + if ((network_ndev == 1) && strcmp(network_host, "none")) { + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2094, (wchar_t *) IDS_2129); + } else if (network_dev_to_id(p) == -1) { + ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2095, (wchar_t *) IDS_2129); + } - strcpy(network_host, "none"); - } else { - strncpy(network_host, p, sizeof(network_host) - 1); - } + strcpy(network_host, "none"); + } else { + strncpy(network_host, p, sizeof(network_host) - 1); + } } else - strcpy(network_host, "none"); + strcpy(network_host, "none"); p = config_get_string(cat, "net_card", NULL); if (p != NULL) - network_card = network_card_get_from_internal_name(p); - else - network_card = 0; + network_card = network_card_get_from_internal_name(p); + else + network_card = 0; } - /* Load "Ports" section. */ static void load_ports(void) { char *cat = "Ports (COM & LPT)"; char *p; - char temp[512]; - int c, d; + char temp[512]; + int c, d; for (c = 0; c < SERIAL_MAX; c++) { - sprintf(temp, "serial%d_enabled", c + 1); - serial_enabled[c] = !!config_get_int(cat, temp, (c >= 2) ? 0 : 1); + sprintf(temp, "serial%d_enabled", c + 1); + serial_enabled[c] = !!config_get_int(cat, temp, (c >= 2) ? 0 : 1); -/* - sprintf(temp, "serial%d_device", c + 1); - p = (char *) config_get_string(cat, temp, "none"); - com_ports[c].device = com_device_get_from_internal_name(p); -*/ + /* + sprintf(temp, "serial%d_device", c + 1); + p = (char *) config_get_string(cat, temp, "none"); + com_ports[c].device = com_device_get_from_internal_name(p); + */ } for (c = 0; c < PARALLEL_MAX; c++) { - sprintf(temp, "lpt%d_enabled", c + 1); - lpt_ports[c].enabled = !!config_get_int(cat, temp, (c == 0) ? 1 : 0); + sprintf(temp, "lpt%d_enabled", c + 1); + lpt_ports[c].enabled = !!config_get_int(cat, temp, (c == 0) ? 1 : 0); - sprintf(temp, "lpt%d_device", c + 1); - p = (char *) config_get_string(cat, temp, "none"); - lpt_ports[c].device = lpt_device_get_from_internal_name(p); + sprintf(temp, "lpt%d_device", c + 1); + p = (char *) config_get_string(cat, temp, "none"); + lpt_ports[c].device = lpt_device_get_from_internal_name(p); } /* Legacy config compatibility. */ d = config_get_int(cat, "lpt_enabled", 2); if (d < 2) { - for (c = 0; c < PARALLEL_MAX; c++) - lpt_ports[c].enabled = d; + for (c = 0; c < PARALLEL_MAX; c++) + lpt_ports[c].enabled = d; } config_delete_var(cat, "lpt_enabled"); } - /* Load "Storage Controllers" section. */ static void load_storage_controllers(void) { char *cat = "Storage controllers"; char *p, temp[512]; - int c, min = 0; - int free_p = 0; + int c, min = 0; + int free_p = 0; /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ backwards_compat2 = (find_section(cat) == NULL); @@ -1212,54 +1212,54 @@ load_storage_controllers(void) /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ p = config_get_string(cat, "scsicard", NULL); if (p != NULL) { - scsi_card_current[0] = scsi_card_get_from_internal_name(p); - min++; + scsi_card_current[0] = scsi_card_get_from_internal_name(p); + min++; } config_delete_var(cat, "scsi_card"); for (c = min; c < SCSI_BUS_MAX; c++) { - sprintf(temp, "scsicard_%d", c + 1); + sprintf(temp, "scsicard_%d", c + 1); - p = config_get_string(cat, temp, NULL); - if (p != NULL) - scsi_card_current[c] = scsi_card_get_from_internal_name(p); - else - scsi_card_current[c] = 0; + p = config_get_string(cat, temp, NULL); + if (p != NULL) + scsi_card_current[c] = scsi_card_get_from_internal_name(p); + else + scsi_card_current[c] = 0; } p = config_get_string(cat, "fdc", NULL); if (p != NULL) - fdc_type = fdc_card_get_from_internal_name(p); - else - fdc_type = FDC_INTERNAL; + fdc_type = fdc_card_get_from_internal_name(p); + else + fdc_type = FDC_INTERNAL; p = config_get_string(cat, "hdc", NULL); if (p == NULL) { - if (machine_has_flags(machine, MACHINE_HDC)) { - p = (char *)malloc((strlen("internal")+1)*sizeof(char)); - strcpy(p, "internal"); - } else { - p = (char *)malloc((strlen("none")+1)*sizeof(char)); - strcpy(p, "none"); - } - free_p = 1; + if (machine_has_flags(machine, MACHINE_HDC)) { + p = (char *) malloc((strlen("internal") + 1) * sizeof(char)); + strcpy(p, "internal"); + } else { + p = (char *) malloc((strlen("none") + 1) * sizeof(char)); + strcpy(p, "none"); + } + free_p = 1; } if (!strcmp(p, "mfm_xt")) - hdc_current = hdc_get_from_internal_name("st506_xt"); + hdc_current = hdc_get_from_internal_name("st506_xt"); else if (!strcmp(p, "mfm_xt_dtc5150x")) - hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); + hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); else if (!strcmp(p, "mfm_at")) - hdc_current = hdc_get_from_internal_name("st506_at"); + hdc_current = hdc_get_from_internal_name("st506_at"); else if (!strcmp(p, "vlb_isa")) - hdc_current = hdc_get_from_internal_name("ide_vlb"); + hdc_current = hdc_get_from_internal_name("ide_vlb"); else if (!strcmp(p, "vlb_isa_2ch")) - hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); + hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); else - hdc_current = hdc_get_from_internal_name(p); + hdc_current = hdc_get_from_internal_name(p); if (free_p) { - free(p); - p = NULL; + free(p); + p = NULL; } ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0); @@ -1267,866 +1267,858 @@ load_storage_controllers(void) /* TODO: Re-enable by default after we actually have a proper machine flag for this. */ cassette_enable = !!config_get_int(cat, "cassette_enabled", 0); - p = config_get_string(cat, "cassette_file", ""); + p = config_get_string(cat, "cassette_file", ""); if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); + fatal("load_storage_controllers(): strlen(p) > 511\n"); else - strncpy(cassette_fname, p, MIN(512, strlen(p) + 1)); + strncpy(cassette_fname, p, MIN(512, strlen(p) + 1)); p = config_get_string(cat, "cassette_mode", ""); if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); + fatal("load_storage_controllers(): strlen(p) > 511\n"); else - strncpy(cassette_mode, p, MIN(512, strlen(p) + 1)); - cassette_pos = config_get_int(cat, "cassette_position", 0); - cassette_srate = config_get_int(cat, "cassette_srate", 44100); - cassette_append = !!config_get_int(cat, "cassette_append", 0); - cassette_pcm = config_get_int(cat, "cassette_pcm", 0); + strncpy(cassette_mode, p, MIN(512, strlen(p) + 1)); + cassette_pos = config_get_int(cat, "cassette_position", 0); + cassette_srate = config_get_int(cat, "cassette_srate", 44100); + cassette_append = !!config_get_int(cat, "cassette_append", 0); + cassette_pcm = config_get_int(cat, "cassette_pcm", 0); cassette_ui_writeprot = !!config_get_int(cat, "cassette_writeprot", 0); - for (c=0; c<2; c++) { - sprintf(temp, "cartridge_%02i_fn", c + 1); - p = config_get_string(cat, temp, ""); + for (c = 0; c < 2; c++) { + sprintf(temp, "cartridge_%02i_fn", c + 1); + p = config_get_string(cat, temp, ""); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c])); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(cart_fns[c])); + } else #endif - if (strlen(p) > 511) - fatal("load_storage_controllers(): strlen(p) > 511\n"); - else - strncpy(cart_fns[c], p, strlen(p) + 1); + if (strlen(p) > 511) + fatal("load_storage_controllers(): strlen(p) > 511\n"); + else + strncpy(cart_fns[c], p, strlen(p) + 1); } } - /* Load "Hard Disks" section. */ static void load_hard_disks(void) { - char *cat = "Hard disks"; - char temp[512], tmp2[512]; - char s[512]; - int c; - char *p; + char *cat = "Hard disks"; + char temp[512], tmp2[512]; + char s[512]; + int c; + char *p; uint32_t max_spt, max_hpc, max_tracks; uint32_t board = 0, dev = 0; memset(temp, '\0', sizeof(temp)); - for (c=0; c max_spt) - hdd[c].spt = max_spt; - if (hdd[c].hpc > max_hpc) - hdd[c].hpc = max_hpc; - if (hdd[c].tracks > max_tracks) - hdd[c].tracks = max_tracks; + if (hdd[c].spt > max_spt) + hdd[c].spt = max_spt; + if (hdd[c].hpc > max_hpc) + hdd[c].hpc = max_hpc; + if (hdd[c].tracks > max_tracks) + hdd[c].tracks = max_tracks; - sprintf(temp, "hdd_%02i_speed", c+1); - switch (hdd[c].bus) { - case HDD_BUS_IDE: - sprintf(tmp2, "1997_5400rpm"); - break; - default: - sprintf(tmp2, "ramdisk"); - break; - } - p = config_get_string(cat, temp, tmp2); - hdd[c].speed_preset = hdd_preset_get_from_internal_name(p); + sprintf(temp, "hdd_%02i_speed", c + 1); + switch (hdd[c].bus) { + case HDD_BUS_IDE: + sprintf(tmp2, "1997_5400rpm"); + break; + default: + sprintf(tmp2, "ramdisk"); + break; + } + p = config_get_string(cat, temp, tmp2); + hdd[c].speed_preset = hdd_preset_get_from_internal_name(p); - /* MFM/RLL */ - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - if (hdd[c].bus == HDD_BUS_MFM) - hdd[c].mfm_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); + /* MFM/RLL */ + sprintf(temp, "hdd_%02i_mfm_channel", c + 1); + if (hdd[c].bus == HDD_BUS_MFM) + hdd[c].mfm_channel = !!config_get_int(cat, temp, c & 1); + else + config_delete_var(cat, temp); - /* XTA */ - sprintf(temp, "hdd_%02i_xta_channel", c+1); - if (hdd[c].bus == HDD_BUS_XTA) - hdd[c].xta_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); + /* XTA */ + sprintf(temp, "hdd_%02i_xta_channel", c + 1); + if (hdd[c].bus == HDD_BUS_XTA) + hdd[c].xta_channel = !!config_get_int(cat, temp, c & 1); + else + config_delete_var(cat, temp); - /* ESDI */ - sprintf(temp, "hdd_%02i_esdi_channel", c+1); - if (hdd[c].bus == HDD_BUS_ESDI) - hdd[c].esdi_channel = !!config_get_int(cat, temp, c & 1); - else - config_delete_var(cat, temp); + /* ESDI */ + sprintf(temp, "hdd_%02i_esdi_channel", c + 1); + if (hdd[c].bus == HDD_BUS_ESDI) + hdd[c].esdi_channel = !!config_get_int(cat, temp, c & 1); + else + config_delete_var(cat, temp); - /* IDE */ - sprintf(temp, "hdd_%02i_ide_channel", c+1); - if (hdd[c].bus == HDD_BUS_IDE) { - sprintf(tmp2, "%01u:%01u", c>>1, c&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - hdd[c].ide_channel = (board<<1) + dev; + /* IDE */ + sprintf(temp, "hdd_%02i_ide_channel", c + 1); + if (hdd[c].bus == HDD_BUS_IDE) { + sprintf(tmp2, "%01u:%01u", c >> 1, c & 1); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%01u", &board, &dev); + board &= 3; + dev &= 1; + hdd[c].ide_channel = (board << 1) + dev; - if (hdd[c].ide_channel > 7) - hdd[c].ide_channel = 7; - } else { - config_delete_var(cat, temp); - } + if (hdd[c].ide_channel > 7) + hdd[c].ide_channel = 7; + } else { + config_delete_var(cat, temp); + } - /* SCSI */ - if (hdd[c].bus == HDD_BUS_SCSI) { - sprintf(temp, "hdd_%02i_scsi_location", c+1); - sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%02u", &board, &dev); - if (board >= SCSI_BUS_MAX) { - /* Invalid bus - check legacy ID */ - sprintf(temp, "hdd_%02i_scsi_id", c+1); - hdd[c].scsi_id = config_get_int(cat, temp, c+2); + /* SCSI */ + if (hdd[c].bus == HDD_BUS_SCSI) { + sprintf(temp, "hdd_%02i_scsi_location", c + 1); + sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%02u", &board, &dev); + if (board >= SCSI_BUS_MAX) { + /* Invalid bus - check legacy ID */ + sprintf(temp, "hdd_%02i_scsi_id", c + 1); + hdd[c].scsi_id = config_get_int(cat, temp, c + 2); - if (hdd[c].scsi_id > 15) - hdd[c].scsi_id = 15; - } else { - board %= SCSI_BUS_MAX; - dev &= 15; - hdd[c].scsi_id = (board<<4)+dev; - } - } else { - sprintf(temp, "hdd_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - } + if (hdd[c].scsi_id > 15) + hdd[c].scsi_id = 15; + } else { + board %= SCSI_BUS_MAX; + dev &= 15; + hdd[c].scsi_id = (board << 4) + dev; + } + } else { + sprintf(temp, "hdd_%02i_scsi_location", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "hdd_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn)); - memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn)); - sprintf(temp, "hdd_%02i_fn", c+1); - p = config_get_string(cat, temp, ""); + memset(hdd[c].fn, 0x00, sizeof(hdd[c].fn)); + memset(hdd[c].prev_fn, 0x00, sizeof(hdd[c].prev_fn)); + sprintf(temp, "hdd_%02i_fn", c + 1); + p = config_get_string(cat, temp, ""); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - /* - * ANOTHER NOTE: - * When loading differencing VHDs, the absolute path is required. - * So we should not convert absolute paths to relative. -sards - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the CFG path. Just strip - * that off for now... - */ - wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn)); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + /* + * ANOTHER NOTE: + * When loading differencing VHDs, the absolute path is required. + * So we should not convert absolute paths to relative. -sards + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the CFG path. Just strip + * that off for now... + */ + wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn)); + } else #endif - if (path_abs(p)) { - strncpy(hdd[c].fn, p, sizeof(hdd[c].fn) - 1); - } else { - path_append_filename(hdd[c].fn, usr_path, p); - } - path_normalize(hdd[c].fn); + if (path_abs(p)) { + strncpy(hdd[c].fn, p, sizeof(hdd[c].fn) - 1); + } else { + path_append_filename(hdd[c].fn, usr_path, p); + } + path_normalize(hdd[c].fn); - /* If disk is empty or invalid, mark it for deletion. */ - if (! hdd_is_valid(c)) { - sprintf(temp, "hdd_%02i_parameters", c+1); - config_delete_var(cat, temp); + /* If disk is empty or invalid, mark it for deletion. */ + if (!hdd_is_valid(c)) { + sprintf(temp, "hdd_%02i_parameters", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_preide_channels", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_preide_channels", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_ide_channels", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_ide_channels", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_fn", c+1); - config_delete_var(cat, temp); - } + sprintf(temp, "hdd_%02i_fn", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "hdd_%02i_mfm_channel", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_mfm_channel", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_ide_channel", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); } } - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ /* Load "Floppy Drives" section. */ static void load_floppy_drives(void) { char *cat = "Floppy drives"; - char temp[512], *p; - int c; + char temp[512], *p; + int c; if (!backwards_compat) - return; + return; - for (c=0; c 13) - fdd_set_type(c, 13); - config_delete_var(cat, temp); + for (c = 0; c < FDD_NUM; c++) { + sprintf(temp, "fdd_%02i_type", c + 1); + p = config_get_string(cat, temp, (c < 2) ? "525_2dd" : "none"); + fdd_set_type(c, fdd_get_from_internal_name(p)); + if (fdd_get_type(c) > 13) + fdd_set_type(c, 13); + config_delete_var(cat, temp); - sprintf(temp, "fdd_%02i_fn", c + 1); - p = config_get_string(cat, temp, ""); - config_delete_var(cat, temp); + sprintf(temp, "fdd_%02i_fn", c + 1); + p = config_get_string(cat, temp, ""); + config_delete_var(cat, temp); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); + } else #endif - if (strlen(p) > 511) - fatal("load_floppy_drives(): strlen(p) > 511\n"); - else - strncpy(floppyfns[c], p, strlen(p) + 1); + if (strlen(p) > 511) + fatal("load_floppy_drives(): strlen(p) > 511\n"); + else + strncpy(floppyfns[c], p, strlen(p) + 1); - /* if (*wp != L'\0') - config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ - sprintf(temp, "fdd_%02i_writeprot", c+1); - ui_writeprot[c] = !!config_get_int(cat, temp, 0); - config_delete_var(cat, temp); - sprintf(temp, "fdd_%02i_turbo", c + 1); - fdd_set_turbo(c, !!config_get_int(cat, temp, 0)); - config_delete_var(cat, temp); - sprintf(temp, "fdd_%02i_check_bpb", c+1); - fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1)); - config_delete_var(cat, temp); + /* if (*wp != L'\0') + config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ + sprintf(temp, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = !!config_get_int(cat, temp, 0); + config_delete_var(cat, temp); + sprintf(temp, "fdd_%02i_turbo", c + 1); + fdd_set_turbo(c, !!config_get_int(cat, temp, 0)); + config_delete_var(cat, temp); + sprintf(temp, "fdd_%02i_check_bpb", c + 1); + fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1)); + config_delete_var(cat, temp); } delete_section_if_empty(cat); } - /* Load "Floppy and CD-ROM Drives" section. */ static void load_floppy_and_cdrom_drives(void) { - char *cat = "Floppy and CD-ROM drives"; - char temp[512], tmp2[512], *p; - char s[512]; + char *cat = "Floppy and CD-ROM drives"; + char temp[512], tmp2[512], *p; + char s[512]; unsigned int board = 0, dev = 0; - int c, d = 0; + int c, d = 0; /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ backwards_compat = (find_section(cat) == NULL); memset(temp, 0x00, sizeof(temp)); - for (c=0; c 13) - fdd_set_type(c, 13); + for (c = 0; c < FDD_NUM; c++) { + sprintf(temp, "fdd_%02i_type", c + 1); + p = config_get_string(cat, temp, (c < 2) ? "525_2dd" : "none"); + fdd_set_type(c, fdd_get_from_internal_name(p)); + if (fdd_get_type(c) > 13) + fdd_set_type(c, 13); - sprintf(temp, "fdd_%02i_fn", c + 1); - p = config_get_string(cat, temp, ""); + sprintf(temp, "fdd_%02i_fn", c + 1); + p = config_get_string(cat, temp, ""); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c])); + } else #endif - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511\n"); - else - strncpy(floppyfns[c], p, strlen(p) + 1); + if (strlen(p) > 511) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511\n"); + else + strncpy(floppyfns[c], p, strlen(p) + 1); - /* if (*wp != L'\0') - config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ - sprintf(temp, "fdd_%02i_writeprot", c+1); - ui_writeprot[c] = !!config_get_int(cat, temp, 0); - sprintf(temp, "fdd_%02i_turbo", c + 1); - fdd_set_turbo(c, !!config_get_int(cat, temp, 0)); - sprintf(temp, "fdd_%02i_check_bpb", c+1); - fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1)); + /* if (*wp != L'\0') + config_log("Floppy%d: %ls\n", c, floppyfns[c]); */ + sprintf(temp, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = !!config_get_int(cat, temp, 0); + sprintf(temp, "fdd_%02i_turbo", c + 1); + fdd_set_turbo(c, !!config_get_int(cat, temp, 0)); + sprintf(temp, "fdd_%02i_check_bpb", c + 1); + fdd_set_check_bpb(c, !!config_get_int(cat, temp, 1)); - /* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */ - if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) { - sprintf(temp, "fdd_%02i_type", c+1); - config_delete_var(cat, temp); - } - if (strlen(floppyfns[c]) == 0) { - sprintf(temp, "fdd_%02i_fn", c+1); - config_delete_var(cat, temp); - } - if (ui_writeprot[c] == 0) { - sprintf(temp, "fdd_%02i_writeprot", c+1); - config_delete_var(cat, temp); - } - if (fdd_get_turbo(c) == 0) { - sprintf(temp, "fdd_%02i_turbo", c+1); - config_delete_var(cat, temp); - } - if (fdd_get_check_bpb(c) == 1) { - sprintf(temp, "fdd_%02i_check_bpb", c+1); - config_delete_var(cat, temp); - } + /* Check whether each value is default, if yes, delete it so that only non-default values will later be saved. */ + if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) { + sprintf(temp, "fdd_%02i_type", c + 1); + config_delete_var(cat, temp); + } + if (strlen(floppyfns[c]) == 0) { + sprintf(temp, "fdd_%02i_fn", c + 1); + config_delete_var(cat, temp); + } + if (ui_writeprot[c] == 0) { + sprintf(temp, "fdd_%02i_writeprot", c + 1); + config_delete_var(cat, temp); + } + if (fdd_get_turbo(c) == 0) { + sprintf(temp, "fdd_%02i_turbo", c + 1); + config_delete_var(cat, temp); + } + if (fdd_get_check_bpb(c) == 1) { + sprintf(temp, "fdd_%02i_check_bpb", c + 1); + config_delete_var(cat, temp); + } } memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - cdrom[c].ide_channel = (board<<1)+dev; + if (cdrom[c].bus_type == CDROM_BUS_ATAPI) { + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); + sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%01u", &board, &dev); + board &= 3; + dev &= 1; + cdrom[c].ide_channel = (board << 1) + dev; - if (cdrom[c].ide_channel > 7) - cdrom[c].ide_channel = 7; - } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%02u", &board, &dev); - if (board >= SCSI_BUS_MAX) { - /* Invalid bus - check legacy ID */ - sprintf(temp, "cdrom_%02i_scsi_id", c+1); - cdrom[c].scsi_device_id = config_get_int(cat, temp, c+2); + if (cdrom[c].ide_channel > 7) + cdrom[c].ide_channel = 7; + } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { + sprintf(temp, "cdrom_%02i_scsi_location", c + 1); + sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%02u", &board, &dev); + if (board >= SCSI_BUS_MAX) { + /* Invalid bus - check legacy ID */ + sprintf(temp, "cdrom_%02i_scsi_id", c + 1); + cdrom[c].scsi_device_id = config_get_int(cat, temp, c + 2); - if (cdrom[c].scsi_device_id > 15) - cdrom[c].scsi_device_id = 15; - } else { - board %= SCSI_BUS_MAX; - dev &= 15; - cdrom[c].scsi_device_id = (board<<4)+dev; - } - } + if (cdrom[c].scsi_device_id > 15) + cdrom[c].scsi_device_id = 15; + } else { + board %= SCSI_BUS_MAX; + dev &= 15; + cdrom[c].scsi_device_id = (board << 4) + dev; + } + } - if (cdrom[c].bus_type != CDROM_BUS_ATAPI) { - sprintf(temp, "cdrom_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - } + if (cdrom[c].bus_type != CDROM_BUS_ATAPI) { + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); + } - if (cdrom[c].bus_type != CDROM_BUS_SCSI) { - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - } + if (cdrom[c].bus_type != CDROM_BUS_SCSI) { + sprintf(temp, "cdrom_%02i_scsi_location", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "cdrom_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_image_path", c+1); - p = config_get_string(cat, temp, ""); + sprintf(temp, "cdrom_%02i_image_path", c + 1); + p = config_get_string(cat, temp, ""); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); + } else #endif - strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); + strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); - if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) - cdrom[c].host_drive = 0; + if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) + cdrom[c].host_drive = 0; - if ((cdrom[c].host_drive == 0x200) && - (strlen(cdrom[c].image_path) == 0)) - cdrom[c].host_drive = 0; + if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0)) + cdrom[c].host_drive = 0; - /* If the CD-ROM is disabled, delete all its variables. */ - if (cdrom[c].bus_type == CDROM_BUS_DISABLED) { - sprintf(temp, "cdrom_%02i_host_drive", c+1); - config_delete_var(cat, temp); + /* If the CD-ROM is disabled, delete all its variables. */ + if (cdrom[c].bus_type == CDROM_BUS_DISABLED) { + sprintf(temp, "cdrom_%02i_host_drive", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_parameters", c+1); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_parameters", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_ide_channel", c+1); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_image_path", c+1); - config_delete_var(cat, temp); - } + sprintf(temp, "cdrom_%02i_image_path", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "cdrom_%02i_iso_path", c+1); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_iso_path", c + 1); + config_delete_var(cat, temp); } } - /* Load "Other Removable Devices" section. */ static void load_other_removable_devices(void) { - char *cat = "Other removable devices"; - char temp[512], tmp2[512], *p; - char s[512]; + char *cat = "Other removable devices"; + char temp[512], tmp2[512], *p; + char s[512]; unsigned int board = 0, dev = 0; - int c, d = 0; + int c, d = 0; /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ if (backwards_compat) { - memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - cdrom[c].ide_channel = (board<<1)+dev; + if (cdrom[c].bus_type == CDROM_BUS_ATAPI) { + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); + sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%01u", &board, &dev); + board &= 3; + dev &= 1; + cdrom[c].ide_channel = (board << 1) + dev; - if (cdrom[c].ide_channel > 7) - cdrom[c].ide_channel = 7; + if (cdrom[c].ide_channel > 7) + cdrom[c].ide_channel = 7; - config_delete_var(cat, temp); - } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { - sprintf(temp, "cdrom_%02i_scsi_id", c+1); - cdrom[c].scsi_device_id = config_get_int(cat, temp, c+2); + config_delete_var(cat, temp); + } else if (cdrom[c].bus_type == CDROM_BUS_SCSI) { + sprintf(temp, "cdrom_%02i_scsi_id", c + 1); + cdrom[c].scsi_device_id = config_get_int(cat, temp, c + 2); - if (cdrom[c].scsi_device_id > 15) - cdrom[c].scsi_device_id = 15; + if (cdrom[c].scsi_device_id > 15) + cdrom[c].scsi_device_id = 15; - config_delete_var(cat, temp); - } + config_delete_var(cat, temp); + } - sprintf(temp, "cdrom_%02i_image_path", c+1); - p = config_get_string(cat, temp, ""); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_image_path", c + 1); + p = config_get_string(cat, temp, ""); + config_delete_var(cat, temp); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(cdrom[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom[c].image_path)); + } else #endif - strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); + strncpy(cdrom[c].image_path, p, sizeof(cdrom[c].image_path) - 1); - if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) - cdrom[c].host_drive = 0; + if (cdrom[c].host_drive && (cdrom[c].host_drive != 200)) + cdrom[c].host_drive = 0; - if ((cdrom[c].host_drive == 0x200) && - (strlen(cdrom[c].image_path) == 0)) - cdrom[c].host_drive = 0; - } + if ((cdrom[c].host_drive == 0x200) && (strlen(cdrom[c].image_path) == 0)) + cdrom[c].host_drive = 0; + } } backwards_compat = 0; memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - zip_drives[c].ide_channel = (board<<1)+dev; + if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) { + sprintf(temp, "zip_%02i_ide_channel", c + 1); + sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%01u", &board, &dev); + board &= 3; + dev &= 1; + zip_drives[c].ide_channel = (board << 1) + dev; - if (zip_drives[c].ide_channel > 7) - zip_drives[c].ide_channel = 7; - } else if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { - sprintf(temp, "zip_%02i_scsi_location", c+1); - sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%02u", &board, &dev); - if (board >= SCSI_BUS_MAX) { - /* Invalid bus - check legacy ID */ - sprintf(temp, "zip_%02i_scsi_id", c+1); - zip_drives[c].scsi_device_id = config_get_int(cat, temp, c+2); + if (zip_drives[c].ide_channel > 7) + zip_drives[c].ide_channel = 7; + } else if (zip_drives[c].bus_type == ZIP_BUS_SCSI) { + sprintf(temp, "zip_%02i_scsi_location", c + 1); + sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%02u", &board, &dev); + if (board >= SCSI_BUS_MAX) { + /* Invalid bus - check legacy ID */ + sprintf(temp, "zip_%02i_scsi_id", c + 1); + zip_drives[c].scsi_device_id = config_get_int(cat, temp, c + 2); - if (zip_drives[c].scsi_device_id > 15) - zip_drives[c].scsi_device_id = 15; - } else { - board %= SCSI_BUS_MAX; - dev &= 15; - zip_drives[c].scsi_device_id = (board<<4)+dev; - } - } + if (zip_drives[c].scsi_device_id > 15) + zip_drives[c].scsi_device_id = 15; + } else { + board %= SCSI_BUS_MAX; + dev &= 15; + zip_drives[c].scsi_device_id = (board << 4) + dev; + } + } - if (zip_drives[c].bus_type != ZIP_BUS_ATAPI) { - sprintf(temp, "zip_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - } + if (zip_drives[c].bus_type != ZIP_BUS_ATAPI) { + sprintf(temp, "zip_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); + } - if (zip_drives[c].bus_type != ZIP_BUS_SCSI) { - sprintf(temp, "zip_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - } + if (zip_drives[c].bus_type != ZIP_BUS_SCSI) { + sprintf(temp, "zip_%02i_scsi_location", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "zip_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "zip_%02i_image_path", c+1); - p = config_get_string(cat, temp, ""); + sprintf(temp, "zip_%02i_image_path", c + 1); + p = config_get_string(cat, temp, ""); #if 0 - /* - * NOTE: - * Temporary hack to remove the absolute - * path currently saved in most config - * files. We should remove this before - * finalizing this release! --FvK - */ - if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { - /* - * Yep, its absolute and prefixed - * with the EXE path. Just strip - * that off for now... - */ - wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path)); - } else + /* + * NOTE: + * Temporary hack to remove the absolute + * path currently saved in most config + * files. We should remove this before + * finalizing this release! --FvK + */ + if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) { + /* + * Yep, its absolute and prefixed + * with the EXE path. Just strip + * that off for now... + */ + wcsncpy(zip_drives[c].image_path, &wp[wcslen(usr_path)], sizeof_w(zip_drives[c].image_path)); + } else #endif - strncpy(zip_drives[c].image_path, p, sizeof(zip_drives[c].image_path) - 1); + strncpy(zip_drives[c].image_path, p, sizeof(zip_drives[c].image_path) - 1); - /* If the CD-ROM is disabled, delete all its variables. */ - if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { - sprintf(temp, "zip_%02i_host_drive", c+1); - config_delete_var(cat, temp); + /* If the CD-ROM is disabled, delete all its variables. */ + if (zip_drives[c].bus_type == ZIP_BUS_DISABLED) { + sprintf(temp, "zip_%02i_host_drive", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "zip_%02i_parameters", c+1); - config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_parameters", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "zip_%02i_ide_channel", c+1); - config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "zip_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "zip_%02i_image_path", c+1); - config_delete_var(cat, temp); - } + sprintf(temp, "zip_%02i_image_path", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "zip_%02i_iso_path", c+1); - config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_iso_path", c + 1); + config_delete_var(cat, temp); } memset(temp, 0x00, sizeof(temp)); - for (c=0; c>1, (c+2)&1); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - mo_drives[c].ide_channel = (board<<1)+dev; + if (mo_drives[c].bus_type == MO_BUS_ATAPI) { + sprintf(temp, "mo_%02i_ide_channel", c + 1); + sprintf(tmp2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%01u", &board, &dev); + board &= 3; + dev &= 1; + mo_drives[c].ide_channel = (board << 1) + dev; - if (mo_drives[c].ide_channel > 7) - mo_drives[c].ide_channel = 7; - } else if (mo_drives[c].bus_type == MO_BUS_SCSI) { - sprintf(temp, "mo_%02i_scsi_location", c+1); - sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c+2); - p = config_get_string(cat, temp, tmp2); - sscanf(p, "%01u:%02u", &board, &dev); - if (board >= SCSI_BUS_MAX) { - /* Invalid bus - check legacy ID */ - sprintf(temp, "mo_%02i_scsi_id", c+1); - mo_drives[c].scsi_device_id = config_get_int(cat, temp, c+2); + if (mo_drives[c].ide_channel > 7) + mo_drives[c].ide_channel = 7; + } else if (mo_drives[c].bus_type == MO_BUS_SCSI) { + sprintf(temp, "mo_%02i_scsi_location", c + 1); + sprintf(tmp2, "%01u:%02u", SCSI_BUS_MAX, c + 2); + p = config_get_string(cat, temp, tmp2); + sscanf(p, "%01u:%02u", &board, &dev); + if (board >= SCSI_BUS_MAX) { + /* Invalid bus - check legacy ID */ + sprintf(temp, "mo_%02i_scsi_id", c + 1); + mo_drives[c].scsi_device_id = config_get_int(cat, temp, c + 2); - if (mo_drives[c].scsi_device_id > 15) - mo_drives[c].scsi_device_id = 15; - } else { - board %= SCSI_BUS_MAX; - dev &= 15; - mo_drives[c].scsi_device_id = (board<<4)+dev; - } - } + if (mo_drives[c].scsi_device_id > 15) + mo_drives[c].scsi_device_id = 15; + } else { + board %= SCSI_BUS_MAX; + dev &= 15; + mo_drives[c].scsi_device_id = (board << 4) + dev; + } + } - if (mo_drives[c].bus_type != MO_BUS_ATAPI) { - sprintf(temp, "mo_%02i_ide_channel", c+1); - config_delete_var(cat, temp); - } + if (mo_drives[c].bus_type != MO_BUS_ATAPI) { + sprintf(temp, "mo_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); + } - if (mo_drives[c].bus_type != MO_BUS_SCSI) { - sprintf(temp, "mo_%02i_scsi_location", c+1); - config_delete_var(cat, temp); - } + if (mo_drives[c].bus_type != MO_BUS_SCSI) { + sprintf(temp, "mo_%02i_scsi_location", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "mo_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "mo_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "mo_%02i_image_path", c+1); - p = config_get_string(cat, temp, ""); + sprintf(temp, "mo_%02i_image_path", c + 1); + p = config_get_string(cat, temp, ""); - strncpy(mo_drives[c].image_path, p, sizeof(mo_drives[c].image_path) - 1); + strncpy(mo_drives[c].image_path, p, sizeof(mo_drives[c].image_path) - 1); - /* If the CD-ROM is disabled, delete all its variables. */ - if (mo_drives[c].bus_type == MO_BUS_DISABLED) { - sprintf(temp, "mo_%02i_host_drive", c+1); - config_delete_var(cat, temp); + /* If the CD-ROM is disabled, delete all its variables. */ + if (mo_drives[c].bus_type == MO_BUS_DISABLED) { + sprintf(temp, "mo_%02i_host_drive", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "mo_%02i_parameters", c+1); - config_delete_var(cat, temp); + sprintf(temp, "mo_%02i_parameters", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "mo_%02i_ide_channel", c+1); - config_delete_var(cat, temp); + sprintf(temp, "mo_%02i_ide_channel", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "mo_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "mo_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "mo_%02i_image_path", c+1); - config_delete_var(cat, temp); - } + sprintf(temp, "mo_%02i_image_path", c + 1); + config_delete_var(cat, temp); + } - sprintf(temp, "mo_%02i_iso_path", c+1); - config_delete_var(cat, temp); + sprintf(temp, "mo_%02i_iso_path", c + 1); + config_delete_var(cat, temp); } } - /* Load "Other Peripherals" section. */ static void load_other_peripherals(void) { char *cat = "Other peripherals"; char *p; - char temp[512]; - int c, free_p = 0; + char temp[512]; + int c, free_p = 0; if (backwards_compat2) { - p = config_get_string(cat, "scsicard", NULL); - if (p != NULL) - scsi_card_current[0] = scsi_card_get_from_internal_name(p); - else - scsi_card_current[0] = 0; - config_delete_var(cat, "scsicard"); + p = config_get_string(cat, "scsicard", NULL); + if (p != NULL) + scsi_card_current[0] = scsi_card_get_from_internal_name(p); + else + scsi_card_current[0] = 0; + config_delete_var(cat, "scsicard"); - p = config_get_string(cat, "fdc", NULL); - if (p != NULL) - fdc_type = fdc_card_get_from_internal_name(p); - else - fdc_type = FDC_INTERNAL; - config_delete_var(cat, "fdc"); + p = config_get_string(cat, "fdc", NULL); + if (p != NULL) + fdc_type = fdc_card_get_from_internal_name(p); + else + fdc_type = FDC_INTERNAL; + config_delete_var(cat, "fdc"); - p = config_get_string(cat, "hdc", NULL); - if (p == NULL) { - if (machine_has_flags(machine, MACHINE_HDC)) { - p = (char *)malloc((strlen("internal")+1)*sizeof(char)); - strcpy(p, "internal"); - } else { - p = (char *)malloc((strlen("none")+1)*sizeof(char)); - strcpy(p, "none"); - } - free_p = 1; - } - if (!strcmp(p, "mfm_xt")) - hdc_current = hdc_get_from_internal_name("st506_xt"); - else if (!strcmp(p, "mfm_xt_dtc5150x")) - hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); - else if (!strcmp(p, "mfm_at")) - hdc_current = hdc_get_from_internal_name("st506_at"); - else if (!strcmp(p, "vlb_isa")) - hdc_current = hdc_get_from_internal_name("ide_vlb"); - else if (!strcmp(p, "vlb_isa_2ch")) - hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); - else - hdc_current = hdc_get_from_internal_name(p); - config_delete_var(cat, "hdc"); + p = config_get_string(cat, "hdc", NULL); + if (p == NULL) { + if (machine_has_flags(machine, MACHINE_HDC)) { + p = (char *) malloc((strlen("internal") + 1) * sizeof(char)); + strcpy(p, "internal"); + } else { + p = (char *) malloc((strlen("none") + 1) * sizeof(char)); + strcpy(p, "none"); + } + free_p = 1; + } + if (!strcmp(p, "mfm_xt")) + hdc_current = hdc_get_from_internal_name("st506_xt"); + else if (!strcmp(p, "mfm_xt_dtc5150x")) + hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x"); + else if (!strcmp(p, "mfm_at")) + hdc_current = hdc_get_from_internal_name("st506_at"); + else if (!strcmp(p, "vlb_isa")) + hdc_current = hdc_get_from_internal_name("ide_vlb"); + else if (!strcmp(p, "vlb_isa_2ch")) + hdc_current = hdc_get_from_internal_name("ide_vlb_2ch"); + else + hdc_current = hdc_get_from_internal_name(p); + config_delete_var(cat, "hdc"); - if (free_p) { - free(p); - p = NULL; - } + if (free_p) { + free(p); + p = NULL; + } - ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0); - config_delete_var(cat, "ide_ter"); - ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0); - config_delete_var(cat, "ide_qua"); + ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0); + config_delete_var(cat, "ide_ter"); + ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0); + config_delete_var(cat, "ide_qua"); } backwards_compat2 = 0; - bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); + bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); postcard_enabled = !!config_get_int(cat, "postcard_enabled", 0); for (c = 0; c < ISAMEM_MAX; c++) { - sprintf(temp, "isamem%d_type", c); + sprintf(temp, "isamem%d_type", c); - p = config_get_string(cat, temp, "none"); - isamem_type[c] = isamem_get_from_internal_name(p); + p = config_get_string(cat, temp, "none"); + isamem_type[c] = isamem_get_from_internal_name(p); } - p = config_get_string(cat, "isartc_type", "none"); + p = config_get_string(cat, "isartc_type", "none"); isartc_type = isartc_get_from_internal_name(p); } - /* Load the specified or a default configuration file. */ void config_load(void) @@ -2142,267 +2134,265 @@ config_load(void) #endif memset(zip_drives, 0, sizeof(zip_drive_t)); - if (! config_read(cfg_path)) { - config_changed = 1; + if (!config_read(cfg_path)) { + config_changed = 1; - cpu_f = (cpu_family_t *) &cpu_families[0]; - cpu = 0; + cpu_f = (cpu_family_t *) &cpu_families[0]; + cpu = 0; - kbd_req_capture = 0; - hide_status_bar = 0; - hide_tool_bar = 0; - scale = 1; - machine = machine_get_machine_from_internal_name("ibmpc"); - dpi_scale = 1; + kbd_req_capture = 0; + hide_status_bar = 0; + hide_tool_bar = 0; + scale = 1; + machine = machine_get_machine_from_internal_name("ibmpc"); + dpi_scale = 1; - fpu_type = fpu_get_type(cpu_f, cpu, "none"); - gfxcard = video_get_video_from_internal_name("cga"); - vid_api = plat_vidapi("default"); - vid_resize = 0; - video_fullscreen_first = 1; - time_sync = TIME_SYNC_ENABLED; - hdc_current = hdc_get_from_internal_name("none"); + fpu_type = fpu_get_type(cpu_f, cpu, "none"); + gfxcard = video_get_video_from_internal_name("cga"); + vid_api = plat_vidapi("default"); + vid_resize = 0; + video_fullscreen_first = 1; + time_sync = TIME_SYNC_ENABLED; + hdc_current = hdc_get_from_internal_name("none"); - serial_enabled[0] = 1; - serial_enabled[1] = 1; - for (i = 2 ; i < SERIAL_MAX; i++) - serial_enabled[i] = 0; + serial_enabled[0] = 1; + serial_enabled[1] = 1; + for (i = 2; i < SERIAL_MAX; i++) + serial_enabled[i] = 0; - lpt_ports[0].enabled = 1; + lpt_ports[0].enabled = 1; - for (i = 1 ; i < PARALLEL_MAX; i++) - lpt_ports[i].enabled = 0; + for (i = 1; i < PARALLEL_MAX; i++) + lpt_ports[i].enabled = 0; - for (i = 0; i < FDD_NUM; i++) { - if (i < 2) - fdd_set_type(i, 2); - else - fdd_set_type(i, 0); + for (i = 0; i < FDD_NUM; i++) { + if (i < 2) + fdd_set_type(i, 2); + else + fdd_set_type(i, 0); - fdd_set_turbo(i, 0); - fdd_set_check_bpb(i, 1); - } + fdd_set_turbo(i, 0); + fdd_set_check_bpb(i, 1); + } - /* Unmute the CD audio on the first CD-ROM drive. */ - cdrom[0].sound_on = 1; - mem_size = 64; - isartc_type = 0; - for (i = 0; i < ISAMEM_MAX; i++) - isamem_type[i] = 0; + /* Unmute the CD audio on the first CD-ROM drive. */ + cdrom[0].sound_on = 1; + mem_size = 64; + isartc_type = 0; + for (i = 0; i < ISAMEM_MAX; i++) + isamem_type[i] = 0; /* TODO: Re-enable by default when we have a proper machine flag for this. */ - cassette_enable = 0; - memset(cassette_fname, 0x00, sizeof(cassette_fname)); - memcpy(cassette_mode, "load", strlen("load") + 1); - cassette_pos = 0; - cassette_srate = 44100; - cassette_append = 0; - cassette_pcm = 0; - cassette_ui_writeprot = 0; + cassette_enable = 0; + memset(cassette_fname, 0x00, sizeof(cassette_fname)); + memcpy(cassette_mode, "load", strlen("load") + 1); + cassette_pos = 0; + cassette_srate = 44100; + cassette_append = 0; + cassette_pcm = 0; + cassette_ui_writeprot = 0; - config_log("Config file not present or invalid!\n"); + config_log("Config file not present or invalid!\n"); } else { - load_general(); /* General */ - for (i = 0; i < MONITORS_NUM; i++) - load_monitor(i); - load_machine(); /* Machine */ - load_video(); /* Video */ - load_input_devices(); /* Input devices */ - load_sound(); /* Sound */ - load_network(); /* Network */ - load_ports(); /* Ports (COM & LPT) */ - load_storage_controllers(); /* Storage controllers */ - load_hard_disks(); /* Hard disks */ - load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ - /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ - load_floppy_drives(); /* Floppy drives */ - load_other_removable_devices(); /* Other removable devices */ - load_other_peripherals(); /* Other peripherals */ + load_general(); /* General */ + for (i = 0; i < MONITORS_NUM; i++) + load_monitor(i); + load_machine(); /* Machine */ + load_video(); /* Video */ + load_input_devices(); /* Input devices */ + load_sound(); /* Sound */ + load_network(); /* Network */ + load_ports(); /* Ports (COM & LPT) */ + load_storage_controllers(); /* Storage controllers */ + load_hard_disks(); /* Hard disks */ + load_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ + /* TODO: Backwards compatibility, get rid of this when enough time has passed. */ + load_floppy_drives(); /* Floppy drives */ + load_other_removable_devices(); /* Other removable devices */ + load_other_peripherals(); /* Other peripherals */ - /* Mark the configuration as changed. */ - config_changed = 1; + /* Mark the configuration as changed. */ + config_changed = 1; - config_log("Config loaded.\n\n"); + config_log("Config loaded.\n\n"); } video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; } - /* Save "General" section. */ static void save_general(void) { char *cat = "General"; - char temp[512], buffer[512] = {0}; + char temp[512], buffer[512] = { 0 }; char *va_name; config_set_int(cat, "vid_resize", vid_resize); if (vid_resize == 0) - config_delete_var(cat, "vid_resize"); + config_delete_var(cat, "vid_resize"); va_name = plat_vidapi_name(vid_api); if (!strcmp(va_name, "default")) - config_delete_var(cat, "vid_renderer"); + config_delete_var(cat, "vid_renderer"); else - config_set_string(cat, "vid_renderer", va_name); + config_set_string(cat, "vid_renderer", va_name); if (video_fullscreen_scale == 0) - config_delete_var(cat, "video_fullscreen_scale"); - else - config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); + config_delete_var(cat, "video_fullscreen_scale"); + else + config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); if (video_fullscreen_first == 1) - config_delete_var(cat, "video_fullscreen_first"); - else - config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); + config_delete_var(cat, "video_fullscreen_first"); + else + config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); if (video_filter_method == 1) - config_delete_var(cat, "video_filter_method"); - else - config_set_int(cat, "video_filter_method", video_filter_method); + config_delete_var(cat, "video_filter_method"); + else + config_set_int(cat, "video_filter_method", video_filter_method); if (force_43 == 0) - config_delete_var(cat, "force_43"); - else - config_set_int(cat, "force_43", force_43); + config_delete_var(cat, "force_43"); + else + config_set_int(cat, "force_43", force_43); if (scale == 1) - config_delete_var(cat, "scale"); - else - config_set_int(cat, "scale", scale); + config_delete_var(cat, "scale"); + else + config_set_int(cat, "scale", scale); if (dpi_scale == 1) - config_delete_var(cat, "dpi_scale"); - else - config_set_int(cat, "dpi_scale", dpi_scale); + config_delete_var(cat, "dpi_scale"); + else + config_set_int(cat, "dpi_scale", dpi_scale); if (enable_overscan == 0) - config_delete_var(cat, "enable_overscan"); - else - config_set_int(cat, "enable_overscan", enable_overscan); + config_delete_var(cat, "enable_overscan"); + else + config_set_int(cat, "enable_overscan", enable_overscan); if (vid_cga_contrast == 0) - config_delete_var(cat, "vid_cga_contrast"); - else - config_set_int(cat, "vid_cga_contrast", vid_cga_contrast); + config_delete_var(cat, "vid_cga_contrast"); + else + config_set_int(cat, "vid_cga_contrast", vid_cga_contrast); if (video_grayscale == 0) - config_delete_var(cat, "video_grayscale"); - else - config_set_int(cat, "video_grayscale", video_grayscale); + config_delete_var(cat, "video_grayscale"); + else + config_set_int(cat, "video_grayscale", video_grayscale); if (video_graytype == 0) - config_delete_var(cat, "video_graytype"); - else - config_set_int(cat, "video_graytype", video_graytype); + config_delete_var(cat, "video_graytype"); + else + config_set_int(cat, "video_graytype", video_graytype); if (rctrl_is_lalt == 0) - config_delete_var(cat, "rctrl_is_lalt"); - else - config_set_int(cat, "rctrl_is_lalt", rctrl_is_lalt); + config_delete_var(cat, "rctrl_is_lalt"); + else + config_set_int(cat, "rctrl_is_lalt", rctrl_is_lalt); if (update_icons == 1) - config_delete_var(cat, "update_icons"); - else - config_set_int(cat, "update_icons", update_icons); + config_delete_var(cat, "update_icons"); + else + config_set_int(cat, "update_icons", update_icons); if (window_remember || (vid_resize & 2)) { - if (window_remember) - config_set_int(cat, "window_remember", window_remember); - else - config_delete_var(cat, "window_remember"); + if (window_remember) + config_set_int(cat, "window_remember", window_remember); + else + config_delete_var(cat, "window_remember"); } else - config_delete_var(cat, "window_remember"); + config_delete_var(cat, "window_remember"); if (vid_resize & 2) { - sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y); - config_set_string(cat, "window_fixed_res", temp); + sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y); + config_set_string(cat, "window_fixed_res", temp); } else - config_delete_var(cat, "window_fixed_res"); + config_delete_var(cat, "window_fixed_res"); if (sound_gain != 0) - config_set_int(cat, "sound_gain", sound_gain); + config_set_int(cat, "sound_gain", sound_gain); else - config_delete_var(cat, "sound_gain"); + config_delete_var(cat, "sound_gain"); if (kbd_req_capture != 0) - config_set_int(cat, "kbd_req_capture", kbd_req_capture); + config_set_int(cat, "kbd_req_capture", kbd_req_capture); else - config_delete_var(cat, "kbd_req_capture"); + config_delete_var(cat, "kbd_req_capture"); if (hide_status_bar != 0) - config_set_int(cat, "hide_status_bar", hide_status_bar); + config_set_int(cat, "hide_status_bar", hide_status_bar); else - config_delete_var(cat, "hide_status_bar"); + config_delete_var(cat, "hide_status_bar"); if (hide_tool_bar != 0) - config_set_int(cat, "hide_tool_bar", hide_tool_bar); + config_set_int(cat, "hide_tool_bar", hide_tool_bar); else - config_delete_var(cat, "hide_tool_bar"); + config_delete_var(cat, "hide_tool_bar"); if (confirm_reset != 1) - config_set_int(cat, "confirm_reset", confirm_reset); + config_set_int(cat, "confirm_reset", confirm_reset); else - config_delete_var(cat, "confirm_reset"); + config_delete_var(cat, "confirm_reset"); if (confirm_exit != 1) - config_set_int(cat, "confirm_exit", confirm_exit); + config_set_int(cat, "confirm_exit", confirm_exit); else - config_delete_var(cat, "confirm_exit"); + config_delete_var(cat, "confirm_exit"); if (confirm_save != 1) - config_set_int(cat, "confirm_save", confirm_save); + config_set_int(cat, "confirm_save", confirm_save); else - config_delete_var(cat, "confirm_save"); + config_delete_var(cat, "confirm_save"); if (mouse_sensitivity != 1.0) - config_set_double(cat, "mouse_sensitivity", mouse_sensitivity); + config_set_double(cat, "mouse_sensitivity", mouse_sensitivity); else - config_delete_var(cat, "mouse_sensitivity"); + config_delete_var(cat, "mouse_sensitivity"); if (lang_id == DEFAULT_LANGUAGE) - config_delete_var(cat, "language"); + config_delete_var(cat, "language"); else { - plat_language_code_r(lang_id, buffer, 511); - config_set_string(cat, "language", buffer); + plat_language_code_r(lang_id, buffer, 511); + config_set_string(cat, "language", buffer); } if (!strcmp(icon_set, "")) - config_delete_var(cat, "iconset"); + config_delete_var(cat, "iconset"); else - config_set_string(cat, "iconset", icon_set); + config_set_string(cat, "iconset", icon_set); if (enable_discord) - config_set_int(cat, "enable_discord", enable_discord); + config_set_int(cat, "enable_discord", enable_discord); else - config_delete_var(cat, "enable_discord"); + config_delete_var(cat, "enable_discord"); if (video_framerate != -1) - config_set_int(cat, "video_gl_framerate", video_framerate); + config_set_int(cat, "video_gl_framerate", video_framerate); else - config_delete_var(cat, "video_gl_framerate"); + config_delete_var(cat, "video_gl_framerate"); if (video_vsync != 0) - config_set_int(cat, "video_gl_vsync", video_vsync); + config_set_int(cat, "video_gl_vsync", video_vsync); else - config_delete_var(cat, "video_gl_vsync"); + config_delete_var(cat, "video_gl_vsync"); if (strlen(video_shader) > 0) - config_set_string(cat, "video_gl_shader", video_shader); + config_set_string(cat, "video_gl_shader", video_shader); else - config_delete_var(cat, "video_gl_shader"); + config_delete_var(cat, "video_gl_shader"); delete_section_if_empty(cat); } - /* Save "Machine" section. */ static void save_machine(void) { char *cat = "Machine"; char *p; - int c, i = 0, legacy_mfg, legacy_cpu = -1, closest_legacy_cpu = -1; + int c, i = 0, legacy_mfg, legacy_cpu = -1, closest_legacy_cpu = -1; p = machine_get_internal_name(); config_set_string(cat, "machine", p); @@ -2411,9 +2401,9 @@ save_machine(void) config_set_int(cat, "cpu_speed", cpu_f->cpus[cpu].rspeed); config_set_double(cat, "cpu_multi", cpu_f->cpus[cpu].multi); if (cpu_override) - config_set_int(cat, "cpu_override", cpu_override); + config_set_int(cat, "cpu_override", cpu_override); else - config_delete_var(cat, "cpu_override"); + config_delete_var(cat, "cpu_override"); /* Forwards compatibility with the previous CPU model system. */ config_delete_var(cat, "cpu_manufacturer"); @@ -2422,81 +2412,83 @@ save_machine(void) /* Look for a machine entry on the legacy table. */ c = 0; while (cpu_legacy_table[c].machine) { - if (!strcmp(p, cpu_legacy_table[c].machine)) - break; - c++; + if (!strcmp(p, cpu_legacy_table[c].machine)) + break; + c++; } if (cpu_legacy_table[c].machine) { - /* Look for a corresponding CPU entry. */ - cpu_legacy_table_t *legacy_table_entry; - for (legacy_mfg = 0; legacy_mfg < 4; legacy_mfg++) { - if (!cpu_legacy_table[c].tables[legacy_mfg]) - continue; + /* Look for a corresponding CPU entry. */ + cpu_legacy_table_t *legacy_table_entry; + for (legacy_mfg = 0; legacy_mfg < 4; legacy_mfg++) { + if (!cpu_legacy_table[c].tables[legacy_mfg]) + continue; - i = 0; - while (cpu_legacy_table[c].tables[legacy_mfg][i].family) { - legacy_table_entry = (cpu_legacy_table_t *) &cpu_legacy_table[c].tables[legacy_mfg][i]; + i = 0; + while (cpu_legacy_table[c].tables[legacy_mfg][i].family) { + legacy_table_entry = (cpu_legacy_table_t *) &cpu_legacy_table[c].tables[legacy_mfg][i]; - /* Match the family name, speed and multiplier. */ - if (!strcmp(cpu_f->internal_name, legacy_table_entry->family)) { - if ((legacy_table_entry->rspeed == cpu_f->cpus[cpu].rspeed) && - (legacy_table_entry->multi == cpu_f->cpus[cpu].multi)) { /* exact speed/multiplier match */ - legacy_cpu = i; - break; - } else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) && - (closest_legacy_cpu == -1)) { /* closest speed match */ - closest_legacy_cpu = i; - } - } + /* Match the family name, speed and multiplier. */ + if (!strcmp(cpu_f->internal_name, legacy_table_entry->family)) { + if ((legacy_table_entry->rspeed == cpu_f->cpus[cpu].rspeed) && (legacy_table_entry->multi == cpu_f->cpus[cpu].multi)) { /* exact speed/multiplier match */ + legacy_cpu = i; + break; + } else if ((legacy_table_entry->rspeed >= cpu_f->cpus[cpu].rspeed) && (closest_legacy_cpu == -1)) { /* closest speed match */ + closest_legacy_cpu = i; + } + } - i++; - } + i++; + } - /* Use the closest speed match if no exact match was found. */ - if ((legacy_cpu == -1) && (closest_legacy_cpu > -1)) { - legacy_cpu = closest_legacy_cpu; - break; - } else if (legacy_cpu > -1) /* exact match found */ - break; - } + /* Use the closest speed match if no exact match was found. */ + if ((legacy_cpu == -1) && (closest_legacy_cpu > -1)) { + legacy_cpu = closest_legacy_cpu; + break; + } else if (legacy_cpu > -1) /* exact match found */ + break; + } - /* Set legacy values if a match was found. */ - if (legacy_cpu > -1) { - if (legacy_mfg) - config_set_int(cat, "cpu_manufacturer", legacy_mfg); - if (legacy_cpu) - config_set_int(cat, "cpu", legacy_cpu); - } + /* Set legacy values if a match was found. */ + if (legacy_cpu > -1) { + if (legacy_mfg) + config_set_int(cat, "cpu_manufacturer", legacy_mfg); + if (legacy_cpu) + config_set_int(cat, "cpu", legacy_cpu); + } } if (cpu_waitstates == 0) - config_delete_var(cat, "cpu_waitstates"); - else - config_set_int(cat, "cpu_waitstates", cpu_waitstates); + config_delete_var(cat, "cpu_waitstates"); + else + config_set_int(cat, "cpu_waitstates", cpu_waitstates); if (fpu_type == 0) - config_delete_var(cat, "fpu_type"); + config_delete_var(cat, "fpu_type"); else - config_set_string(cat, "fpu_type", (char *) fpu_get_internal_name(cpu_f, cpu, fpu_type)); + config_set_string(cat, "fpu_type", (char *) fpu_get_internal_name(cpu_f, cpu, fpu_type)); - //Write the mem_size explicitly to the setttings in order to help managers to display it without having the actual machine table + // Write the mem_size explicitly to the setttings in order to help managers to display it without having the actual machine table config_delete_var(cat, "mem_size"); config_set_int(cat, "mem_size", mem_size); config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); if (time_sync & TIME_SYNC_ENABLED) - if (time_sync & TIME_SYNC_UTC) - config_set_string(cat, "time_sync", "utc"); - else - config_set_string(cat, "time_sync", "local"); + if (time_sync & TIME_SYNC_UTC) + config_set_string(cat, "time_sync", "utc"); + else + config_set_string(cat, "time_sync", "local"); else - config_set_string(cat, "time_sync", "disabled"); + config_set_string(cat, "time_sync", "disabled"); + + if (pit_mode == -1) + config_delete_var(cat, "pit_mode"); + else + config_set_int(cat, "pit_mode", pit_mode); delete_section_if_empty(cat); } - /* Save "Video" section. */ static void save_video(void) @@ -2504,27 +2496,27 @@ save_video(void) char *cat = "Video"; config_set_string(cat, "gfxcard", - video_get_internal_name(gfxcard)); + video_get_internal_name(gfxcard)); if (voodoo_enabled == 0) - config_delete_var(cat, "voodoo"); - else - config_set_int(cat, "voodoo", voodoo_enabled); + config_delete_var(cat, "voodoo"); + else + config_set_int(cat, "voodoo", voodoo_enabled); if (ibm8514_enabled == 0) - config_delete_var(cat, "8514a"); - else - config_set_int(cat, "8514a", ibm8514_enabled); + config_delete_var(cat, "8514a"); + else + config_set_int(cat, "8514a", ibm8514_enabled); if (xga_enabled == 0) - config_delete_var(cat, "xga"); - else - config_set_int(cat, "xga", xga_enabled); + config_delete_var(cat, "xga"); + else + config_set_int(cat, "xga", xga_enabled); if (gfxcard_2 == 0) - config_delete_var(cat, "gfxcard_2"); + config_delete_var(cat, "gfxcard_2"); else - config_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard_2)); + config_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard_2)); if (show_second_monitors == 1) config_delete_var(cat, "show_second_monitors"); @@ -2534,66 +2526,64 @@ save_video(void) delete_section_if_empty(cat); } - /* Save "Input Devices" section. */ static void save_input_devices(void) { char *cat = "Input devices"; - char temp[512], tmp2[512]; - int c, d; + char temp[512], tmp2[512]; + int c, d; config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); if (!joystick_type) { - config_delete_var(cat, "joystick_type"); + config_delete_var(cat, "joystick_type"); - for (c = 0; c < 16; c++) { - sprintf(tmp2, "joystick_%i_nr", c); - config_delete_var(cat, tmp2); + for (c = 0; c < 16; c++) { + sprintf(tmp2, "joystick_%i_nr", c); + config_delete_var(cat, tmp2); - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_axis_%i", c, d); - config_delete_var(cat, tmp2); - } - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_button_%i", c, d); - config_delete_var(cat, tmp2); - } - for (d=0; d<16; d++) { - sprintf(tmp2, "joystick_%i_pov_%i", c, d); - config_delete_var(cat, tmp2); - } - } + for (d = 0; d < 16; d++) { + sprintf(tmp2, "joystick_%i_axis_%i", c, d); + config_delete_var(cat, tmp2); + } + for (d = 0; d < 16; d++) { + sprintf(tmp2, "joystick_%i_button_%i", c, d); + config_delete_var(cat, tmp2); + } + for (d = 0; d < 16; d++) { + sprintf(tmp2, "joystick_%i_pov_%i", c, d); + config_delete_var(cat, tmp2); + } + } } else { - config_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type)); + config_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type)); - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - sprintf(tmp2, "joystick_%i_nr", c); - config_set_int(cat, tmp2, joystick_state[c].plat_joystick_nr); + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + sprintf(tmp2, "joystick_%i_nr", c); + config_set_int(cat, tmp2, joystick_state[c].plat_joystick_nr); - if (joystick_state[c].plat_joystick_nr) { - for (d=0; d= 2) && !serial_enabled[c])) - config_delete_var(cat, temp); - else - config_set_int(cat, temp, serial_enabled[c]); + sprintf(temp, "serial%d_enabled", c + 1); + if (((c < 2) && serial_enabled[c]) || ((c >= 2) && !serial_enabled[c])) + config_delete_var(cat, temp); + else + config_set_int(cat, temp, serial_enabled[c]); -/* - sprintf(temp, "serial%d_type", c + 1); - if (!serial_enabled[c]) - config_delete_var(cat, temp); -// else -// config_set_string(cat, temp, (char *) serial_type[c]) + /* + sprintf(temp, "serial%d_type", c + 1); + if (!serial_enabled[c]) + config_delete_var(cat, temp); + // else + // config_set_string(cat, temp, (char *) serial_type[c]) - sprintf(temp, "serial%d_device", c + 1); - if (com_ports[c].device == 0) - config_delete_var(cat, temp); - else - config_set_string(cat, temp, - (char *) com_device_get_internal_name(com_ports[c].device)); -*/ + sprintf(temp, "serial%d_device", c + 1); + if (com_ports[c].device == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, + (char *) com_device_get_internal_name(com_ports[c].device)); + */ } for (c = 0; c < PARALLEL_MAX; c++) { - sprintf(temp, "lpt%d_enabled", c + 1); - d = (c == 0) ? 1 : 0; - if (lpt_ports[c].enabled == d) - config_delete_var(cat, temp); - else - config_set_int(cat, temp, lpt_ports[c].enabled); + sprintf(temp, "lpt%d_enabled", c + 1); + d = (c == 0) ? 1 : 0; + if (lpt_ports[c].enabled == d) + config_delete_var(cat, temp); + else + config_set_int(cat, temp, lpt_ports[c].enabled); - sprintf(temp, "lpt%d_device", c + 1); - if (lpt_ports[c].device == 0) - config_delete_var(cat, temp); - else - config_set_string(cat, temp, - (char *) lpt_device_get_internal_name(lpt_ports[c].device)); + sprintf(temp, "lpt%d_device", c + 1); + if (lpt_ports[c].device == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, + (char *) lpt_device_get_internal_name(lpt_ports[c].device)); } delete_section_if_empty(cat); } - /* Save "Storage Controllers" section. */ static void save_storage_controllers(void) { char *cat = "Storage controllers"; - char temp[512]; - int c; + char temp[512]; + int c; config_delete_var(cat, "scsicard"); for (c = 0; c < SCSI_BUS_MAX; c++) { - sprintf(temp, "scsicard_%d", c + 1); + sprintf(temp, "scsicard_%d", c + 1); - if (scsi_card_current[c] == 0) - config_delete_var(cat, temp); - else - config_set_string(cat, temp, - scsi_card_get_internal_name(scsi_card_current[c])); + if (scsi_card_current[c] == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, + scsi_card_get_internal_name(scsi_card_current[c])); } if (fdc_type == FDC_INTERNAL) - config_delete_var(cat, "fdc"); - else - config_set_string(cat, "fdc", - fdc_card_get_internal_name(fdc_type)); + config_delete_var(cat, "fdc"); + else + config_set_string(cat, "fdc", + fdc_card_get_internal_name(fdc_type)); config_set_string(cat, "hdc", - hdc_get_internal_name(hdc_current)); + hdc_get_internal_name(hdc_current)); if (ide_ter_enabled == 0) - config_delete_var(cat, "ide_ter"); - else - config_set_int(cat, "ide_ter", ide_ter_enabled); + config_delete_var(cat, "ide_ter"); + else + config_set_int(cat, "ide_ter", ide_ter_enabled); if (ide_qua_enabled == 0) - config_delete_var(cat, "ide_qua"); - else - config_set_int(cat, "ide_qua", ide_qua_enabled); + config_delete_var(cat, "ide_qua"); + else + config_set_int(cat, "ide_qua", ide_qua_enabled); delete_section_if_empty(cat); if (cassette_enable == 1) - config_delete_var(cat, "cassette_enabled"); + config_delete_var(cat, "cassette_enabled"); else - config_set_int(cat, "cassette_enabled", cassette_enable); + config_set_int(cat, "cassette_enabled", cassette_enable); if (strlen(cassette_fname) == 0) - config_delete_var(cat, "cassette_file"); + config_delete_var(cat, "cassette_file"); else - config_set_string(cat, "cassette_file", cassette_fname); + config_set_string(cat, "cassette_file", cassette_fname); if (strlen(cassette_mode) == 0) - config_delete_var(cat, "cassette_mode"); + config_delete_var(cat, "cassette_mode"); else - config_set_string(cat, "cassette_mode", cassette_mode); + config_set_string(cat, "cassette_mode", cassette_mode); if (cassette_pos == 0) - config_delete_var(cat, "cassette_position"); + config_delete_var(cat, "cassette_position"); else - config_set_int(cat, "cassette_position", cassette_pos); + config_set_int(cat, "cassette_position", cassette_pos); if (cassette_srate == 44100) - config_delete_var(cat, "cassette_srate"); + config_delete_var(cat, "cassette_srate"); else - config_set_int(cat, "cassette_srate", cassette_srate); + config_set_int(cat, "cassette_srate", cassette_srate); if (cassette_append == 0) - config_delete_var(cat, "cassette_append"); + config_delete_var(cat, "cassette_append"); else - config_set_int(cat, "cassette_append", cassette_append); + config_set_int(cat, "cassette_append", cassette_append); if (cassette_pcm == 0) - config_delete_var(cat, "cassette_pcm"); + config_delete_var(cat, "cassette_pcm"); else - config_set_int(cat, "cassette_pcm", cassette_pcm); + config_set_int(cat, "cassette_pcm", cassette_pcm); if (cassette_ui_writeprot == 0) - config_delete_var(cat, "cassette_writeprot"); + config_delete_var(cat, "cassette_writeprot"); else - config_set_int(cat, "cassette_writeprot", cassette_ui_writeprot); + config_set_int(cat, "cassette_writeprot", cassette_ui_writeprot); - for (c=0; c<2; c++) { - sprintf(temp, "cartridge_%02i_fn", c+1); - if (strlen(cart_fns[c]) == 0) - config_delete_var(cat, temp); - else - config_set_string(cat, temp, cart_fns[c]); + for (c = 0; c < 2; c++) { + sprintf(temp, "cartridge_%02i_fn", c + 1); + if (strlen(cart_fns[c]) == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, cart_fns[c]); } } - /* Save "Other Peripherals" section. */ static void save_other_peripherals(void) { char *cat = "Other peripherals"; - char temp[512]; - int c; + char temp[512]; + int c; if (bugger_enabled == 0) - config_delete_var(cat, "bugger_enabled"); - else - config_set_int(cat, "bugger_enabled", bugger_enabled); + config_delete_var(cat, "bugger_enabled"); + else + config_set_int(cat, "bugger_enabled", bugger_enabled); if (postcard_enabled == 0) - config_delete_var(cat, "postcard_enabled"); - else - config_set_int(cat, "postcard_enabled", postcard_enabled); + config_delete_var(cat, "postcard_enabled"); + else + config_set_int(cat, "postcard_enabled", postcard_enabled); for (c = 0; c < ISAMEM_MAX; c++) { - sprintf(temp, "isamem%d_type", c); - if (isamem_type[c] == 0) - config_delete_var(cat, temp); - else - config_set_string(cat, temp, - (char *) isamem_get_internal_name(isamem_type[c])); + sprintf(temp, "isamem%d_type", c); + if (isamem_type[c] == 0) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, + (char *) isamem_get_internal_name(isamem_type[c])); } if (isartc_type == 0) - config_delete_var(cat, "isartc_type"); - else - config_set_string(cat, "isartc_type", - isartc_get_internal_name(isartc_type)); + config_delete_var(cat, "isartc_type"); + else + config_set_string(cat, "isartc_type", + isartc_get_internal_name(isartc_type)); delete_section_if_empty(cat); } - /* Save "Hard Disks" section. */ static void save_hard_disks(void) { char *cat = "Hard disks"; - char temp[32], tmp2[512]; + char temp[32], tmp2[512]; char *p; - int c; + int c; memset(temp, 0x00, sizeof(temp)); - for (c=0; c> 1, hdd[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "hdd_%02i_ide_channel", c + 1); + if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE)) { + config_delete_var(cat, temp); + } else { + sprintf(tmp2, "%01u:%01u", hdd[c].ide_channel >> 1, hdd[c].ide_channel & 1); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "hdd_%02i_scsi_id", c+1); - config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "hdd_%02i_scsi_location", c+1); - if (hdd[c].bus != HDD_BUS_SCSI) - config_delete_var(cat, temp); - else { - sprintf(tmp2, "%01u:%02u", hdd[c].scsi_id>>4, - hdd[c].scsi_id & 15); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "hdd_%02i_scsi_location", c + 1); + if (hdd[c].bus != HDD_BUS_SCSI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%02u", hdd[c].scsi_id >> 4, + hdd[c].scsi_id & 15); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "hdd_%02i_fn", c+1); - if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) { - path_normalize(hdd[c].fn); - if (!strnicmp(hdd[c].fn, usr_path, strlen(usr_path))) - config_set_string(cat, temp, &hdd[c].fn[strlen(usr_path)]); - else - config_set_string(cat, temp, hdd[c].fn); - } - else - config_delete_var(cat, temp); - - sprintf(temp, "hdd_%02i_speed", c+1); - if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE)) - config_delete_var(cat, temp); - else - config_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset)); + sprintf(temp, "hdd_%02i_fn", c + 1); + if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) { + path_normalize(hdd[c].fn); + if (!strnicmp(hdd[c].fn, usr_path, strlen(usr_path))) + config_set_string(cat, temp, &hdd[c].fn[strlen(usr_path)]); + else + config_set_string(cat, temp, hdd[c].fn); + } else + config_delete_var(cat, temp); + sprintf(temp, "hdd_%02i_speed", c + 1); + if (!hdd_is_valid(c) || (hdd[c].bus != HDD_BUS_IDE)) + config_delete_var(cat, temp); + else + config_set_string(cat, temp, hdd_preset_get_internal_name(hdd[c].speed_preset)); } delete_section_if_empty(cat); } - /* Save "Floppy Drives" section. */ static void save_floppy_and_cdrom_drives(void) { char *cat = "Floppy and CD-ROM drives"; - char temp[512], tmp2[512]; - int c; + char temp[512], tmp2[512]; + int c; - for (c=0; c>1, - cdrom[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "cdrom_%02i_ide_channel", c + 1); + if (cdrom[c].bus_type != CDROM_BUS_ATAPI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%01u", cdrom[c].ide_channel >> 1, + cdrom[c].ide_channel & 1); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "cdrom_%02i_scsi_id", c + 1); - config_delete_var(cat, temp); + sprintf(temp, "cdrom_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "cdrom_%02i_scsi_location", c+1); - if (cdrom[c].bus_type != CDROM_BUS_SCSI) - config_delete_var(cat, temp); - else { - sprintf(tmp2, "%01u:%02u", cdrom[c].scsi_device_id>>4, - cdrom[c].scsi_device_id & 15); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "cdrom_%02i_scsi_location", c + 1); + if (cdrom[c].bus_type != CDROM_BUS_SCSI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%02u", cdrom[c].scsi_device_id >> 4, + cdrom[c].scsi_device_id & 15); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "cdrom_%02i_image_path", c + 1); - if ((cdrom[c].bus_type == 0) || - (strlen(cdrom[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_string(cat, temp, cdrom[c].image_path); - } + sprintf(temp, "cdrom_%02i_image_path", c + 1); + if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) { + config_delete_var(cat, temp); + } else { + config_set_string(cat, temp, cdrom[c].image_path); + } } delete_section_if_empty(cat); } - /* Save "Other Removable Devices" section. */ static void save_other_removable_devices(void) { char *cat = "Other removable devices"; - char temp[512], tmp2[512]; - int c; + char temp[512], tmp2[512]; + int c; - for (c=0; c>1, - zip_drives[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "zip_%02i_ide_channel", c + 1); + if (zip_drives[c].bus_type != ZIP_BUS_ATAPI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%01u", zip_drives[c].ide_channel >> 1, + zip_drives[c].ide_channel & 1); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "zip_%02i_scsi_id", c + 1); - config_delete_var(cat, temp); + sprintf(temp, "zip_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "zip_%02i_scsi_location", c+1); - if (zip_drives[c].bus_type != ZIP_BUS_SCSI) - config_delete_var(cat, temp); - else { - sprintf(tmp2, "%01u:%02u", zip_drives[c].scsi_device_id>>4, - zip_drives[c].scsi_device_id & 15); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "zip_%02i_scsi_location", c + 1); + if (zip_drives[c].bus_type != ZIP_BUS_SCSI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%02u", zip_drives[c].scsi_device_id >> 4, + zip_drives[c].scsi_device_id & 15); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "zip_%02i_image_path", c + 1); - if ((zip_drives[c].bus_type == 0) || - (strlen(zip_drives[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_string(cat, temp, zip_drives[c].image_path); - } + sprintf(temp, "zip_%02i_image_path", c + 1); + if ((zip_drives[c].bus_type == 0) || (strlen(zip_drives[c].image_path) == 0)) { + config_delete_var(cat, temp); + } else { + config_set_string(cat, temp, zip_drives[c].image_path); + } } - for (c=0; c>1, - mo_drives[c].ide_channel & 1); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "mo_%02i_ide_channel", c + 1); + if (mo_drives[c].bus_type != MO_BUS_ATAPI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%01u", mo_drives[c].ide_channel >> 1, + mo_drives[c].ide_channel & 1); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "mo_%02i_scsi_id", c + 1); - config_delete_var(cat, temp); + sprintf(temp, "mo_%02i_scsi_id", c + 1); + config_delete_var(cat, temp); - sprintf(temp, "mo_%02i_scsi_location", c+1); - if (mo_drives[c].bus_type != MO_BUS_SCSI) - config_delete_var(cat, temp); - else { - sprintf(tmp2, "%01u:%02u", mo_drives[c].scsi_device_id>>4, - mo_drives[c].scsi_device_id & 15); - config_set_string(cat, temp, tmp2); - } + sprintf(temp, "mo_%02i_scsi_location", c + 1); + if (mo_drives[c].bus_type != MO_BUS_SCSI) + config_delete_var(cat, temp); + else { + sprintf(tmp2, "%01u:%02u", mo_drives[c].scsi_device_id >> 4, + mo_drives[c].scsi_device_id & 15); + config_set_string(cat, temp, tmp2); + } - sprintf(temp, "mo_%02i_image_path", c + 1); - if ((mo_drives[c].bus_type == 0) || - (strlen(mo_drives[c].image_path) == 0)) { - config_delete_var(cat, temp); - } else { - config_set_string(cat, temp, mo_drives[c].image_path); - } + sprintf(temp, "mo_%02i_image_path", c + 1); + if ((mo_drives[c].bus_type == 0) || (strlen(mo_drives[c].image_path) == 0)) { + config_delete_var(cat, temp); + } else { + config_set_string(cat, temp, mo_drives[c].image_path); + } } delete_section_if_empty(cat); } - void config_save(void) { - int i; + int i; - save_general(); /* General */ - for (i = 0; i < MONITORS_NUM; i++) - save_monitor(i); - save_machine(); /* Machine */ - save_video(); /* Video */ - save_input_devices(); /* Input devices */ - save_sound(); /* Sound */ - save_network(); /* Network */ - save_ports(); /* Ports (COM & LPT) */ - save_storage_controllers(); /* Storage controllers */ - save_hard_disks(); /* Hard disks */ - save_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ - save_other_removable_devices(); /* Other removable devices */ - save_other_peripherals(); /* Other peripherals */ + save_general(); /* General */ + for (i = 0; i < MONITORS_NUM; i++) + save_monitor(i); + save_machine(); /* Machine */ + save_video(); /* Video */ + save_input_devices(); /* Input devices */ + save_sound(); /* Sound */ + save_network(); /* Network */ + save_ports(); /* Ports (COM & LPT) */ + save_storage_controllers(); /* Storage controllers */ + save_hard_disks(); /* Hard disks */ + save_floppy_and_cdrom_drives(); /* Floppy and CD-ROM drives */ + save_other_removable_devices(); /* Other removable devices */ + save_other_peripherals(); /* Other peripherals */ config_write(cfg_path); } - void config_dump(void) { section_t *sec; - sec = (section_t *)config_head.next; + sec = (section_t *) config_head.next; while (sec != NULL) { - entry_t *ent; + entry_t *ent; - if (sec->name[0]) - config_log("[%s]\n", sec->name); + if (sec->name[0]) + config_log("[%s]\n", sec->name); - ent = (entry_t *)sec->entry_head.next; - while (ent != NULL) { - config_log("%s = %s\n", ent->name, ent->data); + ent = (entry_t *) sec->entry_head.next; + while (ent != NULL) { + config_log("%s = %s\n", ent->name, ent->data); - ent = (entry_t *)ent->list.next; - } + ent = (entry_t *) ent->list.next; + } - sec = (section_t *)sec->list.next; + sec = (section_t *) sec->list.next; } } - void config_delete_var(char *head, char *name) { section_t *section; - entry_t *entry; + entry_t *entry; section = find_section(head); - if (section == NULL) return; + if (section == NULL) + return; entry = find_entry(section, name); if (entry != NULL) { - list_delete(&entry->list, §ion->entry_head); - free(entry); + list_delete(&entry->list, §ion->entry_head); + free(entry); } } - int config_get_int(char *head, char *name, int def) { section_t *section; - entry_t *entry; - int value; + entry_t *entry; + int value; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); sscanf(entry->data, "%i", &value); - return(value); + return (value); } - double config_get_double(char *head, char *name, double def) { section_t *section; - entry_t *entry; - double value; + entry_t *entry; + double value; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); sscanf(entry->data, "%lg", &value); - return(value); + return (value); } - int config_get_hex16(char *head, char *name, int def) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; unsigned int value; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); sscanf(entry->data, "%04X", &value); - return(value); + return (value); } - int config_get_hex20(char *head, char *name, int def) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; unsigned int value; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); sscanf(entry->data, "%05X", &value); - return(value); + return (value); } - int config_get_mac(char *head, char *name, int def) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; unsigned int val0 = 0, val1 = 0, val2 = 0; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); sscanf(entry->data, "%02x:%02x:%02x", &val0, &val1, &val2); - return((val0 << 16) + (val1 << 8) + val2); + return ((val0 << 16) + (val1 << 8) + val2); } - char * config_get_string(char *head, char *name, char *def) { section_t *section; - entry_t *entry; + entry_t *entry; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); - return(entry->data); + return (entry->data); } - wchar_t * config_get_wstring(char *head, char *name, wchar_t *def) { section_t *section; - entry_t *entry; + entry_t *entry; section = find_section(head); if (section == NULL) - return(def); + return (def); entry = find_entry(section, name); if (entry == NULL) - return(def); + return (def); - return(entry->wdata); + return (entry->wdata); } - void config_set_int(char *head, char *name, int val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); sprintf(ent->data, "%i", val); mbstowcs(ent->wdata, ent->data, 512); } - void config_set_double(char *head, char *name, double val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); sprintf(ent->data, "%lg", val); mbstowcs(ent->wdata, ent->data, 512); } - void config_set_hex16(char *head, char *name, int val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); sprintf(ent->data, "%04X", val); mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); } - void config_set_hex20(char *head, char *name, int val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); sprintf(ent->data, "%05X", val); mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); } - void config_set_mac(char *head, char *name, int val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); sprintf(ent->data, "%02x:%02x:%02x", - (val>>16)&0xff, (val>>8)&0xff, val&0xff); + (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff); mbstowcs(ent->wdata, ent->data, 512); } - void config_set_string(char *head, char *name, char *val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); if ((strlen(val) + 1) <= sizeof(ent->data)) - memcpy(ent->data, val, strlen(val) + 1); + memcpy(ent->data, val, strlen(val) + 1); else - memcpy(ent->data, val, sizeof(ent->data)); -#ifdef _WIN32 /* Make sure the string is converted from UTF-8 rather than a legacy codepage */ + memcpy(ent->data, val, sizeof(ent->data)); +#ifdef _WIN32 /* Make sure the string is converted from UTF-8 rather than a legacy codepage */ mbstoc16s(ent->wdata, ent->data, sizeof_w(ent->wdata)); #else mbstowcs(ent->wdata, ent->data, sizeof_w(ent->wdata)); #endif } - void config_set_wstring(char *head, char *name, wchar_t *val) { section_t *section; - entry_t *ent; + entry_t *ent; section = find_section(head); if (section == NULL) - section = create_section(head); + section = create_section(head); ent = find_entry(section, name); if (ent == NULL) - ent = create_entry(section, name); + ent = create_entry(section, name); memcpy(ent->wdata, val, sizeof_w(ent->wdata)); -#ifdef _WIN32 /* Make sure the string is converted to UTF-8 rather than a legacy codepage */ +#ifdef _WIN32 /* Make sure the string is converted to UTF-8 rather than a legacy codepage */ c16stombs(ent->data, ent->wdata, sizeof(ent->data)); #else wcstombs(ent->data, ent->wdata, sizeof(ent->data)); diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 546da2aa3..6c09e588a 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1870,9 +1870,6 @@ cpu_fast_off_period_set(uint16_t val, double period) void cpu_fast_off_reset(void) { - if (cpu_fast_off_timer) - timer_disable(cpu_fast_off_timer); - cpu_register_fast_off_handler(NULL); cpu_fast_off_period = 0.0; cpu_fast_off_advance(); diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 53a9801b2..4eaadfa13 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -51,21 +51,21 @@ enum { - CPUID_FPU = (1 << 0), - CPUID_VME = (1 << 1), - CPUID_PSE = (1 << 3), - CPUID_TSC = (1 << 4), - CPUID_MSR = (1 << 5), - CPUID_PAE = (1 << 6), - CPUID_MCE = (1 << 7), - CPUID_CMPXCHG8B = (1 << 8), - CPUID_AMDSEP = (1 << 10), - CPUID_SEP = (1 << 11), - CPUID_MTRR = (1 << 12), - CPUID_MCA = (1 << 14), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23), - CPUID_FXSR = (1 << 24) + CPUID_FPU = (1 << 0), + CPUID_VME = (1 << 1), + CPUID_PSE = (1 << 3), + CPUID_TSC = (1 << 4), + CPUID_MSR = (1 << 5), + CPUID_PAE = (1 << 6), + CPUID_MCE = (1 << 7), + CPUID_CMPXCHG8B = (1 << 8), + CPUID_AMDSEP = (1 << 10), + CPUID_SEP = (1 << 11), + CPUID_MTRR = (1 << 12), + CPUID_MCA = (1 << 14), + CPUID_CMOV = (1 << 15), + CPUID_MMX = (1 << 23), + CPUID_FXSR = (1 << 24) }; /*Addition flags returned by CPUID function 0x80000001*/ diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 50da6f2a0..7fde5dacc 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -259,7 +259,7 @@ static int opF6_a32(uint32_t fetchdat) static int opF7_w_a16(uint32_t fetchdat) { - uint32_t templ, templ2; + uint32_t templ, templ2 = 0; int tempws, tempws2 = 0; int16_t temps16; uint16_t src, dst; @@ -356,7 +356,7 @@ static int opF7_w_a16(uint32_t fetchdat) } static int opF7_w_a32(uint32_t fetchdat) { - uint32_t templ, templ2; + uint32_t templ, templ2 = 0; int tempws, tempws2 = 1; int16_t temps16; uint16_t src, dst; diff --git a/src/device.c b/src/device.c index 501ae6b64..331305f2d 100644 --- a/src/device.c +++ b/src/device.c @@ -48,6 +48,8 @@ #include <86box/config.h> #include <86box/device.h> #include <86box/machine.h> +#include <86box/mem.h> +#include <86box/rom.h> #include <86box/sound.h> @@ -329,13 +331,46 @@ device_get_priv(const device_t *d) int device_available(const device_t *d) { + device_config_t *config; + device_config_bios_t *bios; + int bf, roms_present = 0; + int i = 0; + #ifdef RELEASE_BUILD if (d->flags & DEVICE_NOT_WORKING) return(0); #endif - if (d->available != NULL) - return(d->available()); + if (d != NULL) { + config = (device_config_t *) d->config; + if (config != NULL) { + while (config->type != -1) { + if (config->type == CONFIG_BIOS) { + bios = (device_config_bios_t *) config->bios; - return(1); + /* Go through the ROM's in the device configuration. */ + while (bios->files_no != 0) { + i = 0; + for (bf = 0; bf < bios->files_no; bf++) + i += !!rom_present((char *) bios->files[bf]); + if (i == bios->files_no) + roms_present++; + bios++; + } + + return(roms_present ? -1 : 0); + } + config++; + } + } + + /* No CONFIG_BIOS field present, use the classic available(). */ + if (d->available != NULL) + return(d->available()); + else + return(1); + } + + /* A NULL device is never available. */ + return(0); } diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 087fa2b96..8bb436a0c 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -89,6 +89,7 @@ #define KBC_VEN_OLIVETTI 0x24 #define KBC_VEN_NCR 0x28 #define KBC_VEN_SAMSUNG 0x2c +#define KBC_VEN_ALI 0x30 #define KBC_VEN_MASK 0x3c @@ -1093,6 +1094,8 @@ write_output(atkbd_t *dev, uint8_t val) softresetx86(); /*Pulse reset!*/ cpu_set_edx(); flushmmucache(); + if (kbc_ven == KBC_VEN_ALI) + smbase = 0x00030000; } } @@ -1353,6 +1356,7 @@ static uint8_t write64_ami(void *priv, uint8_t val) { atkbd_t *dev = (atkbd_t *)priv; + uint8_t kbc_ven = dev->flags & KBC_VEN_MASK; switch (val) { case 0x00: case 0x01: case 0x02: case 0x03: @@ -1386,7 +1390,15 @@ write64_ami(void *priv, uint8_t val) case 0xa1: /* get controller version */ kbd_log("ATkbc: AMI - get controller version\n"); - add_data(dev, 'H'); + if ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_NOREF) { + if (kbc_ven == KBC_VEN_ALI) + add_data(dev, 'F'); + else if ((dev->flags & KBC_VEN_MASK) == KBC_VEN_INTEL_AMI) + add_data(dev, '5'); + else + add_data(dev, 'H'); + } else + add_data(dev, 'F'); return 0; case 0xa2: /* clear keyboard controller lines P22/P23 */ @@ -1456,9 +1468,14 @@ write64_ami(void *priv, uint8_t val) break; case 0xaf: /* set extended controller RAM */ - kbd_log("ATkbc: set extended controller RAM\n"); - dev->want60 = 1; - dev->secr_phase = 1; + if (kbc_ven == KBC_VEN_ALI) { + kbd_log("ATkbc: Award/ALi/VIA keyboard controller revision\n"); + add_to_kbc_queue_front(dev, 0x43, 0, 0x00); + } else { + kbd_log("ATkbc: set extended controller RAM\n"); + dev->want60 = 1; + dev->secr_phase = 1; + } return 0; case 0xb0: case 0xb1: case 0xb2: case 0xb3: @@ -1754,8 +1771,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) { atkbd_t *dev = (atkbd_t *)priv; int i = 0, bad = 1; - uint8_t mask, kbc_ven = 0x0; - kbc_ven = dev->flags & KBC_VEN_MASK; + uint8_t mask, kbc_ven = dev->flags & KBC_VEN_MASK; switch (port) { case 0x60: @@ -2315,6 +2331,7 @@ kbd_init(const device_t *info) case KBC_VEN_AMI: case KBC_VEN_INTEL_AMI: case KBC_VEN_SAMSUNG: + case KBC_VEN_ALI: dev->write60_ven = write60_ami; dev->write64_ven = write64_ami; break; @@ -2592,6 +2609,20 @@ const device_t keyboard_ps2_ami_pci_device = { .config = NULL }; +const device_t keyboard_ps2_ali_pci_device = { + .name = "PS/2 Keyboard (ALi M5123/M1543C)", + .internal_name = "keyboard_ps2_ali_pci", + .flags = DEVICE_PCI, + .local = KBC_TYPE_PS2_NOREF | KBC_VEN_ALI, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_intel_ami_pci_device = { .name = "PS/2 Keyboard (AMI)", .internal_name = "keyboard_ps2_intel_ami_pci", diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index 9b19669e2..d13bab56d 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -535,7 +535,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) if (speaker_enable) was_speaker_enable = 1; - pit_ctr_set_gate(&pit->counters[2], val & 1); + pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); if (val & 0x80) { kbd->pa = 0; diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index a771dc6bb..583b77262 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -32,16 +32,16 @@ #include <86box/pci.h> -#define PCI_BRIDGE_DEC_21150 0x10110022 -#define AGP_BRIDGE_ALI_M5243 0x10b95243 -#define AGP_BRIDGE_ALI_M5247 0x10b95247 -#define AGP_BRIDGE_INTEL_440LX 0x80867181 -#define AGP_BRIDGE_INTEL_440BX 0x80867191 -#define AGP_BRIDGE_INTEL_440GX 0x808671a1 -#define AGP_BRIDGE_VIA_597 0x11068597 -#define AGP_BRIDGE_VIA_598 0x11068598 -#define AGP_BRIDGE_VIA_691 0x11068691 -#define AGP_BRIDGE_VIA_8601 0x11068601 +#define PCI_BRIDGE_DEC_21150 0x10110022 +#define AGP_BRIDGE_ALI_M5243 0x10b95243 +#define AGP_BRIDGE_ALI_M5247 0x10b95247 +#define AGP_BRIDGE_INTEL_440LX 0x80867181 +#define AGP_BRIDGE_INTEL_440BX 0x80867191 +#define AGP_BRIDGE_INTEL_440GX 0x808671a1 +#define AGP_BRIDGE_VIA_597 0x11068597 +#define AGP_BRIDGE_VIA_598 0x11068598 +#define AGP_BRIDGE_VIA_691 0x11068691 +#define AGP_BRIDGE_VIA_8601 0x11068601 #define AGP_BRIDGE_ALI(x) (((x) >> 16) == 0x10b9) #define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086) @@ -471,6 +471,7 @@ pci_bridge_init(const device_t *info) pci_bridge_reset(dev); dev->slot = pci_add_card(AGP_BRIDGE(dev->local) ? PCI_ADD_AGPBRIDGE : PCI_ADD_BRIDGE, pci_bridge_read, pci_bridge_write, dev); + interrupt_count = sizeof(interrupts); interrupt_mask = interrupt_count - 1; if (dev->slot < 32) { diff --git a/src/device/smbus_piix4.c b/src/device/smbus_piix4.c index de26b061c..c96a9fa57 100644 --- a/src/device/smbus_piix4.c +++ b/src/device/smbus_piix4.c @@ -28,7 +28,6 @@ #include <86box/i2c.h> #include <86box/smbus.h> - #ifdef ENABLE_SMBUS_PIIX4_LOG int smbus_piix4_do_log = ENABLE_SMBUS_PIIX4_LOG; @@ -99,7 +98,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv) { smbus_piix4_t *dev = (smbus_piix4_t *) priv; uint8_t smbus_addr, cmd, read, block_len, prev_stat; - uint16_t timer_bytes = 0, i; + uint16_t timer_bytes = 0, i = 0; smbus_piix4_log("SMBus PIIX4: write(%02X, %02X)\n", addr, val); diff --git a/src/dma.c b/src/dma.c index c109f1b8d..5eb129860 100644 --- a/src/dma.c +++ b/src/dma.c @@ -62,6 +62,7 @@ static struct { #define DMA_PS2_IOA (1 << 0) +#define DMA_PS2_AUTOINIT (1 << 1) #define DMA_PS2_XFER_MEM_TO_IO (1 << 2) #define DMA_PS2_XFER_IO_TO_MEM (3 << 2) #define DMA_PS2_XFER_MASK (3 << 2) @@ -729,6 +730,8 @@ dma_ps2_write(uint16_t addr, uint8_t val, void *priv) else if ((val & DMA_PS2_XFER_MASK) == DMA_PS2_XFER_IO_TO_MEM) mode |= 4; dma_c->mode = (dma_c->mode & ~0x2c) | mode; + if (val & DMA_PS2_AUTOINIT) + dma_c->mode |= 0x10; dma_c->ps2_mode = val; dma_c->size = val & DMA_PS2_SIZE16; break; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index a28328587..a1165f14b 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -314,8 +314,10 @@ fdc_request_next_sector_id(fdc_t *fdc) { if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat = 0xf0; - else + else { + dma_set_drq(fdc->dma_ch, 1); fdc->stat = 0xd0; + } } @@ -701,6 +703,8 @@ fdc_io_command_phase1(fdc_t *fdc, int out) fdc->stat = out ? 0x90 : 0x50; if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat |= 0x20; + else + dma_set_drq(fdc->dma_ch, 1); if (out) fdc->pos = 0; else @@ -926,6 +930,12 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->pos = 0; fdc->mfm = (fdc->command&0x40)?1:0; break; + case 0x17: /*Powerdown mode*/ + if (!(fdc->flags & FDC_FLAG_ALI)) { + fdc_bad_command(fdc); + break; + } + /*FALLTHROUGH*/ case 0x07: /*Recalibrate*/ fdc->pnum=0; fdc->ptot=1; @@ -1062,6 +1072,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->specify[0] = fdc->params[0]; fdc->specify[1] = fdc->params[1]; fdc->dma = (fdc->specify[1] & 1) ^ 1; + if (!fdc->dma) + dma_set_drq(fdc->dma_ch, 0); break; case 0x04: /*Sense drive status*/ fdd_set_head(real_drive(fdc, fdc->drive), (fdc->params[0] & 4) ? 1 : 0); @@ -1287,7 +1299,6 @@ fdc_read(uint16_t addr, void *priv) ret = 0x00; /* TODO: Bit 2: INDEX (best return always 0 as it goes by very fast) - Bit 6: DRQ */ if (fdc->seek_dir) /* nDIRECTION */ ret |= 0x01; @@ -1299,6 +1310,8 @@ fdc_read(uint16_t addr, void *priv) ret |= 0x10; if (fdc->step) /* STEP */ ret |= 0x20; + if (dma_get_drq(fdc->dma_ch)) /* DRQ */ + ret |= 0x40; if (fdc->fintr || fdc->reset_stat) /* INTR */ ret |= 0x80; } else @@ -1504,6 +1517,7 @@ fdc_poll_common_finish(fdc_t *fdc, int compare, int st5) fdc_log("Read/write finish (%02X %02X %02X %02X %02X %02X %02X)\n" , fdc->res[4], fdc->res[5], fdc->res[6], fdc->res[7], fdc->res[8], fdc->res[9], fdc->res[10]); ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 0); fdc->paramstogo = 7; + dma_set_drq(fdc->dma_ch, 0); } @@ -1567,8 +1581,10 @@ fdc_callback(void *priv) fdd_readsector(real_drive(fdc, fdc->drive), SECTOR_NEXT, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat = 0x70; - else + else { + dma_set_drq(fdc->dma_ch, 1); fdc->stat = 0x50; + } } fdc->inread = 1; return; @@ -1684,8 +1700,10 @@ fdc_callback(void *priv) fdd_writesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat = 0xb0; - else + else { + dma_set_drq(fdc->dma_ch, 1); fdc->stat = 0x90; + } break; case 6: case 0xC: @@ -1693,8 +1711,10 @@ fdc_callback(void *priv) fdd_readsector(real_drive(fdc, fdc->drive), fdc->sector, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat = 0x70; - else + else { + dma_set_drq(fdc->dma_ch, 1); fdc->stat = 0x50; + } break; case 0x11: case 0x19: @@ -1702,8 +1722,10 @@ fdc_callback(void *priv) fdd_comparesector(real_drive(fdc, fdc->drive), fdc->sector, fdc->rw_track, fdc->head, fdc->rate, fdc->params[4]); if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) fdc->stat = 0xb0; - else + else { + dma_set_drq(fdc->dma_ch, 1); fdc->stat = 0x90; + } break; } fdc->inread = 1; @@ -1780,6 +1802,12 @@ fdc_callback(void *priv) fdc->paramstogo = 1; fdc->interrupt = 0; return; + case 0x17: /*Powerdown mode*/ + fdc->stat = (fdc->stat & 0xf) | 0xd0; + fdc->res[10] = fdc->params[0]; + fdc->paramstogo = 1; + fdc->interrupt = 0; + return; case 0x13: /*Configure*/ fdc->config = fdc->params[1]; fdc->pretrk = fdc->params[2]; @@ -1809,6 +1837,7 @@ fdc_callback(void *priv) void fdc_error(fdc_t *fdc, int st5, int st6) { + dma_set_drq(fdc->dma_ch, 0); #if 1 timer_disable(&fdc->timer); @@ -1947,15 +1976,18 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) if (!fdc->fifo || (fdc->tfifo < 1)) { fdc->data_ready = 1; fdc->stat = 0xd0; + dma_set_drq(fdc->dma_ch, 1); fdc->fifobufpos = 0; result = dma_channel_write(fdc->dma_ch, data); if (result & DMA_OVER) { + dma_set_drq(fdc->dma_ch, 0); fdc->tc = 1; return -1; } + dma_set_drq(fdc->dma_ch, 0); } else { /* FIFO enabled */ fdc_fifo_buf_write(fdc, data); @@ -1963,6 +1995,7 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) /* We have wrapped around, means FIFO is over */ fdc->data_ready = 1; fdc->stat = 0xd0; + dma_set_drq(fdc->dma_ch, 1); n = (fdc->fifobufpos > 0) ? (fdc->fifobufpos - 1) : fdc->tfifo; if (fdc->fifobufpos > 0) @@ -1972,10 +2005,12 @@ fdc_data(fdc_t *fdc, uint8_t data, int last) result = dma_channel_write(fdc->dma_ch, fdc->fifobuf[i]); if (result & DMA_OVER) { + dma_set_drq(fdc->dma_ch, 0); fdc->tc = 1; return -1; } } + dma_set_drq(fdc->dma_ch, 0); } } } @@ -2105,12 +2140,15 @@ int fdc_getdata(fdc_t *fdc, int last) } else { if (!fdc->fifo || (fdc->tfifo < 1)) { data = dma_channel_read(fdc->dma_ch); + dma_set_drq(fdc->dma_ch, 0); if (data & DMA_OVER) fdc->tc = 1; - if (!last) + if (!last) { fdc->stat = 0x90; + dma_set_drq(fdc->dma_ch, 1); + } } else { if (fdc->fifobufpos == 0) { for (i = 0; i <= fdc->tfifo; i++) { @@ -2118,16 +2156,20 @@ int fdc_getdata(fdc_t *fdc, int last) fdc->fifobuf[i] = data; if (data & DMA_OVER) { + dma_set_drq(fdc->dma_ch, 0); fdc->tc = 1; break; } } + dma_set_drq(fdc->dma_ch, 0); } data = fdc_fifo_buf_read(fdc); - if (!last && (fdc->fifobufpos == 0)) + if (!last && (fdc->fifobufpos == 0)) { + dma_set_drq(fdc->dma_ch, 1); fdc->stat = 0x90; + } } } @@ -2149,6 +2191,7 @@ fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t si fdc->res[10] = size; ui_sb_update_icon(SB_FLOPPY | real_drive(fdc, fdc->drive), 0); fdc->paramstogo = 7; + dma_set_drq(fdc->dma_ch, 0); } @@ -2514,6 +2557,20 @@ const device_t fdc_at_smc_device = { .config = NULL }; +const device_t fdc_at_ali_device = { + .name = "PC/AT Floppy Drive Controller (ALi M512x/M1543C)", + .internal_name = "fdc_at_ali", + .flags = 0, + .local = FDC_FLAG_AT | FDC_FLAG_SUPERIO | FDC_FLAG_ALI, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t fdc_at_winbond_device = { .name = "PC/AT Floppy Drive Controller (Winbond W83x77F)", .internal_name = "fdc_at_winbond", diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 6afa66695..86fe740c9 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -135,6 +135,7 @@ extern int is_pentium; /* TODO: Move back to cpu/cpu.h when it's figured out, how to remove that hack from the ET4000/W32p. */ extern int fixed_size_x, fixed_size_y; extern double mouse_sensitivity; /* (C) Mouse sensitivity scale */ +extern int pit_mode; /* (C) force setting PIT mode */ extern char exe_path[2048]; /* path (dir) of executable */ diff --git a/src/include/86box/acpi.h b/src/include/86box/acpi.h index d12b45507..94b2cd0fe 100644 --- a/src/include/86box/acpi.h +++ b/src/include/86box/acpi.h @@ -49,12 +49,12 @@ extern "C" { #define ACPI_ENABLE 0xf1 #define ACPI_DISABLE 0xf0 -#define VEN_ALI 0x010b9 -#define VEN_INTEL 0x08086 -#define VEN_SIS 0x01039 -#define VEN_SMC 0x01055 -#define VEN_VIA 0x01106 -#define VEN_VIA_596B 0x11106 +#define VEN_ALI 0x010b9 +#define VEN_INTEL 0x08086 +#define VEN_SIS 0x01039 +#define VEN_SMC 0x01055 +#define VEN_VIA 0x01106 +#define VEN_VIA_596B 0x11106 typedef struct diff --git a/src/include/86box/device.h b/src/include/86box/device.h index 04cc071c4..20a4babc5 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -52,6 +52,7 @@ #define CONFIG_HEX20 8 #define CONFIG_MAC 9 #define CONFIG_MIDI_IN 10 +#define CONFIG_BIOS 11 enum { @@ -77,6 +78,14 @@ typedef struct { int value; } device_config_selection_t; +typedef struct { + const char *name; + const char *internal_name; + int bios_type; + int files_no; + const char **files; +} device_config_bios_t; + typedef struct { int16_t min; int16_t max; @@ -92,6 +101,7 @@ typedef struct { const char *file_filter; const device_config_spinner_t spinner; const device_config_selection_t selection[16]; + const device_config_bios_t *bios; } device_config_t; typedef struct _device_ { @@ -161,6 +171,7 @@ extern void device_set_config_hex16(const char *s, int val); extern void device_set_config_hex20(const char *s, int val); extern void device_set_config_mac(const char *s, int val); extern const char *device_get_config_string(const char *name); +#define device_get_config_bios device_get_config_string extern char * device_get_internal_name(const device_t *d); diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index f50e82b58..fa763b0ef 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -50,7 +50,8 @@ extern int fdc_type; #define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ #define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ #define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ -#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ +#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ +#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ typedef struct { @@ -194,6 +195,7 @@ extern const device_t fdc_at_device; extern const device_t fdc_at_actlow_device; extern const device_t fdc_at_ps1_device; extern const device_t fdc_at_smc_device; +extern const device_t fdc_at_ali_device; extern const device_t fdc_at_winbond_device; extern const device_t fdc_at_nsc_device; extern const device_t fdc_dp8473_device; diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index c07fe6a8b..29ea8e5fb 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -178,6 +178,7 @@ extern const device_t keyboard_ps2_pci_device; extern const device_t keyboard_ps2_ami_pci_device; extern const device_t keyboard_ps2_intel_ami_pci_device; extern const device_t keyboard_ps2_acer_pci_device; +extern const device_t keyboard_ps2_ali_pci_device; #endif extern void keyboard_init(void); diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 1e93cbb1f..1873d329c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -332,6 +332,11 @@ extern int machine_get_ram_granularity(int m); extern int machine_get_type(int m); extern void machine_close(void); +extern uint8_t machine_get_p1(void); +extern void machine_load_p1(int m); +extern uint32_t machine_get_gpi(void); +extern void machine_load_gpi(int m); +extern void machine_set_gpi(uint32_t gpi); /* Initialization functions for boards and systems. */ extern void machine_common_init(const machine_t *); @@ -344,15 +349,6 @@ extern int machine_ppc512_init(const machine_t *); extern int machine_pc2086_init(const machine_t *); extern int machine_pc3086_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *pc1512_get_device(void); -extern const device_t *pc1640_get_device(void); -extern const device_t *pc200_get_device(void); -extern const device_t *ppc512_get_device(void); -extern const device_t *pc2086_get_device(void); -extern const device_t *pc3086_get_device(void); -#endif - /* m_at.c */ extern void machine_at_common_init_ex(const machine_t *, int type); extern void machine_at_common_init(const machine_t *); @@ -425,14 +421,6 @@ extern int machine_at_awardsx_init(const machine_t *); extern int machine_at_pc916sx_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_ama932j_get_device(void); -extern const device_t *at_flytech386_get_device(void); -extern const device_t *at_cmdsl386sx25_get_device(void); -extern const device_t *at_spc4620p_get_device(void); -extern const device_t *at_spc6033p_get_device(void); -#endif - /* m_at_386dx_486.c */ extern int machine_at_acc386_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); @@ -516,15 +504,6 @@ extern int machine_at_actionpc2600_init(const machine_t *); extern int machine_at_m919_init(const machine_t *); extern int machine_at_spc7700plw_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_acera1g_get_device(void); -extern const device_t *at_vect486vl_get_device(void); -extern const device_t *at_d824_get_device(void); -extern const device_t *at_pcs46c_get_device(void); -extern const device_t *at_valuepoint433_get_device(void); -extern const device_t *at_sbc490_get_device(void); -#endif - /* m_at_commodore.c */ extern int machine_at_cmdpc_init(const machine_t *); @@ -535,9 +514,6 @@ extern int machine_at_portableiii386_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_DESKPRO386) extern int machine_at_deskpro386_init(const machine_t *); #endif -#ifdef EMU_DEVICE_H -extern const device_t *at_cpqiii_get_device(void); -#endif /* m_at_socket4.c */ extern void machine_at_premiere_common_init(const machine_t *, int); @@ -562,10 +538,6 @@ extern int machine_at_p5vl_init(const machine_t *); extern int machine_at_excaliburpci2_init(const machine_t *); extern int machine_at_p5sp4_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_pb520r_get_device(void); -#endif - /* m_at_socket5.c */ extern int machine_at_plato_init(const machine_t *); extern int machine_at_ambradp90_init(const machine_t *); @@ -609,14 +581,6 @@ extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_endeavor_get_device(void); -#define at_vectra54_get_device at_endeavor_get_device -extern const device_t *at_thor_get_device(void); -#define at_mrthor_get_device at_thor_get_device -extern const device_t *at_pb640_get_device(void); -#endif - /* m_at_socket7.c */ extern int machine_at_acerv35n_init(const machine_t *); extern int machine_at_p55t2p4_init(const machine_t *); @@ -658,11 +622,6 @@ extern int machine_at_ms5146_init(const machine_t *); extern int machine_at_m560_init(const machine_t *); extern int machine_at_ms5164_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_presario2240_get_device(void); -#define at_presario4500_get_device at_presario2240_get_device -#endif - /* m_at_sockets7.c */ extern int machine_at_p5a_init(const machine_t *); extern int machine_at_m579_init(const machine_t *); @@ -718,14 +677,6 @@ extern int machine_at_vei8_init(const machine_t *); extern int machine_at_borapro_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_s1846_get_device(void); -#define at_s1857_get_device at_s1846_get_device -#define at_gt694va_get_device at_s1846_get_device -extern const device_t *at_ms6168_get_device(void); -#define at_borapro_get_device at_ms6168_get_device -#endif - /* m_at_slot2.c */ extern int machine_at_6gxu_init(const machine_t *); extern int machine_at_s2dge_init(const machine_t *); @@ -743,9 +694,6 @@ extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); extern int machine_at_gt694va_init(const machine_t *); extern int machine_at_cuv4xls_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *at_cuv4xls_get_device(void); -#endif extern int machine_at_6via90ap_init(const machine_t *); extern int machine_at_s1857_init(const machine_t *); extern int machine_at_p6bap_init(const machine_t *); @@ -764,22 +712,12 @@ extern const device_t europc_device; /* m_xt_olivetti.c */ extern int machine_xt_m24_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *m24_get_device(void); -#endif extern int machine_xt_m240_init(const machine_t *); extern int machine_xt_m19_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *m19_get_device(void); -#endif /* m_pcjr.c */ extern int machine_pcjr_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *pcjr_get_device(void); -#endif - /* m_ps1.c */ extern int machine_ps1_m2011_init(const machine_t *); extern int machine_ps1_m2121_init(const machine_t *); @@ -811,12 +749,6 @@ extern int machine_tandy1000sl2_init(const machine_t *); /* m_v86p.c */ extern int machine_v86p_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *tandy1k_get_device(void); -extern const device_t *tandy1k_hx_get_device(void); -extern const device_t *tandy1k_sl_get_device(void); -#endif - /* m_xt.c */ extern int machine_pc_init(const machine_t *); extern int machine_pc82_init(const machine_t *); @@ -866,24 +798,13 @@ extern int machine_xt_p3120_init(const machine_t *); extern int machine_xt_t1000_init(const machine_t *); extern int machine_xt_t1200_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *t1000_get_device(void); -extern const device_t *t1200_get_device(void); -#endif /* m_xt_zenith.c */ extern int machine_xt_z184_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *z184_get_device(void); -#endif extern int machine_xt_z151_init(const machine_t *); extern int machine_xt_z159_init(const machine_t *); /* m_xt_xi8088.c */ extern int machine_xt_xi8088_init(const machine_t *); -#ifdef EMU_DEVICE_H -extern const device_t *xi8088_get_device(void); -#endif - #endif /*EMU_MACHINE_H*/ diff --git a/src/include/86box/net_wd8003.h b/src/include/86box/net_wd8003.h index 8fc89a88b..08bd901fe 100644 --- a/src/include/86box/net_wd8003.h +++ b/src/include/86box/net_wd8003.h @@ -50,7 +50,8 @@ enum { WD8003EB, /* WD8003EB : 8-bit ISA, 5x3 interface chip */ WD8013EBT, /* WD8013EBT : 16-bit ISA, no interface chip */ WD8003ETA, /* WD8003ET/A: 16-bit MCA, no interface chip */ - WD8003EA /* WD8003E/A : 16-bit MCA, 5x3 interface chip */ + WD8003EA, /* WD8003E/A : 16-bit MCA, 5x3 interface chip */ + WD8013EPA }; extern const device_t wd8003e_device; @@ -58,5 +59,6 @@ extern const device_t wd8003eb_device; extern const device_t wd8013ebt_device; extern const device_t wd8003eta_device; extern const device_t wd8003ea_device; +extern const device_t wd8013epa_device; #endif /*NET_WD8003_H*/ diff --git a/src/include/86box/nvr_ps2.h b/src/include/86box/nvr_ps2.h index fe3f141e2..0287cdd57 100644 --- a/src/include/86box/nvr_ps2.h +++ b/src/include/86box/nvr_ps2.h @@ -39,7 +39,7 @@ # define EMU_NVRPS2_H -extern const device_t ps2_nvr_device; +extern const device_t ps2_nvr_device; extern const device_t ps2_nvr_55ls_device; diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 98aac3436..7908ea558 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -58,6 +58,9 @@ enum { PCI_CARD_NORTHBRIDGE = 0, PCI_CARD_AGPBRIDGE, PCI_CARD_SOUTHBRIDGE, + PCI_CARD_SOUTHBRIDGE_IDE, + PCI_CARD_SOUTHBRIDGE_PMU, + PCI_CARD_SOUTHBRIDGE_USB, PCI_CARD_AGP = 0x0f, PCI_CARD_NORMAL = 0x10, PCI_CARD_VIDEO, @@ -72,6 +75,9 @@ enum { PCI_ADD_NORTHBRIDGE = 0, PCI_ADD_AGPBRIDGE, PCI_ADD_SOUTHBRIDGE, + PCI_ADD_SOUTHBRIDGE_IDE, + PCI_ADD_SOUTHBRIDGE_PMU, + PCI_ADD_SOUTHBRIDGE_USB, PCI_ADD_AGP = 0x0f, PCI_ADD_NORMAL = 0x10, PCI_ADD_VIDEO, @@ -111,6 +117,7 @@ extern void pci_init(int type); extern uint8_t pci_register_bus(); extern void pci_set_pmc(uint8_t pmc); extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number); +extern void pci_relocate_slot(int type, int new_slot); extern void pci_register_slot(int card, int type, int inta, int intb, int intc, int intd); extern void pci_register_bus_slot(int bus, int card, int type, diff --git a/src/include/86box/pit.h b/src/include/86box/pit.h index e823794df..95541014b 100644 --- a/src/include/86box/pit.h +++ b/src/include/86box/pit.h @@ -58,9 +58,33 @@ typedef struct PIT { uint8_t ctrl; } pit_t; +enum { + PIT_8253 = 0, + PIT_8254, + PIT_8253_FAST, + PIT_8254_FAST +}; + +typedef struct { + uint8_t (*read)(uint16_t addr, void *priv); + void (*write)(uint16_t addr, uint8_t val, void *priv); + /* Gets a counter's count. */ + uint16_t (*get_count)(void *data, int counter_id); + /* Sets a counter's GATE input. */ + void (*set_gate)(void *data, int counter_id, int gate); + /* Sets if a counter's CLOCK input is from the timer or not - used by PCjr. */ + void(*set_using_timer)(void *data, int counter_id, int using_timer); + /* Sets a counter's OUT output handler. */ + void (*set_out_func)(void *data, int counter_id, void (*func)(int new_out, int old_out)); + /* Sets a counter's load count handler. */ + void (*set_load_func)(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)); + void (*ctr_clock)(void *data, int counter_id); + void *data; +} pit_intf_t; + +extern pit_intf_t pit_devs[2]; +extern const pit_intf_t pit_classic_intf; -extern pit_t *pit, - *pit2; extern double SYSCLK, PCICLK, AGPCLK; @@ -74,26 +98,13 @@ extern uint64_t PITCONST, ISACONST, extern int refresh_at_enable; - -/* Gets a counter's count. */ -extern uint16_t pit_ctr_get_count(ctr_t *ctr); -/* Sets a counter's load count handler. */ -extern void pit_ctr_set_load_func(ctr_t *ctr, void (*func)(uint8_t new_m, int new_count)); -/* Sets a counter's OUT output handler. */ -extern void pit_ctr_set_out_func(ctr_t *ctr, void (*func)(int new_out, int old_out)); -/* Sets a counter's GATE input. */ -extern void pit_ctr_set_gate(ctr_t *ctr, int gate); /* Sets a counter's CLOCK input. */ extern void pit_ctr_set_clock(ctr_t *ctr, int clock); -/* Sets if a counter's CLOCK input is from the timer or not - used by PCjr. */ -extern void pit_ctr_set_using_timer(ctr_t *ctr, int using_timer); extern pit_t * pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(int new_out, int old_out)); -extern pit_t * pit_ps2_init(void); +extern pit_t * pit_ps2_init(int type); extern void pit_reset(pit_t *dev); -extern void pit_irq0_timer(int new_out, int old_out); -extern void pit_irq0_timer_pcjr(int new_out, int old_out); extern void pit_irq0_timer_ps2(int new_out, int old_out); extern void pit_refresh_timer_xt(int new_out, int old_out); diff --git a/src/include/86box/pit_fast.h b/src/include/86box/pit_fast.h new file mode 100644 index 000000000..bc09174fb --- /dev/null +++ b/src/include/86box/pit_fast.h @@ -0,0 +1,72 @@ +/* + * 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. + * + * Header of the implementation of the Intel 8253/8254 + * Programmable Interval Timer. + * + * + * + * Author: Miran Grca, + * Copyright 2019,2020 Miran Grca. + */ + +#ifndef EMU_PIT_FAST_H +#define EMU_PIT_FAST_H + +typedef struct { + uint8_t m, ctrl, + read_status, latch, bcd; + + uint16_t rl; + + int rm, wm, gate, out, + newcount, clock, using_timer, latched, + do_read_status; + int enabled; + int disabled; + int initial; + int thit; + int running; + int rereadlatch; + + union { + int count; + struct { + int units : 4; + int tens : 4; + int hundreds : 4; + int thousands : 4; + int myriads : 4; + }; + }; + + uint32_t l; + pc_timer_t timer; + + void (*load_func)(uint8_t new_m, int new_count); + void (*out_func)(int new_out, int old_out); +} ctrf_t; + +typedef struct { + int flags; + ctrf_t counters[3]; + + uint8_t ctrl; +} pitf_t; + +extern const pit_intf_t pit_fast_intf; + +#ifdef EMU_DEVICE_H +extern const device_t i8253_fast_device; +extern const device_t i8254_fast_device; +extern const device_t i8254_sec_fast_device; +extern const device_t i8254_ext_io_fast_device; +extern const device_t i8254_ps2_fast_device; +#endif + +#endif /*EMU_PIT_FAST_H*/ diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 6f9cfa731..e0cf20fe0 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -19,6 +19,7 @@ extern void vt82c686_sio_write(uint8_t addr, uint8_t val, void *priv); extern const device_t acc3221_device; +extern const device_t ali5123_device; extern const device_t f82c710_device; extern const device_t f82c606_device; extern const device_t fdc37c651_device; diff --git a/src/include/86box/smbus.h b/src/include/86box/smbus.h index 4c2c00c17..2a4d4f0ee 100644 --- a/src/include/86box/smbus.h +++ b/src/include/86box/smbus.h @@ -53,7 +53,6 @@ typedef struct { void *i2c; } smbus_ali7101_t; - extern void smbus_piix4_remap(smbus_piix4_t *dev, uint16_t new_io_base, uint8_t enable); extern void smbus_piix4_setclock(smbus_piix4_t *dev, int clock); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 2696954ef..71d4942d0 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -120,6 +120,7 @@ extern const device_t sb_16_device; extern const device_t sb_16_pnp_device; extern const device_t sb_16_compat_device; extern const device_t sb_16_compat_nompu_device; +extern const device_t sb_16_reply_mca_device; extern const device_t sb_32_pnp_device; extern const device_t sb_awe32_device; extern const device_t sb_awe32_pnp_device; diff --git a/src/include/86box/vid_ega_render_remap.h b/src/include/86box/vid_ega_render_remap.h index b21233fbd..cae9a2b1d 100644 --- a/src/include/86box/vid_ega_render_remap.h +++ b/src/include/86box/vid_ega_render_remap.h @@ -10,44 +10,44 @@ #define VAR_ROW1_MA14 (1 << 3) #define ADDRESS_REMAP_FUNC(nr) \ - static uint32_t address_remap_func_ ## nr(ega_t *ega, uint32_t in_addr) \ - { \ - uint32_t out_addr; \ - \ - switch (nr & VAR_MODE_MASK) \ - { \ - case VAR_BYTE_MODE: \ - out_addr = in_addr; \ - break; \ - \ - case VAR_WORD_MODE_MA13: \ - out_addr = ((in_addr << 1) & 0x1fff8) | \ - ((in_addr >> 13) & 0x4) | \ - (in_addr & ~0x1ffff); \ - break; \ - \ - case VAR_WORD_MODE_MA15: \ - out_addr = ((in_addr << 1) & 0x1fff8) | \ - ((in_addr >> 15) & 0x4) | \ - (in_addr & ~0x1ffff); \ - break; \ - \ - case VAR_DWORD_MODE: \ - out_addr = ((in_addr << 2) & 0x3fff0) | \ - ((in_addr >> 14) & 0xc) | \ - (in_addr & ~0x3ffff); \ - break; \ - } \ - \ - if (nr & VAR_ROW0_MA13) \ - out_addr = (out_addr & ~0x8000) | \ - ((ega->sc & 1) ? 0x8000 : 0); \ - if (nr & VAR_ROW1_MA14) \ - out_addr = (out_addr & ~0x10000) | \ - ((ega->sc & 2) ? 0x10000 : 0); \ - \ - return out_addr; \ - } + static uint32_t address_remap_func_ ## nr(ega_t *ega, uint32_t in_addr) \ + { \ + uint32_t out_addr; \ + \ + switch (nr & VAR_MODE_MASK) \ + { \ + case VAR_BYTE_MODE: \ + out_addr = in_addr; \ + break; \ + \ + case VAR_WORD_MODE_MA13: \ + out_addr = ((in_addr << 1) & 0x1fff8) | \ + ((in_addr >> 13) & 0x4) | \ + (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_WORD_MODE_MA15: \ + out_addr = ((in_addr << 1) & 0x1fff8) | \ + ((in_addr >> 15) & 0x4) | \ + (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_DWORD_MODE: \ + out_addr = ((in_addr << 2) & 0x3fff0) | \ + ((in_addr >> 14) & 0xc) | \ + (in_addr & ~0x3ffff); \ + break; \ + } \ + \ + if (nr & VAR_ROW0_MA13) \ + out_addr = (out_addr & ~0x8000) | \ + ((ega->sc & 1) ? 0x8000 : 0); \ + if (nr & VAR_ROW1_MA14) \ + out_addr = (out_addr & ~0x10000) | \ + ((ega->sc & 2) ? 0x10000 : 0); \ + \ + return out_addr; \ + } ADDRESS_REMAP_FUNC(0) ADDRESS_REMAP_FUNC(1) @@ -68,22 +68,22 @@ ADDRESS_REMAP_FUNC(15) static uint32_t (*address_remap_funcs[16])(ega_t *ega, uint32_t in_addr) = { - address_remap_func_0, - address_remap_func_1, - address_remap_func_2, - address_remap_func_3, - address_remap_func_4, - address_remap_func_5, - address_remap_func_6, - address_remap_func_7, - address_remap_func_8, - address_remap_func_9, - address_remap_func_10, - address_remap_func_11, - address_remap_func_12, - address_remap_func_13, - address_remap_func_14, - address_remap_func_15 + address_remap_func_0, + address_remap_func_1, + address_remap_func_2, + address_remap_func_3, + address_remap_func_4, + address_remap_func_5, + address_remap_func_6, + address_remap_func_7, + address_remap_func_8, + address_remap_func_9, + address_remap_func_10, + address_remap_func_11, + address_remap_func_12, + address_remap_func_13, + address_remap_func_14, + address_remap_func_15 }; void ega_recalc_remap_func(ega_t *ega) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 43a8093c8..3b0235d51 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -2059,7 +2059,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 0x02; if (speaker_enable) was_speaker_enable = 1; - pit_ctr_set_gate(&pit->counters[2], val & 0x01); + pit_devs[0].set_gate(pit_devs[0].data, 2, val & 0x01); if (val & 0x80) { /* Keyboard enabled, so enable PA reading. */ diff --git a/src/machine/m_at.c b/src/machine/m_at.c index dc47b6207..df3c4bd8b 100644 --- a/src/machine/m_at.c +++ b/src/machine/m_at.c @@ -66,7 +66,7 @@ machine_at_common_init_ex(const machine_t *model, int type) machine_common_init(model); refresh_at_enable = 1; - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_at); pic2_init(); dma16_init(); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 39a60b0f9..f3b225ae1 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -709,15 +709,14 @@ machine_at_m729_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&ali1621_device); - device_add(&ali1543c_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543c_device); /* +0 */ device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 4adcb2ad9..2856a599c 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -996,16 +996,15 @@ machine_at_m560_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); device_add(&ali1531_device); - device_add(&ali1543_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543_device); /* -5 */ device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); @@ -1029,9 +1028,9 @@ machine_at_ms5164_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE, 5, 6, 0, 0); - pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_SOUTHBRIDGE_IDE, 5, 6, 0, 0); + pci_register_slot(0x0C, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x03, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x04, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -1039,8 +1038,7 @@ machine_at_ms5164_init(const machine_t *model) pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&ali1531_device); - device_add(&ali1543_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543_device); /* -5 */ device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x3, 256); diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index dae4e5396..a32bf3883 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -62,9 +62,9 @@ machine_at_p5a_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); @@ -72,8 +72,7 @@ machine_at_p5a_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x06, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&ali1541_device); - device_add(&ali1543c_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543c_device); /* +0 */ device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); device_add(&w83781d_p5a_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ @@ -99,15 +98,14 @@ machine_at_m579_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&ali1541_device); - device_add(&ali1543c_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543c_device); /* +0 */ device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -132,15 +130,14 @@ machine_at_5aa_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&ali1541_device); - device_add(&ali1543c_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543c_device); /* +0 */ device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); @@ -165,17 +162,16 @@ machine_at_5ax_init(const machine_t *model) pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 0, 0); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE_IDE, 1, 2, 3, 4); + pci_register_slot(0x03, PCI_CARD_SOUTHBRIDGE_PMU, 1, 2, 3, 4); + pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE_USB, 1, 2, 3, 4); pci_register_slot(0x08, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); device_add(&ali1541_device); - device_add(&ali1543c_device); - device_add(&keyboard_ps2_ami_pci_device); + device_add(&ali1543c_device); /* +0 */ device_add(&sst_flash_29ee010_device); spd_register(SPD_TYPE_SDRAM, 0x7, 512); diff --git a/src/machine/m_europc.c b/src/machine/m_europc.c index 2c035ded1..905515225 100644 --- a/src/machine/m_europc.c +++ b/src/machine/m_europc.c @@ -718,7 +718,7 @@ machine_europc_init(const machine_t *model) return ret; machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); nmi_init(); diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 2491e5064..2665ea164 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -627,7 +627,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_ctr_set_gate(&pit->counters[2], val & 1); + pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); sn76489_mute = speaker_mute = 1; switch (val & 0x60) { case 0x00: @@ -642,7 +642,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xa0: nmi_mask = val & 0x80; - pit_ctr_set_using_timer(&pit->counters[1], !(val & 0x20)); + pit_devs[0].set_using_timer(pit_devs[0].data, 1, !(val & 0x20)); break; } } @@ -770,6 +770,18 @@ speed_changed(void *priv) recalc_timings(pcjr); } +void +pit_irq0_timer_pcjr(int new_out, int old_out) +{ + if (new_out && !old_out) { + picint(1); + pit_devs[0].ctr_clock(pit_devs[0].data, 1); + } + + if (!new_out) + picintc(1); +} + static const device_config_t pcjr_config[] = { { .name = "display_type", diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 101746a03..19abb00bf 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -327,7 +327,7 @@ ps1_common_init(const machine_t *model) machine_common_init(model); refresh_at_enable = 1; - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_at); dma16_init(); pic2_init(); diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 24fa0dfb1..094fc8a5f 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -190,7 +190,7 @@ ps2_isa_common_init(const machine_t *model) machine_common_init(model); refresh_at_enable = 1; - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_at); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_at); dma16_init(); pic2_init(); diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index 7aea5a319..665d42972 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -1363,7 +1363,8 @@ machine_ps2_common_init(const machine_t *model) device_add(&ps_no_nmi_nvr_device); pic2_init(); - pit_ps2_init(); + int pit_type = ((pit_mode == -1 && is486) || pit_mode == 1) ? PIT_8254_FAST : PIT_8254; + pit_ps2_init(pit_type); nmi_mask = 0x80; diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index f95ee2fe0..5b31920c5 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -24,7 +24,7 @@ machine_xt_common_init(const machine_t *model) { machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); if (fdc_type == FDC_INTERNAL) device_add(&fdc_xt_device); diff --git a/src/machine/m_xt_compaq.c b/src/machine/m_xt_compaq.c index bd355a161..a705f0e2b 100644 --- a/src/machine/m_xt_compaq.c +++ b/src/machine/m_xt_compaq.c @@ -50,7 +50,7 @@ machine_xt_compaq_deskpro_init(const machine_t *model) machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_compaq_device); if (fdc_type == FDC_INTERNAL) @@ -78,7 +78,7 @@ machine_xt_compaq_portable_init(const machine_t *model) machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_compaq_device); if (fdc_type == FDC_INTERNAL) diff --git a/src/machine/m_xt_laserxt.c b/src/machine/m_xt_laserxt.c index 58b7d3774..21681a5c2 100644 --- a/src/machine/m_xt_laserxt.c +++ b/src/machine/m_xt_laserxt.c @@ -167,7 +167,7 @@ machine_xt_lxt3_init(const machine_t *model) machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_lxt3_device); diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 716bb9c18..62fcda138 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -241,7 +241,7 @@ m24_kbd_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_ctr_set_gate(&pit->counters[2], val & 1); + pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); break; } } @@ -792,7 +792,7 @@ machine_xt_m240_init(const machine_t *model) machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); /* Address 66-67 = mainboard dip-switch settings */ io_sethandler(0x0066, 2, m24_read, NULL, NULL, NULL, NULL, NULL, NULL); @@ -846,7 +846,7 @@ machine_xt_m19_init(const machine_t *model) machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); /* On-board FDC cannot be disabled */ device_add(&fdc_xt_device); diff --git a/src/machine/m_xt_philips.c b/src/machine/m_xt_philips.c index cafccf061..b10e3a37e 100644 --- a/src/machine/m_xt_philips.c +++ b/src/machine/m_xt_philips.c @@ -152,7 +152,7 @@ machine_xt_philips_common_init(const machine_t *model) { machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); nmi_init(); diff --git a/src/machine/m_xt_t1000.c b/src/machine/m_xt_t1000.c index 961cc627a..ba96b74e7 100644 --- a/src/machine/m_xt_t1000.c +++ b/src/machine/m_xt_t1000.c @@ -911,7 +911,7 @@ machine_xt_t1000_init(const machine_t *model) machine_common_init(model); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_device); t1000.fdc = device_add(&fdc_xt_device); nmi_init(); @@ -979,7 +979,7 @@ machine_xt_t1200_init(const machine_t *model) write_t1200_nvram, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, &t1000); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_device); t1000.fdc = device_add(&fdc_xt_t1x00_device); nmi_init(); diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index f9806b610..6eab9aee2 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -122,7 +122,7 @@ machine_zenith_init(const machine_t *model){ device_add(&zenith_scratchpad_device); - pit_ctr_set_out_func(&pit->counters[1], pit_refresh_timer_xt); + pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt); device_add(&keyboard_xt_zenith_device); diff --git a/src/machine/machine.c b/src/machine/machine.c index 00516d8fb..774b972c2 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -145,15 +145,32 @@ int machine_available(int m) { int ret; + device_t *d = (device_t *) machine_getdevice(m); bios_only = 1; - ret = machine_init_ex(m); + + ret = device_available(d); + /* Do not check via machine_init_ex() if the device is not NULL and + it has a CONFIG_BIOS field. */ + if ((d == NULL) || (ret != -1)) + ret = machine_init_ex(m); bios_only = 0; - return ret; + + return !!ret; } +void +pit_irq0_timer(int new_out, int old_out) +{ + if (new_out && !old_out) + picint(1); + + if (!new_out) + picintc(1); +} + void machine_common_init(const machine_t *model) { @@ -161,5 +178,10 @@ machine_common_init(const machine_t *model) pic_init(); dma_init(); - pit_common_init(!!IS_AT(machine), pit_irq0_timer, NULL); + int pit_type = IS_AT(machine) ? PIT_8254 : PIT_8253; + /* Select fast PIT if needed */ + if ((pit_mode == -1 && is486) || pit_mode == 1) + pit_type += 2; + + pit_common_init(pit_type, pit_irq0_timer, NULL); } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1e7b8f329..6ece57fdf 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3175,7 +3175,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE | MACHINE_VIDEO, + .flags = MACHINE_IDE, .ram = { .min = 1024, .max = 16384, @@ -4176,8 +4176,8 @@ const machine_t machines[] = { .min_multi = 0, .max_multi = 0 }, - .flags = MACHINE_PS2_MCA, - .bus_flags = MACHINE_VIDEO, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO, .ram = { .min = 2048, .max = 65536, @@ -4721,7 +4721,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO, + .flags = MACHINE_IDE_DUAL, /* No MACHINE_VIDEO yet, because on-board video is not yet implemented. */ .ram = { .min = 1024, .max = 32768, @@ -4756,7 +4756,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO, + .flags = MACHINE_IDE_DUAL, .ram = { .min = 1024, .max = 32768, @@ -10967,6 +10967,41 @@ const machine_t machines[] = { } }; +/* Saved copies - jumpers get applied to these. + We use also machine_gpio to store IBM PC/XT jumpers as they need more than one byte. */ +static uint16_t machine_p1; +static uint32_t machine_gpio; + +uint8_t +machine_get_p1(void) +{ + return machine_p1; +} + +void +machine_load_p1(int m) +{ + machine_p1 = machines[machine].kbc_p1; +} + +uint32_t +machine_get_gpio(void) +{ + return machine_gpio; +} + +void +machine_load_gpio(int m) +{ + machine_gpio = machines[machine].gpio; +} + +void +machine_set_gpio(uint32_t gpio) +{ + machine_gpio = gpio; +} + int machine_count(void) { diff --git a/src/mem/rom.c b/src/mem/rom.c index eb2b5791b..debdf5c39 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -646,7 +646,7 @@ rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, addr, sz, rom_read, rom_readw, rom_readl, NULL, NULL, NULL, - rom->rom, flags | MEM_MAPPING_ROM, rom); + rom->rom, flags | MEM_MAPPING_ROM_WS, rom); return(0); } @@ -674,7 +674,7 @@ rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, in addr, sz, rom_read, rom_readw, rom_readl, NULL, NULL, NULL, - rom->rom, flags | MEM_MAPPING_ROM, rom); + rom->rom, flags | MEM_MAPPING_ROM_WS, rom); return(0); } diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 81e6d91ec..81429fe19 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -540,7 +540,6 @@ wd_mca_read(int port, void *priv) #define MCA_6FC0_IRQS { 3, 4, 10, 15 } - static void wd_mca_write(int port, uint8_t val, void *priv) { @@ -582,6 +581,68 @@ wd_mca_write(int port, uint8_t val, void *priv) dev->base_address, dev->irq, dev->ram_addr); } +static void +wd_8013epa_mca_write(int port, uint8_t val, void *priv) +{ + wd_t *dev = (wd_t *)priv; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) return; + + /* Save the MCA register value. */ + dev->pos_regs[port & 7] = val; + + /* + * The PS/2 Model 80 BIOS always enables a card if it finds one, + * even if no resources were assigned yet (because we only added + * the card, but have not run AutoConfig yet...) + * + * So, remove current address, if any. + */ + if (dev->base_address) + wd_io_remove(dev, dev->base_address); + + dev->base_address = 0x800 + ((dev->pos_regs[2] & 0xf0) << 8); + + switch (dev->pos_regs[5] & 0x0c) { + case 0: + dev->irq = 3; + break; + case 4: + dev->irq = 4; + break; + case 8: + dev->irq = 10; + break; + case 0x0c: + dev->irq = 14; + break; + } + + if (dev->pos_regs[3] & 0x10) + dev->ram_size = 0x4000; + else + dev->ram_size = 0x2000; + + dev->ram_addr = ((dev->pos_regs[3] & 0x0f) << 13) + 0xc0000; + if (dev->pos_regs[3] & 0x80) + dev->ram_addr += 0xf00000; + + /* Initialize the device if fully configured. */ + /* Register (new) I/O handler. */ + if (dev->pos_regs[2] & 0x01) + wd_io_set(dev, dev->base_address); + + mem_mapping_set_addr(&dev->ram_mapping, dev->ram_addr, dev->ram_size); + + mem_mapping_disable(&dev->ram_mapping); + if ((dev->msr & WE_MSR_ENABLE_RAM) && (dev->pos_regs[2] & 0x01)) + mem_mapping_enable(&dev->ram_mapping); + + wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name, + dev->base_address, dev->irq, dev->ram_addr); +} + static uint8_t wd_mca_feedb(void *priv) @@ -624,9 +685,12 @@ wd_init(const device_t *info) dev->maclocal[5] = (mac & 0xff); } - if ((dev->board == WD8003ETA) || (dev->board == WD8003EA)) - mca_add(wd_mca_read, wd_mca_write, wd_mca_feedb, NULL, dev); - else { + if ((dev->board == WD8003ETA) || (dev->board == WD8003EA) || dev->board == WD8013EPA) { + if (dev->board == WD8013EPA) + mca_add(wd_mca_read, wd_8013epa_mca_write, wd_mca_feedb, NULL, dev); + else + mca_add(wd_mca_read, wd_mca_write, wd_mca_feedb, NULL, dev); + } else { dev->base_address = device_get_config_hex16("base"); dev->irq = device_get_config_int("irq"); dev->ram_addr = device_get_config_hex20("ram_addr"); @@ -679,12 +743,20 @@ wd_init(const device_t *info) dev->board_chip = WE_ID_SOFT_CONFIG; /* Ethernet, MCA, no interface chip, RAM 16k */ case WD8003ETA: - dev->board_chip |= 0x05 | WE_ID_BUS_MCA; + dev->board_chip |= WE_TYPE_WD8013EBT | WE_ID_BUS_MCA; dev->ram_size = 0x4000; dev->pos_regs[0] = 0xC0; dev->pos_regs[1] = 0x6F; dev->bit16 = 3; break; + + case WD8013EPA: + dev->board_chip = WE_TYPE_WD8013EP | WE_ID_BUS_MCA; + dev->ram_size = device_get_config_int("ram_size"); + dev->pos_regs[0] = 0xC8; + dev->pos_regs[1] = 0x61; + dev->bit16 = 3; + break; } dev->irr |= WE_IRR_ENABLE_IRQ; @@ -969,6 +1041,31 @@ static const device_config_t wd8013_config[] = { { .name = "", .description = "", .type = CONFIG_END } }; +static const device_config_t wd8013epa_config[] = { + { + .name = "ram_size", + .description = "Initial RAM size", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 16384, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "8 kB", .value = 8192 }, + { .description = "16 kB", .value = 16384 }, + { .description = "" } + }, + }, + { + .name = "mac", + .description = "MAC Address", + .type = CONFIG_MAC, + .default_string = "", + .default_int = -1 + }, + { .name = "", .description = "", .type = CONFIG_END } +}; + static const device_config_t mca_mac_config[] = { { .name = "mac", @@ -1050,3 +1147,17 @@ const device_t wd8003ea_device = { .force_redraw = NULL, .config = mca_mac_config }; + +const device_t wd8013epa_device = { + .name = "Western Digital WD8013EP/A", + .internal_name = "wd8013epa", + .flags = DEVICE_MCA, + .local = WD8013EPA, + .init = wd_init, + .close = wd_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = wd8013epa_config +}; diff --git a/src/network/network.c b/src/network/network.c index 49915024a..6a7fbdfa5 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -103,6 +103,7 @@ static netcard_t net_cards[] = { { ðernext_mc_device, NULL }, { &wd8003eta_device, NULL }, { &wd8003ea_device, NULL }, + { &wd8013epa_device, NULL }, { &pcnet_am79c973_device, NULL }, { &pcnet_am79c970a_device, NULL }, { &rtl8029as_device, NULL }, diff --git a/src/pci.c b/src/pci.c index 7b4a7c6ed..36dd09002 100644 --- a/src/pci.c +++ b/src/pci.c @@ -94,6 +94,53 @@ pci_log(const char *fmt, ...) #endif +static void +pci_clear_slot(int card) +{ + int i; + + pci_card_to_slot_mapping[pci_cards[card].bus][pci_cards[card].id] = 0xff; + + pci_cards[card].id = 0xff; + pci_cards[card].type = 0xff; + + for (i = 0; i < 4; i++) + pci_cards[card].irq_routing[i] = 0; + + pci_cards[card].read = NULL; + pci_cards[card].write = NULL; + pci_cards[card].priv = NULL; +} + + +void +pci_relocate_slot(int type, int new_slot) +{ + int i, card = -1; + int old_slot; + uint8_t mapping; + + if ((new_slot < 0) || (new_slot > 31)) + return; + + for (i = 0; i < 32; i++) { + if ((pci_cards[i].bus == 0) && (pci_cards[i].type == type)) { + card = i; + break; + } + } + + if (card == -1) + return; + + old_slot = pci_cards[card].id; + pci_cards[card].id = new_slot; + mapping = pci_card_to_slot_mapping[0][old_slot]; + pci_card_to_slot_mapping[0][old_slot] = 0xff; + pci_card_to_slot_mapping[0][new_slot] = mapping; +} + + static void pci_cf8_write(uint16_t port, uint32_t val, void *priv) { @@ -809,17 +856,8 @@ pci_slots_clear(void) last_pci_card = last_normal_pci_card = 0; last_pci_bus = 1; - for (i = 0; i < 32; i++) { - pci_cards[i].id = 0xff; - pci_cards[i].type = 0xff; - - for (j = 0; j < 4; j++) - pci_cards[i].irq_routing[j] = 0; - - pci_cards[i].read = NULL; - pci_cards[i].write = NULL; - pci_cards[i].priv = NULL; - } + for (i = 0; i < 32; i++) + pci_clear_slot(i); i = 0; do { diff --git a/src/pic.c b/src/pic.c index 13c13d6df..fe6b29fc8 100644 --- a/src/pic.c +++ b/src/pic.c @@ -61,7 +61,6 @@ static uint16_t smi_irq_mask = 0x0000, static void (*update_pending)(void); - #ifdef ENABLE_PIC_LOG int pic_do_log = ENABLE_PIC_LOG; @@ -751,8 +750,8 @@ picinterrupt() pic.interrupt |= 0x40; /* Mark slave pending. */ } - if ((pic.interrupt == 0) && (pit2 != NULL)) - pit_ctr_set_gate(&pit2->counters[0], 0); + if ((pic.interrupt == 0) && (pit_devs[1].data != NULL)) + pit_devs[1].set_gate(pit_devs[1].data, 0, 0); /* Two ACK's - do them in a loop to avoid potential compiler misoptimizations. */ for (i = 0; i < 2; i++) { diff --git a/src/pit.c b/src/pit.c index f19a1acf7..ba71928ca 100644 --- a/src/pit.c +++ b/src/pit.c @@ -34,14 +34,15 @@ #include <86box/pic.h> #include <86box/timer.h> #include <86box/pit.h> +#include <86box/pit_fast.h> #include <86box/ppi.h> #include <86box/machine.h> #include <86box/sound.h> #include <86box/snd_speaker.h> #include <86box/video.h> +pit_intf_t pit_devs[2]; -pit_t *pit, *pit2; double cpuclock, PITCONSTD, SYSCLK, isa_timing, @@ -67,12 +68,6 @@ int64_t firsttime = 1; #define PIT_SECONDARY 128 /* The PIT is secondary (ports 0048-004B). */ -enum { - PIT_8253 = 0, - PIT_8254 -}; - - #ifdef ENABLE_PIT_LOG int pit_do_log = ENABLE_PIT_LOG; @@ -293,8 +288,11 @@ ctr_tick(ctr_t *ctr) static void -ctr_clock(ctr_t *ctr) +ctr_clock(void *data, int counter_id) { + pit_t *pit = (pit_t *)data; + ctr_t *ctr = &pit->counters[counter_id]; + /* FIXME: Is this even needed? */ if ((ctr->state == 3) && (ctr->m != 2) && (ctr->m != 3)) return; @@ -379,35 +377,47 @@ ctr_latch_count(ctr_t *ctr) uint16_t -pit_ctr_get_count(ctr_t *ctr) +pit_ctr_get_count(void *data, int counter_id) { + pit_t *pit = (pit_t *)data; + ctr_t *ctr = &pit->counters[counter_id]; + return (uint16_t) ctr->l; } void -pit_ctr_set_load_func(ctr_t *ctr, void (*func)(uint8_t new_m, int new_count)) +pit_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)) { - if (ctr == NULL) + if (data == NULL) return; + pit_t *pit = (pit_t *)data; + ctr_t *ctr = &pit->counters[counter_id]; + ctr->load_func = func; } void -pit_ctr_set_out_func(ctr_t *ctr, void (*func)(int new_out, int old_out)) +pit_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out)) { - if (ctr == NULL) + if (data == NULL) return; + pit_t *pit = (pit_t *)data; + ctr_t *ctr = &pit->counters[counter_id]; + ctr->out_func = func; } void -pit_ctr_set_gate(ctr_t *ctr, int gate) +pit_ctr_set_gate(void *data, int counter_id, int gate) { + pit_t *pit = (pit_t *)data; + ctr_t *ctr = &pit->counters[counter_id]; + int old = ctr->gate; uint8_t mode = ctr->m & 3; @@ -470,10 +480,12 @@ pit_ctr_set_clock(ctr_t *ctr, int clock) void -pit_ctr_set_using_timer(ctr_t *ctr, int using_timer) +pit_ctr_set_using_timer(void *data, int counter_id, int using_timer) { - timer_process(); - + if (tsc > 0) + timer_process(); + pit_t *pit = (pit_t *)data; + ctr_t *ctr = &pit->counters[counter_id]; ctr->using_timer = using_timer; } @@ -673,46 +685,19 @@ pit_read(uint16_t addr, void *priv) } -/* FIXME: Should be moved to machine.c (default for most machine). */ -void -pit_irq0_timer(int new_out, int old_out) -{ - if (new_out && !old_out) - picint(1); - - if (!new_out) - picintc(1); -} - - -void -pit_irq0_timer_pcjr(int new_out, int old_out) -{ - if (new_out && !old_out) { - picint(1); - ctr_clock(&pit->counters[1]); - } - - if (!new_out) - picintc(1); -} - - void pit_irq0_timer_ps2(int new_out, int old_out) { - ctr_t *ctr = &pit2->counters[0]; - if (new_out && !old_out) { picint(1); - pit_ctr_set_gate(ctr, 1); + pit_devs[1].set_gate(pit_devs[1].data, 0, 1); } if (!new_out) picintc(1); if (!new_out && old_out) - ctr_clock(ctr); + pit_devs[1].ctr_clock(pit_devs[1].data, 0); } @@ -742,7 +727,8 @@ pit_speaker_timer(int new_out, int old_out) speaker_update(); - l = pit->counters[2].l ? pit->counters[2].l : 0x10000; + uint16_t count = pit_devs[0].get_count(pit_devs[0].data, 2); + l = count ? count : 0x10000; if (l < 25) speakon = 0; else @@ -809,11 +795,11 @@ pit_close(void *priv) { pit_t *dev = (pit_t *) priv; - if (dev == pit) - pit = NULL; + if (dev == pit_devs[0].data) + pit_devs[0].data = NULL; - if (dev == pit2) - pit2 = NULL; + if (dev == pit_devs[1].data) + pit_devs[1].data = NULL; if (dev != NULL) free(dev); @@ -915,47 +901,83 @@ pit_t * pit_common_init(int type, void (*out0)(int new_out, int old_out), void (*out1)(int new_out, int old_out)) { int i; + void *pit; + + pit_intf_t *pit_intf = &pit_devs[0]; switch (type) { case PIT_8253: default: pit = device_add(&i8253_device); + *pit_intf = pit_classic_intf; break; case PIT_8254: pit = device_add(&i8254_device); + *pit_intf = pit_classic_intf; break; + case PIT_8253_FAST: + pit = device_add(&i8253_fast_device); + *pit_intf = pit_fast_intf; + break; + case PIT_8254_FAST: + pit = device_add(&i8254_fast_device); + *pit_intf = pit_fast_intf; + break; + } + pit_intf->data = pit; + for (i = 0; i < 3; i++) { - pit->counters[i].gate = 1; - pit->counters[i].using_timer = 1; + pit_intf->set_gate(pit_intf->data, i, 1); + pit_intf->set_using_timer(pit_intf->data, i, 1); } - pit_ctr_set_out_func(&pit->counters[0], out0); - pit_ctr_set_out_func(&pit->counters[1], out1); - pit_ctr_set_out_func(&pit->counters[2], pit_speaker_timer); - pit_ctr_set_load_func(&pit->counters[2], speaker_set_count); - pit->counters[2].gate = 0; + pit_intf->set_out_func(pit_intf->data, 0, out0); + pit_intf->set_out_func(pit_intf->data, 1, out1); + pit_intf->set_out_func(pit_intf->data, 2, pit_speaker_timer); + pit_intf->set_load_func(pit_intf->data, 2, speaker_set_count); + + pit_intf->set_gate(pit_intf->data, 2, 0); return pit; } pit_t * -pit_ps2_init(void) +pit_ps2_init(int type) { - pit2 = device_add(&i8254_ps2_device); + void *pit; - pit_handler(1, 0x0044, 0x0001, pit2); - pit_handler(1, 0x0047, 0x0001, pit2); + pit_intf_t *ps2_pit = &pit_devs[1]; - pit2->counters[0].gate = 0; - pit2->counters[0].using_timer = pit2->counters[1].using_timer = pit2->counters[2].using_timer = 0; + switch (type) { + case PIT_8254: + default: + pit = device_add(&i8254_ps2_device); + *ps2_pit = pit_classic_intf; + break; - pit_ctr_set_out_func(&pit->counters[0], pit_irq0_timer_ps2); - pit_ctr_set_out_func(&pit2->counters[0], pit_nmi_timer_ps2); + case PIT_8254_FAST: + pit = device_add(&i8254_ps2_fast_device); + *ps2_pit = pit_fast_intf; + break; + } - return pit2; + ps2_pit->data = pit; + + ps2_pit->set_gate(ps2_pit->data, 0, 0); + for (int i = 0; i < 3; i++) { + ps2_pit->set_using_timer(ps2_pit->data, i, 0); + } + + io_sethandler(0x0044, 0x0001, ps2_pit->read, NULL, NULL, ps2_pit->write, NULL, NULL, pit); + io_sethandler(0x0047, 0x0001, ps2_pit->read, NULL, NULL, ps2_pit->write, NULL, NULL, pit); + + pit_devs[0].set_out_func(pit_devs[0].data, 0, pit_irq0_timer_ps2); + ps2_pit->set_out_func(ps2_pit->data, 0, pit_nmi_timer_ps2); + + return pit; } @@ -1063,3 +1085,15 @@ pit_set_clock(int clock) device_speed_changed(); } + +const pit_intf_t pit_classic_intf = { + &pit_read, + &pit_write, + &pit_ctr_get_count, + &pit_ctr_set_gate, + &pit_ctr_set_using_timer, + &pit_ctr_set_out_func, + &pit_ctr_set_load_func, + &ctr_clock, + NULL, +}; \ No newline at end of file diff --git a/src/pit_fast.c b/src/pit_fast.c new file mode 100644 index 000000000..704cfd68c --- /dev/null +++ b/src/pit_fast.c @@ -0,0 +1,706 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 8253/8254 Programmable Interval + * Timer. + * + * + * + * Author: Miran Grca, + * Copyright 2019 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/device.h> +#include <86box/timer.h> +#include <86box/cassette.h> +#include <86box/dma.h> +#include <86box/io.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/pit.h> +#include <86box/pit_fast.h> +#include <86box/ppi.h> +#include <86box/machine.h> +#include <86box/sound.h> +#include <86box/snd_speaker.h> +#include <86box/video.h> + +#define PIT_PS2 16 /* The PIT is the PS/2's second PIT. */ +#define PIT_EXT_IO 32 /* The PIT has externally specified port I/O. */ +#define PIT_CUSTOM_CLOCK 64 /* The PIT uses custom clock inputs provided by another provider. */ +#define PIT_SECONDARY 128 /* The PIT is secondary (ports 0048-004B). */ + +#ifdef ENABLE_PIT_LOG +int pit_do_log = ENABLE_PIT_LOG; + +static void +pit_log(const char *fmt, ...) +{ + va_list ap; + + if (pit_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define pit_log(fmt, ...) +#endif + +static void +pitf_ctr_set_out(ctrf_t *ctr, int out) +{ + if (ctr == NULL) + return; + + if (ctr->out_func != NULL) + ctr->out_func(out, ctr->out); + ctr->out = out; +} + +static void +pitf_ctr_set_load_func(void *data, int counter_id, void (*func)(uint8_t new_m, int new_count)) +{ + if (data == NULL) + return; + + pitf_t *pit = (pitf_t *)data; + ctrf_t *ctr = &pit->counters[counter_id]; + + ctr->load_func = func; +} + +static uint16_t +pitf_ctr_get_count(void *data, int counter_id) +{ + pitf_t *pit = (pitf_t *)data; + ctrf_t *ctr = &pit->counters[counter_id]; + return (uint16_t) ctr->l; +} + +static void +pitf_ctr_set_out_func(void *data, int counter_id, void (*func)(int new_out, int old_out)) +{ + if (data == NULL) + return; + + pitf_t *pit = (pitf_t *)data; + ctrf_t *ctr = &pit->counters[counter_id]; + + ctr->out_func = func; +} + +static void +pitf_ctr_set_using_timer(void *data, int counter_id, int using_timer) +{ + if (tsc > 0) + timer_process(); + + pitf_t *pit = (pitf_t *)data; + ctrf_t *ctr = &pit->counters[counter_id]; + ctr->using_timer = using_timer; +} + +static int +pitf_read_timer(ctrf_t *ctr) +{ + if (ctr->using_timer && !(ctr->m == 3 && !ctr->gate) && timer_is_enabled(&ctr->timer)) { + int read = (int) ((timer_get_remaining_u64(&ctr->timer)) / PITCONST); + if (ctr->m == 2) + read++; + if (read < 0) + read = 0; + if (read > 0x10000) + read = 0x10000; + if (ctr->m == 3) + read <<= 1; + return read; + } + if (ctr->m == 2) + return ctr->count + 1; + return ctr->count; +} + +/*Dump timer count back to pit->count[], and disable timer. This should be used + when stopping a PIT timer, to ensure the correct value can be read back.*/ +static void +pitf_dump_and_disable_timer(ctrf_t *ctr) +{ + if (ctr->using_timer && timer_is_enabled(&ctr->timer)) { + ctr->count = pitf_read_timer(ctr); + timer_disable(&ctr->timer); + } +} + +static void +pitf_ctr_load(ctrf_t *ctr) +{ + int l = ctr->l ? ctr->l : 0x10000; + + ctr->newcount = 0; + ctr->disabled = 0; + + switch (ctr->m) { + case 0: /*Interrupt on terminal count*/ + ctr->count = l; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + pitf_ctr_set_out(ctr, 0); + ctr->thit = 0; + ctr->enabled = ctr->gate; + break; + case 1: /*Hardware retriggerable one-shot*/ + ctr->enabled = 1; + break; + case 2: /*Rate generator*/ + if (ctr->initial) { + ctr->count = l - 1; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) ((l - 1) * PITCONST)); + pitf_ctr_set_out(ctr, 1); + ctr->thit = 0; + } + ctr->enabled = ctr->gate; + break; + case 3: /*Square wave mode*/ + if (ctr->initial) { + ctr->count = l; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + pitf_ctr_set_out(ctr, 1); + ctr->thit = 0; + } + ctr->enabled = ctr->gate; + break; + case 4: /*Software triggered stobe*/ + if (!ctr->thit && !ctr->initial) + ctr->newcount = 1; + else { + ctr->count = l; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + pitf_ctr_set_out(ctr, 0); + ctr->thit = 0; + } + ctr->enabled = ctr->gate; + break; + case 5: /*Hardware triggered stobe*/ + ctr->enabled = 1; + break; + } + + if (ctr->load_func != NULL) + ctr->load_func(ctr->m, l); + + ctr->initial = 0; + ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled; + if (ctr->using_timer && !ctr->running) + pitf_dump_and_disable_timer(ctr); +} + +static void +pitf_set_gate_no_timer(ctrf_t *ctr, int gate) +{ + int l = ctr->l ? ctr->l : 0x10000; + + if (ctr->disabled) { + ctr->gate = gate; + return; + } + + switch (ctr->m) { + case 0: /*Interrupt on terminal count*/ + case 4: /*Software triggered stobe*/ + if (ctr->using_timer && !ctr->running) + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + ctr->enabled = gate; + break; + case 1: /*Hardware retriggerable one-shot*/ + case 5: /*Hardware triggered stobe*/ + if (gate && !ctr->gate) { + ctr->count = l; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + pitf_ctr_set_out(ctr, 0); + ctr->thit = 0; + ctr->enabled = 1; + } + break; + case 2: /*Rate generator*/ + if (gate && !ctr->gate) { + ctr->count = l - 1; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + pitf_ctr_set_out(ctr, 1); + ctr->thit = 0; + } + ctr->enabled = gate; + break; + case 3: /*Square wave mode*/ + if (gate && !ctr->gate) { + ctr->count = l; + if (ctr->using_timer) + timer_set_delay_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + pitf_ctr_set_out(ctr, 1); + ctr->thit = 0; + } + ctr->enabled = gate; + break; + } + ctr->gate = gate; + ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled; + if (ctr->using_timer && !ctr->running) + pitf_dump_and_disable_timer(ctr); +} + +static void +pitf_ctr_set_gate(void *data, int counter_id, int gate) +{ + pitf_t *pit = (pitf_t *)data; + ctrf_t *ctr = &pit->counters[counter_id]; + + if (ctr->disabled) { + ctr->gate = gate; + return; + } + + pitf_set_gate_no_timer(ctr, gate); +} + +static void +pitf_over(ctrf_t *ctr) +{ + int l = ctr->l ? ctr->l : 0x10000; + if (ctr->disabled) { + ctr->count += 0xffff; + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + return; + } + + switch (ctr->m) { + case 0: /*Interrupt on terminal count*/ + case 1: /*Hardware retriggerable one-shot*/ + if (!ctr->thit) + pitf_ctr_set_out(ctr, 1); + ctr->thit = 1; + ctr->count += 0xffff; + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + break; + case 2: /*Rate generator*/ + ctr->count += l; + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 1); + break; + case 3: /*Square wave mode*/ + if (ctr->out) { + pitf_ctr_set_out(ctr, 0); + ctr->count += (l >> 1); + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) ((l >> 1) * PITCONST)); + } else { + pitf_ctr_set_out(ctr, 1); + ctr->count += ((l + 1) >> 1); + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (((l + 1) >> 1) * PITCONST)); + } + // if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); + break; + case 4: /*Software triggered strove*/ + if (!ctr->thit) { + pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 1); + } + if (ctr->newcount) { + ctr->newcount = 0; + ctr->count += l; + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (l * PITCONST)); + } else { + ctr->thit = 1; + ctr->count += 0xffff; + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + } + break; + case 5: /*Hardware triggered strove*/ + if (!ctr->thit) { + pitf_ctr_set_out(ctr, 0); + pitf_ctr_set_out(ctr, 1); + } + ctr->thit = 1; + ctr->count += 0xffff; + if (ctr->using_timer) + timer_advance_u64(&ctr->timer, (uint64_t) (0xffff * PITCONST)); + break; + } + ctr->running = ctr->enabled && ctr->using_timer && !ctr->disabled; + if (ctr->using_timer && !ctr->running) + pitf_dump_and_disable_timer(ctr); +} + +static __inline void +pitf_ctr_latch_count(ctrf_t *ctr) +{ + ctr->rl = pitf_read_timer(ctr); + // pclog("Timer latch %f %04X %04X\n",pit->c[0],pit->rl[0],pit->l[0]); + // pit->ctrl |= 0x30; + ctr->rereadlatch = 0; + ctr->rm = 3; + ctr->latched = 1; +} + +static __inline void +pitf_ctr_latch_status(ctrf_t *ctr) +{ + ctr->read_status = (ctr->ctrl & 0x3f) | (ctr->out ? 0x80 : 0); + ctr->do_read_status = 1; +} + +static void +pitf_write(uint16_t addr, uint8_t val, void *priv) +{ + pitf_t *dev = (pitf_t *) priv; + int t = (addr & 3); + ctrf_t *ctr; + + pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + + switch (addr & 3) { + case 3: /* control */ + t = val >> 6; + + if (t == 3) { + if (dev->flags & PIT_8254) { + /* This is 8254-only. */ + if (!(val & 0x20)) { + if (val & 2) + pitf_ctr_latch_count(&dev->counters[0]); + if (val & 4) + pitf_ctr_latch_count(&dev->counters[1]); + if (val & 8) + pitf_ctr_latch_count(&dev->counters[2]); + pit_log("PIT %i: Initiated readback command\n", t); + } + if (!(val & 0x10)) { + if (val & 2) + pitf_ctr_latch_status(&dev->counters[0]); + if (val & 4) + pitf_ctr_latch_status(&dev->counters[1]); + if (val & 8) + pitf_ctr_latch_status(&dev->counters[2]); + } + } + } else { + dev->ctrl = val; + ctr = &dev->counters[t]; + + if (!(dev->ctrl & 0x30)) { + pitf_ctr_latch_count(ctr); + dev->ctrl |= 0x30; + pit_log("PIT %i: Initiated latched read, %i bytes latched\n", + t, ctr->latched); + } else { + ctr->ctrl = val; + ctr->rm = ctr->wm = (ctr->ctrl >> 4) & 3; + ctr->m = (val >> 1) & 7; + if (ctr->m > 5) + ctr->m &= 3; + if (!(ctr->rm)) { + ctr->rm = 3; + ctr->rl = pitf_read_timer(ctr); + } + ctr->rereadlatch = 1; + ctr->initial = 1; + if (!ctr->m) + pitf_ctr_set_out(ctr, 0); + else + pitf_ctr_set_out(ctr, 1); + ctr->disabled = 1; + + pit_log("PIT %i: M = %i, RM/WM = %i, State = %i, Out = %i\n", t, ctr->m, ctr->rm, ctr->state, ctr->out); + } + ctr->thit = 0; + } + break; + + case 0: + case 1: + case 2: /* the actual timers */ + ctr = &dev->counters[t]; + + switch (ctr->wm) { + case 1: + ctr->l = val; + pitf_ctr_load(ctr); + break; + case 2: + ctr->l = (val << 8); + pitf_ctr_load(ctr); + break; + case 0: + ctr->l &= 0xFF; + ctr->l |= (val << 8); + pitf_ctr_load(ctr); + ctr->wm = 3; + break; + case 3: + ctr->l &= 0xFF00; + ctr->l |= val; + ctr->wm = 0; + break; + } + break; + } +} + +static uint8_t +pitf_read(uint16_t addr, void *priv) +{ + pitf_t *dev = (pitf_t *) priv; + uint8_t ret = 0xff; + int t = (addr & 3); + ctrf_t *ctr; + + switch (addr & 3) { + case 3: /* Control. */ + /* This is 8254-only, 8253 returns 0x00. */ + ret = (dev->flags & PIT_8254) ? dev->ctrl : 0x00; + break; + + case 0: + case 1: + case 2: /* The actual timers. */ + ctr = &dev->counters[t]; + + if (ctr->do_read_status) { + ctr->do_read_status = 0; + ret = ctr->read_status; + break; + } + + if (ctr->rereadlatch && !ctr->latched) { + ctr->rereadlatch = 0; + ctr->rl = pitf_read_timer(ctr); + } + switch (ctr->rm) { + case 0: + ret = ctr->rl >> 8; + ctr->rm = 3; + ctr->latched = 0; + ctr->rereadlatch = 1; + break; + case 1: + ret = (ctr->rl) & 0xFF; + ctr->latched = 0; + ctr->rereadlatch = 1; + break; + case 2: + ret = (ctr->rl) >> 8; + ctr->latched = 0; + ctr->rereadlatch = 1; + break; + case 3: + ret = (ctr->rl) & 0xFF; + if (ctr->m & 0x80) + ctr->m &= 7; + else + ctr->rm = 0; + break; + } + break; + } + + pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + + return ret; +} + +static void +pitf_timer_over(void *p) +{ + ctrf_t *ctr = (ctrf_t *) p; + pitf_over(ctr); +} + +static void +pitf_ctr_clock(void *data, int counter_id) +{ + pitf_t *pit = (pitf_t *)data; + ctrf_t *ctr = &pit->counters[counter_id]; + + if (ctr->thit || !ctr->enabled) + return; + + if (ctr->using_timer) + return; + + ctr->count -= (ctr->m == 3) ? 2 : 1; + if (!ctr->count) + pitf_over(ctr); +} + +static void +ctr_reset(ctrf_t *ctr) +{ + ctr->ctrl = 0; + ctr->m = 0; + ctr->gate = 0; + ctr->l = 0xffff; + ctr->thit = 1; + ctr->using_timer = 1; +} + +static void +pitf_reset(pitf_t *dev) +{ + int i; + + memset(dev, 0, sizeof(pitf_t)); + + for (i = 0; i < 3; i++) + ctr_reset(&dev->counters[i]); + + /* Disable speaker gate. */ + dev->counters[2].gate = 0; +} + +static void +pitf_close(void *priv) +{ + pitf_t *dev = (pitf_t *) priv; + + if (dev == pit_devs[0].data) + pit_devs[0].data = NULL; + + if (dev == pit_devs[1].data) + pit_devs[1].data = NULL; + + if (dev != NULL) + free(dev); +} + +static void * +pitf_init(const device_t *info) +{ + pitf_t *dev = (pitf_t *) malloc(sizeof(pitf_t)); + pitf_reset(dev); + + dev->flags = info->local; + + if (!(dev->flags & PIT_PS2) && !(dev->flags & PIT_CUSTOM_CLOCK)) { + for (int i = 0; i < 3; i++) { + ctrf_t *ctr = &dev->counters[i]; + timer_add(&ctr->timer, pitf_timer_over, (void *)ctr, 0); + } + } + + if (!(dev->flags & PIT_EXT_IO)) { + io_sethandler((dev->flags & PIT_SECONDARY) ? 0x0048 : 0x0040, 0x0004, + pitf_read, NULL, NULL, pitf_write, NULL, NULL, dev); + } + + return dev; +} + +const device_t i8253_fast_device = { + .name = "Intel 8253/8253-5 Programmable Interval Timer", + .internal_name = "i8253_fast", + .flags = DEVICE_ISA, + .local = PIT_8253, + .init = pitf_init, + .close = pitf_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t i8254_fast_device = { + .name = "Intel 8254 Programmable Interval Timer", + .internal_name = "i8254_fast", + .flags = DEVICE_ISA, + .local = PIT_8254, + .init = pitf_init, + .close = pitf_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t i8254_sec_fast_device = { + .name = "Intel 8254 Programmable Interval Timer (Secondary)", + .internal_name = "i8254_sec_fast", + .flags = DEVICE_ISA, + .local = PIT_8254 | PIT_SECONDARY, + .init = pitf_init, + .close = pitf_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t i8254_ext_io_fast_device = { + .name = "Intel 8254 Programmable Interval Timer (External I/O)", + .internal_name = "i8254_ext_io_fast", + .flags = DEVICE_ISA, + .local = PIT_8254 | PIT_EXT_IO, + .init = pitf_init, + .close = pitf_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t i8254_ps2_fast_device = { + .name = "Intel 8254 Programmable Interval Timer (PS/2)", + .internal_name = "i8254_ps2_fast", + .flags = DEVICE_ISA, + .local = PIT_8254 | PIT_PS2 | PIT_EXT_IO, + .init = pitf_init, + .close = pitf_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const pit_intf_t pit_fast_intf = { + &pitf_read, + &pitf_write, + &pitf_ctr_get_count, + &pitf_ctr_set_gate, + &pitf_ctr_set_using_timer, + &pitf_ctr_set_out_func, + &pitf_ctr_set_load_func, + &pitf_ctr_clock, + NULL, +}; \ No newline at end of file diff --git a/src/port_6x.c b/src/port_6x.c index c583ffdf0..0fe168a3c 100644 --- a/src/port_6x.c +++ b/src/port_6x.c @@ -63,7 +63,7 @@ port_6x_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_ctr_set_gate(&pit->counters[2], val & 1); + pit_devs[0].set_gate(pit_devs[0].data, 2, val & 1); if (dev->flags & PORT_6X_TURBO) xi8088_turbo_set(!!(val & 0x04)); diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index b9d0e40e9..0cb4560c4 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -178,6 +178,7 @@ endif() if(WIN32) enable_language(RC) target_sources(86Box PUBLIC ../win/86Box-qt.rc) + target_sources(plat PRIVATE win_dynld.c) target_sources(plat PRIVATE win_joystick_rawinput.c) target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp) target_link_libraries(86Box hid d3d9) diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 7d1eecb09..b7f325a9a 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -116,7 +116,7 @@ msgid "VGA screen &type" msgstr "&Tipo de tela VGA" msgid "RGB &Color" -msgstr "&Cor RGB" +msgstr "&Cores RGB" msgid "&RGB Grayscale" msgstr "Tons de cinza &RGB" @@ -347,13 +347,13 @@ msgid "Time synchronization" msgstr "Sincronização da hora" msgid "Disabled" -msgstr "Desativada" +msgstr "Desativar" msgid "Enabled (local time)" -msgstr "Ativada (hora local)" +msgstr "Ativar (hora local)" msgid "Enabled (UTC)" -msgstr "Ativada (UTC)" +msgstr "Ativar (UTC)" msgid "Dynamic Recompiler" msgstr "Recompilador dinâmico" @@ -386,10 +386,10 @@ msgid "Sound card:" msgstr "Placa de som:" msgid "MIDI Out Device:" -msgstr "Disp. saída MIDI:" +msgstr "Disp. de saída MIDI:" msgid "MIDI In Device:" -msgstr "Disp. entrada MIDI:" +msgstr "Disp. de entrada MIDI:" msgid "Standalone MPU-401" msgstr "MPU-401 autônomo" @@ -506,7 +506,7 @@ msgid "&Remove" msgstr "&Remover" msgid "Bus:" -msgstr "Bar.:" +msgstr "Barramento:" msgid "Channel:" msgstr "Canal:" @@ -536,7 +536,7 @@ msgid "Image Format:" msgstr "Formato:" msgid "Block Size:" -msgstr "Bloco:" +msgstr "Blocos:" msgid "Floppy drives:" msgstr "Unidades de disquete:" @@ -599,7 +599,7 @@ msgid "Fatal error" msgstr "Erro fatal" msgid " - PAUSED" -msgstr " - PAUSED" +msgstr " - PAUSADO" msgid "Press Ctrl+Alt+PgDn to return to windowed mode." msgstr "Use Ctrl+Alt+PgDn para retornar ao modo janela" @@ -749,7 +749,7 @@ msgid "Microsoft SideWinder Pad" msgstr "Microsoft SideWinder Pad" msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgstr "Sistema de Controle de Voo Thrustmaster" msgid "None" msgstr "Nada" @@ -821,7 +821,7 @@ msgid "About 86Box" msgstr "Sobre o 86Box" msgid "86Box v" -msgstr "86Box versão" +msgstr "86Box versão " msgid "An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "Um emulador de computadores antigos\n\nAutores: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva\n\nLançado sob a Licença Pública Geral GNU versão 2 ou posterior. Veja o arquivo LICENSE para mais informações." diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 0b2047785..6ebc59b5d 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -31,6 +31,8 @@ extern "C" { #include <86box/config.h> #include <86box/device.h> #include <86box/midi_rtmidi.h> +#include <86box/mem.h> +#include <86box/rom.h> } #include "qt_filefield.hpp" @@ -51,6 +53,8 @@ DeviceConfig::~DeviceConfig() void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Settings* settings) { DeviceConfig dc(settings); dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); + int combo_to_struct[256]; + int c, d, p, q; device_context_t device_context; device_set_context(&device_context, device, instance); @@ -140,6 +144,33 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting cbox->setCurrentIndex(currentIndex); break; } + case CONFIG_BIOS: + { + auto* cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto* model = cbox->model(); + int currentIndex = -1; + char *selected; + selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + + c = q = 0; + for (auto* bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { + p = 0; + for (d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + int row = Models::AddEntry(model, bios->name, q); + if (!strcmp(selected, bios->internal_name)) { + currentIndex = row; + } + c++; + } + q++; + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_SPINNER: { int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); @@ -188,6 +219,13 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); break; } + case CONFIG_BIOS: + { + auto* cbox = dc.findChild(config->name); + int idx = cbox->currentData().toInt(); + config_set_string(device_context.name, const_cast(config->name), const_cast(config->bios[idx].internal_name)); + break; + } case CONFIG_HEX16: { auto* cbox = dc.findChild(config->name); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 91f76d900..eff022b3d 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -431,6 +431,7 @@ void plat_language_code_r(uint32_t lcid, char* outbuf, int len) { return; } +#ifndef Q_OS_WINDOWS void* dynld_module(const char *name, dllimp_t *table) { QString libraryName = name; @@ -462,6 +463,7 @@ void dynld_close(void *handle) { delete reinterpret_cast(handle); } +#endif void startblit() { diff --git a/src/qt/win_dynld.c b/src/qt/win_dynld.c new file mode 100644 index 000000000..98eb4739f --- /dev/null +++ b/src/qt/win_dynld.c @@ -0,0 +1,87 @@ +/* + * 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. + * + * Try to load a support DLL. + * + * + * + * Author: Fred N. van Kempen, + * + * Copyright 2017,2018 Fred N. van Kempen + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/plat_dynld.h> + + +#ifdef ENABLE_DYNLD_LOG +int dynld_do_log = ENABLE_DYNLD_LOG; + + +static void +dynld_log(const char *fmt, ...) +{ + va_list ap; + + if (dynld_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define dynld_log(fmt, ...) +#endif + + +void * +dynld_module(const char *name, dllimp_t *table) +{ + HMODULE h; + dllimp_t *imp; + void *func; + + /* See if we can load the desired module. */ + if ((h = LoadLibrary(name)) == NULL) { + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); + return(NULL); + } + + /* Now load the desired function pointers. */ + for (imp=table; imp->name!=NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); + FreeLibrary(h); + return(NULL); + } + + /* To overcome typing issues.. */ + *(char **)imp->func = (char *)func; + } + + /* All good. */ + dynld_log("loaded %s\n", name); + return((void *)h); +} + + +void +dynld_close(void *handle) +{ + if (handle != NULL) + FreeLibrary((HMODULE)handle); +} diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 52677a544..5017295b1 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -13,8 +13,8 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c6xx.c - sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c +add_library(sio OBJECT sio_acc3221.c sio_ali5123.c sio_f82c710.c sio_82091aa.c + sio_fdc37c6xx.c sio_fdc37c67x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c sio_it8661f.c sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87310.c sio_pc87311.c sio_pc87332.c sio_prime3b.c sio_prime3c.c diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c new file mode 100644 index 000000000..79d9219ba --- /dev/null +++ b/src/sio/sio_ali5123.c @@ -0,0 +1,478 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ALi M5123/1543C Super I/O Chip. + * + * + * + * Author: Miran Grca, + * Copyright 2016-2018 Miran Grca. + */ +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/pic.h> +#include <86box/pci.h> +#include <86box/keyboard.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include "cpu.h" +#include <86box/sio.h> + + +#define AB_RST 0x80 + + +typedef struct { + uint8_t chip_id, is_apm, + tries, + regs[48], + ld_regs[13][256]; + int locked, + cur_reg; + fdc_t *fdc; + serial_t *uart[3]; +} ali5123_t; + + +static void ali5123_write(uint16_t port, uint8_t val, void *priv); +static uint8_t ali5123_read(uint16_t port, void *priv); + + +static uint16_t +make_port(ali5123_t *dev, uint8_t ld) +{ + uint16_t r0 = dev->ld_regs[ld][0x60]; + uint16_t r1 = dev->ld_regs[ld][0x61]; + + uint16_t p = (r0 << 8) + r1; + + return p; +} + + +static void +ali5123_fdc_handler(ali5123_t *dev) +{ + uint16_t ld_port = 0; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 0)); + uint8_t local_enable = !!dev->ld_regs[0][0x30]; + + fdc_remove(dev->fdc); + if (global_enable && local_enable) { + ld_port = make_port(dev, 0) & 0xFFF8; + if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) + fdc_set_base(dev->fdc, ld_port); + } +} + + +static void +ali5123_lpt_handler(ali5123_t *dev) +{ + uint16_t ld_port = 0; + uint8_t global_enable = !!(dev->regs[0x22] & (1 << 3)); + uint8_t local_enable = !!dev->ld_regs[3][0x30]; + uint8_t lpt_irq = dev->ld_regs[3][0x70]; + + if (lpt_irq > 15) + lpt_irq = 0xff; + + lpt1_remove(); + if (global_enable && local_enable) { + ld_port = make_port(dev, 3) & 0xFFFC; + if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) + lpt1_init(ld_port); + } + lpt1_irq(lpt_irq); +} + + +static void +ali5123_serial_handler(ali5123_t *dev, int uart) +{ + uint16_t ld_port = 0; + uint8_t uart_no = (uart == 2) ? 0x0b : (4 + uart); + uint8_t global_enable = !!(dev->regs[0x22] & (1 << uart_no)); + uint8_t local_enable = !!dev->ld_regs[uart_no][0x30]; + uint8_t mask = (uart == 1) ? 0x04 : 0x05; + + serial_remove(dev->uart[uart]); + if (global_enable && local_enable) { + ld_port = make_port(dev, uart_no) & 0xFFF8; + if ((ld_port >= 0x0100) && (ld_port <= 0x0FF8)) + serial_setup(dev->uart[uart], ld_port, dev->ld_regs[uart_no][0x70]); + } + + switch (dev->ld_regs[uart_no][0xf0] & mask) { + case 0x00: + serial_set_clock_src(dev->uart[uart], 1843200.0); + break; + case 0x04: + serial_set_clock_src(dev->uart[uart], 8000000.0); + break; + case 0x01: case 0x05: + serial_set_clock_src(dev->uart[uart], 2000000.0); + break; + } +} + + +static void +ali5123_reset(ali5123_t *dev) +{ + int i = 0; + + memset(dev->regs, 0, 48); + + dev->regs[0x20] = 0x43; + dev->regs[0x21] = 0x15; + dev->regs[0x2d] = 0x20; + + for (i = 0; i < 13; i++) + memset(dev->ld_regs[i], 0, 256); + + /* Logical device 0: FDD */ + dev->ld_regs[0][0x60] = 3; + dev->ld_regs[0][0x61] = 0xf0; + dev->ld_regs[0][0x70] = 6; + dev->ld_regs[0][0x74] = 2; + dev->ld_regs[0][0xf0] = 0x08; + dev->ld_regs[0][0xf2] = 0xff; + + /* Logical device 3: Parallel Port */ + dev->ld_regs[3][0x60] = 3; + dev->ld_regs[3][0x61] = 0x78; + dev->ld_regs[3][0x70] = 5; + dev->ld_regs[3][0x74] = 4; + dev->ld_regs[3][0xf0] = 0x8c; + dev->ld_regs[3][0xf1] = 0x85; + + /* Logical device 4: Serial Port 1 */ + dev->ld_regs[4][0x60] = 3; + dev->ld_regs[4][0x61] = 0xf8; + dev->ld_regs[4][0x70] = 4; + dev->ld_regs[4][0xf2] = 0x0c; + serial_setup(dev->uart[0], COM1_ADDR, dev->ld_regs[4][0x70]); + + /* Logical device 5: Serial Port 2 - HP like module */ + dev->ld_regs[5][0x60] = 3; + dev->ld_regs[5][0x61] = 0xe8; + dev->ld_regs[5][0x70] = 9; + dev->ld_regs[5][0xf0] = 0x80; + dev->ld_regs[4][0xf2] = 0x0c; + serial_setup(dev->uart[1], 0x03e8, dev->ld_regs[5][0x70]); + + /* Logical device 7: Keyboard */ + dev->ld_regs[7][0x70] = 1; + /* TODO: Register F0 bit 6: 0 = PS/2, 1 = AT */ + + /* Logical device B: Serial Port 2 - HP like module */ + dev->ld_regs[0x0b][0x60] = 2; + dev->ld_regs[0x0b][0x61] = 0xf8; + dev->ld_regs[0x0b][0x70] = 3; + dev->ld_regs[0x0b][0xf0] = 0x00; + dev->ld_regs[0x0b][0xf2] = 0x0c; + serial_setup(dev->uart[2], COM2_ADDR, dev->ld_regs[0x0b][0x70]); + + /* Logical device C: Hotkey */ + dev->ld_regs[0x0c][0xf0] = 0x35; + dev->ld_regs[0x0c][0xf1] = 0x14; + dev->ld_regs[0x0c][0xf2] = 0x11; + dev->ld_regs[0x0c][0xf3] = 0x71; + dev->ld_regs[0x0c][0xf4] = 0x42; + + ali5123_lpt_handler(dev); + ali5123_serial_handler(dev, 0); + ali5123_serial_handler(dev, 1); + ali5123_serial_handler(dev, 2); + + fdc_reset(dev->fdc); + ali5123_fdc_handler(dev); + + dev->locked = 0; +} + + +static void +ali5123_write(uint16_t port, uint8_t val, void *priv) +{ + ali5123_t *dev = (ali5123_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0x00, keep = 0x00; + uint8_t cur_ld; + + if (index) { + if (((val == 0x51) && (!dev->tries) && (!dev->locked)) || + ((val == 0x23) && (dev->tries) && (!dev->locked))) { + if (dev->tries) { + dev->locked = 1; + fdc_3f1_enable(dev->fdc, 0); + dev->tries = 0; + } else + dev->tries++; + } else { + if (dev->locked) { + if (val == 0xbb) { + dev->locked = 0; + fdc_3f1_enable(dev->fdc, 1); + return; + } + dev->cur_reg = val; + } else { + if (dev->tries) + dev->tries = 0; + } + } + return; + } else { + if (dev->locked) { + if (dev->cur_reg < 48) { + valxor = val ^ dev->regs[dev->cur_reg]; + if ((val == 0x1f) || (val == 0x20) || (val == 0x21)) + return; + dev->regs[dev->cur_reg] = val; + } else { + valxor = val ^ dev->ld_regs[dev->regs[7]][dev->cur_reg]; + if (((dev->cur_reg & 0xf0) == 0x70) && (dev->regs[7] < 4)) + return; + /* Block writes to some logical devices. */ + if (dev->regs[7] > 0x0c) + return; + else switch (dev->regs[7]) { + case 0x01: case 0x02: case 0x06: case 0x08: + case 0x09: case 0x0a: + return; + } + dev->ld_regs[dev->regs[7]][dev->cur_reg] = val | keep; + } + } else + return; + } + + if (dev->cur_reg < 48) { + switch(dev->cur_reg) { + case 0x02: + if (val & 0x01) + ali5123_reset(dev); + dev->regs[0x02] = 0x00; + break; + case 0x22: + if (valxor & 0x01) + ali5123_fdc_handler(dev); + if (valxor & 0x08) + ali5123_lpt_handler(dev); + if (valxor & 0x10) + ali5123_serial_handler(dev, 0); + if (valxor & 0x20) + ali5123_serial_handler(dev, 1); + if (valxor & 0x40) + ali5123_serial_handler(dev, 2); + break; + } + + return; + } + + cur_ld = dev->regs[7]; + if ((dev->regs[7] == 5) && (dev->regs[0x2d] & 0x20)) + cur_ld = 0x0b; + else if ((dev->regs[7] == 0x0b) && (dev->regs[0x2d] & 0x20)) + cur_ld = 5; + switch(cur_ld) { + case 0: + /* FDD */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x01; + if (valxor) + ali5123_fdc_handler(dev); + break; + case 0xf0: + if (valxor & 0x08) + fdc_update_enh_mode(dev->fdc, !(val & 0x08)); + if (valxor & 0x10) + fdc_set_swap(dev->fdc, (val & 0x10) >> 4); + break; + case 0xf1: + if (valxor & 0xc) + fdc_update_densel_force(dev->fdc, (val & 0xc) >> 2); + break; + case 0xf4: + if (valxor & 0x08) + fdc_update_drvrate(dev->fdc, 0, (val & 0x08) >> 3); + break; + case 0xf5: + if (valxor & 0x08) + fdc_update_drvrate(dev->fdc, 1, (val & 0x08) >> 3); + break; + case 0xf6: + if (valxor & 0x08) + fdc_update_drvrate(dev->fdc, 2, (val & 0x08) >> 3); + break; + case 0xf7: + if (valxor & 0x08) + fdc_update_drvrate(dev->fdc, 3, (val & 0x08) >> 3); + break; + } + break; + case 3: + /* Parallel port */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x08; + if (valxor) + ali5123_lpt_handler(dev); + break; + } + break; + case 4: + /* Serial port 1 */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + case 0xf0: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x10; + if (valxor) + ali5123_serial_handler(dev, 0); + break; + } + break; + case 5: + /* Serial port 2 - HP like module */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + case 0xf0: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x20; + if (valxor) + ali5123_serial_handler(dev, 1); + break; + } + break; + case 0x0b: + /* Serial port 3 */ + switch(dev->cur_reg) { + case 0x30: + case 0x60: + case 0x61: + case 0x70: + case 0xf0: + if ((dev->cur_reg == 0x30) && (val & 0x01)) + dev->regs[0x22] |= 0x40; + if (valxor) + ali5123_serial_handler(dev, 2); + break; + } + break; + } +} + + +static uint8_t +ali5123_read(uint16_t port, void *priv) +{ + ali5123_t *dev = (ali5123_t *) priv; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff, cur_ld; + + if (dev->locked) { + if (index) + ret = dev->cur_reg; + else { + if (dev->cur_reg < 0x30) { + if (dev->cur_reg == 0x20) + ret = dev->chip_id; + else + ret = dev->regs[dev->cur_reg]; + } else { + cur_ld = dev->regs[7]; + if ((dev->regs[7] == 5) && (dev->regs[0x2d] & 0x20)) + cur_ld = 0x0b; + else if ((dev->regs[7] == 0x0b) && (dev->regs[0x2d] & 0x20)) + cur_ld = 5; + + ret = dev->ld_regs[cur_ld][dev->cur_reg]; + } + } + } + + return ret; +} + + +static void +ali5123_close(void *priv) +{ + ali5123_t *dev = (ali5123_t *) priv; + + free(dev); +} + + +static void * +ali5123_init(const device_t *info) +{ + ali5123_t *dev = (ali5123_t *) malloc(sizeof(ali5123_t)); + memset(dev, 0, sizeof(ali5123_t)); + + dev->fdc = device_add(&fdc_at_ali_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + dev->uart[2] = device_add_inst(&ns16550_device, 3); + + dev->chip_id = info->local & 0xff; + + ali5123_reset(dev); + + io_sethandler(FDC_PRIMARY_ADDR, 0x0002, + ali5123_read, NULL, NULL, ali5123_write, NULL, NULL, dev); + + device_add(&keyboard_ps2_ali_pci_device); + + return dev; +} + + +const device_t ali5123_device = { + .name = "ALi M5123/M1543C Super I/O", + .internal_name = "ali5123", + .flags = 0, + .local = 0x40, + .init = ali5123_init, + .close = ali5123_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index c65a42b87..c60f224ab 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -15,12 +15,12 @@ */ #if defined __has_include -# if __has_include () -# include -# endif -# if __has_include () -# include -# endif +# if __has_include() +# include +# endif +# if __has_include() +# include +# endif #endif #include @@ -38,16 +38,15 @@ extern "C" // Disable c99-designator to avoid the warnings in rtmidi_*_device #ifdef __clang__ -#if __has_warning("-Wc99-designator") -#pragma clang diagnostic ignored "-Wc99-designator" -#endif +# if __has_warning("-Wc99-designator") +# pragma clang diagnostic ignored "-Wc99-designator" +# endif #endif -static RtMidiOut * midiout = nullptr; -static RtMidiIn * midiin = nullptr; -static int midi_out_id = 0, midi_in_id = 0; -static const int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; - +static RtMidiOut *midiout = nullptr; +static RtMidiIn *midiin = nullptr; +static int midi_out_id = 0, midi_in_id = 0; +static const int midi_lengths[8] = { 3, 3, 3, 3, 2, 2, 3, 1 }; int rtmidi_write(uint8_t val) @@ -55,55 +54,53 @@ rtmidi_write(uint8_t val) return 0; } - void rtmidi_play_msg(uint8_t *msg) { if (midiout) - midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); + midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); } - void rtmidi_play_sysex(uint8_t *sysex, unsigned int len) { if (midiout) - midiout->sendMessage(sysex, len); + midiout->sendMessage(sysex, len); } - void* rtmidi_output_init(const device_t *info) { - midi_device_t* dev = (midi_device_t*)malloc(sizeof(midi_device_t)); + midi_device_t *dev = (midi_device_t *) malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); - dev->play_msg = rtmidi_play_msg; + dev->play_msg = rtmidi_play_msg; dev->play_sysex = rtmidi_play_sysex; - dev->write = rtmidi_write; + dev->write = rtmidi_write; try { - if (!midiout) midiout = new RtMidiOut; - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - return nullptr; - } - - midi_out_id = config_get_int((char*)SYSTEM_MIDI_NAME, (char*)"midi", 0); - - try { - midiout->openPort(midi_out_id); - } catch (RtMidiError& error) { - pclog("Fallback to default MIDI output port: %s\n", error.getMessage().c_str()); - - try { - midiout->openPort(0); - } catch (RtMidiError& error) { + if (!midiout) + midiout = new RtMidiOut; + } catch (RtMidiError &error) { pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - delete midiout; - midiout = nullptr; return nullptr; } + + midi_out_id = config_get_int((char *) SYSTEM_MIDI_NAME, (char *) "midi", 0); + + try { + midiout->openPort(midi_out_id); + } catch (RtMidiError &error) { + pclog("Fallback to default MIDI output port: %s\n", error.getMessage().c_str()); + + try { + midiout->openPort(0); + } catch (RtMidiError &error) { + pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); + delete midiout; + midiout = nullptr; + return nullptr; + } } midi_out_init(dev); @@ -111,12 +108,11 @@ rtmidi_output_init(const device_t *info) return dev; } - void rtmidi_output_close(void *p) { if (!midiout) - return; + return; midiout->closePort(); @@ -126,68 +122,64 @@ rtmidi_output_close(void *p) midi_out_close(); } - int rtmidi_out_get_num_devs(void) { if (!midiout) { - try { - midiout = new RtMidiOut; - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); - } + try { + midiout = new RtMidiOut; + } catch (RtMidiError &error) { + pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); + } } return midiout ? midiout->getPortCount() : 0; } - void rtmidi_out_get_dev_name(int num, char *s) { strcpy(s, midiout->getPortName(num).c_str()); } - void rtmidi_input_callback(double timeStamp, std::vector *message, void *userData) { if (message->front() == 0xF0) midi_in_sysex(message->data(), message->size()); else - midi_in_msg(message->data(), message->size()); + midi_in_msg(message->data(), message->size()); } - void* rtmidi_input_init(const device_t *info) { - midi_device_t* dev = (midi_device_t*)malloc(sizeof(midi_device_t)); + midi_device_t *dev = (midi_device_t *) malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); try { - if (!midiin) - midiin = new RtMidiIn; - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - return nullptr; - } - - midi_in_id = config_get_int((char*)MIDI_INPUT_NAME, (char*)"midi_input", 0); - - try { - midiin->openPort(midi_in_id); - } catch (RtMidiError& error) { - pclog("Fallback to default MIDI input port: %s\n", error.getMessage().c_str()); - - try { - midiin->openPort(0); - } catch (RtMidiError& error) { + if (!midiin) + midiin = new RtMidiIn; + } catch (RtMidiError &error) { pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - delete midiin; - midiin = nullptr; return nullptr; } + + midi_in_id = config_get_int((char *) MIDI_INPUT_NAME, (char *) "midi_input", 0); + + try { + midiin->openPort(midi_in_id); + } catch (RtMidiError &error) { + pclog("Fallback to default MIDI input port: %s\n", error.getMessage().c_str()); + + try { + midiin->openPort(0); + } catch (RtMidiError &error) { + pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); + delete midiin; + midiin = nullptr; + return nullptr; + } } midiin->setCallback(&rtmidi_input_callback); @@ -198,15 +190,14 @@ rtmidi_input_init(const device_t *info) midi_in_init(dev, &midi_in); midi_in->midi_realtime = device_get_config_int("realtime"); - midi_in->thruchan = device_get_config_int("thruchan"); + midi_in->thruchan = device_get_config_int("thruchan"); midi_in->midi_clockout = device_get_config_int("clockout"); return dev; } - void -rtmidi_input_close(void* p) +rtmidi_input_close(void *p) { midiin->cancelCallback(); midiin->closePort(); @@ -217,22 +208,20 @@ rtmidi_input_close(void* p) midi_out_close(); } - int rtmidi_in_get_num_devs(void) { if (!midiin) { - try { - midiin = new RtMidiIn; - } catch (RtMidiError& error) { - pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); - } + try { + midiin = new RtMidiIn; + } catch (RtMidiError &error) { + pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); + } } return midiin ? midiin->getPortCount() : 0; } - void rtmidi_in_get_dev_name(int num, char *s) { @@ -240,6 +229,7 @@ rtmidi_in_get_dev_name(int num, char *s) } static const device_config_t system_midi_config[] = { + // clang-format off { .name = "midi", .description = "MIDI out device", @@ -248,9 +238,11 @@ static const device_config_t system_midi_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } + // clang-format on }; static const device_config_t midi_input_config[] = { + // clang-format off { .name = "midi_input", .description = "MIDI in device", @@ -280,6 +272,7 @@ static const device_config_t midi_input_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } + // clang-format on }; const device_t rtmidi_output_device = { @@ -309,5 +302,4 @@ const device_t rtmidi_input_device = { .force_redraw = NULL, .config = midi_input_config }; - } diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 652c672e2..655a93a1f 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -20,6 +20,7 @@ typedef struct adgold_t { int adgold_irq_status; + int irq, dma, hdma; uint8_t adgold_eeprom[0x1a]; @@ -157,7 +158,7 @@ adgold_update_irq_status(adgold_t *adgold) adgold->adgold_status = temp; if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) { - picint(0x80); + picint(1 << adgold->irq); } adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; @@ -167,23 +168,26 @@ void adgold_getsamp_dma(adgold_t *adgold, int channel) { int temp; + dma_set_drq(adgold->dma, 1); if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) return; - temp = dma_channel_read(1); - if (temp == DMA_NODATA) + temp = dma_channel_read(adgold->dma); + if (temp == DMA_NODATA) { return; + } adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; - adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; + adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; if (adgold->adgold_mma_regs[channel][0xc] & 0x60) { - temp = dma_channel_read(1); + temp = dma_channel_read(adgold->dma); adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; - adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; + adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; } if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) { adgold->adgold_mma_status &= ~(0x01 << channel); adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } } @@ -335,10 +339,11 @@ adgold_write(uint16_t addr, uint8_t val, void *p) break; /* 7350 Hz*/ } if (val & 0x80) { - adgold->adgold_mma_enable[0] = 0; + adgold->adgold_mma_enable[0] = 0; adgold->adgold_mma_fifo_end[0] = adgold->adgold_mma_fifo_start[0] = 0; adgold->adgold_mma_status &= ~0x01; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } if ((val & 0x01)) /*Start playback*/ { @@ -347,7 +352,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p) if (adgold->adgold_mma_regs[0][0xc] & 1) { if (adgold->adgold_mma_regs[0][0xc] & 0x80) { - adgold->adgold_mma_enable[1] = 1; + adgold->adgold_mma_enable[1] = 1; adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { @@ -357,10 +362,12 @@ adgold_write(uint16_t addr, uint8_t val, void *p) if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) { adgold->adgold_mma_status &= ~0x02; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } } else { while (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { @@ -369,6 +376,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p) if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } } } @@ -379,10 +387,11 @@ adgold_write(uint16_t addr, uint8_t val, void *p) case 0xb: if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { adgold->adgold_mma_fifo[0][adgold->adgold_mma_fifo_end[0]] = val; - adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255; + adgold->adgold_mma_fifo_end[0] = (adgold->adgold_mma_fifo_end[0] + 1) & 255; if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) >= adgold->adgold_mma_intpos[0]) { adgold->adgold_mma_status &= ~0x01; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } } break; @@ -457,6 +466,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p) adgold->adgold_mma_fifo_end[1] = adgold->adgold_mma_fifo_start[1] = 0; adgold->adgold_mma_status &= ~0x02; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } if ((val & 0x01)) /*Start playback*/ { @@ -479,6 +489,7 @@ adgold_write(uint16_t addr, uint8_t val, void *p) if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) >= adgold->adgold_mma_intpos[1]) { adgold->adgold_mma_status &= ~0x02; adgold_update_irq_status(adgold); + dma_set_drq(adgold->dma, 0); } } break; @@ -525,6 +536,7 @@ adgold_read(uint16_t addr, void *p) default: temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr]; + break; } } else temp = opl3_read(addr, &adgold->opl); @@ -877,8 +889,9 @@ adgold_init(const device_t *info) adgold_t *adgold = malloc(sizeof(adgold_t)); memset(adgold, 0, sizeof(adgold_t)); + adgold->dma = device_get_config_int("dma"); + adgold->irq = device_get_config_int("irq"); adgold->surround_enabled = device_get_config_int("surround"); - adgold->gameport_enabled = device_get_config_int("gameport"); opl3_init(&adgold->opl); @@ -912,9 +925,9 @@ adgold_init(const device_t *info) adgold->adgold_eeprom[0x10] = 0xff; adgold->adgold_eeprom[0x11] = 0x20; adgold->adgold_eeprom[0x12] = 0x00; - adgold->adgold_eeprom[0x13] = 0x0b; /* IRQ 1, DMA1 */ - adgold->adgold_eeprom[0x14] = 0x00; /* DMA2 */ - adgold->adgold_eeprom[0x15] = 0x71; /* Port */ + adgold->adgold_eeprom[0x13] = 0xa0; + adgold->adgold_eeprom[0x14] = 0x00; + adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ adgold->adgold_eeprom[0x16] = 0x00; adgold->adgold_eeprom[0x17] = 0x68; adgold->adgold_eeprom[0x18] = 0x00; /* Surround */ @@ -927,25 +940,36 @@ adgold_init(const device_t *info) fclose(f); } - adgold->adgold_status = 0xf; - adgold->adgold_38x_addr = 0; - adgold->adgold_eeprom[0x13] = 3 | (1 << 3); /*IRQ 7, DMA 1*/ - // adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3 - Double check this */ - adgold->adgold_eeprom[0x14] = 0x00; /*DMA ?*/ - adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ + adgold->adgold_status = 0xf; + adgold->adgold_38x_addr = 0; + switch (adgold->irq) { + case 3: + adgold->adgold_eeprom[0x13] |= 0x00; + break; + case 4: + adgold->adgold_eeprom[0x13] |= 0x01; + break; + case 5: + adgold->adgold_eeprom[0x13] |= 0x02; + break; + case 7: + adgold->adgold_eeprom[0x13] |= 0x03; + break; + } + adgold->adgold_eeprom[0x13] |= (adgold->dma << 3); memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); - adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; - adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; - adgold->bass = adgold->adgold_eeprom[0x06] & 0xf; - adgold->treble = adgold->adgold_eeprom[0x07] & 0xf; - adgold->fm_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x09] - 128); - adgold->fm_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0a] - 128); + adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; + adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; + adgold->bass = adgold->adgold_eeprom[0x06] & 0xf; + adgold->treble = adgold->adgold_eeprom[0x07] & 0xf; + adgold->fm_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x09] - 128); + adgold->fm_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0a] - 128); adgold->samp_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x0b] - 128); adgold->samp_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0c] - 128); adgold->aux_vol_l = (int) (int8_t) (adgold->adgold_eeprom[0x0d] - 128); adgold->aux_vol_r = (int) (int8_t) (adgold->adgold_eeprom[0x0e] - 128); - adgold->adgold_mma_enable[0] = 0; + adgold->adgold_mma_enable[0] = 0; adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; /*388/389 are handled by adlib_init*/ @@ -982,6 +1006,54 @@ adgold_close(void *p) static const device_config_t adgold_config[] = { // clang-format off + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 7, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 4", + .value = 4 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { .description = "" } + } + }, + { + .name = "dma", + .description = "Low DMA channel", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 1, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "DMA 1", + .value = 1 + }, + { + .description = "DMA 3", + .value = 3 + }, + { .description = "" } + } + }, { .name = "gameport", .description = "Enable Game port", diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index aaafd11fa..1038567fa 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1198,6 +1198,151 @@ sb_pro_mcv_write(int port, uint8_t val, void *p) sb_dsp_setdma8(&sb->dsp, sb->pos_regs[4] & 3); } +static uint8_t +sb_16_reply_mca_read(int port, void *p) +{ + sb_t *sb = (sb_t *) p; + uint8_t ret = sb->pos_regs[port & 7]; + + sb_log("sb_16_reply_mca_read: port=%04x ret=%02x\n", port, ret); + + return ret; +} + +static void +sb_16_reply_mca_write(int port, uint8_t val, void *p) +{ + uint16_t addr, mpu401_addr; + int low_dma, high_dma; + sb_t *sb = (sb_t *) p; + + if (port < 0x102) + return; + + sb_log("sb_16_reply_mca_write: port=%04x val=%02x\n", port, val); + + switch (sb->pos_regs[2] & 0xc4) { + case 4: + addr = 0x220; + break; + case 0x44: + addr = 0x240; + break; + case 0x84: + addr = 0x260; + break; + case 0xc4: + addr = 0x280; + break; + case 0: + default: + addr = 0; + break; + } + + if (addr) { + io_removehandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_removehandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&sb->dsp, 0); + mpu401_change_addr(sb->mpu, 0); + gameport_remap(sb->gameport, 0); + + sb->pos_regs[port & 7] = val; + + if (sb->pos_regs[2] & 1) { + switch (sb->pos_regs[2] & 0xc4) { + case 4: + addr = 0x220; + break; + case 0x44: + addr = 0x240; + break; + case 0x84: + addr = 0x260; + break; + case 0xc4: + addr = 0x280; + break; + case 0: + default: + addr = 0; + break; + } + switch (sb->pos_regs[2] & 0x18) { + case 8: + mpu401_addr = 0x330; + break; + case 0x18: + mpu401_addr = 0x300; + break; + case 0: + default: + mpu401_addr = 0; + break; + } + + if (addr) { + io_sethandler(addr, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(addr + 8, 0x0002, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, + &sb->opl); + io_sethandler(0x0388, 0x0004, + opl3_read, NULL, NULL, + opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); + } + + /* DSP I/O handler is activated in sb_dsp_setaddr */ + sb_dsp_setaddr(&sb->dsp, addr); + mpu401_change_addr(sb->mpu, mpu401_addr); + gameport_remap(sb->gameport, (sb->pos_regs[2] & 0x20) ? 0x200 : 0); + } + + switch (sb->pos_regs[4] & 0x60) { + case 0x20: + sb_dsp_setirq(&sb->dsp, 5); + break; + case 0x40: + sb_dsp_setirq(&sb->dsp, 7); + break; + case 0x60: + sb_dsp_setirq(&sb->dsp, 10); + break; + } + + low_dma = sb->pos_regs[3] & 3; + high_dma = (sb->pos_regs[3] >> 4) & 7; + if (!high_dma) + high_dma = low_dma; + + sb_dsp_setdma8(&sb->dsp, low_dma); + sb_dsp_setdma16(&sb->dsp, high_dma); +} + static void sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -1785,6 +1930,41 @@ sb_16_init(const device_t *info) return sb; } +static void * +sb_16_reply_mca_init(const device_t *info) +{ + sb_t *sb = malloc(sizeof(sb_t)); + memset(sb, 0x00, sizeof(sb_t)); + + sb->opl_enabled = 1; + opl3_init(&sb->opl); + + sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_ct1745_mixer_reset(sb); + + sb->mixer_enabled = 1; + sb->mixer_sb16.output_filter = 1; + sound_add_handler(sb_get_buffer_sb16_awe32, sb); + sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + + sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(sb->mpu, 0, sizeof(mpu_t)); + mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&sb->dsp, sb->mpu); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + + sb->gameport = gameport_add(&gameport_device); + + /* I/O handlers activated in sb_pro_mcv_write */ + mca_add(sb_16_reply_mca_read, sb_16_reply_mca_write, sb_mcv_feedb, NULL, sb); + sb->pos_regs[0] = 0x38; + sb->pos_regs[1] = 0x51; + + return sb; +} + static void * sb_16_pnp_init(const device_t *info) { @@ -3371,6 +3551,20 @@ const device_t sb_16_device = { .config = sb_16_config }; +const device_t sb_16_reply_mca_device = { + .name = "Sound Blaster 16 Reply MCA", + .internal_name = "sb16_reply_mca", + .flags = DEVICE_MCA, + .local = 0, + .init = sb_16_reply_mca_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + const device_t sb_16_pnp_device = { .name = "Sound Blaster 16 PnP", .internal_name = "sb16_pnp", diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 3cbb223f3..c87f45e2f 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -326,14 +326,14 @@ void sb_dsp_speed_changed(sb_dsp_t *dsp) { if (dsp->sb_timeo < 256) - dsp->sblatcho = (256.0 - (double) dsp->sb_timeo); + dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); else - dsp->sblatcho = ((1000000.0 / ((double) dsp->sb_timeo - 256.0))); + dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timeo - 256))); if (dsp->sb_timei < 256) - dsp->sblatchi = (256.0 - (double) dsp->sb_timei); + dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); else - dsp->sblatchi = ((1000000.0 / ((double) dsp->sb_timei - 256.0))); + dsp->sblatchi = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_timei - 256))); } void @@ -359,7 +359,7 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_enable = 0; dsp->sb_8_output = 1; if (!timer_is_enabled(&dsp->output_timer)) - timer_on_auto(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); dsp->sbleftright = dsp->sbleftright_default; dsp->sbdacpos = 0; } else { @@ -372,7 +372,7 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_enable = 0; dsp->sb_16_output = 1; if (!timer_is_enabled(&dsp->output_timer)) - timer_on_auto(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); } } @@ -389,7 +389,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_enable = 0; dsp->sb_8_output = 0; if (!timer_is_enabled(&dsp->input_timer)) - timer_on_auto(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); } else { dsp->sb_16_length = dsp->sb_16_origlength = len; dsp->sb_16_format = format; @@ -400,7 +400,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_enable = 0; dsp->sb_16_output = 0; if (!timer_is_enabled(&dsp->input_timer)) - timer_on_auto(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); } memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); @@ -508,10 +508,10 @@ sb_exec_command(sb_dsp_t *dsp) mode does not imply such samplerate. Position is increased in sb_poll_i(). */ if (!timer_is_enabled(&dsp->input_timer)) { dsp->sb_timei = 256 - 22; - dsp->sblatchi = 22.0; + dsp->sblatchi = TIMER_USEC * 22; temp = 1000000 / 22; dsp->sb_freq = temp; - timer_on_auto(&dsp->input_timer, dsp->sblatchi); + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); } break; case 0x24: /* 8-bit single cycle DMA input */ @@ -561,7 +561,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x40: /* Set time constant */ dsp->sb_timei = dsp->sb_timeo = dsp->sb_data[0]; - dsp->sblatcho = dsp->sblatchi = (256.0 - (double) dsp->sb_data[0]); + dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; sb_dsp_log("Sample rate - %ihz (%i)\n", temp, dsp->sblatcho); @@ -572,8 +572,8 @@ sb_exec_command(sb_dsp_t *dsp) case 0x41: /* Set output sampling rate */ case 0x42: /* Set input sampling rate */ if (dsp->sb_type >= SB16) { - dsp->sblatcho = ((1000000.0 / (double) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); - sb_dsp_log("Sample rate - %ihz (%lf)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); + dsp->sblatcho = (uint64_t) (TIMER_USEC * (1000000.0f / (float) (dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); + sb_dsp_log("Sample rate - %ihz (%i)\n", dsp->sb_data[1] + (dsp->sb_data[0] << 8), dsp->sblatcho); temp = dsp->sb_freq; dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256LL + dsp->sb_freq; @@ -631,7 +631,7 @@ sb_exec_command(sb_dsp_t *dsp) case 0x80: /* Pause DAC */ dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); if (!timer_is_enabled(&dsp->output_timer)) - timer_on_auto(&dsp->output_timer, dsp->sblatcho); + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); break; case 0x90: /* High speed 8-bit autoinit DMA output */ if (dsp->sb_type >= SB2) @@ -1200,7 +1200,7 @@ pollsb(void *p) int tempi, ref; int data[2]; - timer_on_auto(&dsp->output_timer, dsp->sblatcho); + timer_advance_u64(&dsp->output_timer, dsp->sblatcho); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { sb_dsp_update(dsp); @@ -1457,7 +1457,7 @@ sb_poll_i(void *p) sb_dsp_t *dsp = (sb_dsp_t *) p; int processed = 0; - timer_on_auto(&dsp->input_timer, dsp->sblatchi); + timer_advance_u64(&dsp->input_timer, dsp->sblatchi); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { switch (dsp->sb_8_format) { diff --git a/src/sound/sound.c b/src/sound/sound.c index ec9e51f91..604dac38f 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -140,6 +140,7 @@ static const SOUND_CARD sound_cards[] = { { &ncr_business_audio_device }, { &sb_mcv_device }, { &sb_pro_mcv_device }, + { &sb_16_reply_mca_device }, { &cmi8338_device }, { &cmi8738_device }, { &es1371_device }, diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 59b9f2247..3ca44746c 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -77,6 +77,64 @@ static video_timings_t timing_paradise_wd90c = {VIDEO_ISA, 3, 3, 6, 5, 5, 1 void paradise_remap(paradise_t *paradise); +uint8_t paradise_in(uint16_t addr, void *p) +{ + paradise_t *paradise = (paradise_t *)p; + svga_t *svga = ¶dise->svga; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) + { + case 0x3c5: + if (svga->seqaddr > 7) + { + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) + return 0xff; + if (svga->seqaddr > 0x12) + return 0xff; + return svga->seqregs[svga->seqaddr & 0x1f]; + } + break; + + case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: + if (paradise->type == WD90C30) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); + + case 0x3cf: + if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { + if (svga->gdcreg[0x0f] & 0x10) + return 0xff; + } + switch (svga->gdcaddr) { + case 0x0b: + if (paradise->type == WD90C30) { + if (paradise->vram_mask == ((512 << 10) - 1)) { + svga->gdcreg[0x0b] |= 0xc0; + svga->gdcreg[0x0b] &= ~0x40; + } + } + return svga->gdcreg[0x0b]; + + case 0x0f: + return (svga->gdcreg[0x0f] & 0x17) | 0x80; + } + break; + + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return 0xff; + if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) + return 0xff; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); +} + void paradise_out(uint16_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; @@ -187,69 +245,21 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) } } break; + + case 0x46e8: + io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_disable(¶dise->svga.mapping); + if (val & 8) + { + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_enable(¶dise->svga.mapping); + } + break; } svga_out(addr, val, svga); } -uint8_t paradise_in(uint16_t addr, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c5: - if (svga->seqaddr > 7) - { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return 0xff; - if (svga->seqaddr > 0x12) - return 0xff; - return svga->seqregs[svga->seqaddr & 0x1f]; - } - break; - - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (paradise->type == WD90C30) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); - return svga_in(addr, svga); - - case 0x3cf: - if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { - if (svga->gdcreg[0x0f] & 0x10) - return 0xff; - } - switch (svga->gdcaddr) { - case 0x0b: - if (paradise->type == WD90C30) { - if (paradise->vram_mask == ((512 << 10) - 1)) { - svga->gdcreg[0x0b] |= 0xc0; - svga->gdcreg[0x0b] &= ~0x40; - } - } - return svga->gdcreg[0x0b]; - - case 0x0f: - return (svga->gdcreg[0x0f] & 0x17) | 0x80; - } - break; - - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return 0xff; - if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - void paradise_remap(paradise_t *paradise) { svga_t *svga = ¶dise->svga; @@ -579,6 +589,7 @@ void *paradise_init(const device_t *info, uint32_t memsize) case WD90C11: svga->crtc[0x36] = '1'; svga->crtc[0x37] = '1'; + io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); break; case WD90C30: svga->crtc[0x36] = '3'; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index a4fd83a0e..bac0242e1 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -483,7 +483,8 @@ tgui_out(uint16_t addr, uint8_t val, void *p) break; case 0x37: - i2c_gpio_set(tgui->i2c, (val & 0x02) || !(val & 0x04), (val & 0x01) || !(val & 0x08)); + if (tgui->type >= TGUI_9440) + i2c_gpio_set(tgui->i2c, (val & 0x02) || !(val & 0x04), (val & 0x01) || !(val & 0x08)); break; case 0x40: case 0x41: case 0x42: case 0x43: @@ -609,7 +610,7 @@ tgui_in(uint16_t addr, void *p) return svga->crtcreg; case 0x3D5: temp = svga->crtc[svga->crtcreg]; - if (svga->crtcreg == 0x37) { + if ((svga->crtcreg == 0x37) && (tgui->type >= TGUI_9440)) { if (!(temp & 0x04)) { temp &= ~0x02; if (i2c_gpio_get_scl(tgui->i2c)) @@ -3150,14 +3151,16 @@ static int tgui96xx_available(void) void tgui_close(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; - svga_close(&tgui->svga); + svga_close(&tgui->svga); + if (tgui->type >= TGUI_9440) { ddc_close(tgui->ddc); i2c_gpio_close(tgui->i2c); + }; - free(tgui); + free(tgui); } void tgui_speed_changed(void *p) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index b4b802bbb..8c29a24a1 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -31,6 +31,9 @@ ifeq ($(DEV_BUILD), y) ifndef DEBUG DEBUG := y endif + ifndef GDBSTUB + GDBSTUB := n + endif ifndef DEV_BRANCH DEV_BRANCH := y endif @@ -92,6 +95,9 @@ else ifndef DEBUG DEBUG := n endif + ifndef GDBSTUB + GDBSTUB := n + endif ifndef DEV_BRANCH DEV_BRANCH := n endif @@ -506,6 +512,10 @@ OPTS += -DUSE_OLIVETTI DEVBROBJ += olivetti_eva.o endif +ifeq ($(GDBSTUB), y) +OPTS += -DUSE_GDBSTUB +DEVBROBJ += gdbstub.o +endif endif @@ -525,7 +535,7 @@ CXXFLAGS := $(CFLAGS) # Create the (final) list of objects to build. # ######################################################################### MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \ - nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \ + nmi.o pic.o pit.o pit_fast.o port_6x.o port_92.o ppi.o pci.o mca.o fifo8.o \ usb.o device.o nvr.o nvr_at.o nvr_ps2.o machine_status.o \ $(VNCOBJ) @@ -595,7 +605,7 @@ DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hw phoenix_486_jumper.o endif -SIOOBJ := sio_acc3221.o \ +SIOOBJ := sio_acc3221.o sio_ali5123.o \ sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ sio_fdc37c67x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ sio_it8661f.o \ diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 81b2e290a..5e23a9d71 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -80,7 +80,7 @@ BEGIN MENUITEM "Monitor VGA &invertido", IDM_VID_INVERT POPUP "&Tipo de tela VGA" BEGIN - MENUITEM "&Cor RGB", IDM_VID_GRAY_RGB + MENUITEM "&Cores RGB", IDM_VID_GRAY_RGB MENUITEM "Tons de cinza &RGB", IDM_VID_GRAY_MONO MENUITEM "Monitor &âmbar", IDM_VID_GRAY_AMBER MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN @@ -267,15 +267,15 @@ END #define STR_MB "MB" #define STR_MEMORY "Memória:" #define STR_TIME_SYNC "Sincronização da hora" -#define STR_DISABLED "Desativada" -#define STR_ENABLED_LOCAL "Ativada (hora local)" -#define STR_ENABLED_UTC "Ativada (UTC)" +#define STR_DISABLED "Desativar" +#define STR_ENABLED_LOCAL "Ativar (hora local)" +#define STR_ENABLED_UTC "Ativar (UTC)" #define STR_DYNAREC "Recompilador dinâmico" #define STR_VIDEO "Vídeo:" #define STR_VOODOO "3DFX Voodoo" -#define STR_IBM8514 "IBM 8514/a Graphics" -#define STR_XGA "XGA Graphics" +#define STR_IBM8514 "Gráficos IBM 8514/a" +#define STR_XGA "Gráficos XGA" #define STR_MOUSE "Mouse:" #define STR_JOYSTICK "Joystick:" @@ -340,7 +340,7 @@ END #define STR_SIZE_MB "Tamanho (MB):" #define STR_TYPE "Tipo:" #define STR_IMG_FORMAT "Formato:" -#define STR_BLOCK_SIZE "Bloco:" +#define STR_BLOCK_SIZE "Blocos:" #define STR_FLOPPY_DRIVES "Unidades de disquete:" #define STR_TURBO "Turbo" @@ -376,7 +376,7 @@ BEGIN 2048 "86Box" IDS_2049 "Erro" IDS_2050 "Erro fatal" - IDS_2051 " - PAUSED" + IDS_2051 " - PAUSADO" IDS_2052 "Use Ctrl+Alt+PgDn para retornar ao modo janela" IDS_2053 "Velocidade" IDS_2054 "ZIP %03i %i (%s): %ls" @@ -435,7 +435,7 @@ BEGIN IDS_2099 "Joystick padrão de 8 botões" IDS_2100 "CH Flightstick Pro" IDS_2101 "Microsoft SideWinder Pad" - IDS_2102 "Thrustmaster Flight Control System" + IDS_2102 "Sistema de Controle de Voo Thrustmaster" IDS_2103 "Nada" IDS_2104 "Não foi possível carregar os aceleradores do teclado." IDS_2105 "Não foi possível registrar a entrada bruta." diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 804762af6..01bd58d0d 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -25,6 +25,8 @@ #include <86box/config.h> #include <86box/device.h> #include <86box/plat.h> +#include <86box/mem.h> +#include <86box/rom.h> #include <86box/midi_rtmidi.h> #include <86box/ui.h> #include <86box/win.h> @@ -33,7 +35,8 @@ static device_context_t config_device; -static uint8_t deviceconfig_changed = 0; +static uint8_t deviceconfig_changed = 0; +static int combo_to_struct[256]; #if defined(__amd64__) || defined(__aarch64__) @@ -46,14 +49,16 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) HWND h; int val_int, id, c, d; + int p, q; #ifdef USE_RTMIDI int num; #endif int changed, cid; const device_config_t *config; const device_config_selection_t *selection; + const device_config_bios_t *bios; char s[512], file_filter[512]; - char *str; + char *str, *val_str; wchar_t ws[512], *wstr; LPTSTR lptsTemp; @@ -65,9 +70,11 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) config = config_device.dev->config; lptsTemp = (LPTSTR) malloc(512); + memset(combo_to_struct, 0, 256 * sizeof(int)); while (config->type != -1) { selection = config->selection; + bios = config->bios; h = GetDlgItem(hdlg, id); switch (config->type) { @@ -94,6 +101,30 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c++; } + id += 2; + break; + case CONFIG_BIOS: + val_str = config_get_string((char *) config_device.name, + (char *) config->name, (char *) config->default_string); + + c = 0; + q = 0; + while (bios && bios->name && bios->name[0]) { + mbstowcs(lptsTemp, bios->name, strlen(bios->name) + 1); + p = 0; + for (d = 0; d < bios->files_no; d++) + p += !!rom_present((char *) bios->files[d]); + if (p == bios->files_no) { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + if (!strcmp(val_str, bios->internal_name)) + SendMessage(h, CB_SETCURSEL, c, 0); + combo_to_struct[c] = q; + c++; + } + q++; + bios++; + } + id += 2; break; #ifdef USE_RTMIDI @@ -188,6 +219,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (cid == IDOK) { id = IDC_CONFIG_BASE; config = config_device.dev->config; + bios = config->bios; changed = 0; char s[512]; @@ -217,6 +249,20 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (val_int != selection->value) changed = 1; + id += 2; + break; + case CONFIG_BIOS: + val_str = config_get_string((char *) config_device.name, + (char *) config->name, (char *) config->default_string); + + c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + for (; c > 0; c--) + bios++; + + if (strcmp(val_str, bios->internal_name)) + changed = 1; + id += 2; break; case CONFIG_MIDI_OUT: @@ -327,6 +373,14 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) selection++; config_set_int((char *) config_device.name, (char *) config->name, selection->value); + id += 2; + break; + case CONFIG_BIOS: + c = combo_to_struct[SendMessage(h, CB_GETCURSEL, 0, 0)]; + for (; c > 0; c--) + bios++; + config_set_string((char *) config_device.name, (char *) config->name, (char *) bios->internal_name); + id += 2; break; case CONFIG_MIDI_OUT: @@ -396,6 +450,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case CONFIG_SELECTION: case CONFIG_HEX16: case CONFIG_HEX20: + case CONFIG_BIOS: case CONFIG_MIDI_OUT: case CONFIG_MIDI_IN: case CONFIG_SPINNER: