diff --git a/.editorconfig b/.editorconfig index 3b8291ef7..047c9d67c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,3 +20,15 @@ tab_width = 8 [*.manifest] indent_style = space indent_size = 2 + +[*.yml] +indent_style = space +indent_size = 2 + +[**/CMakeLists.txt] +indent_style = space +indent_size = 4 + +[*.cmake] +indent_style = space +indent_size = 4 diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 08d4522ff..aa0368735 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -84,7 +84,7 @@ jobs: - uses: actions/upload-artifact@v2 with: name: '86Box-${{ matrix.build.name }}-MSYS2-${{ matrix.environment.msystem }}-${{ github.sha }}' - path: build/artifacts/bin/** + path: build/artifacts/** vs2019: name: VS2019 ${{ matrix.build.name }} ${{ matrix.target-arch }} build (${{ matrix.toolset }}) @@ -130,7 +130,7 @@ jobs: - uses: actions/upload-artifact@v2 with: name: '86Box-${{ matrix.build.name }}-VS2019-${{ matrix.target-arch }}-${{ matrix.toolset }}-${{ github.sha }}' - path: build/artifacts/bin/** + path: build/artifacts/** linux: name: "Linux GCC 11" diff --git a/.gitignore b/.gitignore index eb01732fb..fe3a35b37 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ CMakeFiles Makefile *.a -*.cmake /src/*.exe /src/86Box /src/include/86box/version.h @@ -22,7 +21,6 @@ Makefile /src/*.log /src/*.dmp /src/nvr/ -/src/printer/ /src/roms/ /src/screenshots/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 127bae80b..b1f56e7da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # cmake_minimum_required(VERSION 3.15) @@ -18,106 +18,146 @@ cmake_minimum_required(VERSION 3.15) cmake_policy(SET CMP0091 NEW) cmake_policy(SET CMP0079 NEW) -if(VCPKG_TOOLCHAIN AND VCPKG_TARGET_TRIPLET MATCHES "static") - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +project(86Box + VERSION 3.2 + DESCRIPTION "Emulator of x86-based systems" + HOMEPAGE_URL "https://86box.net" + LANGUAGES C CXX) + +include(CPack) +include(CMakeDependentOption) + +# Basic build options +if(WIN32) + if(VCPKG_TOOLCHAIN) + # For vcpkg builds we have to respect the linking method used by the + # specified triplet. + set(NO_STATIC_OPTION ON) + if(VCPKG_TARGET_TRIPLET MATCHES "-windows-static$") + # `-static` triplet, use static linking + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + set(STATIC_BUILD ON) + elseif(VCPKG_TARGET_TRIPLET MATCHES "-windows-static-md$") + # `-static-md` triplet, use static linking with dynamic CRT + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + set(STATIC_BUILD ON) + elseif() + # Regular triplet, use dynamic linking + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + set(STATIC_BUILD OFF) + endif() + endif() + + # Prefer static builds on Windows + set(PREFER_STATIC ON) + + # Default value for the `WIN32` target property, which specifies whether + # to build the application for the Windows GUI or console subsystem + option(CMAKE_WIN32_EXECUTABLE "Build a Windows GUI executable" ON) +else() + # Prefer dynamic builds everywhere else + set(PREFER_STATIC OFF) endif() -project(86Box - VERSION 3.1 - DESCRIPTION "Emulator of x86-based systems" - HOMEPAGE_URL "https://86box.net" - LANGUAGES C CXX) +if(APPLE) + option(CMAKE_MACOSX_BUNDLE "Build a macOS bundle (.app)" ON) +endif() + +if(NOT NO_STATIC_OPTION) + if(PREFER_STATIC) + option(STATIC_BUILD "Static build" ON) + else() + option(STATIC_BUILD "Static build" OFF) + endif() +endif() # Detect the target architecture by trying to compile `src/arch_detect.c` try_compile(RESULT_VAR ${CMAKE_BINARY_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/src/arch_detect.c" OUTPUT_VARIABLE ARCH) string(REGEX MATCH "ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}") string(REPLACE "ARCH " "" ARCH "${ARCH}") if (NOT ARCH) - set(ARCH unknown) + set(ARCH unknown) endif() -include(CPack) - -include(CMakeDependentOption) - add_compile_definitions(CMAKE) add_compile_definitions("$<$:DEBUG>") if(WIN32) - # Disables *_s function warnings - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + # Disables *_s function warnings + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) - # Disables POSIX name warnings - add_compile_definitions(_CRT_NONSTDC_NO_WARNINGS) + # Disables POSIX name warnings + add_compile_definitions(_CRT_NONSTDC_NO_WARNINGS) - # Disables WinSock deprecation warnings - add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS) + # Disables WinSock deprecation warnings + add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS) endif() set(CMAKE_CXX_STANDARD 11) -option(RELEASE "Release build" OFF) -option(USB "USB support" OFF) -option(DYNAREC "Dynamic recompiler" ON) -option(FLUIDSYNTH "FluidSynth" ON) -option(MUNT "MUNT" ON) -option(VRAMDUMP "Video RAM dumping" OFF) -option(DINPUT "DirectInput" OFF) -option(DISCORD "Discord integration" ON) +# Optional features +# +# Option Description Def. +# ------ ----------- ---- +option(RELEASE "Release build" OFF) +option(USB "USB support" OFF) +option(DYNAREC "Dynamic recompiler" ON) +option(FLUIDSYNTH "FluidSynth" ON) +option(MUNT "MUNT" ON) +option(VRAMDUMP "Video RAM dumping" OFF) +option(DINPUT "DirectInput" OFF) +option(CPPTHREADS "C++11 threads" ON) +option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) +option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) +option(DEV_BRANCH "Development branch" OFF) -option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) +# Development branch features +# +# Option Description Def. Condition Otherwise +# ------ ----------- ---- --------- --------- +cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) +cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF) +cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) +cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF) +cmake_dependent_option(NO_SIO "Machines without emulated Super I/O chips" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) +cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) +cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" OFF "DEV_BRANCH" OFF) +cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) +cmake_dependent_option(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) +cmake_dependent_option(VNC "VNC renderer" OFF "DEV_BRANCH" OFF) +cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) -option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF) - -option(DEV_BRANCH "Development branch" OFF) -CMAKE_DEPENDENT_OPTION(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(HEDAKA "Hedaka HED-919" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(I450KX "Intel i450KX" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(NO_SIO "Machines without emulated Super I/O chips" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(OPENGL "OpenGL 3.3 Core renderer" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(PAS16 "Pro Audio Spectrum 16" OFF "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(PS2M70T4 "IBM PS/2 model 70 (type 4)" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(S3TRIO3D2X "S3 Trio3D/2X" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(M154X "ALi ALADDiN IV" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(M6117 "ALi M6117" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(VNC "VNC renderer" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) -CMAKE_DEPENDENT_OPTION(VECT486VL "HP Vectra 486VL" ON "DEV_BRANCH" OFF) +# Determine the build type +set(RELEASE_BUILD OFF) +set(BETA_BUILD OFF) +set(ALPHA_BUILD OFF) string(TOLOWER "${BUILD_TYPE}" BUILD_TYPE_LOWER) if(BUILD_TYPE_LOWER STREQUAL "release") - add_compile_definitions(RELEASE_BUILD) + # Release build + set(RELEASE_BUILD ON) + add_compile_definitions(RELEASE_BUILD) elseif(BUILD_TYPE_LOWER STREQUAL "beta") - add_compile_definitions(BETA_BUILD) + # Beta build + set(BETA_BUILD ON) + add_compile_definitions(BETA_BUILD) elseif(BUILD_TYPE_LOWER STREQUAL "alpha") - add_compile_definitions(ALPHA_BUILD) + # Alpha build + set(ALPHA_BUILD ON) + add_compile_definitions(ALPHA_BUILD) endif() -# HACK: Avoid a MSVC2019 compiler bug on ARM64 Debug builds -if(MSVC_TOOLSET_VERSION GREATER_EQUAL 142 AND ARCH STREQUAL "arm64") - # Define a cache option in case somebody wants to disable this workaround - set(AVOID_LNK1322 ON CACHE BOOL "Prevent LNK1322 on MSVC2019 ARM64 debug builds") - - if(AVOID_LNK1322) - message(STATUS "Working around LNK1322 (86Box#1268)") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Gy") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Gy") - endif() +# Variables introduced by richardg867 for versioning stuff +if(NOT CMAKE_PROJECT_VERSION_PATCH) + set(CMAKE_PROJECT_VERSION_PATCH 0) endif() - -# HACK: MinGW and macOS <10.15 does not have `timespec_get` -include(CheckSymbolExists) -check_symbol_exists(timespec_get time.h HAS_TIMESPEC_GET) -if(HAS_TIMESPEC_GET) - add_compile_definitions(HAS_TIMESPEC_GET) +if(NOT EMU_BUILD_NUM) + set(EMU_BUILD_NUM 0) +endif() +if(NOT EMU_COPYRIGHT_YEAR) + set(EMU_COPYRIGHT_YEAR 2021) endif() add_subdirectory(src) diff --git a/README.md b/README.md index cfadfe55f..e270bb2f4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -86Box +86Box [![Build Status](http://ci.86box.net/job/86Box/badge/icon)](http://ci.86box.net/job/86Box) ===== **86Box** is a low level x86 emulator that runs older operating systems and software designed for IBM PC systems and compatibles from 1981 through fairly recent system designs based on the PCI bus. @@ -28,15 +28,6 @@ It is also recommended to use a manager application with 86Box for easier handli However, it is also possible to use 86Box on its own with the `--vmpath`/`-P` command line option. -Downloads ---------- -The latest stable version of 86Box is **v3.0**, which was released on December 1, 2021, and is available from our [GitHub repository](https://github.com/86Box/86Box/releases/tag/v3.0). - -### Automatic builds -We also offer automatic builds, which are built from the latest source code and contain the latest bugfixes and improvements, but may not be as stable and/or optimized as stable builds. - -[![Build Status](http://ci.86box.net/job/86Box/badge/icon)](http://ci.86box.net/job/86Box) - Getting started --------------- See [our documentation](https://86box.readthedocs.io/en/latest/index.html) for an overview of the emulator's features and user interface. diff --git a/cmake/flags-gcc-aarch64.cmake b/cmake/flags-gcc-aarch64.cmake new file mode 100644 index 000000000..146a869fc --- /dev/null +++ b/cmake/flags-gcc-aarch64.cmake @@ -0,0 +1,20 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file defining GCC compiler flags +# for AArch64 (ARM64) targets. +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +string(APPEND CMAKE_C_FLAGS_INIT " -march=armv8-a -mfloat-abi=hard") +string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv8-a -mfloat-abi=hard") + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) \ No newline at end of file diff --git a/cmake/flags-gcc-armv7.cmake b/cmake/flags-gcc-armv7.cmake new file mode 100644 index 000000000..bd49fdfce --- /dev/null +++ b/cmake/flags-gcc-armv7.cmake @@ -0,0 +1,20 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file defining GCC compiler flags +# for ARMv7 targets. +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard ${CMAKE_C_FLAGS_INIT}") +string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a -mfloat-abi=hard ${CMAKE_CXX_FLAGS_INIT}") + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) \ No newline at end of file diff --git a/cmake/flags-gcc-i686.cmake b/cmake/flags-gcc-i686.cmake new file mode 100644 index 000000000..6d1afd6a9 --- /dev/null +++ b/cmake/flags-gcc-i686.cmake @@ -0,0 +1,20 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file defining GCC compiler flags +# for 32-bit x86 targets. +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +string(APPEND CMAKE_C_FLAGS_INIT " -m32 -march=i686 -msse2 -mfpmath=sse ${CMAKE_C_FLAGS_INIT}") +string(APPEND CMAKE_CXX_FLAGS_INIT " -m32 -march=i686 -msse2 -mfpmath=sse ${CMAKE_CXX_FLAGS_INIT}") + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/cmake/flags-gcc-x86_64.cmake b/cmake/flags-gcc-x86_64.cmake new file mode 100644 index 000000000..e373a1fec --- /dev/null +++ b/cmake/flags-gcc-x86_64.cmake @@ -0,0 +1,20 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file defining GCC compiler flags +# for 64-bit x86 targets. +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +string(APPEND CMAKE_C_FLAGS_INIT " -m64 -march=x86-64 -msse2 -mfpmath=sse ${CMAKE_C_FLAGS_INIT}") +string(APPEND CMAKE_CXX_FLAGS_INIT " -m64 -march=x86-64 -msse2 -mfpmath=sse ${CMAKE_CXX_FLAGS_INIT}") + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/cmake/flags-gcc.cmake b/cmake/flags-gcc.cmake new file mode 100644 index 000000000..266b70d44 --- /dev/null +++ b/cmake/flags-gcc.cmake @@ -0,0 +1,35 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file defining GCC compiler flags. +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +# Define our flags +string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -mstackrealign -Wall -fno-strict-aliasing") +string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -mstackrealign -Wall -fno-strict-aliasing") +string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3") +string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3") +string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og") +string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -ggdb -Og") +string(APPEND CMAKE_C_FLAGS_OPTIMIZED_INIT " -march=native -mtune=native -O3 -ffp-contract=fast -flto") +string(APPEND CMAKE_CXX_FLAGS_OPTIMIZED_INIT " -march=native -mtune=native -O3 -ffp-contract=fast -flto") + +# Set up the variables +foreach(LANG C;CXX) + set(CMAKE_${LANG}_FLAGS "$ENV{${LANG}FLAGS} ${CMAKE_${LANG}_FLAGS_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during all build types.") + mark_as_advanced(CMAKE_${LANG}_FLAGS) + + foreach(CONFIG RELEASE;DEBUG;OPTIMIZED) + set(CMAKE_${LANG}_FLAGS_${CONFIG} "${CMAKE_${LANG}_FLAGS_${CONFIG}_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during ${CONFIG} builds.") + mark_as_advanced(CMAKE_${LANG}_FLAGS_${CONFIG}) + endforeach() +endforeach() \ No newline at end of file diff --git a/cmake/llvm-win32-aarch64.cmake b/cmake/llvm-win32-aarch64.cmake new file mode 100644 index 000000000..4aacb248f --- /dev/null +++ b/cmake/llvm-win32-aarch64.cmake @@ -0,0 +1,30 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file for Clang on Windows builds (ARM64 target). +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-aarch64.cmake) + +# Use the GCC-compatible Clang executables in order to use our flags +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +# `llvm-rc` is barely usable as of LLVM 13, using MS' rc.exe for now +set(CMAKE_RC_COMPILER rc) + +set(CMAKE_C_COMPILER_TARGET aarch64-pc-windows-msvc) +set(CMAKE_CXX_COMPILER_TARGET aarch64-pc-windows-msvc) + +set(CMAKE_SYSTEM_PROCESSOR ARM64) + +# TODO: set the vcpkg target triplet perhaps? \ No newline at end of file diff --git a/cmake/llvm-win32-i686.cmake b/cmake/llvm-win32-i686.cmake new file mode 100644 index 000000000..8221f8bc2 --- /dev/null +++ b/cmake/llvm-win32-i686.cmake @@ -0,0 +1,30 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file for Clang on Windows builds (x86 target). +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-i686.cmake) + +# Use the GCC-compatible Clang executables in order to use our flags +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +# `llvm-rc` is barely usable as of LLVM 13, using MS' rc.exe for now +set(CMAKE_RC_COMPILER rc) + +set(CMAKE_C_COMPILER_TARGET i686-pc-windows-msvc) +set(CMAKE_CXX_COMPILER_TARGET i686-pc-windows-msvc) + +set(CMAKE_SYSTEM_PROCESSOR X86) + +# TODO: set the vcpkg target triplet perhaps? \ No newline at end of file diff --git a/cmake/llvm-win32-x86_64.cmake b/cmake/llvm-win32-x86_64.cmake new file mode 100644 index 000000000..7caeb7836 --- /dev/null +++ b/cmake/llvm-win32-x86_64.cmake @@ -0,0 +1,30 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake toolchain file for Clang on Windows builds (x64/AMD64 target). +# +# Authors: David Hrdlička, +# +# Copyright 2021 David Hrdlička. +# + +include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-x86_64.cmake) + +# Use the GCC-compatible Clang executables in order to use our flags +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +# `llvm-rc` is barely usable as of LLVM 13, using MS' rc.exe for now +set(CMAKE_RC_COMPILER rc) + +set(CMAKE_C_COMPILER_TARGET x86_64-pc-windows-msvc) +set(CMAKE_CXX_COMPILER_TARGET x86_64-pc-windows-msvc) + +set(CMAKE_SYSTEM_PROCESSOR AMD64) + +# TODO: set the vcpkg target triplet perhaps? \ No newline at end of file diff --git a/src/86box.c b/src/86box.c index 045b3bd0a..393ce90af 100644 --- a/src/86box.c +++ b/src/86box.c @@ -28,6 +28,8 @@ #include #include #include +#include + #ifndef _WIN32 #include #endif @@ -90,14 +92,13 @@ #include <86box/video.h> #include <86box/ui.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/version.h> /* Stuff that used to be globally declared in plat.h but is now extern there and declared here instead. */ int dopause; /* system is paused */ -int doresize; /* screen resize requested */ +atomic_flag doresize; /* screen resize requested */ volatile int is_quit; /* system exit requested */ uint64_t timer_freq; char emu_version[200]; /* version ID string */ @@ -1041,7 +1042,7 @@ pc_reset_hard_init(void) /* Reset the CPU module. */ resetx86(); dma_reset(); - pic_reset(); + pci_pic_reset(); cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; atfullspeed = 0; @@ -1286,9 +1287,7 @@ set_screen_size(int x, int y) /* If the resolution has changed, let the main thread handle it. */ if ((owsx != scrnsz_x) || (owsy != scrnsz_y)) - doresize = 1; - else - doresize = 0; + atomic_flag_clear(&doresize); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e815c5e9..c3ed435d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,138 +1,90 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, -# dob205 +# Authors: David Hrdlička, +# dob205 # -# Copyright 2020,2021 David Hrdlička. -# Copyright 2021 dob205. +# Copyright 2020,2021 David Hrdlička. +# Copyright 2021 dob205. # -# Prepare the macOS app bundle icon depending on the release channel -set(APP_ICON_MACOSX) -if (APPLE) - if(RELEASE_BUILD) - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/release/86Box.icns) - elseif(BETA_BUILD) - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/beta/86Box.icns) - elseif(ALPHA_BUILD) - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/dev/86Box.icns) - else() - set(APP_ICON_MACOSX ${CMAKE_CURRENT_SOURCE_DIR}/mac/icons/branch/86Box.icns) - endif() - -set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES - MACOSX_PACKAGE_LOCATION "Resources") -endif() - # WIN32 marks us as a GUI app on Windows -# MACOSX_BUNDLE prepares a macOS application bundle including with the app icon add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c - dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c - device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX}) + dma.c ddma.c nmi.c pic.c pit.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) -if(APPLE) - target_link_libraries(86Box "-framework AppKit") +if(CPPTHREADS) + target_sources(86Box PRIVATE thread.cpp) endif() if(NEW_DYNAREC) - add_compile_definitions(USE_NEW_DYNAREC) + add_compile_definitions(USE_NEW_DYNAREC) endif() if(RELEASE) - add_compile_definitions(RELEASE_BUILD) + add_compile_definitions(RELEASE_BUILD) endif() if(DYNAREC) - add_compile_definitions(USE_DYNAREC) + add_compile_definitions(USE_DYNAREC) endif() if(VRAMDUMP) - add_compile_definitions(ENABLE_VRAM_DUMP) + add_compile_definitions(ENABLE_VRAM_DUMP) endif() if(DEV_BRANCH) - add_compile_definitions(DEV_BRANCH) + add_compile_definitions(DEV_BRANCH) endif() if(VNC) - add_compile_definitions(USE_VNC) - add_library(vnc OBJECT vnc.c vnc_keymap.c) - target_link_libraries(86Box vnc vncserver) - if (WIN32) - target_link_libraries(86Box ws2_32) - endif() + add_compile_definitions(USE_VNC) + add_library(vnc OBJECT vnc.c vnc_keymap.c) + target_link_libraries(86Box vnc vncserver) + if (WIN32) + target_link_libraries(86Box ws2_32) + endif() endif() target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd - net print scsi sio snd vid voodoo plat ui) + net print scsi sio snd vid voodoo plat ui) if(WIN32 AND ARCH STREQUAL "i386") - if(MSVC) - target_link_options(86Box PRIVATE "/LARGEADDRESSAWARE") - else() - target_link_options(86Box PRIVATE "LINKER:--large-address-aware") - endif() + if(MINGW) + target_link_options(86Box PRIVATE "LINKER:--large-address-aware") + else() + target_link_options(86Box PRIVATE "LINKER:/LARGEADDRESSAWARE") + endif() endif() -if(MINGW) - target_link_options(86Box PRIVATE "-static") - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".dll.a") +if(STATIC_BUILD) + if(MINGW OR UNIX) + target_link_options(86Box PRIVATE "-static") + set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + endif() endif() -# Variables introduced by richardg867 for versioning stuff -if(NOT CMAKE_PROJECT_VERSION_PATCH) - set(CMAKE_PROJECT_VERSION_PATCH 0) -endif() -if(NOT EMU_BUILD_NUM) - set(EMU_BUILD_NUM 0) -endif() -if(NOT EMU_COPYRIGHT_YEAR) - set(EMU_COPYRIGHT_YEAR 2021) -endif() - -#some macOS specific configuration steps if(APPLE) -# Force using the newest library if it's installed by homebrew - set(CMAKE_FIND_FRAMEWORK LAST) - + # Force using the newest library if it's installed by homebrew + set(CMAKE_FIND_FRAMEWORK LAST) - # prepare stuff for macOS app bundles - set(CMAKE_MACOSX_BUNDLE 1) - - # setting our compilation target to macOS 10.13 High Sierra - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") - - # set the Info.plist properly - set_target_properties(86Box PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/mac/Info.plist.in) - set(MACOSX_BUNDLE_GUI_IDENTIFIER net.86Box.86Box) - set(MACOSX_BUNDLE_BUNDLE_NAME 86Box) - set(MACOSX_BUNDLE_BUNDLE_VERSION 3.1.${EMU_BUILD_NUM}) - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "3.1.${EMU_BUILD_NUM}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "3.1.${EMU_BUILD_NUM}") - set(MACOSX_BUNDLE_ICON_FILE 86Box.icns) - set(MACOSX_BUNDLE_INFO_STRING "A emulator of old computers") - set(MACOSX_BUNDLE_COPYRIGHT "© 2007-${EMU_COPYRIGHT_YEAR} 86Box contributors") - - - # preparing the code signing for easier distribution, Apple dev certificate needed at one point - #set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES") - #set(XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-") - #set(XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/mac/codesign/dev/app.entitlements) - + # setting our compilation target to macOS 10.13 High Sierra + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") endif() find_package(Freetype REQUIRED) include_directories(${FREETYPE_INCLUDE_DIRS}) if(APPLE) - target_link_libraries(86Box Freetype::Freetype) # bundles freetype for the macOS app bundle + # Freetype is dynamically loaded by the emulator, however, we link it + # on macOS so it gets copied to the bundle by the installation process + target_link_libraries(86Box Freetype::Freetype) endif() find_package(OpenAL REQUIRED) @@ -141,16 +93,12 @@ target_link_libraries(86Box ${OPENAL_LIBRARY}) find_package(SDL2 REQUIRED) include_directories(${SDL2_INCLUDE_DIRS}) -if(MINGW) - target_link_libraries(86Box SDL2::SDL2-static) -elseif(WIN32) - target_link_libraries(86Box SDL2::SDL2) +if(STATIC_BUILD AND TARGET SDL2::SDL2-static) + target_link_libraries(86Box SDL2::SDL2-static) +elseif(TARGET SDL2::SDL2) + target_link_libraries(86Box SDL2::SDL2) else() - if (TARGET SDL2::SDL2) - target_link_libraries(86Box SDL2::SDL2) - else() - target_link_libraries(86Box ${SDL2_LIBRARIES}) - endif() + target_link_libraries(86Box ${SDL2_LIBRARIES}) endif() find_package(PNG REQUIRED) @@ -158,17 +106,17 @@ include_directories(${PNG_INCLUDE_DIRS}) target_link_libraries(86Box PNG::PNG) if(VCPKG_TOOLCHAIN) - # vcpkg includes a config file for rtmidi - find_package(RtMidi REQUIRED) - target_link_libraries(86Box RtMidi::rtmidi) + # vcpkg includes a config file for rtmidi + find_package(RtMidi REQUIRED) + target_link_libraries(86Box RtMidi::rtmidi) else() - find_package(PkgConfig REQUIRED) - pkg_check_modules(RTMIDI REQUIRED IMPORTED_TARGET rtmidi) - target_link_libraries(86Box PkgConfig::RTMIDI) + find_package(PkgConfig REQUIRED) + pkg_check_modules(RTMIDI REQUIRED IMPORTED_TARGET rtmidi) + target_link_libraries(86Box PkgConfig::RTMIDI) - if(WIN32) - target_link_libraries(PkgConfig::RTMIDI INTERFACE winmm) - endif() + if(WIN32) + target_link_libraries(PkgConfig::RTMIDI INTERFACE winmm) + endif() endif() configure_file(include/86box/version.h.in include/86box/version.h @ONLY) @@ -176,9 +124,9 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) include_directories(include) if(NEW_DYNAREC) - include_directories(cpu codegen_new) + include_directories(cpu codegen_new) else() - include_directories(cpu codegen) + include_directories(cpu codegen) endif() add_subdirectory(cdrom) @@ -186,9 +134,9 @@ add_subdirectory(chipset) add_subdirectory(cpu) if(NEW_DYNAREC) - add_subdirectory(codegen_new) + add_subdirectory(codegen_new) else() - add_subdirectory(codegen) + add_subdirectory(codegen) endif() if(MINITRACE) @@ -197,30 +145,43 @@ if(MINITRACE) target_link_libraries(86Box minitrace) endif() -if(APPLE) - install(TARGETS 86Box DESTINATION "bin") +if(WIN32 OR (APPLE AND CMAKE_MACOSX_BUNDLE)) + # Copy the binary to the root of the install prefix on Windows and macOS + install(TARGETS 86Box DESTINATION ".") else() - install(TARGETS 86Box) + # On Linux we want to copy the binary to the `bin` folder. + install(TARGETS 86Box) endif() - -# adjustments for macOS app bundles +# Install our dependencies to the macOS bundle if(APPLE) - set(APPS ${CMAKE_CURRENT_BINARY_DIR}/86Box.app) - install(CODE " - include(BundleUtilities) - fixup_bundle(\"${APPS}\" \"\" \"\")" - COMPONENT Runtime) + install(CODE " + include(BundleUtilities) + get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \${CMAKE_INSTALL_PREFIX} ABSOLUTE) + fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"\" \"\")" + COMPONENT Runtime) endif() +# Install our dependencies if using vcpkg if(VCPKG_TOOLCHAIN) - x_vcpkg_install_local_dependencies(TARGETS 86Box DESTINATION "bin") + x_vcpkg_install_local_dependencies(TARGETS 86Box DESTINATION ".") endif() +# Install the PDB file on Windows builds if(MSVC) - install(FILES $ - CONFIGURATIONS Debug RelWithDebInfo - DESTINATION "bin") + # CMake fully supports PDB files on MSVC-compatible compilers + install(FILES $ + CONFIGURATIONS Debug RelWithDebInfo + DESTINATION ".") +elseif(WIN32) + # Other compilers/linkers (such as Clang in GCC-compatible mode) also + # emit PDB files when targeting Windows, however, CMake only supports + # the relevant properties with MSVC and clones. Try to install + # the PDB file assuming it's in the same path as the EXE. + install(FILES "$/$.pdb" + CONFIGURATIONS Debug RelWithDebInfo + DESTINATION "." + OPTIONAL) endif() add_subdirectory(device) @@ -236,10 +197,10 @@ add_subdirectory(scsi) add_subdirectory(sound) add_subdirectory(video) if(APPLE) - add_subdirectory(mac) - add_subdirectory(unix) + add_subdirectory(mac) + add_subdirectory(unix) elseif(WIN32) - add_subdirectory(win) + add_subdirectory(win) else() - add_subdirectory(unix) + add_subdirectory(unix) endif() diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt index 6b6c89022..eaa50bf2c 100644 --- a/src/cdrom/CMakeLists.txt +++ b/src/cdrom/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image.c) \ No newline at end of file diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt index 050db7519..5be4490af 100644 --- a/src/chipset/CMakeLists.txt +++ b/src/chipset/CMakeLists.txt @@ -1,26 +1,26 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1489.c ali1531.c ali1541.c ali1543.c - ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c - intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c - opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c - sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c - sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c - via_pipc.c vl82c480.c wd76c10.c) + ali1621.c ali6117.c headland.c ims8848.c intel_82335.c contaq_82c59x.c cs4031.c intel_420ex.c + intel_4x0.c intel_i450kx.c intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c + opti495.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c + sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c via_vt82c49x.c via_vt82c505.c sis_85c310.c + sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c umc_8886.c umc_hb4.c via_apollo.c + via_pipc.c vl82c480.c wd76c10.c) if(OLIVETTI) - target_sources(chipset PRIVATE olivetti_eva.c) + target_sources(chipset PRIVATE olivetti_eva.c) endif() \ No newline at end of file diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index 33225e4a2..9f4952597 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -143,6 +143,8 @@ sis_85c496_recalcmapping(sis_85c496_t *dev) } else mem_set_mem_state_both(base, 0x8000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); } + + flushmmucache_nopc(); } @@ -240,13 +242,8 @@ sis_85c49x_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x45: /* Shadow Configure */ dev->pci_conf[addr] = val & 0x0f; - if (valxor & 0x03) { + if (valxor & 0x03) sis_85c496_recalcmapping(dev); - if ((old == 0x0a) && (val == 0x09)) - flushmmucache_nopc(); - else - flushmmucache(); - } break; case 0x46: /* Cacheable Control */ dev->pci_conf[addr] = val; diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index b9c7bd61f..1c7f944dd 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -180,6 +180,7 @@ vt82c505_reset(void *priv) } pic_reset(); + pic_set_pci_flag(1); } diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt index 1d310c0de..68b13f24d 100644 --- a/src/codegen/CMakeLists.txt +++ b/src/codegen/CMakeLists.txt @@ -1,31 +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. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # if(DYNAREC) - add_library(dynarec OBJECT codegen.c codegen_ops.c) + add_library(dynarec OBJECT codegen.c codegen_ops.c) - if(ARCH STREQUAL "i386") - target_sources(dynarec PRIVATE codegen_x86.c - codegen_accumulate_x86.c) - elseif(ARCH STREQUAL "x86_64") - target_sources(dynarec PRIVATE codegen_x86-64.c - codegen_accumulate_x86-64.c) - else() - message(SEND_ERROR - "Dynarec is incompatible with target platform ${ARCH}") - endif() + if(ARCH STREQUAL "i386") + target_sources(dynarec PRIVATE codegen_x86.c + codegen_accumulate_x86.c) + elseif(ARCH STREQUAL "x86_64") + target_sources(dynarec PRIVATE codegen_x86-64.c + codegen_accumulate_x86-64.c) + else() + message(SEND_ERROR + "Dynarec is incompatible with target platform ${ARCH}") + endif() - target_link_libraries(86Box dynarec cgt) + target_link_libraries(86Box dynarec cgt) endif() \ No newline at end of file diff --git a/src/codegen_new/CMakeLists.txt b/src/codegen_new/CMakeLists.txt index 15f1874f8..54f3b3c6b 100644 --- a/src/codegen_new/CMakeLists.txt +++ b/src/codegen_new/CMakeLists.txt @@ -1,51 +1,51 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # if(DYNAREC) - add_library(dynarec OBJECT codegen.c codegen_accumulate.c - codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c - codegen_ops_3dnow.c codegen_ops_branch.c codegen_ops_arith.c - codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c - codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c - codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c - codegen_ops_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c - codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c - codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_mov.c - codegen_ops_shift.c codegen_ops_stack.c codegen_reg.c) + add_library(dynarec OBJECT codegen.c codegen_accumulate.c + codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c + codegen_ops_3dnow.c codegen_ops_branch.c codegen_ops_arith.c + codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c + codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c + codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c + codegen_ops_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c + codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c + codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_mov.c + codegen_ops_shift.c codegen_ops_stack.c codegen_reg.c) - if(ARCH STREQUAL "i386") - target_sources(dynarec PRIVATE codegen_backend_x86.c - codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c - codegen_backend_x86_ops_sse.c - codegen_backend_x86_uops.c) - elseif(ARCH STREQUAL "x86_64") - target_sources(dynarec PRIVATE codegen_backend_x86-64.c - codegen_backend_x86-64_ops.c - codegen_backend_x86-64_ops_sse.c - codegen_backend_x86-64_uops.c) - elseif(ARCH STREQUAL "arm64") - target_sources(dynarec PRIVATE codegen_backend_arm64.c - codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c - codegen_backend_arm64_imm.c) - elseif(ARCH STREQUAL "arm") - target_sources(dynarec PRIVATE codegen_backend_arm.c - codegen_backend_arm_ops.c codegen_backend_arm_uops.c) - else() - message(SEND_ERROR - "Dynarec is incompatible with target platform ${ARCH}") - endif() + if(ARCH STREQUAL "i386") + target_sources(dynarec PRIVATE codegen_backend_x86.c + codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c + codegen_backend_x86_ops_sse.c + codegen_backend_x86_uops.c) + elseif(ARCH STREQUAL "x86_64") + target_sources(dynarec PRIVATE codegen_backend_x86-64.c + codegen_backend_x86-64_ops.c + codegen_backend_x86-64_ops_sse.c + codegen_backend_x86-64_uops.c) + elseif(ARCH STREQUAL "arm64") + target_sources(dynarec PRIVATE codegen_backend_arm64.c + codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c + codegen_backend_arm64_imm.c) + elseif(ARCH STREQUAL "arm") + target_sources(dynarec PRIVATE codegen_backend_arm.c + codegen_backend_arm_ops.c codegen_backend_arm_uops.c) + else() + message(SEND_ERROR + "Dynarec is incompatible with target platform ${ARCH}") + endif() - target_link_libraries(86Box dynarec cgt) + target_link_libraries(86Box dynarec cgt) endif() \ No newline at end of file diff --git a/src/config.c b/src/config.c index 6c494a312..bda66d417 100644 --- a/src/config.c +++ b/src/config.c @@ -64,7 +64,6 @@ #include <86box/snd_mpu401.h> #include <86box/video.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/plat_dir.h> #include <86box/ui.h> @@ -645,6 +644,8 @@ load_machine(void) 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")) @@ -657,6 +658,8 @@ load_machine(void) 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")) @@ -831,9 +834,9 @@ load_machine(void) mem_size = config_get_int(cat, "mem_size", 64); #if 0 - if (mem_size < (((machines[machine].flags & MACHINE_AT) && + 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 = (((machines[machine].flags & 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) @@ -859,10 +862,6 @@ load_machine(void) /* Remove this after a while.. */ config_delete_var(cat, "nvr_path"); config_delete_var(cat, "enable_sync"); - - /* Set up the architecture flags. */ - AT = IS_AT(machine); - PCI = IS_ARCH(machine, MACHINE_BUS_PCI); } @@ -874,13 +873,13 @@ load_video(void) char *p; int free_p = 0; - if (machines[machine].flags & MACHINE_VIDEO_ONLY) { + if (machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { config_delete_var(cat, "gfxcard"); gfxcard = VID_INTERNAL; } else { p = config_get_string(cat, "gfxcard", NULL); if (p == NULL) { - if (machines[machine].flags & MACHINE_VIDEO) { + if (machine_has_flags(machine, MACHINE_VIDEO)) { p = (char *)malloc((strlen("internal")+1)*sizeof(char)); strcpy(p, "internal"); } else { @@ -915,15 +914,30 @@ load_input_devices(void) p = config_get_string(cat, "joystick_type", NULL); if (p != NULL) { + if (!strcmp(p, "standard_2button")) + 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"); + joystick_type = joystick_get_from_internal_name(p); if (!joystick_type) { /* Try to read an integer for backwards compatibility with old configs */ c = config_get_int(cat, "joystick_type", 8); - if ((c >= 0) && (c < 8)) - /* "None" was type 8 instead of 0 previously, shift the number accordingly */ - joystick_type = c + 1; - else - joystick_type = 0; + switch (c) { + case 0: case 1: case 2: case 3: /* 2-axis joysticks */ + joystick_type = c + 1; + break; + case 4: case 5: case 6: case 7: /* other joysticks */ + joystick_type = c + 3; + break; + default: /* "None" (8) or invalid value */ + joystick_type = 0; + break; + } } } else joystick_type = 0; @@ -1120,7 +1134,7 @@ load_storage_controllers(void) p = config_get_string(cat, "hdc", NULL); if (p == NULL) { - if (machines[machine].flags & MACHINE_HDC) { + if (machine_has_flags(machine, MACHINE_HDC)) { p = (char *)malloc((strlen("internal")+1)*sizeof(char)); strcpy(p, "internal"); } else { @@ -1150,7 +1164,8 @@ load_storage_controllers(void) ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0); ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0); - cassette_enable = !!config_get_int(cat, "cassette_enabled", AT ? 0 : 1); + /* 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", ""); if (strlen(p) > 511) fatal("load_storage_controllers(): strlen(p) > 511\n"); @@ -1948,7 +1963,7 @@ load_other_peripherals(void) p = config_get_string(cat, "hdc", NULL); if (p == NULL) { - if (machines[machine].flags & MACHINE_HDC) { + if (machine_has_flags(machine, MACHINE_HDC)) { p = (char *)malloc((strlen("internal")+1)*sizeof(char)); strcpy(p, "internal"); } else { @@ -2025,10 +2040,6 @@ config_load(void) machine = machine_get_machine_from_internal_name("ibmpc"); dpi_scale = 1; - /* Set up the architecture flags. */ - AT = IS_AT(machine); - PCI = IS_ARCH(machine, MACHINE_BUS_PCI); - fpu_type = fpu_get_type(cpu_f, cpu, "none"); gfxcard = video_get_video_from_internal_name("cga"); vid_api = plat_vidapi("default"); @@ -2060,7 +2071,8 @@ config_load(void) for (i = 0; i < ISAMEM_MAX; i++) isamem_type[i] = 0; - cassette_enable = AT ? 0 : 1; + /* 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; diff --git a/src/cpu/386.c b/src/cpu/386.c index 86327e5de..298cc66fc 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -189,7 +189,7 @@ exec386(int cycs) loadcs(readmemw(0, addr + 2)); } } else if (nmi && nmi_enable && nmi_mask) { - if (AT && (cpu_fast_off_flags & 0x20000000)) + if (is486 && (cpu_fast_off_flags & 0x20000000)) cpu_fast_off_count = cpu_fast_off_val + 1; cpu_state.oldpc = cpu_state.pc; diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index a030ac915..d11be000e 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -794,7 +794,7 @@ exec386_dynarec(int cycs) if (smi_line) enter_smm_check(0); else if (nmi && nmi_enable && nmi_mask) { - if (AT && (cpu_fast_off_flags & 0x20000000)) + if (is486 && (cpu_fast_off_flags & 0x20000000)) cpu_fast_off_count = cpu_fast_off_val + 1; #ifndef USE_NEW_DYNAREC diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 900286580..750335b60 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -570,15 +570,9 @@ reset_808x(int hard) pfq_clear(); } - if (AT) { - load_cs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - } else { - load_cs(0xFFFF); - cpu_state.pc = 0; - rammask = 0xfffff; - } + load_cs(0xFFFF); + cpu_state.pc = 0; + rammask = 0xfffff; prefetching = 1; cpu_alu_op = 0; diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index ab27b77c0..543ad8ff5 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -1,32 +1,32 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c 386_dynarec.c - 386_dynarec_ops.c x86seg.c x87.c x87_timings.c) + 386_dynarec_ops.c x86seg.c x87.c x87_timings.c) if(AMD_K5) - target_compile_definitions(cpu PRIVATE USE_AMD_K5) + target_compile_definitions(cpu PRIVATE USE_AMD_K5) endif() if(CYRIX_6X86) - target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86) + target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86) endif() if(DYNAREC) - add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c - codegen_timing_common.c codegen_timing_k6.c - codegen_timing_pentium.c codegen_timing_p6.c - codegen_timing_winchip.c codegen_timing_winchip2.c) + add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c + codegen_timing_common.c codegen_timing_k6.c + codegen_timing_pentium.c codegen_timing_p6.c + codegen_timing_winchip.c codegen_timing_winchip2.c) endif() \ No newline at end of file diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 7021a83e4..2004d7336 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -56,10 +56,12 @@ enum { 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) @@ -1616,7 +1618,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else EAX = EBX = ECX = EDX = 0; break; @@ -1631,7 +1633,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else EAX = EBX = ECX = EDX = 0; break; @@ -1645,14 +1647,14 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else if (EAX == 0x80000000) { EAX = 0x80000005; EBX = ECX = EDX = 0; } else if (EAX == 0x80000001) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B; } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x7428354B; @@ -1682,14 +1684,14 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; } else if (EAX == 0x80000000) { EAX = 0x80000005; EBX = ECX = EDX = 0; } else if (EAX == 0x80000001) { EAX = CPUID + 0x100; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX; } else if (EAX == 0x80000002) { EAX = 0x2D444D41; EBX = 0x6D74364B; @@ -1729,14 +1731,14 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000005; break; case 0x80000001: EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D pr */ @@ -1772,14 +1774,14 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000006; break; case 0x80000001: EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm) 3D+ P */ @@ -1819,14 +1821,14 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; break; case 0x80000000: EAX = 0x80000007; break; case 0x80000001: EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ EAX = 0x2d444d41; /* AMD-K6(tm)-III P */ @@ -1869,7 +1871,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX; } else EAX = EBX = ECX = EDX = 0; break; @@ -1941,7 +1943,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -1959,7 +1961,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -1977,7 +1979,7 @@ cpu_CPUID(void) } else if (EAX == 1) { EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_MTRR | CPUID_MCA | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; } else if (EAX == 2) { EAX = 0x00000001; EBX = ECX = 0; @@ -2003,7 +2005,7 @@ cpu_CPUID(void) case 1: EAX = CPUID; EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; break; @@ -2012,7 +2014,7 @@ cpu_CPUID(void) break; case 0x80000001: EAX = CPUID; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_MMX | CPUID_MTRR | CPUID_3DNOW; if (cpu_has_feature(CPU_FEATURE_CX8)) EDX |= CPUID_CMPXCHG8B; break; @@ -2124,6 +2126,8 @@ cpu_RDMSR(void) case CPU_CYRIX3S: EAX = EDX = 0; switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2209,6 +2213,9 @@ cpu_RDMSR(void) case CPU_K6_3P: EAX = EDX = 0; switch (ECX) { + case 0x00000000: + case 0x00000001: + break; case 0x0000000e: EAX = msr.tr12; break; @@ -2289,6 +2296,8 @@ amd_k_invalid_rdmsr: #endif EAX = EDX = 0; switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2302,6 +2311,8 @@ amd_k_invalid_rdmsr: case CPU_PENTIUM2D: EAX = EDX = 0; switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: EAX = tsc & 0xffffffff; EDX = tsc >> 32; @@ -2310,8 +2321,10 @@ amd_k_invalid_rdmsr: if (cpu_s->cpu_type != CPU_PENTIUM2D) goto i686_invalid_rdmsr; - EAX = msr.ecx17 & 0xffffffff; - EDX = msr.ecx17 >> 32; + if (cpu_f->package == CPU_PKG_SLOT2) + EDX |= 0x80000; + else if (cpu_f->package == CPU_PKG_SOCKET370) + EDX |= 0x100000; break; case 0x1B: EAX = msr.apic_base & 0xffffffff; @@ -2404,7 +2417,14 @@ amd_k_invalid_rdmsr: EDX = 0x00000000; break; case 0x179: - EAX = EDX = 0x00000000; + EAX = 0x00000105; + EDX = 0x00000000; + break; + case 0x17a: + break; + case 0x17b: + EAX = msr.mcg_ctl & 0xffffffff; + EDX = msr.mcg_ctl >> 32; break; case 0x186: EAX = msr.ecx186 & 0xffffffff; @@ -2455,21 +2475,14 @@ amd_k_invalid_rdmsr: EAX = msr.mtrr_deftype & 0xffffffff; EDX = msr.mtrr_deftype >> 32; break; - case 0x404: - EAX = msr.ecx404 & 0xffffffff; - EDX = msr.ecx404 >> 32; - break; - case 0x408: - EAX = msr.ecx408 & 0xffffffff; - EDX = msr.ecx408 >> 32; - break; - case 0x40c: - EAX = msr.ecx40c & 0xffffffff; - EDX = msr.ecx40c >> 32; - break; + case 0x400: case 0x404: case 0x408: case 0x40c: case 0x410: - EAX = msr.ecx410 & 0xffffffff; - EDX = msr.ecx410 >> 32; + EAX = msr.mca_ctl[(ECX - 0x400) >> 2] & 0xffffffff; + EDX = msr.mca_ctl[(ECX - 0x400) >> 2] >> 32; + break; + case 0x401: case 0x402: case 0x405: case 0x406: + case 0x407: case 0x409: case 0x40d: case 0x40e: + case 0x411: case 0x412: break; case 0x570: EAX = msr.ecx570 & 0xffffffff; @@ -2575,6 +2588,8 @@ cpu_WRMSR(void) case CPU_CYRIX3S: switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; @@ -2629,6 +2644,8 @@ cpu_WRMSR(void) case CPU_K6_2P: case CPU_K6_3P: switch (ECX) { + case 0x00: case 0x01: + break; case 0x0e: msr.tr12 = EAX & 0x228; break; @@ -2702,6 +2719,8 @@ amd_k_invalid_wrmsr: #endif cpu_log("WRMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX); switch (ECX) { + case 0x00: case 0x01: + break; case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; @@ -2722,15 +2741,13 @@ amd_k_invalid_wrmsr: case CPU_PENTIUM2: case CPU_PENTIUM2D: switch (ECX) { + case 0x00: case 0x01: + if (EAX || EDX) + x86gpf(NULL, 0); + break; case 0x10: tsc = EAX | ((uint64_t)EDX << 32); break; - case 0x17: - if (cpu_s->cpu_type != CPU_PENTIUM2D) - goto i686_invalid_wrmsr; - - msr.ecx17 = EAX | ((uint64_t)EDX << 32); - break; case 0x1b: cpu_log("APIC_BASE write: %08X%08X\n", EDX, EAX); // msr.apic_base = EAX | ((uint64_t)EDX << 32); @@ -2779,6 +2796,13 @@ amd_k_invalid_wrmsr: break; case 0x179: break; + case 0x17a: + if (EAX || EDX) + x86gpf(NULL, 0); + break; + case 0x17b: + msr.mcg_ctl = EAX | ((uint64_t)EDX << 32); + break; case 0x186: msr.ecx186 = EAX | ((uint64_t)EDX << 32); break; @@ -2816,17 +2840,15 @@ amd_k_invalid_wrmsr: case 0x2ff: msr.mtrr_deftype = EAX | ((uint64_t)EDX << 32); break; - case 0x404: - msr.ecx404 = EAX | ((uint64_t)EDX << 32); - break; - case 0x408: - msr.ecx408 = EAX | ((uint64_t)EDX << 32); - break; - case 0x40c: - msr.ecx40c = EAX | ((uint64_t)EDX << 32); - break; + case 0x400: case 0x404: case 0x408: case 0x40c: case 0x410: - msr.ecx410 = EAX | ((uint64_t)EDX << 32); + msr.mca_ctl[(ECX - 0x400) >> 2] = EAX | ((uint64_t)EDX << 32); + break; + case 0x401: case 0x402: case 0x405: case 0x406: + case 0x407: case 0x409: case 0x40d: case 0x40e: + case 0x411: case 0x412: + if (EAX || EDX) + x86gpf(NULL, 0); break; case 0x570: msr.ecx570 = EAX | ((uint64_t)EDX << 32); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 9beac3fab..18962bab0 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -236,7 +236,6 @@ typedef struct { uint32_t cesr; /* 0x00000011 */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx17; /* 0x00000017 - Only on Pentium II Deschutes */ uint64_t apic_base; /* 0x0000001b - Should the Pentium not also have this? */ uint64_t ecx79; /* 0x00000079 */ @@ -262,6 +261,9 @@ typedef struct { uint32_t sysenter_esp; /* 0x00000175 - SYSENTER/SYSEXIT MSR's */ uint32_t sysenter_eip; /* 0x00000176 - SYSENTER/SYSEXIT MSR's */ + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ + uint64_t mcg_ctl; /* 0x0000017b - Machine Check Architecture */ + /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ uint64_t ecx186, ecx187; /* 0x00000186, 0x00000187 */ uint64_t ecx1e0; /* 0x000001e0 */ @@ -283,10 +285,7 @@ typedef struct { uint64_t mtrr_deftype; /* 0x000002ff */ /* Pentium Pro, Pentium II Klamath, and Pentium II Deschutes MSR's */ - uint64_t ecx404; /* 0x00000404 - Model Identification MSR's used by some Acer BIOSes */ - uint64_t ecx408; /* 0x00000408 */ - uint64_t ecx40c; /* 0x0000040c */ - uint64_t ecx410; /* 0x00000410 */ + uint64_t mca_ctl[5]; /* 0x00000400, 0x00000404, 0x00000408, 0x0000040c, 0x00000410 - Machine Check Architecture */ uint64_t ecx570; /* 0x00000570 */ /* IBM 386SLC, 486SLC, and 486BL MSR's */ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 55ef45000..94b2294dd 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -245,6 +245,9 @@ reset_common(int hard) pci_reset(); if (!hard && soft_reset_pci) { dma_reset(); + /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, + and vice-versa. */ + dma_set_at(is286); device_reset_all(); } } @@ -264,15 +267,9 @@ reset_common(int hard) cpu_state.eflags = 0; cgate32 = 0; if (is286) { - if (AT) { - loadcs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - } else { - loadcs(0xFFFF); - cpu_state.pc = 0; - rammask = 0xfffff; - } + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; } idt.base = 0; cpu_state.flags = 2; @@ -353,6 +350,9 @@ void hardresetx86(void) { dma_reset(); + /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, + and vice-versa. */ + dma_set_at(is286); device_reset_all(); cpu_alt_reset = 0; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index bd1d1b864..4399fc4d8 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -83,8 +83,8 @@ seg_reset(x86seg *s) if (s == &cpu_state.seg_cs) { if (!cpu_inited) fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); - s->base = AT ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; - s->seg = AT ? 0xf000 : 0xffff; + s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; + s->seg = is286 ? 0xf000 : 0xffff; } else { s->base = 0; s->seg = 0; diff --git a/src/device.c b/src/device.c index 265fdf215..7b9d4c167 100644 --- a/src/device.c +++ b/src/device.c @@ -646,29 +646,29 @@ device_set_config_mac(const char *s, int val) int -device_is_valid(const device_t *device, int mflags) +device_is_valid(const device_t *device, int m) { if (device == NULL) return(1); - if ((device->flags & DEVICE_AT) && !(mflags & MACHINE_BUS_ISA16)) return(0); + if ((device->flags & DEVICE_AT) && !machine_has_bus(m, MACHINE_BUS_ISA16)) return(0); - if ((device->flags & DEVICE_CBUS) && !(mflags & MACHINE_BUS_CBUS)) return(0); + if ((device->flags & DEVICE_CBUS) && !machine_has_bus(m, MACHINE_BUS_CBUS)) return(0); - if ((device->flags & DEVICE_ISA) && !(mflags & MACHINE_BUS_ISA)) return(0); + if ((device->flags & DEVICE_ISA) && !machine_has_bus(m, MACHINE_BUS_ISA)) return(0); - if ((device->flags & DEVICE_MCA) && !(mflags & MACHINE_BUS_MCA)) return(0); + if ((device->flags & DEVICE_MCA) && !machine_has_bus(m, MACHINE_BUS_MCA)) return(0); - if ((device->flags & DEVICE_EISA) && !(mflags & MACHINE_BUS_EISA)) return(0); + if ((device->flags & DEVICE_EISA) && !machine_has_bus(m, MACHINE_BUS_EISA)) return(0); - if ((device->flags & DEVICE_VLB) && !(mflags & MACHINE_BUS_VLB)) return(0); + if ((device->flags & DEVICE_VLB) && !machine_has_bus(m, MACHINE_BUS_VLB)) return(0); - if ((device->flags & DEVICE_PCI) && !(mflags & MACHINE_BUS_PCI)) return(0); + if ((device->flags & DEVICE_PCI) && !machine_has_bus(m, MACHINE_BUS_PCI)) return(0); - if ((device->flags & DEVICE_AGP) && !(mflags & MACHINE_BUS_AGP)) return(0); + if ((device->flags & DEVICE_AGP) && !machine_has_bus(m, MACHINE_BUS_AGP)) return(0); - if ((device->flags & DEVICE_PS2) && !(mflags & MACHINE_BUS_PS2)) return(0); + if ((device->flags & DEVICE_PS2) && !machine_has_bus(m, MACHINE_BUS_PS2)) return(0); - if ((device->flags & DEVICE_AC97) && !(mflags & MACHINE_BUS_AC97)) return(0); + if ((device->flags & DEVICE_AC97) && !machine_has_bus(m, MACHINE_BUS_AC97)) return(0); return(1); } diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index cbb312aa1..17a9ca1bb 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -1,24 +1,24 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c - hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c - postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c - smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c - mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c) + hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c + postcard.c serial.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c + smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c keyboard_at.c + mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c) if(LASERXT) - target_compile_definitions(dev PRIVATE USE_LASERXT) + target_compile_definitions(dev PRIVATE USE_LASERXT) endif() \ No newline at end of file diff --git a/src/device/cartridge.c b/src/device/cartridge.c index 25e8beac7..9743c2e87 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -194,7 +194,7 @@ cart_reset(void) cart_image_close(1); cart_image_close(0); - if (!(machines[machine].flags & MACHINE_CARTRIDGE)) + if (!machine_has_cartridge(machine)) return; for (i = 0; i < 2; i++) { diff --git a/src/device/isamem.c b/src/device/isamem.c index cc680d9a3..a11a3d68b 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -82,6 +82,8 @@ #include <86box/plat.h> #include <86box/isamem.h> +#include "cpu.h" + #define ISAMEM_DEBUG 0 @@ -455,7 +457,7 @@ dev->frame_addr = 0xE0000; isamem_log(")\n"); /* Force (back to) 8-bit bus if needed. */ - if ((!AT) && (dev->flags & FLAG_WIDE)) { + if ((!is286) && (dev->flags & FLAG_WIDE)) { isamem_log("ISAMEM: not AT+ system, forcing 8-bit mode!\n"); dev->flags &= ~FLAG_WIDE; } @@ -559,7 +561,7 @@ dev->frame_addr = 0xE0000; * real mode (so, not by DOS, for example) but it can be used in * protected mode. */ - if (AT && addr > 0 && tot > 0) { + if (is286 && addr > 0 && tot > 0) { t = tot; isamem_log("ISAMEM: RAM at %05iKB (%iKB)\n", addr>>10, t>>10); diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 82ec6d92e..7c1581d52 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -26,6 +26,8 @@ #include <86box/machine.h> #include <86box/keyboard.h> +#include "cpu.h" + int keyboard_scan; void (*keyboard_send)(uint16_t val); @@ -103,7 +105,8 @@ key_process(uint16_t scan, int down) if (!down && codes[scan].brk[0] == 0) return; - if (AT && ((keyboard_mode & 3) == 3)) { + /* TODO: The keyboard controller needs to report the AT flag to us here. */ + if (is286 && ((keyboard_mode & 3) == 3)) { if (!keyboard_set3_all_break && !down && !(keyboard_set3_flags[codes[scan].mk[0]] & 2)) return; } @@ -212,7 +215,8 @@ keyboard_do_break(uint16_t scan) { scancode *codes = scan_table; - if (AT && ((keyboard_mode & 3) == 3)) { + /* TODO: The keyboard controller needs to report the AT flag to us here. */ + if (is286 && ((keyboard_mode & 3) == 3)) { if (!keyboard_set3_all_break && !recv_key[scan] && !(keyboard_set3_flags[codes[scan].mk[0]] & 2)) diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index 0b9e85eab..584575ec4 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -1063,7 +1063,7 @@ write_output(atkbd_t *dev, uint8_t val) val |= ((dev->mem[0] << 4) & 0x10); /*IRQ 12*/ - if ((dev->output_port ^ val) & 0x20) { + if ((old ^ val) & 0x20) { if (val & 0x20) picint(1 << 12); else @@ -1071,26 +1071,23 @@ write_output(atkbd_t *dev, uint8_t val) } /*IRQ 1*/ - if ((dev->output_port ^ val) & 0x10) { + if ((old ^ val) & 0x10) { if (val & 0x10) picint(1 << 1); else picintc(1 << 1); } - if ((dev->output_port ^ val) & 0x02) { /*A20 enable change*/ + if ((old ^ val) & 0x02) { /*A20 enable change*/ mem_a20_key = val & 0x02; mem_a20_recalc(); flushmmucache(); } - /* Do this here to avoid an infinite reset loop. */ - dev->output_port = val; - /* 0 holds the CPU in the RESET state, 1 releases it. To simplify this, we just do everything on release. */ - if ((val & 0x01) && !(old & 0x01)) { - if (val & 0x01) { + if ((old ^ val) & 0x01) { /*Reset*/ + if (! (val & 0x01)) { /* Pin 0 selected. */ /* Pin 0 selected. */ kbd_log("write_output(): Pulse reset!\n"); softresetx86(); /*Pulse reset!*/ @@ -1098,6 +1095,9 @@ write_output(atkbd_t *dev, uint8_t val) flushmmucache(); } } + + /* Do this here to avoid an infinite reset loop. */ + dev->output_port = val; } @@ -1464,7 +1464,7 @@ write64_ami(void *priv, uint8_t val) case 0xb0: case 0xb1: case 0xb2: case 0xb3: /* set KBC lines P10-P13 (input port bits 0-3) low */ kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) low\n"); - if (!PCI || (val > 0xb1)) + if (!(dev->flags & DEVICE_PCI) || (val > 0xb1)) dev->input_port &= ~(1 << (val & 0x03)); add_data(dev, 0x00); return 0; @@ -1472,7 +1472,7 @@ write64_ami(void *priv, uint8_t val) case 0xb4: case 0xb5: /* set KBC lines P22-P23 (output port bits 2-3) low */ kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) low\n"); - if (! PCI) + if (! (dev->flags & DEVICE_PCI)) write_output(dev, dev->output_port & ~(4 << (val & 0x01))); add_data(dev, 0x00); return 0; @@ -1480,7 +1480,7 @@ write64_ami(void *priv, uint8_t val) case 0xb8: case 0xb9: case 0xba: case 0xbb: /* set KBC lines P10-P13 (input port bits 0-3) high */ kbd_log("ATkbc: set KBC lines P10-P13 (input port bits 0-3) high\n"); - if (!PCI || (val > 0xb9)) { + if (!(dev->flags & DEVICE_PCI) || (val > 0xb9)) { dev->input_port |= (1 << (val & 0x03)); add_data(dev, 0x00); } @@ -1489,7 +1489,7 @@ write64_ami(void *priv, uint8_t val) case 0xbc: case 0xbd: /* set KBC lines P22-P23 (output port bits 2-3) high */ kbd_log("ATkbc: set KBC lines P22-P23 (output port bits 2-3) high\n"); - if (! PCI) + if (! (dev->flags & DEVICE_PCI)) write_output(dev, dev->output_port | (4 << (val & 0x01))); add_data(dev, 0x00); return 0; diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index e98536bf4..78c17ae19 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -755,9 +755,6 @@ kbd_init(const device_t *info) /* Switch 2 - 8087 FPU. */ if (hasfpu) kbd->pd |= 0x02; - - /* Switch 1 - always off. */ - kbd->pd |= 0x01; } else if (kbd-> type == 9) { /* Zenith Data Systems Z-151 * SW2 switch settings: diff --git a/src/device/postcard.c b/src/device/postcard.c index b9f409589..b769cbbd4 100644 --- a/src/device/postcard.c +++ b/src/device/postcard.c @@ -111,15 +111,15 @@ postcard_init(const device_t *info) { postcard_reset(); - if (machines[machine].flags & MACHINE_MCA) + if (machine_has_bus(machine, MACHINE_BUS_MCA)) postcard_port = 0x680; /* MCA machines */ - else if (strstr(machines[machine].name, " PS/2 ") || strstr(machines[machine].name, " PS/1 ")) + else if (strstr(machines[machine].name, " PS/2 ") || strstr(machine_getname_ex(machine), " PS/1 ")) postcard_port = 0x190; /* ISA PS/2 machines */ else if (strstr(machines[machine].name, " IBM XT ")) postcard_port = 0x60; /* IBM XT */ else if (strstr(machines[machine].name, " IBM PCjr")) postcard_port = 0x10; /* IBM PCjr */ - else if (strstr(machines[machine].name, " Compaq ") && !(machines[machine].flags & MACHINE_PCI)) + else if (strstr(machines[machine].name, " Compaq ") && !machine_has_bus(machine, MACHINE_BUS_PCI)) postcard_port = 0x84; /* ISA Compaq machines */ else postcard_port = 0x80; /* AT and clone machines */ diff --git a/src/device/serial.c b/src/device/serial.c index 15527fad4..d9178e566 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -129,7 +129,7 @@ serial_update_ints(serial_t *dev) } if (stat && (dev->irq != 0xff) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))) { - if (dev->type >= SERIAL_NS16450) + if (dev->type >= SERIAL_16450) picintlevel(1 << dev->irq); else picint(1 << dev->irq); @@ -151,9 +151,9 @@ serial_clear_timeout(serial_t *dev) static void write_fifo(serial_t *dev, uint8_t dat) { - serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_NS16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f); + serial_log("write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f); - if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled) { + if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { /* FIFO mode. */ timer_disable(&dev->timeout_timer); /* Indicate overrun. */ @@ -189,7 +189,7 @@ write_fifo(serial_t *dev, uint8_t dat) void serial_write_fifo(serial_t *dev, uint8_t dat) { - serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_NS16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f); + serial_log("serial_write_fifo(%08X, %02X, %i, %i)\n", dev, dat, (dev->type >= SERIAL_16550) && dev->fifo_enabled, dev->rcvr_fifo_pos & 0x0f); if (!(dev->mctrl & 0x10)) write_fifo(dev, dat); @@ -371,7 +371,7 @@ serial_write(uint16_t addr, uint8_t val, void *p) dev->int_status &= ~SERIAL_INT_TRANSMIT; serial_update_ints(dev); - if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) { + if ((dev->type >= SERIAL_16550) && dev->fifo_enabled && (dev->xmit_fifo_pos < 16)) { /* FIFO mode, begin transmitting. */ timer_on_auto(&dev->transmit_timer, dev->transmit_period); dev->transmit_enabled |= 1; /* Start moving. */ @@ -396,7 +396,7 @@ serial_write(uint16_t addr, uint8_t val, void *p) serial_update_ints(dev); break; case 2: - if (dev->type >= SERIAL_NS16550) { + if (dev->type >= SERIAL_16550) { if ((val ^ dev->fcr) & 0x01) serial_reset_fifo(dev); dev->fcr = val & 0xf9; @@ -500,7 +500,7 @@ serial_write(uint16_t addr, uint8_t val, void *p) serial_update_ints(dev); break; case 7: - if (dev->type >= SERIAL_NS16450) + if (dev->type >= SERIAL_16450) dev->scratch = val; break; } @@ -522,7 +522,7 @@ serial_read(uint16_t addr, void *p) break; } - if ((dev->type >= SERIAL_NS16550) && dev->fifo_enabled) { + if ((dev->type >= SERIAL_16550) && dev->fifo_enabled) { /* FIFO mode. */ serial_clear_timeout(dev); @@ -718,12 +718,12 @@ serial_set_next_inst(int ni) void serial_standalone_init(void) { for ( ; next_inst < 4; ) - device_add_inst(&i8250_device, next_inst + 1); + device_add_inst(&ns8250_device, next_inst + 1); }; -const device_t i8250_device = { - "Intel 8250(-compatible) UART", +const device_t ns8250_device = { + "National Semiconductor 8250(-compatible) UART", 0, SERIAL_8250, serial_init, serial_close, NULL, @@ -731,8 +731,8 @@ const device_t i8250_device = { NULL }; -const device_t i8250_pcjr_device = { - "Intel 8250(-compatible) UART for PCjr", +const device_t ns8250_pcjr_device = { + "National Semiconductor 8250(-compatible) UART for PCjr", DEVICE_PCJR, SERIAL_8250_PCJR, serial_init, serial_close, NULL, @@ -743,7 +743,7 @@ const device_t i8250_pcjr_device = { const device_t ns16450_device = { "National Semiconductor NS16450(-compatible) UART", 0, - SERIAL_NS16450, + SERIAL_16450, serial_init, serial_close, NULL, { NULL }, serial_speed_changed, NULL, NULL @@ -752,7 +752,43 @@ const device_t ns16450_device = { const device_t ns16550_device = { "National Semiconductor NS16550(-compatible) UART", 0, - SERIAL_NS16550, + SERIAL_16550, + serial_init, serial_close, NULL, + { NULL }, serial_speed_changed, NULL, + NULL +}; + +const device_t ns16650_device = { + "Startech Semiconductor 16650(-compatible) UART", + 0, + SERIAL_16650, + serial_init, serial_close, NULL, + { NULL }, serial_speed_changed, NULL, + NULL +}; + +const device_t ns16750_device = { + "Texas Instruments 16750(-compatible) UART", + 0, + SERIAL_16750, + serial_init, serial_close, NULL, + { NULL }, serial_speed_changed, NULL, + NULL +}; + +const device_t ns16850_device = { + "Exar Corporation NS16850(-compatible) UART", + 0, + SERIAL_16850, + serial_init, serial_close, NULL, + { NULL }, serial_speed_changed, NULL, + NULL +}; + +const device_t ns16950_device = { + "Oxford Semiconductor NS16950(-compatible) UART", + 0, + SERIAL_16950, serial_init, serial_close, NULL, { NULL }, serial_speed_changed, NULL, NULL diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index 9a5c72e00..f1a101516 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -1,21 +1,21 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c - hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c - hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) + hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c + hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c hdc_ide_sff8038i.c) add_library(zip OBJECT zip.c) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 1b048b8b0..a04de517c 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -445,7 +445,7 @@ ide_get_max(ide_t *ide, int type) switch(type) { case TYPE_PIO: /* PIO */ if (!ide_boards[ide->board]->force_ata3 && (ide_bm[ide->board] != NULL)) - return 1; + return 4; return 0; /* Maximum PIO 0 for legacy PIO-only drive. */ case TYPE_SDMA: /* SDMA */ diff --git a/src/disk/minivhd/CMakeLists.txt b/src/disk/minivhd/CMakeLists.txt index 8afcd4265..a96b871b8 100644 --- a/src/disk/minivhd/CMakeLists.txt +++ b/src/disk/minivhd/CMakeLists.txt @@ -1,18 +1,18 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(minivhd STATIC cwalk.c libxml2_encoding.c minivhd_convert.c - minivhd_create.c minivhd_io.c minivhd_manage.c minivhd_struct_rw.c - minivhd_util.c) \ No newline at end of file + minivhd_create.c minivhd_io.c minivhd_manage.c minivhd_struct_rw.c + minivhd_util.c) \ No newline at end of file diff --git a/src/dma.c b/src/dma.c index aa91ad988..d59160d73 100644 --- a/src/dma.c +++ b/src/dma.c @@ -46,6 +46,7 @@ static uint8_t dma_stat_rq_pc; static uint8_t dma_command[2]; static uint8_t dma_req_is_soft; static uint8_t dma_advanced; +static uint8_t dma_at; static uint8_t dma_buffer[65536]; static uint16_t dma_sg_base; static uint16_t dma16_buffer[65536]; @@ -910,7 +911,7 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv) dma[addr].ab = (dma[addr].ab & 0xff01ffff & dma_mask) | (dma[addr].page << 16); dma[addr].ac = (dma[addr].ac & 0xff01ffff & dma_mask) | (dma[addr].page << 16); } else { - dma[addr].page = (AT) ? val : val & 0xf; + dma[addr].page = (dma_at) ? val : val & 0xf; dma[addr].ab = (dma[addr].ab & 0xff00ffff & dma_mask) | (dma[addr].page << 16); dma[addr].ac = (dma[addr].ac & 0xff00ffff & dma_mask) | (dma[addr].page << 16); } @@ -1002,6 +1003,13 @@ dma_set_mask(uint32_t mask) } +void +dma_set_at(uint8_t at) +{ + dma_at = at; +} + + void dma_reset(void) { @@ -1034,6 +1042,8 @@ dma_reset(void) dma_sg_base = 0x0400; dma_mask = 0x00ffffff; + + dma_at = is286; } @@ -1310,7 +1320,7 @@ _dma_write(uint32_t addr, uint8_t val, dma_t *dma_c) dma_bm_write(addr, &val, 1, dma_transfer_size(dma_c)); } else { mem_writeb_phys(addr, val); - if (AT) + if (dma_at) mem_invalidate_range(addr, addr); } } @@ -1387,7 +1397,7 @@ dma_channel_read(int channel) if ((dma_c->mode & 0xC) != 8) return(DMA_NODATA); - if (!AT && !channel) + if (!dma_at && !channel) refreshread(); if (! dma_c->size) { @@ -1689,6 +1699,6 @@ dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_t TotalSize, mem_write_phys((void *) bytes, PhysAddress + n, TransferSize); } - if (AT) + if (dma_at) mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); } diff --git a/src/fifo8.c b/src/fifo8.c new file mode 100644 index 000000000..34e90d591 --- /dev/null +++ b/src/fifo8.c @@ -0,0 +1,116 @@ +/* + * Generic FIFO component, implemented as a circular buffer. + * + * Copyright (c) 2012 Peter A. G. Crosthwaite + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include +#include <86box/86box.h> +#include <86box/fifo8.h> + +void fifo8_create(Fifo8 *fifo, uint32_t capacity) +{ + fifo->data = (uint8_t *)malloc(capacity); + memset(fifo->data, 0, capacity); + fifo->capacity = capacity; + fifo->head = 0; + fifo->num = 0; +} + +void fifo8_destroy(Fifo8 *fifo) +{ + if (fifo->data) { + free(fifo->data); + fifo->data = NULL; + } +} + +void fifo8_push(Fifo8 *fifo, uint8_t data) +{ + assert(fifo->num < fifo->capacity); + fifo->data[(fifo->head + fifo->num) % fifo->capacity] = data; + fifo->num++; +} + +void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num) +{ + uint32_t start, avail; + + assert(fifo->num + num <= fifo->capacity); + + start = (fifo->head + fifo->num) % fifo->capacity; + + if (start + num <= fifo->capacity) { + memcpy(&fifo->data[start], data, num); + } else { + avail = fifo->capacity - start; + memcpy(&fifo->data[start], data, avail); + memcpy(&fifo->data[0], &data[avail], num - avail); + } + + fifo->num += num; +} + +uint8_t fifo8_pop(Fifo8 *fifo) +{ + uint8_t ret; + + assert(fifo->num > 0); + ret = fifo->data[fifo->head++]; + fifo->head %= fifo->capacity; + fifo->num--; + return ret; +} + +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num) +{ + uint8_t *ret; + + assert(max > 0 && max <= fifo->num); + *num = MIN(fifo->capacity - fifo->head, max); + ret = &fifo->data[fifo->head]; + fifo->head += *num; + fifo->head %= fifo->capacity; + fifo->num -= *num; + return ret; +} + +void fifo8_reset(Fifo8 *fifo) +{ + fifo->num = 0; + fifo->head = 0; +} + +int fifo8_is_empty(Fifo8 *fifo) +{ + return (fifo->num == 0); +} + +int fifo8_is_full(Fifo8 *fifo) +{ + return (fifo->num == fifo->capacity); +} + +uint32_t fifo8_num_free(Fifo8 *fifo) +{ + return fifo->capacity - fifo->num; +} + +uint32_t fifo8_num_used(Fifo8 *fifo) +{ + return fifo->num; +} + diff --git a/src/floppy/CMakeLists.txt b/src/floppy/CMakeLists.txt index 75e7b5947..4517bc634 100644 --- a/src/floppy/CMakeLists.txt +++ b/src/floppy/CMakeLists.txt @@ -1,17 +1,17 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(fdd OBJECT fdd.c fdc.c fdc_magitronic.c fdc_pii15xb.c fdi2raw.c fdd_common.c - fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_json.c fdd_mfm.c fdd_td0.c) \ No newline at end of file + fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_json.c fdd_mfm.c fdd_td0.c) \ No newline at end of file diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 06f700cca..c8fbb41ff 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -1,17 +1,17 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(game OBJECT gameport.c joystick_standard.c - joystick_ch_flightstick_pro.c joystick_sw_pad.c joystick_tm_fcs.c) \ No newline at end of file + joystick_ch_flightstick_pro.c joystick_sw_pad.c joystick_tm_fcs.c) \ No newline at end of file diff --git a/src/game/gameport.c b/src/game/gameport.c index 80c686ec2..145262278 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -80,16 +80,18 @@ static const struct { const char *internal_name; const joystick_if_t *joystick; } joysticks[] = { - { "none", &joystick_none }, - { "standard_2button", &joystick_standard }, - { "standard_4button", &joystick_standard_4button }, - { "standard_6button", &joystick_standard_6button }, - { "standard_8button", &joystick_standard_8button }, - { "4axis_4button", &joystick_4axis_4button }, + { "none", &joystick_none }, + { "2axis_2button", &joystick_2axis_2button }, + { "2axis_4button", &joystick_2axis_4button }, + { "2axis_6button", &joystick_2axis_6button }, + { "2axis_8button", &joystick_2axis_8button }, + { "3axis_2button", &joystick_3axis_2button }, + { "3axis_4button", &joystick_3axis_4button }, + { "4axis_4button", &joystick_4axis_4button }, { "ch_flighstick_pro", &joystick_ch_flightstick_pro }, { "sidewinder_pad", &joystick_sw_pad }, { "thrustmaster_fcs", &joystick_tm_fcs }, - { "", NULL } + { "", NULL } }; static joystick_instance_t *joystick_instance = NULL; @@ -360,7 +362,7 @@ gameport_add(const device_t *gameport_type) { /* Prevent a standalone game port from being added later on, unless this is an unused Super I/O game port (no MACHINE_GAMEPORT machine flag). */ - if (!(gameport_type->local & GAMEPORT_SIO) || (machines[machine].flags & MACHINE_GAMEPORT)) + if (!(gameport_type->local & GAMEPORT_SIO) || machine_has_flags(machine, MACHINE_GAMEPORT)) standalone_gameport_type = NULL; /* Add game port device. */ @@ -444,7 +446,7 @@ const device_t gameport_device = { }; const device_t gameport_201_device = { - "Game port (port 201h only)", + "Game port (Port 201h only)", 0, 0x010201, gameport_init, gameport_close, @@ -452,6 +454,24 @@ const device_t gameport_201_device = { NULL }; +const device_t gameport_208_device = { + "Game port (Port 208h-20fh)", + 0, 0x080208, + gameport_init, + gameport_close, + NULL, { NULL }, NULL, + NULL +}; + +const device_t gameport_209_device = { + "Game port (Port 209h only)", + 0, 0x010209, + gameport_init, + gameport_close, + NULL, { NULL }, NULL, + NULL +}; + const device_t gameport_pnp_device = { "Game port (Plug and Play only)", 0, 0x080000, diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index e72d066cb..75e2ecdf3 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -145,6 +145,26 @@ static int joystick_standard_read_axis_4button(void *p, int axis) } } +static int joystick_standard_read_axis_3axis(void *p, int axis) +{ + if (!JOYSTICK_PRESENT(0)) + return AXIS_NOT_PRESENT; + + switch (axis) + { + case 0: + return joystick_state[0].axis[0]; + case 1: + return joystick_state[0].axis[1]; + case 2: + return joystick_state[0].axis[2]; + case 3: + return 0; + default: + return 0; + } +} + static int joystick_standard_read_axis_4axis(void *p, int axis) { if (!JOYSTICK_PRESENT(0)) @@ -216,9 +236,9 @@ static void joystick_standard_a0_over(void *p) { } -const joystick_if_t joystick_standard = +const joystick_if_t joystick_2axis_2button = { - "Standard 2-button joystick(s)", + "2-axis, 2-button joystick(s)", joystick_standard_init, joystick_standard_close, joystick_standard_read, @@ -232,9 +252,9 @@ const joystick_if_t joystick_standard = {"X axis", "Y axis"}, {"Button 1", "Button 2"} }; -const joystick_if_t joystick_standard_4button = +const joystick_if_t joystick_2axis_4button = { - "Standard 4-button joystick", + "2-axis, 4-button joystick", joystick_standard_init, joystick_standard_close, joystick_standard_read_4button, @@ -248,9 +268,41 @@ const joystick_if_t joystick_standard_4button = {"X axis", "Y axis"}, {"Button 1", "Button 2", "Button 3", "Button 4"} }; +const joystick_if_t joystick_3axis_2button = +{ + "3-axis, 2-button joystick", + joystick_standard_init, + joystick_standard_close, + joystick_standard_read, + joystick_standard_write, + joystick_standard_read_axis_3axis, + joystick_standard_a0_over, + 3, + 2, + 0, + 1, + {"X axis", "Y axis", "Z axis"}, + {"Button 1", "Button 2"} +}; +const joystick_if_t joystick_3axis_4button = +{ + "3-axis, 4-button joystick", + joystick_standard_init, + joystick_standard_close, + joystick_standard_read_4button, + joystick_standard_write, + joystick_standard_read_axis_3axis, + joystick_standard_a0_over, + 3, + 4, + 0, + 1, + {"X axis", "Y axis", "Z axis"}, + {"Button 1", "Button 2", "Button 3", "Button 4"} +}; const joystick_if_t joystick_4axis_4button = { - "4-axis 4-button joystick", + "4-axis, 4-button joystick", joystick_standard_init, joystick_standard_close, joystick_standard_read_4button, @@ -264,9 +316,9 @@ const joystick_if_t joystick_4axis_4button = {"X axis", "Y axis", "Z axis", "zX axis"}, {"Button 1", "Button 2", "Button 3", "Button 4"} }; -const joystick_if_t joystick_standard_6button = +const joystick_if_t joystick_2axis_6button = { - "Standard 6-button joystick", + "2-axis, 6-button joystick", joystick_standard_init, joystick_standard_close, joystick_standard_read_4button, @@ -280,9 +332,9 @@ const joystick_if_t joystick_standard_6button = {"X axis", "Y axis"}, {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"} }; -const joystick_if_t joystick_standard_8button = +const joystick_if_t joystick_2axis_8button = { - "Standard 8-button joystick", + "2-axis, 8-button joystick", joystick_standard_init, joystick_standard_close, joystick_standard_read_4button, diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index b42f0d55a..172b6826d 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -15,7 +15,7 @@ * connected * - Packet preceeded by high data (currently 50us), and * followed by low data (currently 160us) - timings are - * probably wrong, but good enoughfor everything I've tried + * probably wrong, but good enough for everything I've tried * - Analog inputs are only used to time ID packet request. * If A0 timing out is followed after ~64us by another 0x201 * write then an ID packet is triggered @@ -259,7 +259,7 @@ static void sw_a0_over(void *p) { sw_data *sw = (sw_data *)p; - timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); + timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); } const joystick_if_t joystick_sw_pad = @@ -273,7 +273,7 @@ const joystick_if_t joystick_sw_pad = sw_a0_over, 2, 10, - 0, + 0, 4, {"X axis", "Y axis"}, {"A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M"} diff --git a/src/include/86box/device.h b/src/include/86box/device.h index ec567bf57..040dc3830 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -145,7 +145,7 @@ extern void device_speed_changed(void); extern void device_force_redraw(void); extern void device_get_name(const device_t *d, int bus, char *name); -extern int device_is_valid(const device_t *, int machine_flags); +extern int device_is_valid(const device_t *, int m); extern int device_get_config_int(const char *name); extern int device_get_config_int_ex(const char *s, int dflt_int); diff --git a/src/include/86box/dma.h b/src/include/86box/dma.h index bc09bac97..fc6a0b388 100644 --- a/src/include/86box/dma.h +++ b/src/include/86box/dma.h @@ -98,6 +98,8 @@ extern void dma_bm_write(uint32_t PhysAddress, const uint8_t *DataWrite, uint32_ void dma_set_params(uint8_t advanced, uint32_t mask); void dma_set_mask(uint32_t mask); +void dma_set_at(uint8_t at); + void dma_ext_mode_init(void); void dma_high_page_init(void); diff --git a/src/include/86box/fifo8.h b/src/include/86box/fifo8.h new file mode 100644 index 000000000..d1c32fdd7 --- /dev/null +++ b/src/include/86box/fifo8.h @@ -0,0 +1,149 @@ +#ifndef EMU_FIFO8_H +#define EMU_FIFO8_H + + +typedef struct { + /* All fields are private */ + uint8_t *data; + uint32_t capacity; + uint32_t head; + uint32_t num; +} Fifo8; + +/** + * fifo8_create: + * @fifo: struct Fifo8 to initialise with new FIFO + * @capacity: capacity of the newly created FIFO + * + * Create a FIFO of the specified size. Clients should call fifo8_destroy() + * when finished using the fifo. The FIFO is initially empty. + */ + +extern void fifo8_create(Fifo8 *fifo, uint32_t capacity); + +/** + * fifo8_destroy: + * @fifo: FIFO to cleanup + * + * Cleanup a FIFO created with fifo8_create(). Frees memory created for FIFO + *storage. The FIFO is no longer usable after this has been called. + */ + +extern void fifo8_destroy(Fifo8 *fifo); + +/** + * fifo8_push: + * @fifo: FIFO to push to + * @data: data byte to push + * + * Push a data byte to the FIFO. Behaviour is undefined if the FIFO is full. + * Clients are responsible for checking for fullness using fifo8_is_full(). + */ + +extern void fifo8_push(Fifo8 *fifo, uint8_t data); + +/** + * fifo8_push_all: + * @fifo: FIFO to push to + * @data: data to push + * @size: number of bytes to push + * + * Push a byte array to the FIFO. Behaviour is undefined if the FIFO is full. + * Clients are responsible for checking the space left in the FIFO using + * fifo8_num_free(). + */ + +extern void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num); + +/** + * fifo8_pop: + * @fifo: fifo to pop from + * + * Pop a data byte from the FIFO. Behaviour is undefined if the FIFO is empty. + * Clients are responsible for checking for emptyness using fifo8_is_empty(). + * + * Returns: The popped data byte. + */ + +extern uint8_t fifo8_pop(Fifo8 *fifo); + +/** + * fifo8_pop_buf: + * @fifo: FIFO to pop from + * @max: maximum number of bytes to pop + * @num: actual number of returned bytes + * + * Pop a number of elements from the FIFO up to a maximum of max. The buffer + * containing the popped data is returned. This buffer points directly into + * the FIFO backing store and data is invalidated once any of the fifo8_* APIs + * are called on the FIFO. + * + * The function may return fewer bytes than requested when the data wraps + * around in the ring buffer; in this case only a contiguous part of the data + * is returned. + * + * The number of valid bytes returned is populated in *num; will always return + * at least 1 byte. max must not be 0 or greater than the number of bytes in + * the FIFO. + * + * Clients are responsible for checking the availability of requested data + * using fifo8_num_used(). + * + * Returns: A pointer to popped data. + */ +extern const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num); + +/** + * fifo8_reset: + * @fifo: FIFO to reset + * + * Reset a FIFO. All data is discarded and the FIFO is emptied. + */ + +extern void fifo8_reset(Fifo8 *fifo); + +/** + * fifo8_is_empty: + * @fifo: FIFO to check + * + * Check if a FIFO is empty. + * + * Returns: True if the fifo is empty, false otherwise. + */ + +extern int fifo8_is_empty(Fifo8 *fifo); + +/** + * fifo8_is_full: + * @fifo: FIFO to check + * + * Check if a FIFO is full. + * + * Returns: True if the fifo is full, false otherwise. + */ + +extern int fifo8_is_full(Fifo8 *fifo); + +/** + * fifo8_num_free: + * @fifo: FIFO to check + * + * Return the number of free bytes in the FIFO. + * + * Returns: Number of free bytes. + */ + +extern uint32_t fifo8_num_free(Fifo8 *fifo); + +/** + * fifo8_num_used: + * @fifo: FIFO to check + * + * Return the number of used bytes in the FIFO. + * + * Returns: Number of used bytes. + */ + +extern uint32_t fifo8_num_used(Fifo8 *fifo); + +#endif /* EMU_FIFO8_H */ diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 25027d59e..49a6980de 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -108,6 +108,8 @@ extern "C" { #ifdef EMU_DEVICE_H extern const device_t gameport_device; extern const device_t gameport_201_device; +extern const device_t gameport_208_device; +extern const device_t gameport_209_device; extern const device_t gameport_pnp_device; extern const device_t gameport_pnp_6io_device; extern const device_t gameport_sio_device; diff --git a/src/include/86box/joystick_standard.h b/src/include/86box/joystick_standard.h index eb35c384b..9bc86b204 100644 --- a/src/include/86box/joystick_standard.h +++ b/src/include/86box/joystick_standard.h @@ -35,8 +35,10 @@ * USA. */ -extern const joystick_if_t joystick_standard; -extern const joystick_if_t joystick_standard_4button; +extern const joystick_if_t joystick_2axis_2button; +extern const joystick_if_t joystick_2axis_4button; +extern const joystick_if_t joystick_3axis_2button; +extern const joystick_if_t joystick_3axis_4button; extern const joystick_if_t joystick_4axis_4button; -extern const joystick_if_t joystick_standard_6button; -extern const joystick_if_t joystick_standard_8button; +extern const joystick_if_t joystick_2axis_6button; +extern const joystick_if_t joystick_2axis_8button; diff --git a/src/include/86box/language.h b/src/include/86box/language.h index a1f3ce3aa..467a5704c 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -125,6 +125,8 @@ #define IDS_2149 2149 // "Cassette images (*.PCM;*.RAW;*..." #define IDS_2150 2150 // "Cartridge %i: %ls" #define IDS_2151 2151 // "Cartridge images (*.JRC)\0*.JRC\0..." +#define IDS_2152 2152 // "Error initializing renderer" +#define IDS_2153 2153 // "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." #define IDS_4096 4096 // "Hard disk (%s)" #define IDS_4097 4097 // "%01i:%01i" @@ -233,7 +235,7 @@ #define IDS_LANG_ENUS IDS_7168 -#define STR_NUM_2048 104 +#define STR_NUM_2048 106 #define STR_NUM_3072 11 #define STR_NUM_4096 40 #define STR_NUM_4352 6 diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 161db2ec3..f3fb0928f 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -85,8 +85,8 @@ #define MACHINE_SCSI_DUAL 0x18000000 /* sys has int dual SCSI - mark as both pri and sec SCSI */ #define MACHINE_CARTRIDGE 0x20000000 /* sys has two cartridge bays */ -#define IS_ARCH(m, a) (machines[m].flags & (a)) ? 1 : 0; -#define IS_AT(m) ((machines[m].flags & 0x00000FC8) && !(machines[m].flags & MACHINE_PC98)) ? 1 : 0; +#define IS_ARCH(m, a) ((machines[m].flags & (a)) ? 1 : 0) +#define IS_AT(m) (((machines[m].flags & 0x00000FC8) && !(machines[m].flags & MACHINE_PC98)) ? 1 : 0) #define CPU_BLOCK(...) (const uint8_t[]) {__VA_ARGS__, 0} #define MACHINE_MULTIPLIER_FIXED -1, -1 @@ -182,13 +182,13 @@ extern const machine_type_t machine_types[]; extern const machine_t machines[]; extern int bios_only; extern int machine; -extern int AT, PCI; /* Core functions. */ extern int machine_count(void); extern int machine_available(int m); extern char *machine_getname(void); +extern char *machine_getname_ex(int m); extern char *machine_get_internal_name(void); extern int machine_get_machine_from_internal_name(char *s); extern void machine_init(void); @@ -197,6 +197,13 @@ extern const device_t *machine_getdevice(int m); #endif extern char *machine_get_internal_name_ex(int m); extern int machine_get_nvrmask(int m); +extern int machine_has_flags(int m, int flags); +extern int machine_has_bus(int m, int bus_flags); +extern int machine_has_cartridge(int m); +extern int machine_get_min_ram(int m); +extern int machine_get_max_ram(int m); +extern int machine_get_ram_granularity(int m); +extern int machine_get_type(int m); extern void machine_close(void); @@ -351,7 +358,7 @@ extern int machine_at_greenb_init(const machine_t *); extern int machine_at_r418_init(const machine_t *); extern int machine_at_ls486e_init(const machine_t *); extern int machine_at_4dps_init(const machine_t *); -extern int machine_at_4sa2_init(const machine_t *); +extern int machine_at_4saw2_init(const machine_t *); extern int machine_at_m4li_init(const machine_t *); extern int machine_at_alfredo_init(const machine_t *); extern int machine_at_ninja_init(const machine_t *); diff --git a/src/include/86box/midi.h b/src/include/86box/midi.h index 5ff8b505e..e80fe79d6 100644 --- a/src/include/86box/midi.h +++ b/src/include/86box/midi.h @@ -95,7 +95,8 @@ extern void midi_in_sysex(uint8_t *buffer, uint32_t len); #define MIDI_INPUT_INTERNAL_NAME "midi_in" #ifdef EMU_DEVICE_H -extern const device_t system_midi_device; +extern const device_t rtmidi_device; +extern const device_t rtmidi_input_device; #ifdef USE_FLUIDSYNTH extern const device_t fluidsynth_device; #endif diff --git a/src/include/86box/midi_input.h b/src/include/86box/midi_input.h deleted file mode 100644 index 163d6fa91..000000000 --- a/src/include/86box/midi_input.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t midi_input_device; diff --git a/src/include/86box/midi_rtmidi.h b/src/include/86box/midi_rtmidi.h new file mode 100644 index 000000000..beaccdf54 --- /dev/null +++ b/src/include/86box/midi_rtmidi.h @@ -0,0 +1,13 @@ +#ifdef __cplusplus +extern "C" +{ +#endif + +extern int rtmidi_get_num_devs(void); +extern void rtmidi_get_dev_name(int num, char *s); +extern int rtmidi_in_get_num_devs(void); +extern void rtmidi_in_get_dev_name(int num, char *s); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/include/86box/midi_system.h b/src/include/86box/midi_system.h deleted file mode 100644 index b79bbf96f..000000000 --- a/src/include/86box/midi_system.h +++ /dev/null @@ -1 +0,0 @@ -extern const device_t system_midi_device; diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 82bdb01c3..b841d7e6a 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -67,7 +67,7 @@ typedef struct _nvr_ { char *fn; /* pathname of image file */ uint16_t size; /* device configuration */ - int8_t irq, new; + int8_t irq, is_new; uint8_t onesec_cnt; pc_timer_t onesec_time; @@ -112,6 +112,7 @@ extern int nvr_save(void); extern int nvr_is_leap(int year); extern int nvr_get_days(int month, int year); +extern void nvr_time_sync(); extern void nvr_time_get(struct tm *); extern void nvr_time_set(struct tm *); diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index b9fa700bf..919f14ac2 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -98,8 +98,6 @@ extern void pci_set_irq_level(int pci_int, int level); extern void pci_enable_mirq(int mirq); extern void pci_set_mirq_routing(int mirq, int irq); -extern uint8_t pci_use_mirq(uint8_t mirq); - extern int pci_irq_is_level(int irq); extern void pci_set_mirq(uint8_t mirq, int level); @@ -127,6 +125,8 @@ extern void trc_write(uint16_t port, uint8_t val, void *priv); extern void pci_bridge_set_ctl(void *priv, uint8_t ctl); +extern void pci_pic_reset(void); + #ifdef EMU_DEVICE_H extern const device_t dec21150_device; diff --git a/src/include/86box/pic.h b/src/include/86box/pic.h index 33be66135..73b316f2e 100644 --- a/src/include/86box/pic.h +++ b/src/include/86box/pic.h @@ -45,6 +45,7 @@ extern void pic_elcr_write(uint16_t port, uint8_t val, void *priv); extern uint8_t pic_elcr_read(uint16_t port, void *priv); extern void pic_set_shadow(int sh); +extern void pic_set_pci_flag(int pci); extern void pic_set_pci(void); extern void pic_init(void); extern void pic_init_pcjr(void); diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index ca116a684..78795d757 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -63,13 +63,18 @@ extern int strnicmp(const char* s1, const char* s2, size_t n); #ifdef __cplusplus +#include +#define atomic_flag_t std::atomic_flag extern "C" { +#else +#include +#define atomic_flag_t atomic_flag #endif /* Global variables residing in the platform module. */ extern int dopause, /* system is paused */ - doresize, /* screen resize requested */ mouse_capture; /* mouse is captured in app */ +extern atomic_flag_t doresize; /* screen resize requested */ extern volatile int is_quit; /* system exit requested */ #ifdef MTR_ENABLED @@ -165,7 +170,7 @@ typedef void event_t; typedef void mutex_t; extern thread_t *thread_create(void (*thread_func)(void *param), void *param); -extern int thread_wait(thread_t *arg, int timeout); +extern int thread_wait(thread_t *arg); extern event_t *thread_create_event(void); extern void thread_set_event(event_t *arg); extern void thread_reset_event(event_t *arg); @@ -175,7 +180,6 @@ extern void thread_destroy_event(event_t *arg); #define MUTEX_DEFAULT_SPIN_COUNT 1024 extern mutex_t *thread_create_mutex(void); -extern mutex_t *thread_create_mutex_with_spin_count(unsigned int spin_count); extern void thread_close_mutex(mutex_t *arg); extern int thread_wait_mutex(mutex_t *arg); extern int thread_release_mutex(mutex_t *mutex); diff --git a/src/include/86box/plat_midi.h b/src/include/86box/plat_midi.h deleted file mode 100644 index 933e49ee6..000000000 --- a/src/include/86box/plat_midi.h +++ /dev/null @@ -1,15 +0,0 @@ -extern void plat_midi_init(void); -extern void plat_midi_close(void); - -extern void plat_midi_play_msg(uint8_t *msg); -extern void plat_midi_play_sysex(uint8_t *sysex, unsigned int len); -extern int plat_midi_write(uint8_t val); - -extern int plat_midi_get_num_devs(void); -extern void plat_midi_get_dev_name(int num, char *s); - -extern void plat_midi_input_init(void); -extern void plat_midi_input_close(void); - -extern int plat_midi_in_get_num_devs(void); -extern void plat_midi_in_get_dev_name(int num, char *s); diff --git a/src/include/86box/scsi_pcscsi.h b/src/include/86box/scsi_pcscsi.h index a6bfa6999..e21fa3801 100644 --- a/src/include/86box/scsi_pcscsi.h +++ b/src/include/86box/scsi_pcscsi.h @@ -27,6 +27,7 @@ extern const device_t dc390_pci_device; +extern const device_t ncr53c90_mca_device; #endif /*SCSI_BUSLOGIC_H*/ diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 576c0c12e..5203c17f8 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -6,7 +6,8 @@ * * This file is part of the 86Box distribution. * - * Definitions for the NS8250/16450/16550 UART emulation. + * Definitions for the NS8250/16450/16550/16650/16750/16850/16950 + * UART emulation. * * * @@ -22,10 +23,14 @@ # define EMU_SERIAL_H -#define SERIAL_8250 0 +#define SERIAL_8250 0 #define SERIAL_8250_PCJR 1 -#define SERIAL_NS16450 2 -#define SERIAL_NS16550 3 +#define SERIAL_16450 2 +#define SERIAL_16550 3 +#define SERIAL_16650 4 +#define SERIAL_16750 5 +#define SERIAL_16850 6 +#define SERIAL_16950 7 #define SERIAL_FIFO_SIZE 16 @@ -39,8 +44,6 @@ #define SERIAL4_ADDR 0x02e8 #define SERIAL4_IRQ 3 -#define MAX_SERIAL 4 - struct serial_device_s; struct serial_s; @@ -89,10 +92,14 @@ extern void serial_standalone_init(void); extern void serial_set_clock_src(serial_t *dev, double clock_src); extern void serial_reset_port(serial_t *dev); -extern const device_t i8250_device; -extern const device_t i8250_pcjr_device; +extern const device_t ns8250_device; +extern const device_t ns8250_pcjr_device; extern const device_t ns16450_device; extern const device_t ns16550_device; +extern const device_t ns16650_device; +extern const device_t ns16750_device; +extern const device_t ns16850_device; +extern const device_t ns16950_device; #endif /*EMU_SERIAL_H*/ diff --git a/src/include/86box/snd_sb_dsp.h b/src/include/86box/snd_sb_dsp.h index f4626890d..2e6e7eb8f 100644 --- a/src/include/86box/snd_sb_dsp.h +++ b/src/include/86box/snd_sb_dsp.h @@ -66,6 +66,11 @@ typedef struct sb_dsp_t int sb_irqm8, sb_irqm16, sb_irqm401; uint8_t sb_asp_regs[256]; + uint8_t sb_asp_mode; + + uint8_t sb_asp_ram[2048]; + int sb_asp_ram_index; + uint8_t sb_8051_ram[256]; int sbenable, sb_enable_i; diff --git a/src/include/86box/ui.h b/src/include/86box/ui.h index 8b4e77fcd..256ae6002 100644 --- a/src/include/86box/ui.h +++ b/src/include/86box/ui.h @@ -66,6 +66,7 @@ extern void ui_status_update(void); extern int ui_sb_find_part(int tag); extern void ui_sb_set_ready(int ready); extern void ui_sb_update_panes(void); +extern void ui_sb_update_text(void); extern void ui_sb_update_tip(int meaning); extern void ui_sb_timer_callback(int pane); extern void ui_sb_update_icon(int tag, int val); diff --git a/src/include/glad/glad.h b/src/include/glad/glad.h index f8a96f376..0b4d36656 100644 --- a/src/include/glad/glad.h +++ b/src/include/glad/glad.h @@ -1,23 +1,24 @@ /* - OpenGL loader generated by glad 0.1.34 on Tue Apr 27 15:16:07 2021. + OpenGL loader generated by glad 0.1.34 on Sat Dec 4 18:46:02 2021. Language/Generator: C/C++ Specification: gl - APIs: gl=3.3 + APIs: gl=3.0 Profile: core Extensions: GL_ARB_buffer_storage, - GL_ARB_debug_output + GL_ARB_debug_output, + GL_ARB_sync Loader: True Local files: False Omit khrplatform: False Reproducible: False Commandline: - --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_debug_output" + --profile="core" --api="gl=3.0" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_debug_output,GL_ARB_sync" Online: - https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_debug_output + https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.0&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_debug_output&extensions=GL_ARB_sync */ @@ -811,147 +812,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); #define GL_RG32I 0x823B #define GL_RG32UI 0x823C #define GL_VERTEX_ARRAY_BINDING 0x85B5 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFF -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_DEPTH_CLAMP 0x864F -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -#define GL_SRC1_COLOR 0x88F9 -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#define GL_SAMPLER_BINDING 0x8919 -#define GL_RGB10_A2UI 0x906F -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIMESTAMP 0x8E28 -#define GL_INT_2_10_10_10_REV 0x8D9F #ifndef GL_VERSION_1_0 #define GL_VERSION_1_0 1 GLAPI int GLAD_GL_VERSION_1_0; @@ -1843,285 +1703,6 @@ typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC)(GLuint array); GLAPI PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; #define glIsVertexArray glad_glIsVertexArray #endif -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 -GLAPI int GLAD_GL_VERSION_3_1; -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -GLAPI PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; -#define glDrawArraysInstanced glad_glDrawArraysInstanced -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); -GLAPI PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; -#define glDrawElementsInstanced glad_glDrawElementsInstanced -typedef void (APIENTRYP PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); -GLAPI PFNGLTEXBUFFERPROC glad_glTexBuffer; -#define glTexBuffer glad_glTexBuffer -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); -GLAPI PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; -#define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; -#define glCopyBufferSubData glad_glCopyBufferSubData -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); -GLAPI PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; -#define glGetUniformIndices glad_glGetUniformIndices -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -GLAPI PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; -#define glGetActiveUniformsiv glad_glGetActiveUniformsiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -GLAPI PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; -#define glGetActiveUniformName glad_glGetActiveUniformName -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar *uniformBlockName); -GLAPI PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; -#define glGetUniformBlockIndex glad_glGetUniformBlockIndex -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; -#define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -GLAPI PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; -#define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -GLAPI PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; -#define glUniformBlockBinding glad_glUniformBlockBinding -#endif -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 -GLAPI int GLAD_GL_VERSION_3_2; -typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; -#define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); -GLAPI PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; -#define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -GLAPI PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; -#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); -GLAPI PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; -#define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC)(GLenum mode); -GLAPI PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; -#define glProvokingVertex glad_glProvokingVertex -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); -GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; -#define glFenceSync glad_glFenceSync -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync); -GLAPI PFNGLISSYNCPROC glad_glIsSync; -#define glIsSync glad_glIsSync -typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync); -GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; -#define glDeleteSync glad_glDeleteSync -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; -#define glClientWaitSync glad_glClientWaitSync -typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; -#define glWaitSync glad_glWaitSync -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 *data); -GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; -#define glGetInteger64v glad_glGetInteger64v -typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); -GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; -#define glGetSynciv glad_glGetSynciv -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 *data); -GLAPI PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; -#define glGetInteger64i_v glad_glGetInteger64i_v -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 *params); -GLAPI PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; -#define glGetBufferParameteri64v glad_glGetBufferParameteri64v -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; -#define glFramebufferTexture glad_glFramebufferTexture -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; -#define glTexImage2DMultisample glad_glTexImage2DMultisample -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; -#define glTexImage3DMultisample glad_glTexImage3DMultisample -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat *val); -GLAPI PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; -#define glGetMultisamplefv glad_glGetMultisamplefv -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); -GLAPI PFNGLSAMPLEMASKIPROC glad_glSampleMaski; -#define glSampleMaski glad_glSampleMaski -#endif -#ifndef GL_VERSION_3_3 -#define GL_VERSION_3_3 1 -GLAPI int GLAD_GL_VERSION_3_3; -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -GLAPI PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; -#define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed -typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar *name); -GLAPI PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; -#define glGetFragDataIndex glad_glGetFragDataIndex -typedef void (APIENTRYP PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint *samplers); -GLAPI PFNGLGENSAMPLERSPROC glad_glGenSamplers; -#define glGenSamplers glad_glGenSamplers -typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint *samplers); -GLAPI PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; -#define glDeleteSamplers glad_glDeleteSamplers -typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC)(GLuint sampler); -GLAPI PFNGLISSAMPLERPROC glad_glIsSampler; -#define glIsSampler glad_glIsSampler -typedef void (APIENTRYP PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); -GLAPI PFNGLBINDSAMPLERPROC glad_glBindSampler; -#define glBindSampler glad_glBindSampler -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); -GLAPI PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; -#define glSamplerParameteri glad_glSamplerParameteri -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint *param); -GLAPI PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; -#define glSamplerParameteriv glad_glSamplerParameteriv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); -GLAPI PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; -#define glSamplerParameterf glad_glSamplerParameterf -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat *param); -GLAPI PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; -#define glSamplerParameterfv glad_glSamplerParameterfv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint *param); -GLAPI PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; -#define glSamplerParameterIiv glad_glSamplerParameterIiv -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint *param); -GLAPI PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; -#define glSamplerParameterIuiv glad_glSamplerParameterIuiv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; -#define glGetSamplerParameteriv glad_glGetSamplerParameteriv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; -#define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat *params); -GLAPI PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; -#define glGetSamplerParameterfv glad_glGetSamplerParameterfv -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint *params); -GLAPI PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; -#define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv -typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); -GLAPI PFNGLQUERYCOUNTERPROC glad_glQueryCounter; -#define glQueryCounter glad_glQueryCounter -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 *params); -GLAPI PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; -#define glGetQueryObjecti64v glad_glGetQueryObjecti64v -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 *params); -GLAPI PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; -#define glGetQueryObjectui64v glad_glGetQueryObjectui64v -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); -GLAPI PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; -#define glVertexAttribDivisor glad_glVertexAttribDivisor -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; -#define glVertexAttribP1ui glad_glVertexAttribP1ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; -#define glVertexAttribP1uiv glad_glVertexAttribP1uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; -#define glVertexAttribP2ui glad_glVertexAttribP2ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; -#define glVertexAttribP2uiv glad_glVertexAttribP2uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; -#define glVertexAttribP3ui glad_glVertexAttribP3ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; -#define glVertexAttribP3uiv glad_glVertexAttribP3uiv -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; -#define glVertexAttribP4ui glad_glVertexAttribP4ui -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; -#define glVertexAttribP4uiv glad_glVertexAttribP4uiv -typedef void (APIENTRYP PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); -GLAPI PFNGLVERTEXP2UIPROC glad_glVertexP2ui; -#define glVertexP2ui glad_glVertexP2ui -typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint *value); -GLAPI PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; -#define glVertexP2uiv glad_glVertexP2uiv -typedef void (APIENTRYP PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); -GLAPI PFNGLVERTEXP3UIPROC glad_glVertexP3ui; -#define glVertexP3ui glad_glVertexP3ui -typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint *value); -GLAPI PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; -#define glVertexP3uiv glad_glVertexP3uiv -typedef void (APIENTRYP PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); -GLAPI PFNGLVERTEXP4UIPROC glad_glVertexP4ui; -#define glVertexP4ui glad_glVertexP4ui -typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint *value); -GLAPI PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; -#define glVertexP4uiv glad_glVertexP4uiv -typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; -#define glTexCoordP1ui glad_glTexCoordP1ui -typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; -#define glTexCoordP1uiv glad_glTexCoordP1uiv -typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; -#define glTexCoordP2ui glad_glTexCoordP2ui -typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; -#define glTexCoordP2uiv glad_glTexCoordP2uiv -typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; -#define glTexCoordP3ui glad_glTexCoordP3ui -typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; -#define glTexCoordP3uiv glad_glTexCoordP3uiv -typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; -#define glTexCoordP4ui glad_glTexCoordP4ui -typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; -#define glTexCoordP4uiv glad_glTexCoordP4uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; -#define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; -#define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; -#define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; -#define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; -#define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; -#define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); -GLAPI PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; -#define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); -GLAPI PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; -#define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv -typedef void (APIENTRYP PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); -GLAPI PFNGLNORMALP3UIPROC glad_glNormalP3ui; -#define glNormalP3ui glad_glNormalP3ui -typedef void (APIENTRYP PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint *coords); -GLAPI PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; -#define glNormalP3uiv glad_glNormalP3uiv -typedef void (APIENTRYP PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); -GLAPI PFNGLCOLORP3UIPROC glad_glColorP3ui; -#define glColorP3ui glad_glColorP3ui -typedef void (APIENTRYP PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint *color); -GLAPI PFNGLCOLORP3UIVPROC glad_glColorP3uiv; -#define glColorP3uiv glad_glColorP3uiv -typedef void (APIENTRYP PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); -GLAPI PFNGLCOLORP4UIPROC glad_glColorP4ui; -#define glColorP4ui glad_glColorP4ui -typedef void (APIENTRYP PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint *color); -GLAPI PFNGLCOLORP4UIVPROC glad_glColorP4uiv; -#define glColorP4uiv glad_glColorP4uiv -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); -GLAPI PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; -#define glSecondaryColorP3ui glad_glSecondaryColorP3ui -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint *color); -GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; -#define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv -#endif #define GL_MAP_PERSISTENT_BIT 0x0040 #define GL_MAP_COHERENT_BIT 0x0080 #define GL_DYNAMIC_STORAGE_BIT 0x0100 @@ -2151,6 +1732,21 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 +#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 +#define GL_OBJECT_TYPE 0x9112 +#define GL_SYNC_CONDITION 0x9113 +#define GL_SYNC_STATUS 0x9114 +#define GL_SYNC_FLAGS 0x9115 +#define GL_SYNC_FENCE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 +#define GL_UNSIGNALED 0x9118 +#define GL_SIGNALED 0x9119 +#define GL_ALREADY_SIGNALED 0x911A +#define GL_TIMEOUT_EXPIRED 0x911B +#define GL_CONDITION_SATISFIED 0x911C +#define GL_WAIT_FAILED 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFF #ifndef GL_ARB_buffer_storage #define GL_ARB_buffer_storage 1 GLAPI int GLAD_GL_ARB_buffer_storage; @@ -2174,6 +1770,31 @@ typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC)(GLuint count, GLsizei GLAPI PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; #define glGetDebugMessageLogARB glad_glGetDebugMessageLogARB #endif +#ifndef GL_ARB_sync +#define GL_ARB_sync 1 +GLAPI int GLAD_GL_ARB_sync; +typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); +GLAPI PFNGLFENCESYNCPROC glad_glFenceSync; +#define glFenceSync glad_glFenceSync +typedef GLboolean (APIENTRYP PFNGLISSYNCPROC)(GLsync sync); +GLAPI PFNGLISSYNCPROC glad_glIsSync; +#define glIsSync glad_glIsSync +typedef void (APIENTRYP PFNGLDELETESYNCPROC)(GLsync sync); +GLAPI PFNGLDELETESYNCPROC glad_glDeleteSync; +#define glDeleteSync glad_glDeleteSync +typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; +#define glClientWaitSync glad_glClientWaitSync +typedef void (APIENTRYP PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); +GLAPI PFNGLWAITSYNCPROC glad_glWaitSync; +#define glWaitSync glad_glWaitSync +typedef void (APIENTRYP PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 *data); +GLAPI PFNGLGETINTEGER64VPROC glad_glGetInteger64v; +#define glGetInteger64v glad_glGetInteger64v +typedef void (APIENTRYP PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); +GLAPI PFNGLGETSYNCIVPROC glad_glGetSynciv; +#define glGetSynciv glad_glGetSynciv +#endif #ifdef __cplusplus } diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index b2eb49aaf..9228c68e3 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -20,9 +20,9 @@ #define EMU_NAME "86Box" #define EMU_NAME_W LSTR(EMU_NAME) -#define EMU_VERSION "3.1" +#define EMU_VERSION "3.2" #define EMU_VERSION_W LSTR(EMU_VERSION) -#define EMU_VERSION_EX "3.01" +#define EMU_VERSION_EX "3.02" #define EMU_VERSION_MAJ 3 #define EMU_VERSION_MIN 0 #define EMU_VERSION_PATCH 0 diff --git a/src/mac/CMakeLists.txt b/src/mac/CMakeLists.txt index 1bfd8c11e..91759690f 100644 --- a/src/mac/CMakeLists.txt +++ b/src/mac/CMakeLists.txt @@ -1,3 +1,53 @@ -include_directories("./mac") -target_sources(86Box PUBLIC "./macOSXGlue.m") +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: dob205, +# Jerome Vernet +# David Hrdlička, +# +# Copyright 2021 dob205. +# Copyright 2021 Jerome Vernet. +# Copyright 2021 David Hrdlička. +# +# Pick the bundle icon depending on the release channel +if(RELEASE_BUILD) + set(APP_ICON_MACOSX icons/release/86Box.icns) +elseif(BETA_BUILD) + set(APP_ICON_MACOSX icons/beta/86Box.icns) +elseif(ALPHA_BUILD) + set(APP_ICON_MACOSX icons/dev/86Box.icns) +else() + set(APP_ICON_MACOSX icons/branch/86Box.icns) +endif() + +target_link_libraries(86Box "-framework AppKit") +target_sources(86Box PRIVATE macOSXGlue.m ${APP_ICON_MACOSX}) + +# Make sure the icon is copied to the bundle +set_source_files_properties(${APP_ICON_MACOSX} + TARGET_DIRECTORY 86Box + PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") + +# Prepare long version string +if(EMU_BUILD) + set(LONG_VER_STRING "${CMAKE_PROJECT_VERSION} [${EMU_BUILD}]") +else() + set(LONG_VER_STRING "${CMAKE_PROJECT_VERSION}") +endif() + +# Generate Info.plist +configure_file(Info.plist.in Info.plist @ONLY) +set_target_properties(86Box + PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) + +#set(XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES") +#set(XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-") +#set(XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/mac/codesign/dev/app.entitlements) \ No newline at end of file diff --git a/src/mac/Info.plist.in b/src/mac/Info.plist.in index e06b17ecf..2f2080460 100644 --- a/src/mac/Info.plist.in +++ b/src/mac/Info.plist.in @@ -7,29 +7,29 @@ CFBundleExecutable ${MACOSX_BUNDLE_EXECUTABLE_NAME} CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} + An emulator of old computers CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} + 86Box.icns CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} + net.86Box.86Box CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} + @LONG_VER_STRING@ CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} + 86Box CFBundlePackageType APPL CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + @CMAKE_PROJECT_VERSION@ CFBundleSignature ???? CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} + @CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@.@CMAKE_PROJECT_VERSION_PATCH@.@EMU_BUILD_NUM@ CSResourcesFileMapped NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} + © 2007-@EMU_COPYRIGHT_YEAR@ 86Box contributors NSPrincipalClass NSApplication NSHighResolutionCapable diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt index d2500561a..a20c105fe 100644 --- a/src/machine/CMakeLists.txt +++ b/src/machine/CMakeLists.txt @@ -1,42 +1,38 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c - m_xt_philips.c - m_xt_t1000.c m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c - m_amstrad.c m_europc.c m_xt_olivetti.c m_tandy.c m_v86p.c - m_at.c m_at_commodore.c - m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c - m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c - m_at_socket4.c m_at_socket5.c m_at_socket7_3v.c m_at_socket7.c - m_at_sockets7.c m_at_socket8.c m_at_slot1.c m_at_slot2.c m_at_socket370.c - m_at_misc.c) + m_xt_philips.c + m_xt_t1000.c m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c + m_amstrad.c m_europc.c m_xt_olivetti.c m_tandy.c m_v86p.c + m_at.c m_at_commodore.c + m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c + m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c + m_at_socket4.c m_at_socket5.c m_at_socket7_3v.c m_at_socket7.c + m_at_sockets7.c m_at_socket8.c m_at_slot1.c m_at_slot2.c m_at_socket370.c + m_at_misc.c) if(LASERXT) - target_sources(mch PRIVATE m_xt_laserxt.c) - target_compile_definitions(mch PRIVATE USE_LASERXT) + target_sources(mch PRIVATE m_xt_laserxt.c) + target_compile_definitions(mch PRIVATE USE_LASERXT) endif() if(NO_SIO) - target_compile_definitions(mch PRIVATE NO_SIO) + target_compile_definitions(mch PRIVATE NO_SIO) endif() if(OPEN_AT) - target_compile_definitions(mch PRIVATE USE_OPEN_AT) -endif() - -if(M154X) - target_compile_definitions(mch PRIVATE USE_M154X) + target_compile_definitions(mch PRIVATE USE_OPEN_AT) endif() \ No newline at end of file diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index ee9a5e489..9bb4ff21e 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -1025,11 +1025,11 @@ machine_at_486sp3c_init(const machine_t *model) int -machine_at_4sa2_init(const machine_t *model) +machine_at_4saw2_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/4sa2/4saw0911.bin", + ret = bios_load_linear("roms/machines/4saw2/4saw0911.bin", 0x000e0000, 131072, 0); if (bios_only || !ret) diff --git a/src/machine/m_at_commodore.c b/src/machine/m_at_commodore.c index 7d00e51bb..8aa75059f 100644 --- a/src/machine/m_at_commodore.c +++ b/src/machine/m_at_commodore.c @@ -112,7 +112,7 @@ machine_at_cmdpc_init(const machine_t *model) if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - cmd_uart = device_add(&i8250_device); + cmd_uart = device_add(&ns8250_device); cbm_io_init(); diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 482c26ed6..80c982bee 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -866,8 +866,8 @@ machine_pcjr_init(const machine_t *model) device_add(&fdc_pcjr_device); - device_add(&i8250_pcjr_device); - serial_set_next_inst(MAX_SERIAL); /* So that serial_standalone_init() won't do anything. */ + device_add(&ns8250_pcjr_device); + serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ return ret; } diff --git a/src/machine/m_ps2_mca.c b/src/machine/m_ps2_mca.c index ed44b35a7..549168ffb 100644 --- a/src/machine/m_ps2_mca.c +++ b/src/machine/m_ps2_mca.c @@ -82,9 +82,8 @@ static struct uint8_t memory_bank[8]; uint8_t io_id; - uint16_t planar_id; - - mem_mapping_t shadow_mapping; + uint16_t planar_id; + mem_mapping_t split_mapping; mem_mapping_t expansion_mapping; mem_mapping_t cache_mapping; @@ -203,7 +202,7 @@ static uint32_t ps2_read_cache_raml(uint32_t addr, void *priv) } static void ps2_write_cache_ram(uint32_t addr, uint8_t val, void *priv) { - ps2_mca_log("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc, ins); + ps2_mca_log("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc); ps2_cache[addr] = val; } @@ -212,37 +211,6 @@ void ps2_cache_clean(void) memset(ps2_cache_valid, 0, sizeof(ps2_cache_valid)); } -static uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - return mem_read_ram(addr, priv); -} -static uint16_t ps2_read_shadow_ramw(uint32_t addr, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - return mem_read_ramw(addr, priv); -} -static uint32_t ps2_read_shadow_raml(uint32_t addr, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - return mem_read_raml(addr, priv); -} -static void ps2_write_shadow_ram(uint32_t addr, uint8_t val, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - mem_write_ram(addr, val, priv); -} -static void ps2_write_shadow_ramw(uint32_t addr, uint16_t val, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - mem_write_ramw(addr, val, priv); -} -static void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv) -{ - addr = (addr & 0x1ffff) + 0xe0000; - mem_write_raml(addr, val, priv); -} - static uint8_t ps2_read_split_ram(uint32_t addr, void *priv) { addr = (addr % (ps2.split_size << 10)) + ps2.split_phys; @@ -430,6 +398,85 @@ static void model_50_write(uint16_t port, uint8_t val) } } + +static void model_55sx_mem_recalc(void) +{ + int i, j, state, enabled_mem = 0; + int base = 0, remap_size = (ps2.option[3] & 0x10) ? 384 : 256; + int bit_mask = 0x00, max_rows = 4; + int bank_to_rows[16] = { 4, 2, 1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 2, 1, 0 }; + + ps2_mca_log("%02X %02X\n", ps2.option[1], ps2.option[3]); + + mem_remap_top(remap_size); + mem_set_mem_state(0x00000000, (mem_size + 384) * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x000e0000, 0x00020000, MEM_READ_EXTANY | MEM_WRITE_DISABLED); + + for (i = 0; i < 2; i++) + { + max_rows = bank_to_rows[(ps2.memory_bank[i] >> 4) & 0x0f]; + + if (max_rows == 0) + continue; + + for (j = 0; j < max_rows; j++) + { + if (ps2.memory_bank[i] & (1 << j)) { + ps2_mca_log("Set memory at %06X-%06X to internal\n", (base * 1024), (base * 1024) + (((base > 0) ? 1024 : 640) * 1024) - 1); + mem_set_mem_state(base * 1024, ((base > 0) ? 1024 : 640) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + enabled_mem += 1024; + bit_mask |= (1 << (j + (i << 2))); + } + base += 1024; + } + } + + ps2_mca_log("Enabled memory: %i kB (%02X)\n", enabled_mem, bit_mask); + + if (ps2.option[3] & 0x10) + { + /* Enable ROM. */ + ps2_mca_log("Enable ROM\n"); + state = MEM_READ_EXTANY; + } + else + { + /* Disable ROM. */ + if ((ps2.option[1] & 1) && !(ps2.option[3] & 0x20) && (bit_mask & 0x01)) + { + /* Disable RAM between 640 kB and 1 MB. */ + ps2_mca_log("Disable ROM, enable RAM\n"); + state = MEM_READ_INTERNAL; + } + else + { + ps2_mca_log("Disable ROM, disable RAM\n"); + state = MEM_READ_DISABLED; + } + } + + /* Write always disabled. */ + state |= MEM_WRITE_DISABLED; + + mem_set_mem_state(0xe0000, 0x20000, state); + + /* if (!(ps2.option[3] & 0x08)) + { + ps2_mca_log("Memory not yet configured\n"); + return; + } */ + + ps2_mca_log("Enable shadow mapping at %06X-%06X\n", (mem_size * 1024), (mem_size * 1024) + (remap_size * 1024) - 1); + + if ((ps2.option[1] & 1) && !(ps2.option[3] & 0x20) && (bit_mask & 0x01)) { + ps2_mca_log("Set memory at %06X-%06X to internal\n", (mem_size * 1024), (mem_size * 1024) + (remap_size * 1024) - 1); + mem_set_mem_state(mem_size * 1024, remap_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + + flushmmucache_nopc(); +} + + static void model_55sx_write(uint16_t port, uint8_t val) { switch (port) @@ -467,38 +514,20 @@ static void model_55sx_write(uint16_t port, uint8_t val) ps2.option[0] = val; break; case 0x103: + ps2_mca_log("Write POS1: %02X\n", val); ps2.option[1] = val; - break; + model_55sx_mem_recalc(); + break; case 0x104: ps2.memory_bank[ps2.option[3] & 7] &= ~0xf; ps2.memory_bank[ps2.option[3] & 7] |= (val & 0xf); - ps2_mca_log("Write memory bank %i %02x\n", ps2.option[3] & 7, val); + ps2_mca_log("Write memory bank %i: %02X\n", ps2.option[3] & 7, val); + model_55sx_mem_recalc(); break; case 0x105: - ps2_mca_log("Write POS3 %02x\n", val); + ps2_mca_log("Write POS3: %02X\n", val); ps2.option[3] = val; - shadowbios = !(val & 0x10); - shadowbios_write = val & 0x10; - - if (shadowbios) - { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - mem_set_mem_state((mem_size+256) * 1024, 128 * 1024, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - mem_mapping_disable(&ps2.shadow_mapping); - } - else - { - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - mem_set_mem_state((mem_size+256) * 1024, 128 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_enable(&ps2.shadow_mapping); - } - - if ((ps2.option[1] & 1) && !(ps2.option[3] & 0x20)) - mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else - mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - - flushmmucache_nopc(); + model_55sx_mem_recalc(); break; case 0x106: ps2.subaddr_lo = val; @@ -833,13 +862,8 @@ static void ps2_mca_mem_fffc_init(int start_mb) { uint32_t planar_size, expansion_start; - if (start_mb == 2) { - planar_size = 0x160000; - expansion_start = 0x260000; - } else { - planar_size = (start_mb - 1) << 20; - expansion_start = start_mb << 20; - } + planar_size = (start_mb - 1) << 20; + expansion_start = start_mb << 20; mem_mapping_set_addr(&ram_high_mapping, 0x100000, planar_size); @@ -890,6 +914,36 @@ static void ps2_mca_mem_fffc_init(int start_mb) mem_mapping_disable(&ps2.expansion_mapping); } +static void ps2_mca_mem_d071_init(int start_mb) +{ + uint32_t planar_size, expansion_start; + + planar_size = (start_mb - 1) << 20; + expansion_start = start_mb << 20; + + mem_mapping_set_addr(&ram_high_mapping, 0x100000, planar_size); + + ps2.mem_pos_regs[0] = 0xd0; + ps2.mem_pos_regs[1] = 0x71; + ps2.mem_pos_regs[4] = (mem_size / 1024) - start_mb; + + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, ps2_mem_expansion_feedb, NULL, NULL); + mem_mapping_add(&ps2.expansion_mapping, + expansion_start, + (mem_size - (start_mb << 10)) << 10, + mem_read_ram, + mem_read_ramw, + mem_read_raml, + mem_write_ram, + mem_write_ramw, + mem_write_raml, + &ram[expansion_start], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.expansion_mapping); +} + + static void ps2_mca_board_model_50_init() { ps2_mca_board_common_init(); @@ -914,22 +968,9 @@ static void ps2_mca_board_model_50_init() static void ps2_mca_board_model_55sx_init() { ps2_mca_board_common_init(); - - mem_mapping_add(&ps2.shadow_mapping, - (mem_size+256) * 1024, - 128*1024, - ps2_read_shadow_ram, - ps2_read_shadow_ramw, - ps2_read_shadow_raml, - ps2_write_shadow_ram, - ps2_write_shadow_ramw, - ps2_write_shadow_raml, - &ram[0xe0000], - MEM_MAPPING_INTERNAL, - NULL); - - mem_remap_top(256); + ps2.option[1] = 0x00; + ps2.option[2] = 0x00; ps2.option[3] = 0x10; memset(ps2.memory_bank, 0xf0, 8); @@ -975,9 +1016,11 @@ static void ps2_mca_board_model_55sx_init() if (gfxcard == VID_INTERNAL) device_add(&ps1vga_mca_device); + + model_55sx_mem_recalc(); } -static void mem_encoding_update() +static void mem_encoding_update(void) { mem_mapping_disable(&ps2.split_mapping); @@ -987,6 +1030,8 @@ static void mem_encoding_update() mem_set_mem_state(1 << 20, (mem_size << 10) - (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); ps2.split_addr = ((uint32_t) (ps2.mem_regs[0] & 0xf)) << 20; + if (!ps2.split_addr) + ps2.split_addr = 1 << 20; if (ps2.mem_regs[1] & 2) { mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); @@ -1192,14 +1237,22 @@ static void ps2_mca_board_model_70_type34_init(int is_type4, int slots) if (ps2.planar_id == 0xfff9) { if (mem_size > 4096) { - /* Only 4 MB supported on planar, create a memory expansion card for the rest */ - ps2_mca_mem_fffc_init(4); + /* Only 4 MB supported on planar, create a memory expansion card for the rest */ + if (mem_size > 12288) { + ps2_mca_mem_d071_init(4); + } else { + ps2_mca_mem_fffc_init(4); + } } } else { if (mem_size > 8192) { - /* Only 8 MB supported on planar, create a memory expansion card for the rest */ - ps2_mca_mem_fffc_init(8); + /* Only 8 MB supported on planar, create a memory expansion card for the rest */ + if (mem_size > 16384) + ps2_mca_mem_d071_init(8); + else { + ps2_mca_mem_fffc_init(8); + } } } @@ -1270,8 +1323,12 @@ static void ps2_mca_board_model_80_type2_init(int is486) if ((mem_size > 4096) && !is486) { - /* Only 4 MB supported on planar, create a memory expansion card for the rest */ - ps2_mca_mem_fffc_init(4); + /* Only 4 MB supported on planar, create a memory expansion card for the rest */ + if (mem_size > 12288) + ps2_mca_mem_d071_init(4); + else { + ps2_mca_mem_fffc_init(4); + } } if (gfxcard == VID_INTERNAL) diff --git a/src/machine/m_xt_zenith.c b/src/machine/m_xt_zenith.c index 791ebdcd1..f820bfd2e 100644 --- a/src/machine/m_xt_zenith.c +++ b/src/machine/m_xt_zenith.c @@ -153,8 +153,8 @@ machine_xt_z184_init(const machine_t *model) lpt1_remove(); /* only one parallel port */ lpt2_remove(); lpt1_init(0x278); - device_add(&i8250_device); - serial_set_next_inst(MAX_SERIAL); /* So that serial_standalone_init() won't do anything. */ + device_add(&ns8250_device); + serial_set_next_inst(SERIAL_MAX); /* So that serial_standalone_init() won't do anything. */ device_add(&cga_device); diff --git a/src/machine/machine.c b/src/machine/machine.c index 91cdbef33..59c4bee04 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -44,7 +44,7 @@ int bios_only = 0; int machine; -int AT, PCI; +// int AT, PCI; #ifdef ENABLE_MACHINE_LOG @@ -81,8 +81,8 @@ machine_init_ex(int m) gameport_instance_id = 0; /* Set up the architecture flags. */ - AT = IS_AT(machine); - PCI = IS_ARCH(machine, MACHINE_BUS_PCI); + // AT = IS_AT(machine); + // PCI = IS_ARCH(machine, MACHINE_BUS_PCI); cpu_set(); pc_speed_changed(); @@ -146,5 +146,5 @@ machine_common_init(const machine_t *model) pic_init(); dma_init(); - pit_common_init(!!AT, pit_irq0_timer, NULL); + pit_common_init(!!IS_AT(machine), pit_irq0_timer, NULL); } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 9e73c7079..17a3dc335 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -309,11 +309,11 @@ const machine_t machines[] = { /* 386DX machines which utilize the MCA bus */ /* Has IBM PS/2 Type 1 KBC firmware. */ - { "[MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2048, 16384, 2048, 63, machine_ps2_model_70_type3_init, NULL }, + { "[MCA] IBM PS/2 model 70 (type 3)", "ibmps2_m70_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2048, 65536, 2048, 63, machine_ps2_model_70_type3_init, NULL }, /* Has IBM PS/2 Type 1 KBC firmware. */ - { "[MCA] IBM PS/2 model 80", "ibmps2_m80", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 12288, 1024, 63, machine_ps2_model_80_init, NULL }, + { "[MCA] IBM PS/2 model 80 (type 2)", "ibmps2_m80", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL | CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 65536, 1024, 63, machine_ps2_model_80_init, NULL }, /* Has IBM PS/2 Type 1 KBC firmware. */ - { "[MCA] IBM PS/2 model 80 (type 3)", "ibmps2_m80_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2048, 12288, 2048, 63, machine_ps2_model_80_axx_init, NULL }, + { "[MCA] IBM PS/2 model 80 (type 3)", "ibmps2_m80_type3", MACHINE_TYPE_386DX, CPU_PKG_386DX | CPU_PKG_486BL | CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_MCA | MACHINE_BUS_PS2 | MACHINE_VIDEO, 2048, 65536, 2048, 63, machine_ps2_model_80_axx_init, NULL }, /* 386DX/486 machines */ /* The BIOS sends commands C9 without a parameter and D5, both of which are @@ -366,9 +366,8 @@ const machine_t machines[] = { { "[ACC 2168] Packard Bell PB410A", "pb410a", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 4096, 36864, 1024, 127, machine_at_pb410a_init, NULL }, /* Uses an ACER/NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware (V4.01H). */ { "[ALi M1429G] Acer A1G", "acera1g", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 4096, 36864, 1024, 127, machine_at_acera1g_init, at_acera1g_get_device }, - /* There are two similar BIOS strings with -H, and one with -U, so I'm going to - give it an AMIKey H KBC firmware. */ - { "[ALi M1429G] Kaimei 486", "win486", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_winbios1429_init, NULL }, + /* This has an AMIKey-2, which is an updated version of type 'H'. */ + { "[ALi M1429G] Kaimei SA-486 VL-BUS M.B.", "win486", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_winbios1429_init, NULL }, /* Uses an Intel KBC with Phoenix MultiKey KBC firmware. */ { "[SiS 461] DEC DECpc LPV", "decpclpv", MACHINE_TYPE_486_S2, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 1024, 32768, 1024, 127, machine_at_decpclpv_init, NULL }, /* Uses an NEC 90M002A (UPD82C42C, 8042 clone) with unknown firmware. */ @@ -447,7 +446,7 @@ const machine_t machines[] = { { "[SiS 496] Rise Computer R418", "r418", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_r418_init, NULL }, /* This has a Holtek KBC and the BIOS does not send a single non-standard KBC command, so it must be an ASIC that clones the standard IBM PS/2 KBC. */ - { "[SiS 496] Soyo 4SA2", "4sa2", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_4sa2_init, NULL }, + { "[SiS 496] Soyo 4SAW2", "4saw2", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, CPU_BLOCK(CPU_i486SX, CPU_i486DX, CPU_Am486SX, CPU_Am486DX), 0, 0, 0, 0, 0, 0, MACHINE_PCIV | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_4saw2_init, NULL }, /* According to MrKsoft, his real 4DPS has an AMIKey-2, which is an updated version of type 'H'. */ { "[SiS 496] Zida Tomato 4DP", "4dps", MACHINE_TYPE_486_S3, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 1024, 261120, 1024, 255, machine_at_4dps_init, NULL }, @@ -921,7 +920,7 @@ const machine_t machines[] = { /* Miscellaneous/Fake/Hypervisor machines */ /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ - { "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_MISC, CPU_PKG_SLOT1, CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), 0, 0, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vpc2007_init, NULL }, + { "[i440BX] Microsoft Virtual PC 2007", "vpc2007", MACHINE_TYPE_MISC, CPU_PKG_SLOT1, CPU_BLOCK(CPU_PENTIUM2, CPU_CYRIX3S), 0, 66666667, 0, 0, 0, 0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vpc2007_init, NULL }, { NULL, NULL, MACHINE_TYPE_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL } }; @@ -979,6 +978,59 @@ machine_get_nvrmask(int m) } +int +machine_has_flags(int m, int flags) +{ + return(machines[m].flags & flags); +} + + +int +machine_has_bus(int m, int bus_flags) +{ + return(machines[m].flags & bus_flags); +} + + +int +machine_has_cartridge(int m) +{ + return(machine_has_flags(m, MACHINE_CARTRIDGE) ? 1 : 0); +} + + +int +machine_get_min_ram(int m) +{ + return(machines[m].min_ram); +} + + +int +machine_get_max_ram(int m) +{ +#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) + return MIN(((int) machines[m].max_ram), 2097152); +#else + return MIN(((int) machines[m].max_ram), 3145728); +#endif +} + + +int +machine_get_ram_granularity(int m) +{ + return(machines[m].ram_granularity); +} + + +int +machine_get_type(int m) +{ + return(machines[m].type); +} + + int machine_get_machine_from_internal_name(char *s) { diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 6bf044762..4e9e7917d 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -1,17 +1,17 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c - smram.c spd.c sst_flash.c) \ No newline at end of file + smram.c spd.c sst_flash.c) \ No newline at end of file diff --git a/src/mem/mem.c b/src/mem/mem.c index da2e1f31e..ae6c9a0fc 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -1802,7 +1802,7 @@ mem_read_ram(uint32_t addr, void *priv) mem_log("Read B %02X from %08X\n", ram[addr], addr); #endif - if (is286 || AT) + if (is286) addreadlookup(mem_logical_addr, addr); return ram[addr]; @@ -1817,7 +1817,7 @@ mem_read_ramw(uint32_t addr, void *priv) mem_log("Read W %04X from %08X\n", *(uint16_t *)&ram[addr], addr); #endif - if (is286 || AT) + if (is286) addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; @@ -1832,7 +1832,7 @@ mem_read_raml(uint32_t addr, void *priv) mem_log("Read L %08X from %08X\n", *(uint32_t *)&ram[addr], addr); #endif - if (is286 || AT) + if (is286) addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; @@ -2076,7 +2076,7 @@ mem_write_ram(uint32_t addr, uint8_t val, void *priv) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write B %02X to %08X\n", val, addr); #endif - if (is286 || AT) { + if (is286) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); } else @@ -2091,7 +2091,7 @@ mem_write_ramw(uint32_t addr, uint16_t val, void *priv) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write W %04X to %08X\n", val, addr); #endif - if (is286 || AT) { + if (is286) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[addr >> 12]); } else @@ -2106,7 +2106,7 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write L %08X to %08X\n", val, addr); #endif - if (is286 || AT) { + if (is286) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[addr >> 12]); } else @@ -2118,7 +2118,7 @@ static uint8_t mem_read_remapped(uint32_t addr, void *priv) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286 || AT) + if (is286) addreadlookup(mem_logical_addr, addr); return ram[addr]; } @@ -2128,7 +2128,7 @@ static uint16_t mem_read_remappedw(uint32_t addr, void *priv) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286 || AT) + if (is286) addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; } @@ -2138,7 +2138,7 @@ static uint32_t mem_read_remappedl(uint32_t addr, void *priv) { addr = 0xA0000 + (addr - remap_start_addr); - if (is286 || AT) + if (is286) addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; } @@ -2149,7 +2149,7 @@ mem_write_remapped(uint32_t addr, uint8_t val, void *priv) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286 || AT) { + if (is286) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2162,7 +2162,7 @@ mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286 || AT) { + if (is286) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2175,7 +2175,7 @@ mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) { uint32_t oldaddr = addr; addr = 0xA0000 + (addr - remap_start_addr); - if (is286 || AT) { + if (is286) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } else @@ -2537,12 +2537,12 @@ mem_set_access(uint8_t bitmap, int mode, uint32_t base, uint32_t size, uint16_t void mem_a20_init(void) { - if (AT) { + if (is286) { rammask = cpu_16bitbus ? 0xefffff : 0xffefffff; flushmmucache(); mem_a20_state = mem_a20_key | mem_a20_alt; } else { - rammask = is286 ? 0xffffff : 0xfffff; + rammask = 0xfffff; flushmmucache(); mem_a20_key = mem_a20_alt = mem_a20_state = 0; } @@ -2665,7 +2665,7 @@ mem_reset(void) * We re-allocate the table on each (hard) reset, as the * memory amount could have changed. */ - if (AT) { + if (is286) { if (cpu_16bitbus) { /* 80286/386SX; maximum address space is 16MB. */ m = 4096; @@ -2674,13 +2674,8 @@ mem_reset(void) m = 1048576; } } else { - if (is286) { - /* 80286; maximum address space is 16MB. */ - m = 4096; - } else { - /* 8088/86; maximum address space is 1MB. */ - m = 256; - } + /* 8088/86; maximum address space is 1MB. */ + m = 256; } /* @@ -2877,8 +2872,8 @@ mem_a20_recalc(void) { int state; - if (! AT) { - rammask = is286 ? 0xffffff : 0xfffff; + if (! is286) { + rammask = 0xfffff; flushmmucache(); mem_a20_key = mem_a20_alt = mem_a20_state = 0; @@ -2887,10 +2882,10 @@ mem_a20_recalc(void) state = mem_a20_key | mem_a20_alt; if (state && !mem_a20_state) { - rammask = (AT && cpu_16bitbus) ? 0xffffff : 0xffffffff; + rammask = (cpu_16bitbus) ? 0xffffff : 0xffffffff; flushmmucache(); } else if (!state && mem_a20_state) { - rammask = (AT && cpu_16bitbus) ? 0xefffff : 0xffefffff; + rammask = (cpu_16bitbus) ? 0xefffff : 0xffefffff; flushmmucache(); } diff --git a/src/mem/rom.c b/src/mem/rom.c index 3d7f28934..8fbd7ff97 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -422,7 +422,7 @@ bios_add(void) if (/*AT && */cpu_s) { temp_cpu_type = cpu_s->cpu_type; temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC ); - temp_is286 = (temp_cpu_type == CPU_286); + temp_is286 = (temp_cpu_type >= CPU_286); } if (biosmask > 0x1ffff) { @@ -444,7 +444,7 @@ bios_add(void) MEM_READ_ROMCS | MEM_WRITE_ROMCS); } - if (temp_is286 || AT) { + if (temp_is286) { mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, bios_read,bios_readw,bios_readl, NULL,NULL,NULL, diff --git a/src/mem/spd.c b/src/mem/spd.c index 9e5ec9706..547b0c722 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -406,7 +406,7 @@ spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint { uint8_t row, dimm; uint8_t drb; - uint16_t size, size_acc; + uint16_t size, size_acc = 0; uint16_t rows[SPD_MAX_SLOTS]; /* No SPD: split SIMMs into pairs as if they were "DIMM"s. */ diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index e8db1a01e..434daa407 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -1,20 +1,20 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(net OBJECT network.c net_pcap.c net_slirp.c net_dp8390.c net_3c503.c - net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c) + net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c) add_subdirectory(slirp) target_link_libraries(86Box slirp) \ No newline at end of file diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index ba56cebfb..7008d1442 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -172,6 +172,7 @@ poll_thread(void *arg) thread_set_event(poll_state); /* Create a waitable event. */ + pcap_log("PCAP: Creating event...\n"); evt = thread_create_event(); /* As long as the channel is open.. */ @@ -185,8 +186,6 @@ poll_thread(void *arg) if (pcap == NULL) break; - /* Wait for the next packet to arrive. */ - tx = network_tx_queue_check(); if (network_get_wait() || (poll_card->set_link_state && poll_card->set_link_state(poll_card->priv)) || (poll_card->wait && poll_card->wait(poll_card->priv))) data = NULL; else @@ -208,11 +207,14 @@ poll_thread(void *arg) } } + /* Wait for the next packet to arrive. */ + tx = network_tx_queue_check(); + if (tx) network_do_tx(); /* If we did not get anything, wait a while. */ - if ((data == NULL) && !tx) + if (!tx) thread_wait_event(evt, 10); /* Release ownership of the device. */ @@ -224,7 +226,8 @@ poll_thread(void *arg) thread_destroy_event(evt); pcap_log("PCAP: polling stopped.\n"); - thread_set_event(poll_state); + if (poll_state != NULL) + thread_set_event(poll_state); } diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 253b83ffe..4206c88a2 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -63,6 +63,8 @@ #include <86box/net_wd8003.h> #include <86box/bswap.h> +#include "cpu.h" + /* Board type codes in card ID */ #define WE_TYPE_WD8003 0x01 #define WE_TYPE_WD8003S 0x02 @@ -668,7 +670,7 @@ wd_init(const device_t *info) dev->board_chip |= WE_ID_EXTRA_RAM; dev->bit16 = 2; - if (AT) + if (is286) dev->bit16 |= 1; else { dev->bit16 |= 0; diff --git a/src/network/network.c b/src/network/network.c index b545b08ca..0e7f16bac 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -49,6 +49,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include #include #include @@ -107,7 +108,7 @@ int nic_do_log = ENABLE_NIC_LOG; /* Local variables. */ -static volatile int net_wait = 0; +static volatile atomic_int net_wait = 0; static mutex_t *network_mutex; static uint8_t *network_mac; static uint8_t network_timer_active = 0; @@ -388,8 +389,8 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST network_set_wait(0); /* Create the network events. */ - poll_data.wake_poll_thread = thread_create_event(); poll_data.poll_complete = thread_create_event(); + poll_data.wake_poll_thread = thread_create_event(); /* Activate the platform module. */ switch(network_type) { @@ -671,9 +672,7 @@ network_card_get_from_internal_name(char *s) void network_set_wait(int wait) { - network_wait(1); net_wait = wait; - network_wait(0); } @@ -682,8 +681,6 @@ network_get_wait(void) { int ret; - network_wait(1); ret = net_wait; - network_wait(0); return ret; } diff --git a/src/network/slirp/CMakeLists.txt b/src/network/slirp/CMakeLists.txt index 2a6a8adb9..b7f995947 100644 --- a/src/network/slirp/CMakeLists.txt +++ b/src/network/slirp/CMakeLists.txt @@ -1,21 +1,21 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(slirp STATIC tinyglib.c arp_table.c bootp.c cksum.c dnssearch.c if.c ip_icmp.c - ip_input.c ip_output.c mbuf.c misc.c sbuf.c slirp.c socket.c tcp_input.c - tcp_output.c tcp_subr.c tcp_timer.c udp.c util.c version.c) + ip_input.c ip_output.c mbuf.c misc.c sbuf.c slirp.c socket.c tcp_input.c + tcp_output.c tcp_subr.c tcp_timer.c udp.c util.c version.c) #target_link_libraries(slirp wsock32 iphlpapi) #target_link_libraries(slirp) diff --git a/src/nvr.c b/src/nvr.c index 45b89f306..46e0f6c5a 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -166,8 +166,6 @@ onesec_timer(void *priv) void nvr_init(nvr_t *nvr) { - struct tm *tm; - time_t now; int c; /* Set up the NVR file's name. */ @@ -178,15 +176,7 @@ nvr_init(nvr_t *nvr) /* Initialize the internal clock as needed. */ memset(&intclk, 0x00, sizeof(intclk)); if (time_sync & TIME_SYNC_ENABLED) { - /* Get the current time of day, and convert to local time. */ - (void)time(&now); - if(time_sync & TIME_SYNC_UTC) - tm = gmtime(&now); - else - tm = localtime(&now); - - /* Set the internal clock. */ - nvr_time_set(tm); + nvr_time_sync(); } else { /* Reset the internal clock to 1980/01/01 00:00. */ intclk.tm_mon = 1; @@ -262,7 +252,7 @@ nvr_load(void) path = nvr_path(saved_nvr->fn); nvr_log("NVR: loading from '%s'\n", path); fp = plat_fopen(path, "rb"); - saved_nvr->new = (fp == NULL); + saved_nvr->is_new = (fp == NULL); if (fp != NULL) { /* Read NVR contents from file. */ if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) @@ -270,7 +260,7 @@ nvr_load(void) (void)fclose(fp); } } else - saved_nvr->new = 1; + saved_nvr->is_new = 1; /* Get the local RTC running! */ if (saved_nvr->start != NULL) @@ -325,6 +315,24 @@ nvr_close(void) } +void +nvr_time_sync(void) +{ + struct tm *tm; + time_t now; + + /* Get the current time of day, and convert to local time. */ + (void)time(&now); + if(time_sync & TIME_SYNC_UTC) + tm = gmtime(&now); + else + tm = localtime(&now); + + /* Set the internal clock. */ + nvr_time_set(tm); +} + + /* Get current time from internal clock. */ void nvr_time_get(struct tm *tm) diff --git a/src/nvr_at.c b/src/nvr_at.c index cb85cd2d8..5b258a057 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -565,11 +565,11 @@ static void nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) { if ((reg == 0x2c) && (local->flags & FLAG_AMI_1994_HACK)) - nvr->new = 0; + nvr->is_new = 0; if ((reg == 0x2d) && (local->flags & FLAG_AMI_1992_HACK)) - nvr->new = 0; + nvr->is_new = 0; if ((reg == 0x52) && (local->flags & FLAG_AMI_1995_HACK)) - nvr->new = 0; + nvr->is_new = 0; if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0]) return; if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1]) @@ -706,14 +706,14 @@ nvr_read(uint16_t addr, void *priv) break; case 0x2c: - if (!nvr->new && (local->flags & FLAG_AMI_1994_HACK)) + if (!nvr->is_new && (local->flags & FLAG_AMI_1994_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0x7f; else ret = nvr->regs[local->addr[addr_id]]; break; case 0x2d: - if (!nvr->new && (local->flags & FLAG_AMI_1992_HACK)) + if (!nvr->is_new && (local->flags & FLAG_AMI_1992_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0xf7; else ret = nvr->regs[local->addr[addr_id]]; @@ -721,7 +721,7 @@ nvr_read(uint16_t addr, void *priv) case 0x2e: case 0x2f: - if (!nvr->new && (local->flags & FLAG_AMI_1992_HACK)) { + if (!nvr->is_new && (local->flags & FLAG_AMI_1992_HACK)) { for (i = 0x10; i <= 0x2d; i++) { if (i == 0x2d) checksum += (nvr->regs[i] & 0xf7); @@ -732,7 +732,7 @@ nvr_read(uint16_t addr, void *priv) ret = checksum >> 8; else ret = checksum & 0xff; - } else if (!nvr->new && (local->flags & FLAG_AMI_1994_HACK)) { + } else if (!nvr->is_new && (local->flags & FLAG_AMI_1994_HACK)) { for (i = 0x10; i <= 0x2d; i++) { if (i == 0x2c) checksum += (nvr->regs[i] & 0x7f); @@ -749,7 +749,7 @@ nvr_read(uint16_t addr, void *priv) case 0x3e: case 0x3f: - if (!nvr->new && (local->flags & FLAG_AMI_1995_HACK)) { + if (!nvr->is_new && (local->flags & FLAG_AMI_1995_HACK)) { /* The checksum at 3E-3F is for 37-3D and 40-7F. */ for (i = 0x37; i <= 0x3d; i++) checksum += nvr->regs[i]; @@ -763,7 +763,7 @@ nvr_read(uint16_t addr, void *priv) ret = checksum >> 8; else ret = checksum & 0xff; - } else if (!nvr->new && (local->flags & FLAG_P6RP4_HACK)) { + } else if (!nvr->is_new && (local->flags & FLAG_P6RP4_HACK)) { /* The checksum at 3E-3F is for 37-3D and 40-51. */ for (i = 0x37; i <= 0x3d; i++) checksum += nvr->regs[i]; @@ -782,14 +782,14 @@ nvr_read(uint16_t addr, void *priv) break; case 0x43: - if (!nvr->new && (local->flags & FLAG_P6RP4_HACK)) + if (!nvr->is_new && (local->flags & FLAG_P6RP4_HACK)) ret = nvr->regs[local->addr[addr_id]] | 0x02; else ret = nvr->regs[local->addr[addr_id]]; break; case 0x52: - if (!nvr->new && (local->flags & FLAG_AMI_1995_HACK)) + if (!nvr->is_new && (local->flags & FLAG_AMI_1995_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0xf3; else ret = nvr->regs[local->addr[addr_id]]; diff --git a/src/pci.c b/src/pci.c index 163a4409c..b66882bde 100644 --- a/src/pci.c +++ b/src/pci.c @@ -74,7 +74,6 @@ static int trc_reg = 0; static void pci_reset_regs(void); -// #define ENABLE_PCI_LOG 1 #ifdef ENABLE_PCI_LOG int pci_do_log = ENABLE_PCI_LOG; @@ -487,19 +486,6 @@ pci_set_mirq_routing(int mirq, int irq) } -uint8_t -pci_use_mirq(uint8_t mirq) -{ - if (!PCI || !pci_mirqs[mirq].enabled) - return 0; - - if (pci_mirqs[mirq].irq_line & 0x80) - return 0; - - return 1; -} - - void pci_set_mirq(uint8_t mirq, int level) { @@ -768,6 +754,14 @@ pci_reset_regs(void) } +void +pci_pic_reset(void) +{ + pic_reset(); + pic_set_pci_flag(last_pci_card > 0); +} + + static void pci_reset_hard(void) { @@ -783,7 +777,7 @@ pci_reset_hard(void) } } - pic_reset(); + pci_pic_reset(); } @@ -864,6 +858,8 @@ trc_reset(uint8_t val) { if (val & 2) { dma_reset(); + dma_set_at(1); + device_reset_all(); cpu_alt_reset = 0; @@ -923,8 +919,6 @@ pci_init(int type) { int c; - PCI = 1; - pci_slots_clear(); pci_reset_hard(); @@ -972,6 +966,8 @@ pci_init(int type) pci_mirqs[c].enabled = 0; pci_mirqs[c].irq_line = PCI_IRQ_DISABLED; } + + pic_set_pci_flag(1); } @@ -1066,11 +1062,6 @@ pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), if (add_type < PCI_ADD_AGP) pci_log("pci_add_card(): Adding PCI CARD at specific slot %02X [SPECIFIC]\n", add_type); - if (! PCI) { - pci_log("pci_add_card(): Adding PCI CARD failed (non-PCI machine) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); - return 0xff; - } - if (! last_pci_card) { pci_log("pci_add_card(): Adding PCI CARD failed (no PCI slots) [%s]\n", (add_type == PCI_ADD_NORMAL) ? "NORMAL" : ((add_type == PCI_ADD_AGP) ? "AGP" : ((add_type == PCI_ADD_VIDEO) ? "VIDEO" : ((add_type == PCI_ADD_SCSI) ? "SCSI" : ((add_type == PCI_ADD_SOUND) ? "SOUND" : "SPECIFIC"))))); return 0xff; diff --git a/src/pic.c b/src/pic.c index c77f08023..d81d4e5a7 100644 --- a/src/pic.c +++ b/src/pic.c @@ -52,7 +52,8 @@ pic_t pic, pic2; static pc_timer_t pic_timer; static int shadow = 0, elcr_enabled = 0, - tmr_inited = 0, latched = 0; + tmr_inited = 0, latched = 0, + pic_pci = 0; static uint16_t smi_irq_mask = 0x0000, smi_irq_status = 0x0000; @@ -292,6 +293,9 @@ pic_reset() pic.at = pic2.at = is_at; smi_irq_mask = smi_irq_status = 0x0000; + + shadow = 0; + pic_pci = 0; } @@ -302,6 +306,13 @@ pic_set_shadow(int sh) } +void +pic_set_pci_flag(int pci) +{ + pic_pci = pci; +} + + static uint8_t pic_level_triggered(pic_t *dev, int irq) { @@ -487,7 +498,7 @@ pic_write(uint16_t addr, uint8_t val, void *priv) } else { if (val & 0x10) { /* Treat any write with any of the bits 7 to 5 set as invalid if PCI. */ - if (PCI && (val & 0xe0)) + if (pic_pci && (val & 0xe0)) return; dev->icw1 = val; diff --git a/src/pit.c b/src/pit.c index 582c748a7..fe256f53d 100644 --- a/src/pit.c +++ b/src/pit.c @@ -154,6 +154,8 @@ ctr_tick(ctr_t *ctr) /* This is true for all modes */ ctr_load_count(ctr); ctr->state = 2; + if ((ctr->m & 0x07) == 0x01) + ctr_set_out(ctr, 0); return; } diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index ace9ac0c8..0f6c0e38d 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -1,16 +1,16 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(print OBJECT png.c prt_cpmap.c prt_escp.c prt_text.c prt_ps.c) \ No newline at end of file diff --git a/src/scsi/CMakeLists.txt b/src/scsi/CMakeLists.txt index 444c87b70..6b0ebd10e 100644 --- a/src/scsi/CMakeLists.txt +++ b/src/scsi/CMakeLists.txt @@ -1,18 +1,18 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(scsi OBJECT scsi.c scsi_device.c scsi_cdrom.c scsi_disk.c - scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c - scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) \ No newline at end of file + scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c + scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) \ No newline at end of file diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 0839d63e9..4005d5f57 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -72,11 +72,11 @@ static SCSI_CARD scsi_cards[] = { { "t128", &scsi_t128_device, }, { "t130b", &scsi_t130b_device, }, #ifdef WALTJE - { "scsiat", &scsi_scsiat_device, }, { "wd33c93", &scsi_wd33c93_device, }, #endif { "aha1640", &aha1640_device, }, { "bt640a", &buslogic_640a_device, }, + { "ncr53c90", &ncr53c90_mca_device, }, { "spock", &spock_device, }, { "bt958d", &buslogic_pci_device, }, { "ncr53c810", &ncr53c810_pci_device, }, @@ -167,7 +167,7 @@ scsi_card_init(void) /* On-board SCSI controllers get the first bus, so if one is present, increase our instance number here. */ - if (machines[machine].flags & MACHINE_SCSI) + if (machine_has_flags(machine, MACHINE_SCSI)) max--; /* Do not initialize any controllers if we have do not have any SCSI diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index be5aec503..8fddabd7b 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Implementation of the AMD PCscsi and Tekram DC-390 SCSI + * Implementation of the Tekram DC-390 SCSI and related MCA * controllers using the NCR 53c9x series of chips. * * @@ -36,6 +36,7 @@ #include <86box/pic.h> #include <86box/mem.h> #include <86box/rom.h> +#include <86box/mca.h> #include <86box/pci.h> #include <86box/device.h> #include <86box/nvr.h> @@ -44,12 +45,13 @@ #include <86box/scsi_device.h> #include <86box/scsi_pcscsi.h> #include <86box/vid_ati_eeprom.h> +#include <86box/fifo8.h> #define DC390_ROM "roms/scsi/esp_pci/INT13.BIN" #define ESP_REGS 16 -#define TI_BUFSZ 32 -#define ESP_CMDBUF_SZ 32 +#define ESP_FIFO_SZ 16 +#define ESP_CMDFIFO_SZ 32 #define ESP_TCLO 0x0 #define ESP_TCMID 0x1 @@ -114,10 +116,12 @@ #define INTR_RST 0x80 #define SEQ_0 0x0 +#define SEQ_MO 0x1 #define SEQ_CD 0x4 #define CFG1_RESREPT 0x40 +#define TCHI_FAS100A 0x04 #define TCHI_AM53C974 0x12 #define DMA_CMD 0x0 @@ -148,6 +152,7 @@ typedef struct { mem_mapping_t mmio_mapping; + mem_mapping_t ram_mapping; char *nvr_path; uint8_t pci_slot; int has_bios; @@ -162,33 +167,43 @@ typedef struct { int irq; int tchi_written; uint32_t ti_size; - uint32_t ti_rptr, ti_wptr; uint32_t status; - uint32_t deferred_status; - int deferred_complete; uint32_t dma; - uint8_t ti_buf[TI_BUFSZ]; + Fifo8 fifo; uint8_t bus; uint8_t id, lun; - uint8_t cmdbuf[ESP_CMDBUF_SZ]; - uint32_t cmdlen; + Fifo8 cmdfifo; uint32_t do_cmd; + uint8_t cmdfifo_cdb_offset; - uint32_t dma_counter; - uint32_t dma_left; int32_t xfer_counter; int dma_enabled; uint32_t buffer_pos; - uint32_t async_len; uint32_t dma_regs[8]; uint32_t sbac; double period; pc_timer_t timer; + + int mca; + uint16_t Base; + uint8_t HostID, DmaChannel; + + struct + { + uint8_t mode; + uint8_t status; + int pos; + } dma_86c01; + + uint8_t pos_regs[8]; } esp_t; +#define READ_FROM_DEVICE 1 +#define WRITE_TO_DEVICE 0 + #ifdef ENABLE_ESP_LOG int esp_do_log = ENABLE_ESP_LOG; @@ -209,7 +224,9 @@ esp_log(const char *fmt, ...) #define esp_log(fmt, ...) #endif +static void esp_dma_enable(esp_t *dev, int level); static void esp_do_dma(esp_t *dev, scsi_device_t *sd); +static void esp_do_nodma(esp_t *dev, scsi_device_t *sd); static void esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir); static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p); static void esp_command_complete(void *priv, uint32_t status); @@ -221,20 +238,31 @@ static void handle_ti(void *priv); static void esp_irq(esp_t *dev, int level) { - if (level) { - pci_set_irq(dev->pci_slot, PCI_INTA); - esp_log("Raising IRQ...\n"); - } else { - pci_clear_irq(dev->pci_slot, PCI_INTA); - esp_log("Lowering IRQ...\n"); - } + if (dev->mca) { + if (level) { + picint(1 << dev->irq); + dev->dma_86c01.status |= 0x01; + esp_log("Raising IRQ...\n"); + } else { + picintc(1 << dev->irq); + dev->dma_86c01.status &= ~0x01; + esp_log("Lowering IRQ...\n"); + } + } else { + if (level) { + pci_set_irq(dev->pci_slot, PCI_INTA); + esp_log("Raising IRQ...\n"); + } else { + pci_clear_irq(dev->pci_slot, PCI_INTA); + esp_log("Lowering IRQ...\n"); + } + } } - static void esp_raise_irq(esp_t *dev) { - if (!(dev->rregs[ESP_RSTAT] & STAT_INT)) { + if (!(dev->rregs[ESP_RSTAT] & STAT_INT)) { dev->rregs[ESP_RSTAT] |= STAT_INT; esp_irq(dev, 1); } @@ -243,12 +271,82 @@ esp_raise_irq(esp_t *dev) static void esp_lower_irq(esp_t *dev) { - if (dev->rregs[ESP_RSTAT] & STAT_INT) { + if (dev->rregs[ESP_RSTAT] & STAT_INT) { dev->rregs[ESP_RSTAT] &= ~STAT_INT; esp_irq(dev, 0); } } +static void +esp_fifo_push(Fifo8 *fifo, uint8_t val) +{ + if (fifo8_num_used(fifo) == fifo->capacity) { + return; + } + + fifo8_push(fifo, val); +} + +static uint8_t +esp_fifo_pop(Fifo8 *fifo) +{ + if (fifo8_is_empty(fifo)) { + return 0; + } + + return fifo8_pop(fifo); +} + +static uint32_t +esp_fifo_pop_buf(Fifo8 *fifo, uint8_t *dest, int maxlen) +{ + const uint8_t *buf; + uint32_t n; + + if (maxlen == 0) { + return 0; + } + + buf = fifo8_pop_buf(fifo, maxlen, &n); + if (dest) { + memcpy(dest, buf, n); + } + + return n; +} + +static uint32_t +esp_get_tc(esp_t *dev) +{ + uint32_t dmalen; + + dmalen = dev->rregs[ESP_TCLO]; + dmalen |= dev->rregs[ESP_TCMID] << 8; + dmalen |= dev->rregs[ESP_TCHI] << 16; + + return dmalen; +} + +static void +esp_set_tc(esp_t *dev, uint32_t dmalen) +{ + dev->rregs[ESP_TCLO] = dmalen; + dev->rregs[ESP_TCMID] = dmalen >> 8; + dev->rregs[ESP_TCHI] = dmalen >> 16; +} + +static uint32_t +esp_get_stc(esp_t *dev) +{ + uint32_t dmalen; + + dmalen = dev->wregs[ESP_TCLO]; + dmalen |= dev->wregs[ESP_TCMID] << 8; + dmalen |= dev->wregs[ESP_TCHI] << 16; + + return dmalen; +} + static void esp_dma_done(esp_t *dev) { @@ -256,62 +354,73 @@ esp_dma_done(esp_t *dev) dev->rregs[ESP_RINTR] = INTR_BS; dev->rregs[ESP_RSEQ] = 0; dev->rregs[ESP_RFLAGS] = 0; - dev->rregs[ESP_TCLO] = 0; - dev->rregs[ESP_TCMID] = 0; - dev->rregs[ESP_TCHI] = 0; + esp_set_tc(dev, 0); esp_log("ESP DMA Finished\n"); esp_raise_irq(dev); } static uint32_t -esp_get_cmd(esp_t *dev, uint8_t *buf, uint8_t buflen) +esp_get_cmd(esp_t *dev, uint32_t maxlen) { - uint32_t dmalen; + uint8_t buf[ESP_CMDFIFO_SZ]; + uint32_t dmalen, n; dev->id = dev->wregs[ESP_WBUSID] & BUSID_DID; if (dev->dma) { - dmalen = dev->rregs[ESP_TCLO]; - dmalen |= dev->rregs[ESP_TCMID] << 8; - dmalen |= dev->rregs[ESP_TCHI] << 16; + dmalen = MIN(esp_get_tc(dev), maxlen); esp_log("ESP Get data, dmalen = %d\n", dmalen); - if (dmalen > buflen) + if (dmalen == 0) return 0; - esp_pci_dma_memory_rw(dev, buf, dmalen, 0); + if (dev->mca) { + while (dev->dma_86c01.pos < dmalen) { + int val = dma_channel_read(dev->DmaChannel); + buf[dev->dma_86c01.pos++] = val & 0xff; + } + dev->dma_86c01.pos = 0; + } else { + esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE); + dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); + fifo8_push_all(&dev->cmdfifo, buf, dmalen); + } } else { - dmalen = dev->ti_size; - esp_log("ESP Get command, dmalen = %d\n", dmalen); - if (dmalen > TI_BUFSZ) - return 0; - memcpy(buf, dev->ti_buf, dmalen); - dev->lun = buf[0] & 7; - } - - dev->ti_size = 0; - dev->ti_rptr = 0; - dev->ti_wptr = 0; - - if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) { - /* We only support LUN 0 */ - dev->rregs[ESP_RSTAT] = 0; - dev->rregs[ESP_RINTR] = INTR_DC; - dev->rregs[ESP_RSEQ] = SEQ_0; - esp_raise_irq(dev); - return 0; + dmalen = MIN(fifo8_num_used(&dev->fifo), maxlen); + esp_log("ESP Get command, dmalen = %i\n", dmalen); + if (dmalen == 0) { + return 0; + } + n = esp_fifo_pop_buf(&dev->fifo, buf, dmalen); + n = MIN(fifo8_num_free(&dev->cmdfifo), n); + fifo8_push_all(&dev->cmdfifo, buf, n); } - scsi_device_identify(&scsi_devices[dev->bus][dev->id], dev->lun); + dev->ti_size = 0; + fifo8_reset(&dev->fifo); + + dev->rregs[ESP_RINTR] |= INTR_FC; + dev->rregs[ESP_RSEQ] = SEQ_CD; return dmalen; } static void -esp_do_busid_cmd(esp_t *dev, uint8_t *buf, uint8_t busid) +esp_do_command_phase(esp_t *dev) { + uint32_t cmdlen; + uint8_t buf[ESP_CMDFIFO_SZ]; scsi_device_t *sd; - sd = &scsi_devices[dev->bus][busid]; - - sd->buffer_length = -1; + sd = &scsi_devices[dev->bus][dev->id]; + + sd->buffer_length = -1; + + cmdlen = fifo8_num_used(&dev->cmdfifo); + if (!cmdlen) + return; + + esp_fifo_pop_buf(&dev->cmdfifo, buf, cmdlen); + + for (int i = 0; i < cmdlen; i++) + esp_log("CDB[%i] = %02x\n", i, buf[i]); scsi_device_command_phase0(sd, buf); @@ -319,18 +428,19 @@ esp_do_busid_cmd(esp_t *dev, uint8_t *buf, uint8_t busid) dev->ti_size = sd->buffer_length; dev->xfer_counter = sd->buffer_length; - esp_log("ESP SCSI Command = %02x, ID = %d, LUN = %d, len = %d\n", buf[0], busid, buf[1] >> 5, sd->buffer_length); - + esp_log("ESP SCSI Command = 0x%02x, ID = %d, LUN = %d, len = %d\n", buf[0], dev->id, dev->lun, sd->buffer_length); + + fifo8_reset(&dev->cmdfifo); + if (sd->buffer_length > 0) { /* This should be set to the underlying device's buffer by command phase 0. */ dev->rregs[ESP_RSTAT] = STAT_TC; - dev->dma_left = 0; - dev->dma_counter = 0; + dev->rregs[ESP_RSEQ] = SEQ_CD; if (sd->phase == SCSI_PHASE_DATA_IN) { dev->rregs[ESP_RSTAT] |= STAT_DI; esp_log("ESP Data In\n"); - esp_timer_on(dev, sd, scsi_device_get_callback(sd)); + esp_timer_on(dev, sd, scsi_device_get_callback(sd)); } else if (sd->phase == SCSI_PHASE_DATA_OUT) { dev->rregs[ESP_RSTAT] |= STAT_DO; esp_log("ESP Data Out\n"); @@ -341,20 +451,64 @@ esp_do_busid_cmd(esp_t *dev, uint8_t *buf, uint8_t busid) esp_do_dma(dev, sd); } else { esp_log("ESP SCSI Command with no length\n"); - esp_pci_command_complete(dev, sd->status); + if (dev->mca) { + if (buf[0] == 0x43) { + dev->rregs[ESP_RSTAT] = STAT_DI | STAT_TC; + dev->rregs[ESP_RSEQ] = SEQ_CD; + esp_do_dma(dev, sd); + } else + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); } - + scsi_device_identify(sd, SCSI_LUN_USE_CDB); - - dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; - dev->rregs[ESP_RSEQ] = SEQ_CD; - esp_raise_irq(dev); + + dev->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; + esp_raise_irq(dev); } static void -esp_do_cmd(esp_t *dev, uint8_t *buf) +esp_do_message_phase(esp_t *dev) { - esp_do_busid_cmd(dev, &buf[1], dev->id); + int len; + uint8_t message; + + if (dev->cmdfifo_cdb_offset) { + message = esp_fifo_pop(&dev->cmdfifo); + + dev->lun = message & 7; + dev->cmdfifo_cdb_offset--; + + if (scsi_device_present(&scsi_devices[dev->bus][dev->id]) && (dev->lun > 0)) { + /* We only support LUN 0 */ + esp_log("LUN = %i\n", dev->lun); + dev->rregs[ESP_RSTAT] = 0; + dev->rregs[ESP_RINTR] = INTR_DC; + dev->rregs[ESP_RSEQ] = SEQ_0; + esp_raise_irq(dev); + fifo8_reset(&dev->cmdfifo); + return; + } + + scsi_device_identify(&scsi_devices[dev->bus][dev->id], dev->lun); + } + + esp_log("CDB offset = %i\n", dev->cmdfifo_cdb_offset); + + if (dev->cmdfifo_cdb_offset) { + len = MIN(dev->cmdfifo_cdb_offset, fifo8_num_used(&dev->cmdfifo)); + esp_fifo_pop_buf(&dev->cmdfifo, NULL, len); + dev->cmdfifo_cdb_offset = 0; + } +} + +static void +esp_do_cmd(esp_t *dev) +{ + esp_do_message_phase(dev); + if (dev->cmdfifo_cdb_offset == 0) + esp_do_command_phase(dev); } static void @@ -363,13 +517,17 @@ esp_dma_enable(esp_t *dev, int level) if (level) { esp_log("ESP DMA Enabled\n"); dev->dma_enabled = 1; - if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) + dev->dma_86c01.status |= 0x02; + if ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) { timer_on_auto(&dev->timer, 40.0); - else + } else { + esp_log("Period = %lf\n", dev->period); timer_on_auto(&dev->timer, dev->period); + } } else { esp_log("ESP DMA Disabled\n"); dev->dma_enabled = 0; + dev->dma_86c01.status &= ~0x02; } } @@ -380,71 +538,210 @@ esp_hard_reset(esp_t *dev) memset(dev->wregs, 0, ESP_REGS); dev->tchi_written = 0; dev->ti_size = 0; - dev->ti_rptr = 0; - dev->ti_wptr = 0; + fifo8_reset(&dev->fifo); + fifo8_reset(&dev->cmdfifo); dev->dma = 0; dev->do_cmd = 0; - dev->rregs[ESP_CFG1] = 7; + dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; esp_log("ESP Reset\n"); timer_stop(&dev->timer); - - for (int i = 0; i < 8; i++) - scsi_device_reset(&scsi_devices[dev->bus][i]); } +static void +esp_do_nodma(esp_t *dev, scsi_device_t *sd) +{ + int count; + + esp_log("ESP SCSI Actual FIFO len = %d\n", dev->xfer_counter); + + if (dev->do_cmd) { + esp_log("ESP Command on FIFO\n"); + dev->ti_size = 0; + + if ((dev->rregs[ESP_RSTAT] & 7) == STAT_CD) { + if (dev->cmdfifo_cdb_offset == fifo8_num_used(&dev->cmdfifo)) { + esp_log("CDB offset = %i used return\n", dev->cmdfifo_cdb_offset); + return; + } + + dev->do_cmd = 0; + esp_do_cmd(dev); + } else { + dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo);; + esp_log("CDB offset = %i used\n", dev->cmdfifo_cdb_offset); + + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } + return; + } + + if (dev->xfer_counter == 0) { + /* Wait until data is available. */ + esp_log("(ID=%02i LUN=%02i): FIFO no data available\n", dev->id, dev->lun); + return; + } + + esp_log("ESP FIFO = %d, buffer length = %d\n", dev->xfer_counter, sd->buffer_length); + + if (sd->phase == SCSI_PHASE_DATA_IN) { + if (fifo8_is_empty(&dev->fifo)) { + fifo8_push(&dev->fifo, sd->sc->temp_buffer[dev->buffer_pos]); + dev->buffer_pos++; + dev->ti_size--; + dev->xfer_counter--; + } + } else if (sd->phase == SCSI_PHASE_DATA_OUT) { + count = MIN(fifo8_num_used(&dev->fifo), ESP_FIFO_SZ); + esp_fifo_pop_buf(&dev->fifo, sd->sc->temp_buffer + dev->buffer_pos, count); + dev->buffer_pos += count; + dev->ti_size += count; + dev->xfer_counter -= count; + } + + esp_log("ESP FIFO Transfer bytes = %d\n", dev->xfer_counter); + if (dev->xfer_counter <= 0) { + if (sd->phase == SCSI_PHASE_DATA_OUT) { + if (dev->ti_size < 0) { + esp_log("ESP FIFO Keep writing\n"); + esp_do_nodma(dev, sd); + } else { + esp_log("ESP FIFO Write finished\n"); + scsi_device_command_phase1(sd); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); + } + } else if (sd->phase == SCSI_PHASE_DATA_IN) { + /* If there is still data to be read from the device then + complete the DMA operation immediately. Otherwise defer + until the scsi layer has completed. */ + if (dev->ti_size <= 0) { + esp_log("ESP FIFO Read finished\n"); + scsi_device_command_phase1(sd); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); + } else { + esp_log("ESP FIFO Keep reading\n"); + esp_do_nodma(dev, sd); + } + } + } else { + /* Partially filled a scsi buffer. Complete immediately. */ + esp_log("ESP SCSI Partially filled the FIFO buffer\n"); + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } +} + + static void esp_do_dma(esp_t *dev, scsi_device_t *sd) { + uint8_t buf[ESP_CMDFIFO_SZ]; uint32_t tdbc; int count; - esp_log("ESP SCSI Actual DMA len = %d\n", dev->dma_left); + esp_log("ESP SCSI Actual DMA len = %d\n", esp_get_tc(dev)); if (!scsi_device_present(sd)) { - esp_log("ESP SCSI no devices on ID %d, LUN %d\n", dev->id, dev->cmdbuf[8] >> 5); + esp_log("ESP SCSI no devices on ID %d, LUN %d\n", dev->id, dev->lun); /* No such drive */ dev->rregs[ESP_RSTAT] = 0; dev->rregs[ESP_RINTR] = INTR_DC; dev->rregs[ESP_RSEQ] = SEQ_0; esp_raise_irq(dev); + fifo8_reset(&dev->cmdfifo); return; } else { - esp_log("ESP SCSI device found on ID %d, LUN %d\n", dev->id, dev->cmdbuf[8] >> 5); + esp_log("ESP SCSI device found on ID %d, LUN %d\n", dev->id, dev->lun); } - count = tdbc = dev->dma_left; + count = tdbc = esp_get_tc(dev); - if (dev->xfer_counter == 0) { - /* Wait until data is available. */ - esp_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DMA no data available\n", dev->id, dev->cmdbuf[8] >> 5, dev->cmdbuf[7]); - return; - } - - esp_log("ESP SCSI dmaleft = %d, async_len = %i, buffer length = %d\n", dev->dma_counter, dev->async_len, sd->buffer_length); - - /* Make sure count is never bigger than buffer_length. */ - if (count > dev->xfer_counter) - count = dev->xfer_counter; + if (dev->mca) { /*See the comment in the esp_do_busid_cmd() function.*/ + if (sd->buffer_length < 0) { + if (dev->dma_enabled) + goto done; + else + goto partial; + } + } if (dev->do_cmd) { esp_log("ESP Command on DMA\n"); - esp_pci_dma_memory_rw(dev, &dev->cmdbuf[dev->cmdlen], count, 1); + count = MIN(count, fifo8_num_free(&dev->cmdfifo)); + if (dev->mca) { + while (dev->dma_86c01.pos < count) { + dma_channel_write(dev->DmaChannel, buf[dev->dma_86c01.pos]); + dev->dma_86c01.pos++; + } + dev->dma_86c01.pos = 0; + } else + esp_pci_dma_memory_rw(dev, buf, count, READ_FROM_DEVICE); + fifo8_push_all(&dev->cmdfifo, buf, count); dev->ti_size = 0; - dev->cmdlen = 0; - dev->do_cmd = 0; - esp_do_cmd(dev, dev->cmdbuf); + + if ((dev->rregs[ESP_RSTAT] & 7) == STAT_CD) { + if (dev->cmdfifo_cdb_offset == fifo8_num_used(&dev->cmdfifo)) + return; + + dev->do_cmd = 0; + esp_do_cmd(dev); + } else { + dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); + + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } return; } - if (sd->phase == SCSI_PHASE_DATA_IN) { - esp_log("ESP SCSI Read, dma cnt = %i, ti size = %i, positive len = %i\n", dev->dma_counter, dev->ti_size, count); - esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, 1); - } else if (sd->phase == SCSI_PHASE_DATA_OUT) { - esp_log("ESP SCSI Write, negative len = %i, ti size = %i, dma cnt = %i\n", count, -dev->ti_size, dev->dma_counter); - esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, 0); + if (dev->xfer_counter == 0) { + /* Wait until data is available. */ + esp_log("(ID=%02i LUN=%02i): DMA no data available\n", dev->id, dev->lun); + return; } - dev->dma_left -= count; + esp_log("ESP SCSI dmaleft = %d, async_len = %i, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length); + + /* Make sure count is never bigger than buffer_length. */ + if (count > dev->xfer_counter) + count = dev->xfer_counter; + + if (sd->phase == SCSI_PHASE_DATA_IN) { + esp_log("ESP SCSI Read, dma cnt = %i, ti size = %i, positive len = %i\n", esp_get_tc(dev), dev->ti_size, count); + if (dev->mca) { + while (dev->dma_86c01.pos < count) { + dma_channel_write(dev->DmaChannel, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); + esp_log("ESP SCSI DMA read for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos]); + dev->dma_86c01.pos++; + } + dev->dma_86c01.pos = 0; + } else { + esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, READ_FROM_DEVICE); + } + } else if (sd->phase == SCSI_PHASE_DATA_OUT) { + esp_log("ESP SCSI Write, negative len = %i, ti size = %i, dma cnt = %i\n", count, -dev->ti_size, esp_get_tc(dev)); + if (dev->mca) { + while (dev->dma_86c01.pos < count) { + int val = dma_channel_read(dev->DmaChannel); + esp_log("ESP SCSI DMA write for 53C90: pos = %i, val = %02x\n", dev->dma_86c01.pos, val & 0xff); + sd->sc->temp_buffer[dev->buffer_pos + dev->dma_86c01.pos] = val & 0xff; + dev->dma_86c01.pos++; + } + dev->dma_86c01.pos = 0; + } else + esp_pci_dma_memory_rw(dev, sd->sc->temp_buffer + dev->buffer_pos, count, WRITE_TO_DEVICE); + } + esp_set_tc(dev, esp_get_tc(dev) - count); dev->buffer_pos += count; dev->xfer_counter -= count; if (sd->phase == SCSI_PHASE_DATA_IN) { @@ -462,16 +759,23 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) } else { esp_log("ESP SCSI Write finished\n"); scsi_device_command_phase1(sd); - esp_pci_command_complete(dev, sd->status); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); } } else if (sd->phase == SCSI_PHASE_DATA_IN) { /* If there is still data to be read from the device then complete the DMA operation immediately. Otherwise defer until the scsi layer has completed. */ if (dev->ti_size <= 0) { +done: esp_log("ESP SCSI Read finished\n"); scsi_device_command_phase1(sd); - esp_pci_command_complete(dev, sd->status); + if (dev->mca) { + esp_command_complete(dev, sd->status); + } else + esp_pci_command_complete(dev, sd->status); } else { esp_log("ESP SCSI Keep reading\n"); esp_do_dma(dev, sd); @@ -479,6 +783,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) } } else { /* Partially filled a scsi buffer. Complete immediately. */ +partial: esp_log("ESP SCSI Partially filled the SCSI buffer\n"); esp_dma_done(dev); } @@ -489,11 +794,11 @@ static void esp_report_command_complete(esp_t *dev, uint32_t status) { esp_log("ESP Command complete\n"); - dev->ti_size = 0; - dev->dma_counter = 0; + + dev->ti_size = 0; dev->status = status; - dev->rregs[ESP_RSTAT] = STAT_ST; - esp_dma_done(dev); + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; + esp_dma_done(dev); } /* Callback to indicate that the SCSI layer has completed a command. */ @@ -501,16 +806,7 @@ static void esp_command_complete(void *priv, uint32_t status) { esp_t *dev = (esp_t *)priv; - - if (dev->rregs[ESP_RSTAT] & STAT_INT) { - /* Defer handling command complete until the previous - * interrupt has been handled. - */ - esp_log("ESP Deferred status\n"); - dev->deferred_status = status; - dev->deferred_complete = 1; - return; - } + esp_report_command_complete(dev, status); } @@ -527,10 +823,15 @@ esp_pci_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - /* Fast SCSI: 10000000 bytes per second */ - dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + if (dev->mca) { + /* Normal SCSI: 5000000 bytes per second */ + dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.2); + } else { + /* Fast SCSI: 10000000 bytes per second */ + dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + } - timer_on_auto(&dev->timer, dev->period + 40.0); + timer_on_auto(&dev->timer, dev->period + 40.0); } static void @@ -538,24 +839,13 @@ handle_ti(void *priv) { esp_t *dev = (esp_t *)priv; scsi_device_t *sd = &scsi_devices[dev->bus][dev->id]; - uint32_t dmalen; if (dev->dma) { - dmalen = dev->rregs[ESP_TCLO]; - dmalen |= dev->rregs[ESP_TCMID] << 8; - dmalen |= dev->rregs[ESP_TCHI] << 16; - - dev->dma_counter = dmalen; - dev->dma_left = dmalen; - - esp_log("ESP Handle TI, do data, minlen = %i, tclo = %02x, tcmid = %02x, tchi = %02x\n", dev->dma_counter, dev->rregs[ESP_TCLO], dev->rregs[ESP_TCMID], dev->rregs[ESP_TCHI]); + esp_log("ESP Handle TI, do data, minlen = %i\n", esp_get_tc(dev)); esp_do_dma(dev, sd); - } else if (dev->do_cmd) { - dev->ti_size = 0; - dev->cmdlen = 0; - dev->do_cmd = 0; - esp_log("ESP Handle TI, do cmd, CDB[1] = 0x%02x\n", dev->cmdbuf[8]); - esp_do_cmd(dev, dev->cmdbuf); + } else { + esp_log("ESP Handle TI, do nodma, minlen = %i\n", dev->xfer_counter); + esp_do_nodma(dev, sd); } } @@ -563,64 +853,92 @@ static void handle_s_without_atn(void *priv) { esp_t *dev = (esp_t *)priv; - uint8_t buf[32]; int len; - len = esp_get_cmd(dev, buf, sizeof(buf)); + len = esp_get_cmd(dev, ESP_CMDFIFO_SZ); esp_log("ESP SEL w/o ATN len = %d, id = %d\n", len, dev->id); - if (len) { - esp_do_busid_cmd(dev, buf, 0); - } + if (len > 0) { + dev->cmdfifo_cdb_offset = 0; + dev->do_cmd = 0; + esp_do_cmd(dev); + } else if (len == 0) { + dev->do_cmd = 1; + /* Target present, but no cmd yet - switch to command phase */ + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RSTAT] = STAT_CD; + } } static void handle_satn(void *priv) { esp_t *dev = (esp_t *)priv; - uint8_t buf[32]; int len; - len = esp_get_cmd(dev, buf, sizeof(buf)); + len = esp_get_cmd(dev, ESP_CMDFIFO_SZ); esp_log("ESP SEL with ATN len = %d, id = %d\n", len, dev->id); - if (len) { - esp_do_cmd(dev, buf); - } + if (len > 0) { + dev->cmdfifo_cdb_offset = 1; + dev->do_cmd = 0; + esp_do_cmd(dev); + } else if (len == 0) { + dev->do_cmd = 1; + /* Target present, but no cmd yet - switch to command phase */ + dev->rregs[ESP_RSEQ] = SEQ_CD; + dev->rregs[ESP_RSTAT] = STAT_CD; + } } static void handle_satn_stop(void *priv) { esp_t *dev = (esp_t *)priv; + int cmdlen; - dev->cmdlen = esp_get_cmd(dev, dev->cmdbuf, sizeof(dev->cmdbuf)); - if (dev->cmdlen) { + cmdlen = esp_get_cmd(dev, 1); + if (cmdlen > 0) { dev->do_cmd = 1; - dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; + dev->cmdfifo_cdb_offset = 1; + dev->rregs[ESP_RSTAT] = STAT_MO; dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; - dev->rregs[ESP_RSEQ] = SEQ_CD; - esp_log("ESP SCSI Command len = %d, raising IRQ\n", dev->cmdlen); + dev->rregs[ESP_RSEQ] = SEQ_MO; + esp_log("ESP SCSI Command len = %d, raising IRQ\n", cmdlen); esp_raise_irq(dev); - } + } else if (cmdlen == 0) { + dev->do_cmd = 1; + /* Target present, switch to message out phase */ + dev->rregs[ESP_RSEQ] = SEQ_MO; + dev->rregs[ESP_RSTAT] = STAT_MO; + } } static void esp_write_response(esp_t *dev) { - dev->ti_buf[0] = dev->status; - dev->ti_buf[1] = 0; + uint8_t buf[2]; + + buf[0] = dev->status; + buf[1] = 0; + if (dev->dma) { - esp_pci_dma_memory_rw(dev, dev->ti_buf, 2, 0); + if (dev->mca) { + while (dev->dma_86c01.pos < 2) { + int val = dma_channel_read(dev->DmaChannel); + buf[dev->dma_86c01.pos++] = val & 0xff; + } + dev->dma_86c01.pos = 0; + } else + esp_pci_dma_memory_rw(dev, buf, 2, WRITE_TO_DEVICE); dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; dev->rregs[ESP_RINTR] = INTR_BS | INTR_FC; dev->rregs[ESP_RSEQ] = SEQ_CD; } else { - dev->ti_size = 2; - dev->ti_rptr = 0; - dev->ti_wptr = 2; + fifo8_reset(&dev->fifo); + fifo8_push_all(&dev->fifo, buf, 2); dev->rregs[ESP_RFLAGS] = 2; } esp_log("ESP SCSI ICCS IRQ\n"); - esp_raise_irq(dev); + esp_raise_irq(dev); } static void @@ -634,53 +952,61 @@ esp_callback(void *p) handle_ti(dev); } } - esp_log("ESP DMA activated = %d, CMD activated = %d\n", dev->dma_enabled, dev->do_cmd); + + esp_log("ESP DMA activated = %d, CMD activated = %d\n", dev->dma_enabled, dev->do_cmd); } static uint32_t esp_reg_read(esp_t *dev, uint32_t saddr) { - uint32_t old_val; + uint32_t ret; switch (saddr) { case ESP_FIFO: - esp_log("ESP FIFO decrease = %d, readsize = %d, writesize = %d\n", dev->ti_size, dev->ti_rptr, dev->ti_wptr); - if (dev->ti_rptr < dev->ti_wptr) { - dev->ti_size--; - dev->rregs[ESP_FIFO] = dev->ti_buf[dev->ti_rptr++]; - } - if (dev->ti_rptr == dev->ti_wptr) { - dev->ti_rptr = 0; - dev->ti_wptr = 0; + if ((dev->rregs[ESP_RSTAT] & 7) == STAT_DI) { + if (dev->ti_size) { + esp_log("TI size FIFO = %i\n", dev->ti_size); + esp_do_nodma(dev, &scsi_devices[dev->bus][dev->id]); + } else { + /* + * The last byte of a non-DMA transfer has been read out + * of the FIFO so switch to status phase + */ + dev->rregs[ESP_RSTAT] = STAT_TC | STAT_ST; + } } + + dev->rregs[ESP_FIFO] = esp_fifo_pop(&dev->fifo); + ret = dev->rregs[ESP_FIFO]; break; case ESP_RINTR: /* Clear sequence step, interrupt register and all status bits except TC */ - old_val = dev->rregs[ESP_RINTR]; + ret = dev->rregs[ESP_RINTR]; dev->rregs[ESP_RINTR] = 0; dev->rregs[ESP_RSTAT] &= ~STAT_TC; - dev->rregs[ESP_RSEQ] = SEQ_CD; esp_log("ESP SCSI Clear sequence step\n"); esp_lower_irq(dev); - if (dev->deferred_complete) { - esp_report_command_complete(dev, dev->deferred_status); - dev->deferred_complete = 0; - } - esp_log("ESP RINTR read old val = %02x\n", old_val); - return old_val; + esp_log("ESP RINTR read old val = %02x\n", ret); + break; case ESP_TCHI: /* Return the unique id if the value has never been written */ - if (!dev->tchi_written) { + if (!dev->tchi_written && !dev->mca) { esp_log("ESP TCHI read id 0x12\n"); - return TCHI_AM53C974; - } + ret = TCHI_AM53C974; + } else + ret = dev->rregs[saddr]; + break; + case ESP_RFLAGS: + ret = fifo8_num_used(&dev->fifo); + break; default: + ret = dev->rregs[saddr]; break; } - esp_log("Read reg %02x = %02x\n", saddr, dev->rregs[saddr]); - return dev->rregs[saddr]; + esp_log("Read reg %02x = %02x\n", saddr, ret); + return ret; } @@ -695,19 +1021,24 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) /* fall through */ case ESP_TCLO: case ESP_TCMID: - esp_log("Transfer count regs %02x = %02x\n", saddr, val); + esp_log("Transfer count regs %02x = %i\n", saddr, val); dev->rregs[ESP_RSTAT] &= ~STAT_TC; break; case ESP_FIFO: if (dev->do_cmd) { - if (dev->cmdlen < ESP_CMDBUF_SZ) { - dev->cmdbuf[dev->cmdlen++] = val & 0xff; - esp_log("ESP CmdBuf Write len = %d, = %02x\n", dev->cmdlen, val & 0xff); - } + esp_fifo_push(&dev->cmdfifo, val); + esp_log("ESP CmdVal = %02x\n", val); + /* + * If any unexpected message out/command phase data is + * transferred using non-DMA, raise the interrupt + */ + if (dev->rregs[ESP_CMD] == CMD_TI) { + dev->rregs[ESP_RINTR] |= INTR_BS; + esp_raise_irq(dev); + } } else { - esp_log("ESP FIFO write = %02x\n", val & 0xff); - dev->ti_size++; - dev->ti_buf[dev->ti_wptr++] = val & 0xff; + esp_fifo_push(&dev->fifo, val); + esp_log("ESP fifoval = %02x\n", val); } break; case ESP_CMD: @@ -715,36 +1046,40 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) if (val & CMD_DMA) { dev->dma = 1; - /* Reload DMA counter.*/ - dev->rregs[ESP_TCLO] = dev->wregs[ESP_TCLO]; - dev->rregs[ESP_TCMID] = dev->wregs[ESP_TCMID]; - dev->rregs[ESP_TCHI] = dev->wregs[ESP_TCHI]; - esp_log("ESP Command for DMA, wregs: TCLO = %02x, TCMID = %02x, TCHI = %02x\n", dev->wregs[ESP_TCLO], - dev->wregs[ESP_TCMID], dev->wregs[ESP_TCHI]); + /* Reload DMA counter. */ + esp_set_tc(dev, esp_get_stc(dev)); + if (dev->mca) + esp_dma_enable(dev, 1); } else { dev->dma = 0; esp_log("ESP Command not for DMA\n"); + if (dev->mca) + esp_dma_enable(dev, 0); } - esp_log("ESP Command = %02x, DMA ena1 = %d, DMA ena2 = %d\n", val & CMD_CMD, dev->dma, dev->dma_enabled); + esp_log("[%04X:%08X]: ESP Command = %02x, DMA ena1 = %d, DMA ena2 = %d\n", CS, cpu_state.pc, val & (CMD_CMD|CMD_DMA), dev->dma, dev->dma_enabled); switch (val & CMD_CMD) { case CMD_NOP: break; case CMD_FLUSH: - dev->rregs[ESP_RINTR] = INTR_FC; - dev->rregs[ESP_RSEQ] = 0; - dev->rregs[ESP_RFLAGS] = 0; + fifo8_reset(&dev->fifo); timer_on_auto(&dev->timer, 10.0); break; case CMD_RESET: - esp_pci_soft_reset(dev); + if (dev->mca) { + esp_lower_irq(dev); + esp_hard_reset(dev); + } else + esp_pci_soft_reset(dev); break; case CMD_BUSRESET: - dev->rregs[ESP_RINTR] = INTR_RST; if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { - esp_log("ESP Bus Reset with IRQ\n"); + dev->rregs[ESP_RINTR] |= INTR_RST; + esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); } break; + case CMD_TI: + break; case CMD_SEL: handle_s_without_atn(dev); break; @@ -756,11 +1091,11 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_ICCS: esp_write_response(dev); - dev->rregs[ESP_RINTR] = INTR_FC; + dev->rregs[ESP_RINTR] |= INTR_FC; dev->rregs[ESP_RSTAT] |= STAT_MI; break; case CMD_MSGACC: - dev->rregs[ESP_RINTR] = INTR_DC; + dev->rregs[ESP_RINTR] |= INTR_DC; dev->rregs[ESP_RSEQ] = 0; dev->rregs[ESP_RFLAGS] = 0; esp_log("ESP SCSI MSGACC IRQ\n"); @@ -768,7 +1103,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_PAD: dev->rregs[ESP_RSTAT] = STAT_TC; - dev->rregs[ESP_RINTR] = INTR_FC; + dev->rregs[ESP_RINTR] |= INTR_FC; dev->rregs[ESP_RSEQ] = 0; esp_log("ESP Transfer Pad\n"); break; @@ -813,32 +1148,32 @@ static void esp_pci_dma_memory_rw(esp_t *dev, uint8_t *buf, uint32_t len, int dir) { int expected_dir; - - if (dev->dma_regs[DMA_CMD] & DMA_CMD_DIR) - expected_dir = 1; - else - expected_dir = 0; - if (dir != expected_dir) { + if (dev->dma_regs[DMA_CMD] & DMA_CMD_DIR) + expected_dir = READ_FROM_DEVICE; + else + expected_dir = WRITE_TO_DEVICE; + + esp_log("ESP DMA WBC = %d, addr = %06x, expected direction = %d, dir = %i\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir, dir); + + if (dir != expected_dir) { esp_log("ESP unexpected direction\n"); return; - } - - esp_log("ESP DMA WBC = %d, addr = %06x, dir = %d\n", dev->dma_regs[DMA_WBC], dev->dma_regs[DMA_SPA], expected_dir); + } - if (dev->dma_regs[DMA_WBC] < len) + if (dev->dma_regs[DMA_WBC] < len) len = dev->dma_regs[DMA_WBC]; - if (expected_dir) { + if (expected_dir) { dma_bm_write(dev->dma_regs[DMA_SPA], buf, len, 4); - } else { + } else { dma_bm_read(dev->dma_regs[DMA_SPA], buf, len, 4); - } + } - /* update status registers */ - dev->dma_regs[DMA_WBC] -= len; - dev->dma_regs[DMA_WAC] += len; - if (dev->dma_regs[DMA_WBC] == 0) + /* update status registers */ + dev->dma_regs[DMA_WBC] -= len; + dev->dma_regs[DMA_WAC] += len; + if (dev->dma_regs[DMA_WBC] == 0) dev->dma_regs[DMA_STAT] |= DMA_STAT_DONE; } @@ -881,6 +1216,7 @@ esp_pci_dma_write(esp_t *dev, uint16_t saddr, uint32_t val) case 1: /*BLAST*/ break; case 2: /*ABORT*/ + scsi_device_command_stop(&scsi_devices[dev->bus][dev->id]); break; case 3: /*START*/ dev->dma_regs[DMA_WBC] = dev->dma_regs[DMA_STC]; @@ -1276,11 +1612,11 @@ esp_pci_read(int func, int addr, void *p) { esp_t *dev = (esp_t *)p; - esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); + //esp_log("ESP PCI: Reading register %02X\n", addr & 0xff); switch (addr) { case 0x00: - esp_log("ESP PCI: Read DO line = %02x\n", dev->eeprom.out); + //esp_log("ESP PCI: Read DO line = %02x\n", dev->eeprom.out); if (!dev->has_bios) return 0x22; else { @@ -1340,6 +1676,9 @@ esp_pci_read(int func, int addr, void *p) return dev->irq; case 0x3D: return PCI_INTA; + + case 0x40 ... 0x4f: + return esp_pci_regs[addr]; } return(0); @@ -1354,7 +1693,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) int eesk; int eedi; - esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); + //esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); if ((addr >= 0x80) && (addr <= 0xFF)) { if (addr == 0x80) { @@ -1363,7 +1702,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) dc390_write_eeprom(dev, 1, eesk, eedi); } else if (addr == 0xc0) dc390_write_eeprom(dev, 0, 0, 0); - esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); + //esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); return; } @@ -1388,7 +1727,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) esp_pci_bar[0].addr &= 0xff00; dev->PCIBase = esp_pci_bar[0].addr; /* Log the new base. */ - esp_log("ESP PCI: New I/O base is %04X\n" , dev->PCIBase); + //esp_log("ESP PCI: New I/O base is %04X\n" , dev->PCIBase); /* We're done, so get out of the here. */ if (esp_pci_regs[4] & PCI_COMMAND_IO) { if (dev->PCIBase != 0) { @@ -1409,7 +1748,7 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) esp_pci_bar[1].addr &= 0xfff80001; dev->BIOSBase = esp_pci_bar[1].addr & 0xfff80000; /* Log the new base. */ - esp_log("ESP PCI: New BIOS base is %08X\n" , dev->BIOSBase); + //esp_log("ESP PCI: New BIOS base is %08X\n" , dev->BIOSBase); /* We're done, so get out of the here. */ if (esp_pci_bar[1].addr & 0x00000001) esp_bios_set_addr(dev, dev->BIOSBase); @@ -1420,6 +1759,10 @@ esp_pci_write(int func, int addr, uint8_t val, void *p) dev->irq = val; esp_log("ESP IRQ now: %i\n", val); return; + + case 0x40 ... 0x4f: + esp_pci_regs[addr] = val; + return; } } @@ -1432,7 +1775,12 @@ dc390_init(const device_t *info) memset(dev, 0x00, sizeof(esp_t)); dev->bus = scsi_get_bus(); - + + dev->mca = 0; + + fifo8_create(&dev->fifo, ESP_FIFO_SZ); + fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); + dev->PCIBase = 0; dev->MMIOBase = 0; @@ -1453,12 +1801,12 @@ dc390_init(const device_t *info) } if (dev->has_bios) - esp_bios_disable(dev); + esp_bios_disable(dev); - dev->nvr_path = "dc390.nvr"; + dev->nvr_path = "dc390.nvr"; - /* Load the serial EEPROM. */ - dc390_load_eeprom(dev); + /* Load the serial EEPROM. */ + dc390_load_eeprom(dev); esp_pci_hard_reset(dev); @@ -1467,6 +1815,174 @@ dc390_init(const device_t *info) return(dev); } +static uint16_t +ncr53c90_in(uint16_t port, void *priv) +{ + esp_t *dev = (esp_t *)priv; + uint16_t ret = 0; + + port &= 0x1f; + + if (port >= 0x10) + ret = esp_reg_read(dev, port - 0x10); + else { + switch (port) { + case 0x02: + ret = dev->dma_86c01.mode; + break; + + case 0x0c: + ret = dev->dma_86c01.status; + break; + } + } + + esp_log("[%04X:%08X]: NCR53c90 DMA read port = %02x, ret = %02x\n", CS, cpu_state.pc, port, ret); + + return ret; +} + +static uint8_t +ncr53c90_inb(uint16_t port, void *priv) +{ + return ncr53c90_in(port, priv); +} + +static uint16_t +ncr53c90_inw(uint16_t port, void *priv) +{ + return (ncr53c90_in(port, priv) & 0xff) | (ncr53c90_in(port + 1, priv) << 8); +} + +static void +ncr53c90_out(uint16_t port, uint16_t val, void *priv) +{ + esp_t *dev = (esp_t *)priv; + + port &= 0x1f; + + esp_log("[%04X:%08X]: NCR53c90 DMA write port = %02x, val = %02x\n", CS, cpu_state.pc, port, val); + + if (port >= 0x10) + esp_reg_write(dev, port - 0x10, val); + else { + if (port == 0x02) { + dev->dma_86c01.mode = (val & 0x40); + } + } +} + +static void +ncr53c90_outb(uint16_t port, uint8_t val, void *priv) +{ + ncr53c90_out(port, val, priv); +} + +static void +ncr53c90_outw(uint16_t port, uint16_t val, void *priv) +{ + ncr53c90_out(port, val & 0xff, priv); + ncr53c90_out(port + 1, val >> 8, priv); +} + +static uint8_t +ncr53c90_mca_read(int port, void *priv) +{ + esp_t *dev = (esp_t *)priv; + + return(dev->pos_regs[port & 7]); +} + + +static void +ncr53c90_mca_write(int port, uint8_t val, void *priv) +{ + esp_t *dev = (esp_t *)priv; + static const uint16_t ncrmca_iobase[] = { + 0, 0x240, 0x340, 0x400, 0x420, 0x3240, 0x8240, 0xa240 + }; + + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) return; + + /* Save the MCA register value. */ + dev->pos_regs[port & 7] = val; + + /* This is always necessary so that the old handler doesn't remain. */ + if (dev->Base != 0) { + io_removehandler(dev->Base, 0x20, + ncr53c90_inb, ncr53c90_inw, NULL, + ncr53c90_outb, ncr53c90_outw, NULL, dev); + } + + /* Get the new assigned I/O base address. */ + dev->Base = ncrmca_iobase[(dev->pos_regs[2] & 0x0e) >> 1]; + + /* Save the new IRQ and DMA channel values. */ + dev->irq = 3 + (2 * ((dev->pos_regs[2] & 0x30) >> 4)); + if (dev->irq == 9) + dev->irq = 2; + + dev->DmaChannel = dev->pos_regs[3] & 0x0f; + + /* + * Get misc SCSI config stuff. For now, we are only + * interested in the configured HA target ID. + */ + dev->HostID = 6 + ((dev->pos_regs[5] & 0x20) ? 1 : 0); + + /* Initialize the device if fully configured. */ + if (dev->pos_regs[2] & 0x01) { + if (dev->Base != 0) { + /* Card enabled; register (new) I/O handler. */ + io_sethandler(dev->Base, 0x20, + ncr53c90_inb, ncr53c90_inw, NULL, + ncr53c90_outb, ncr53c90_outw, NULL, dev); + + esp_hard_reset(dev); + } + + /* Say hello. */ + esp_log("NCR 53c90: I/O=%04x, IRQ=%d, DMA=%d, HOST ID %i\n", + dev->Base, dev->irq, dev->DmaChannel, dev->HostID); + } +} + + +static uint8_t +ncr53c90_mca_feedb(void *priv) +{ + esp_t *dev = (esp_t *)priv; + + return (dev->pos_regs[2] & 0x01); +} + + +static void * +ncr53c90_mca_init(const device_t *info) +{ + esp_t *dev; + + dev = malloc(sizeof(esp_t)); + memset(dev, 0x00, sizeof(esp_t)); + + dev->bus = scsi_get_bus(); + + dev->mca = 1; + + fifo8_create(&dev->fifo, ESP_FIFO_SZ); + fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); + + dev->pos_regs[0] = 0x4d; /* MCA board ID */ + dev->pos_regs[1] = 0x7f; + mca_add(ncr53c90_mca_read, ncr53c90_mca_write, ncr53c90_mca_feedb, NULL, dev); + + esp_hard_reset(dev); + + timer_add(&dev->timer, esp_callback, dev, 0); + + return(dev); +} static void esp_close(void *priv) @@ -1474,13 +1990,16 @@ esp_close(void *priv) esp_t *dev = (esp_t *)priv; if (dev) { + fifo8_destroy(&dev->fifo); + fifo8_destroy(&dev->cmdfifo); + free(dev); dev = NULL; } } -static const device_config_t dc390_pci_config[] = { +static const device_config_t bios_enable_config[] = { { "bios", "Enable BIOS", CONFIG_BINARY, "", 0 }, @@ -1497,5 +2016,15 @@ const device_t dc390_pci_device = 0, dc390_init, esp_close, NULL, { NULL }, NULL, NULL, - dc390_pci_config + bios_enable_config +}; + +const device_t ncr53c90_mca_device = +{ + "NCR 53c90 MCA", + DEVICE_MCA, + 0, + ncr53c90_mca_init, esp_close, NULL, + { NULL }, NULL, NULL, + NULL }; diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt index 856f6aaa6..482c2c2d6 100644 --- a/src/sio/CMakeLists.txt +++ b/src/sio/CMakeLists.txt @@ -1,26 +1,26 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# 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 - 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 - sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c - sio_vt82c686.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 + sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c + sio_vt82c686.c) if(SIO_DETECT) - target_sources(sio PRIVATE sio_detect.c) + target_sources(sio PRIVATE sio_detect.c) endif() \ No newline at end of file diff --git a/src/sio/sio_w83787f.c b/src/sio/sio_w83787f.c index ca0bfcc49..6affb7e1c 100644 --- a/src/sio/sio_w83787f.c +++ b/src/sio/sio_w83787f.c @@ -261,7 +261,7 @@ w83787f_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0: - pclog("REG 00: %02X\n", val); + w83787_log("REG 00: %02X\n", val); if ((valxor & 0xc0) && (HAS_IDE_FUNCTIONALITY)) w83787f_ide_handler(dev); if (valxor & 0x30) diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index f5a6435c4..e3420ac01 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -1,44 +1,44 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(snd OBJECT sound.c openal.c snd_opl.c snd_opl_nuked.c snd_resid.cc - midi.c midi_system.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c - snd_lpt_dss.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c - snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c - snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) + midi.c midi_rtmidi.cpp snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c + snd_lpt_dss.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c + snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c + snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) if(FLUIDSYNTH) - target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) - target_sources(snd PRIVATE midi_fluidsynth.c) + target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) + target_sources(snd PRIVATE midi_fluidsynth.c) endif() if(MUNT) - target_compile_definitions(snd PRIVATE USE_MUNT) - target_sources(snd PRIVATE midi_mt32.c) + target_compile_definitions(snd PRIVATE USE_MUNT) + target_sources(snd PRIVATE midi_mt32.c) - add_subdirectory(munt) - target_link_libraries(86Box mt32emu) + add_subdirectory(munt) + target_link_libraries(86Box mt32emu) endif() if(PAS16) - target_compile_definitions(snd PRIVATE USE_PAS16) - target_sources(snd PRIVATE snd_pas16.c) + target_compile_definitions(snd PRIVATE USE_PAS16) + target_sources(snd PRIVATE snd_pas16.c) endif() if(GUSMAX) - target_compile_definitions(snd PRIVATE USE_GUSMAX) + target_compile_definitions(snd PRIVATE USE_GUSMAX) endif() add_subdirectory(resid-fp) diff --git a/src/sound/midi.c b/src/sound/midi.c index e985f277f..8a195e2f9 100644 --- a/src/sound/midi.c +++ b/src/sound/midi.c @@ -28,9 +28,7 @@ #include <86box/86box.h> #include <86box/device.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/midi.h> -#include <86box/midi_input.h> int midi_device_current = 0; @@ -84,14 +82,14 @@ static const MIDI_DEVICE devices[] = { "mt32", &mt32_device }, { "cm32l", &cm32l_device }, #endif - { SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device }, + { SYSTEM_MIDI_INTERNAL_NAME, &rtmidi_device }, { "", NULL } }; static const MIDI_IN_DEVICE midi_in_devices[] = { { "none", NULL }, - { MIDI_INPUT_INTERNAL_NAME, &midi_input_device }, + { MIDI_INPUT_INTERNAL_NAME, &rtmidi_input_device }, { "", NULL } }; diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 283188fef..a93618cd4 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -346,7 +346,7 @@ void fluidsynth_close(void* p) data->on = 0; thread_set_event(data->event); - thread_wait(data->thread_h, -1); + thread_wait(data->thread_h); if (data->synth) { f_delete_fluid_synth(data->synth); diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index c41942574..8ade99b51 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -240,7 +240,7 @@ void mt32_close(void* p) mt32_on = 0; thread_set_event(event); - thread_wait(thread_h, -1); + thread_wait(thread_h); event = NULL; start_event = NULL; diff --git a/src/rtmidi_midi.cpp b/src/sound/midi_rtmidi.cpp similarity index 58% rename from src/rtmidi_midi.cpp rename to src/sound/midi_rtmidi.cpp index af9fc5439..e150159e4 100644 --- a/src/rtmidi_midi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -8,9 +8,9 @@ * * MIDI backend implemented using the RtMidi library. * - * Author: jgilje, + * Author: Cacodemon345, * Miran Grca, - * Copyright 2021 jgilje. + * Copyright 2021 Cacodemon345. * Copyright 2021 Miran Grca. */ #if defined __has_include @@ -30,8 +30,9 @@ extern "C" { #include <86box/86box.h> +#include <86box/device.h> #include <86box/midi.h> -#include <86box/plat_midi.h> +#include <86box/midi_rtmidi.h> #include <86box/config.h> @@ -42,19 +43,43 @@ static const int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; int -plat_midi_write(uint8_t val) +rtmidi_write(uint8_t val) { return 0; } -void plat_midi_init(void) +void +rtmidi_play_msg(uint8_t *msg) { + if (midiout) + 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); +} + + +void* +rtmidi_init(const device_t *info) +{ + 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_sysex = rtmidi_play_sysex; + 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; + 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); @@ -70,14 +95,18 @@ void plat_midi_init(void) pclog("Failed to initialize MIDI output: %s\n", error.getMessage().c_str()); delete midiout; midiout = nullptr; - return; + return nullptr; } } + + midi_init(dev); + + return dev; } void -plat_midi_close(void) +rtmidi_close(void *p) { if (!midiout) return; @@ -86,11 +115,13 @@ plat_midi_close(void) delete midiout; midiout = nullptr; + + midi_close(); } int -plat_midi_get_num_devs(void) +rtmidi_get_num_devs(void) { if (!midiout) { try { @@ -105,30 +136,14 @@ plat_midi_get_num_devs(void) void -plat_midi_play_msg(uint8_t *msg) -{ - if (midiout) - midiout->sendMessage(msg, midi_lengths[(msg[0] >> 4) & 7]); -} - - -void -plat_midi_get_dev_name(int num, char *s) +rtmidi_get_dev_name(int num, char *s) { strcpy(s, midiout->getPortName(num).c_str()); } void -plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{ - if (midiout) - midiout->sendMessage(sysex, len); -} - - -static void -plat_midi_callback(double timeStamp, std::vector *message, void *userData) +rtmidi_input_callback(double timeStamp, std::vector *message, void *userData) { if (message->size() <= 3) midi_in_msg(message->data()); @@ -137,15 +152,18 @@ plat_midi_callback(double timeStamp, std::vector *message, void * } -void -plat_midi_input_init(void) +void* +rtmidi_input_init(const device_t *info) { + 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; + return nullptr; } midi_in_id = config_get_int((char*)SYSTEM_MIDI_NAME, (char*)"midi_input", 0); @@ -161,16 +179,24 @@ plat_midi_input_init(void) pclog("Failed to initialize MIDI input: %s\n", error.getMessage().c_str()); delete midiin; midiin = nullptr; - return; + return nullptr; } } - midiin->setCallback(plat_midi_callback); + midiin->setCallback(rtmidi_input_callback); + + 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->midi_clockout = device_get_config_int("clockout"); + + return dev; } void -plat_midi_input_close(void) +rtmidi_input_close(void* p) { midiin->cancelCallback(); midiin->closePort(); @@ -178,12 +204,12 @@ plat_midi_input_close(void) delete midiin; midiin = nullptr; - return; + midi_close(); } int -plat_midi_in_get_num_devs(void) +rtmidi_in_get_num_devs(void) { if (!midiin) { try { @@ -198,9 +224,65 @@ plat_midi_in_get_num_devs(void) void -plat_midi_in_get_dev_name(int num, char *s) +rtmidi_in_get_dev_name(int num, char *s) { strcpy(s, midiin->getPortName(num).c_str()); } +static const device_config_t system_midi_config[] = +{ + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, + { + "", "", -1 + } +}; + +static const device_config_t midi_input_config[] = +{ + { + "midi_input", "MIDI in device", CONFIG_MIDI_IN, "", 0 + }, + { + "realtime", "MIDI Real time", CONFIG_BINARY, "", 0 + }, + { + "thruchan", "MIDI Thru", CONFIG_BINARY, "", 1 + }, + { + "clockout", "MIDI Clockout", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } +}; + +const device_t rtmidi_device = +{ + SYSTEM_MIDI_NAME, + 0, 0, + rtmidi_init, + rtmidi_close, + NULL, + { rtmidi_get_num_devs }, + NULL, + NULL, + system_midi_config +}; + + +const device_t rtmidi_input_device = +{ + MIDI_INPUT_NAME, + 0, 0, + rtmidi_input_init, + rtmidi_input_close, + NULL, + { rtmidi_in_get_num_devs }, + NULL, + NULL, + midi_input_config +}; + } diff --git a/src/sound/midi_system.c b/src/sound/midi_system.c deleted file mode 100644 index 1a577d932..000000000 --- a/src/sound/midi_system.c +++ /dev/null @@ -1,139 +0,0 @@ -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include <86box/device.h> -#include <86box/plat.h> -#include <86box/plat_midi.h> -#include <86box/midi.h> -#include <86box/midi_input.h> - - -void* system_midi_init(const device_t *info) -{ - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - dev->play_msg = plat_midi_play_msg; - dev->play_sysex = plat_midi_play_sysex; - dev->write = plat_midi_write; - - plat_midi_init(); - - midi_init(dev); - - return dev; -} - -void* midi_input_init(const device_t *info) -{ - midi_device_t* dev = malloc(sizeof(midi_device_t)); - memset(dev, 0, sizeof(midi_device_t)); - - plat_midi_input_init(); - - 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->midi_clockout = device_get_config_int("clockout"); - - return dev; -} - -void system_midi_close(void* p) -{ - plat_midi_close(); - - midi_close(); -} - -void midi_input_close(void* p) -{ - plat_midi_input_close(); - - midi_close(); -} - -int system_midi_available(void) -{ - return plat_midi_get_num_devs(); -} - -int midi_input_available(void) -{ - return plat_midi_in_get_num_devs(); -} - -static const device_config_t system_midi_config[] = -{ - { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 - }, - { - .type = -1 - } -}; - -static const device_config_t midi_input_config[] = -{ - { - .name = "midi_input", - .description = "MIDI in device", - .type = CONFIG_MIDI_IN, - .default_int = 0 - }, - { - .name = "realtime", - .description = "MIDI Real time", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "thruchan", - .description = "MIDI Thru", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "clockout", - .description = "MIDI Clockout", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .type = -1 - } -}; - -const device_t system_midi_device = -{ - SYSTEM_MIDI_NAME, - 0, 0, - system_midi_init, - system_midi_close, - NULL, - { system_midi_available }, - NULL, - NULL, - system_midi_config -}; - - -const device_t midi_input_device = -{ - MIDI_INPUT_NAME, - 0, 0, - midi_input_init, - midi_input_close, - NULL, - { midi_input_available }, - NULL, - NULL, - midi_input_config -}; \ No newline at end of file diff --git a/src/sound/munt/CMakeLists.txt b/src/sound/munt/CMakeLists.txt index e694bc7ae..79ac7b2d9 100644 --- a/src/sound/munt/CMakeLists.txt +++ b/src/sound/munt/CMakeLists.txt @@ -1,26 +1,26 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(mt32emu STATIC Analog.cpp BReverbModel.cpp File.cpp FileStream.cpp - LA32Ramp.cpp LA32FloatWaveGenerator.cpp LA32WaveGenerator.cpp - MidiStreamParser.cpp Part.cpp Partial.cpp PartialManager.cpp - Poly.cpp ROMInfo.cpp SampleRateConverter.cpp - srchelper/srctools/src/FIRResampler.cpp - srchelper/srctools/src/IIR2xResampler.cpp - srchelper/srctools/src/LinearResampler.cpp - srchelper/srctools/src/ResamplerModel.cpp - srchelper/srctools/src/SincResampler.cpp - srchelper/InternalResampler.cpp Synth.cpp Tables.cpp TVA.cpp TVF.cpp - TVP.cpp sha1/sha1.cpp c_interface/c_interface.cpp) \ No newline at end of file + LA32Ramp.cpp LA32FloatWaveGenerator.cpp LA32WaveGenerator.cpp + MidiStreamParser.cpp Part.cpp Partial.cpp PartialManager.cpp + Poly.cpp ROMInfo.cpp SampleRateConverter.cpp + srchelper/srctools/src/FIRResampler.cpp + srchelper/srctools/src/IIR2xResampler.cpp + srchelper/srctools/src/LinearResampler.cpp + srchelper/srctools/src/ResamplerModel.cpp + srchelper/srctools/src/SincResampler.cpp + srchelper/InternalResampler.cpp Synth.cpp Tables.cpp TVA.cpp TVF.cpp + TVP.cpp sha1/sha1.cpp c_interface/c_interface.cpp) \ No newline at end of file diff --git a/src/sound/resid-fp/CMakeLists.txt b/src/sound/resid-fp/CMakeLists.txt index 8b5a16f40..fb9b5396e 100644 --- a/src/sound/resid-fp/CMakeLists.txt +++ b/src/sound/resid-fp/CMakeLists.txt @@ -1,19 +1,19 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(resid-fp STATIC convolve-sse.cc convolve.cc envelope.cc extfilt.cc - filter.cc pot.cc sid.cc voice.cc wave.cc wave6581_PST.cc - wave6581_PS_.cc wave6581_P_T.cc wave6581__ST.cc wave8580_PST.cc - wave8580_PS_.cc wave8580_P_T.cc wave8580__ST.cc) \ No newline at end of file + filter.cc pot.cc sid.cc voice.cc wave.cc wave6581_PST.cc + wave6581_PS_.cc wave6581_P_T.cc wave6581__ST.cc wave8580_PST.cc + wave8580_PS_.cc wave8580_P_T.cc wave8580__ST.cc) \ No newline at end of file diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 95cdb1a52..d79776fb8 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1703,7 +1703,7 @@ mpu401_device_add(void) if (!mpu401_standalone_enable) return; - if (machines[machine].flags & MACHINE_MCA) + if (machine_has_bus(machine, MACHINE_BUS_MCA)) device_add(&mpu401_mca_device); else device_add(&mpu401_device); diff --git a/src/sound/snd_sb_dsp.c b/src/sound/snd_sb_dsp.c index 01a2ca6e0..d41467bb5 100644 --- a/src/sound/snd_sb_dsp.c +++ b/src/sound/snd_sb_dsp.c @@ -46,22 +46,22 @@ static int sbe2dat[4][9] = { static int sb_commands[256]= { - -1, 2,-1,-1, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, - 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, - 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0, - 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1, - 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, - 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, - -1,-1, 0,-1,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0 + -1, 2,-1, 0, 1, 2,-1, 0, 1,-1,-1,-1,-1,-1, 2, 1, + 1,-1,-1,-1, 2,-1, 2, 2,-1,-1,-1,-1, 0,-1,-1, 0, + 0,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 1, 2, 2,-1,-1,-1,-1,-1, 2,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1, 2, 2, 2, 2,-1,-1,-1,-1,-1, 0,-1, 0, + 2, 2,-1,-1,-1,-1,-1,-1, 2, 2,-1,-1,-1,-1,-1,-1, + 0,-1,-1,-1,-1,-1,-1,-1, 0,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 0,-1, 0, 0, 0, 0,-1, 0, 0, 0,-1,-1,-1,-1,-1, + 1, 0, 1, 0, 1,-1,-1, 0, 0,-1,-1,-1,-1,-1,-1,-1, + -1,-1, 0, 0,-1,-1,-1,-1,-1, 1, 2,-1,-1,-1,-1, 0 }; @@ -71,50 +71,50 @@ uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x /*These tables were 'borrowed' from DOSBox*/ int8_t scaleMap4[64] = { - 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, - 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, - 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, - 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 + 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7, + 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15, + 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30, + 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60 }; uint8_t adjustMap4[64] = { - 0, 0, 0, 0, 0, 16, 16, 16, - 0, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 16, 16, 16, - 240, 0, 0, 0, 0, 0, 0, 0, - 240, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 16, 16, 16, + 0, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 16, 16, 16, + 240, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0 }; int8_t scaleMap26[40] = { - 0, 1, 2, 3, 0, -1, -2, -3, - 1, 3, 5, 7, -1, -3, -5, -7, - 2, 6, 10, 14, -2, -6, -10, -14, - 4, 12, 20, 28, -4, -12, -20, -28, - 5, 15, 25, 35, -5, -15, -25, -35 + 0, 1, 2, 3, 0, -1, -2, -3, + 1, 3, 5, 7, -1, -3, -5, -7, + 2, 6, 10, 14, -2, -6, -10, -14, + 4, 12, 20, 28, -4, -12, -20, -28, + 5, 15, 25, 35, -5, -15, -25, -35 }; uint8_t adjustMap26[40] = { - 0, 0, 0, 8, 0, 0, 0, 8, - 248, 0, 0, 8, 248, 0, 0, 8, - 248, 0, 0, 8, 248, 0, 0, 8, - 248, 0, 0, 8, 248, 0, 0, 8, - 248, 0, 0, 0, 248, 0, 0, 0 + 0, 0, 0, 8, 0, 0, 0, 8, + 248, 0, 0, 8, 248, 0, 0, 8, + 248, 0, 0, 8, 248, 0, 0, 8, + 248, 0, 0, 8, 248, 0, 0, 8, + 248, 0, 0, 0, 248, 0, 0, 0 }; int8_t scaleMap2[24] = { - 0, 1, 0, -1, 1, 3, -1, -3, - 2, 6, -2, -6, 4, 12, -4, -12, - 8, 24, -8, -24, 6, 48, -16, -48 + 0, 1, 0, -1, 1, 3, -1, -3, + 2, 6, -2, -6, 4, 12, -4, -12, + 8, 24, -8, -24, 6, 48, -16, -48 }; uint8_t adjustMap2[24] = { - 0, 4, 0, 4, - 252, 4, 252, 4, 252, 4, 252, 4, - 252, 4, 252, 4, 252, 4, 252, 4, - 252, 0, 252, 0 + 0, 4, 0, 4, + 252, 4, 252, 4, 252, 4, 252, 4, + 252, 4, 252, 4, 252, 4, 252, 4, + 252, 0, 252, 0 }; double low_fir_sb16_coef[2][SB16_NCoef]; @@ -127,13 +127,13 @@ int sb_dsp_do_log = ENABLE_SB_DSP_LOG; static void sb_dsp_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (sb_dsp_do_log) { + if (sb_dsp_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); - } + } } #else #define sb_dsp_log(fmt, ...) @@ -143,19 +143,19 @@ sb_dsp_log(const char *fmt, ...) static __inline double sinc(double x) { - return sin(M_PI * x) / (M_PI * x); + return sin(M_PI * x) / (M_PI * x); } static void recalc_sb16_filter(int c, int playback_freq) { - /* Cutoff frequency = playback / 2 */ - int n; - double w, h; - double fC = ((double) playback_freq) / 96000.0; - double gain; + /* Cutoff frequency = playback / 2 */ + int n; + double w, h; + double fC = ((double) playback_freq) / 96000.0; + double gain; - for (n = 0; n < SB16_NCoef; n++) { + for (n = 0; n < SB16_NCoef; n++) { /* Blackman window */ w = 0.42 - (0.5 * cos((2.0*n*M_PI)/(double)(SB16_NCoef-1))) + (0.08 * cos((4.0*n*M_PI)/(double)(SB16_NCoef-1))); /* Sinc filter */ @@ -163,16 +163,16 @@ recalc_sb16_filter(int c, int playback_freq) /* Create windowed-sinc filter */ low_fir_sb16_coef[c][n] = w * h; - } + } - low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; + low_fir_sb16_coef[c][(SB16_NCoef - 1) / 2] = 1.0; - gain = 0.0; - for (n = 0; n < SB16_NCoef; n++) + gain = 0.0; + for (n = 0; n < SB16_NCoef; n++) gain += low_fir_sb16_coef[c][n]; - /* Normalise filter, to produce unity gain */ - for (n = 0; n < SB16_NCoef; n++) + /* Normalise filter, to produce unity gain */ + for (n = 0; n < SB16_NCoef; n++) low_fir_sb16_coef[c][n] /= gain; } @@ -180,19 +180,19 @@ recalc_sb16_filter(int c, int playback_freq) void sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401) { - int clear = 0; + int clear = 0; - if (!dsp->sb_irqm8 && irqm8) + if (!dsp->sb_irqm8 && irqm8) clear |= 1; - dsp->sb_irqm8 = irqm8; - if (!dsp->sb_irqm16 && irqm16) + dsp->sb_irqm8 = irqm8; + if (!dsp->sb_irqm16 && irqm16) clear |= 1; - dsp->sb_irqm16 = irqm16; - if (!dsp->sb_irqm401 && irqm401) + dsp->sb_irqm16 = irqm16; + if (!dsp->sb_irqm401 && irqm401) clear |= 1; - dsp->sb_irqm401 = irqm401; + dsp->sb_irqm401 = irqm401; - if (clear) + if (clear) picintc(1 << dsp->sb_irqnum); } @@ -200,9 +200,9 @@ sb_update_mask(sb_dsp_t *dsp, int irqm8, int irqm16, int irqm401) void sb_update_status(sb_dsp_t *dsp, int bit, int set) { - int masked = 0; + int masked = 0; - switch (bit) { + switch (bit) { case 0: default: dsp->sb_irq8 = set; @@ -216,11 +216,11 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) dsp->sb_irq401 = set; masked = dsp->sb_irqm401; break; - } + } - if (set && !masked) + if (set && !masked) picint(1 << dsp->sb_irqnum); - else if (!set) + else if (!set) picintc(1 << dsp->sb_irqnum); } @@ -228,41 +228,41 @@ sb_update_status(sb_dsp_t *dsp, int bit, int set) void sb_irq(sb_dsp_t *dsp, int irq8) { - sb_update_status(dsp, !irq8, 1); + sb_update_status(dsp, !irq8, 1); } void sb_irqc(sb_dsp_t *dsp, int irq8) { - sb_update_status(dsp, !irq8, 0); + sb_update_status(dsp, !irq8, 0); } static void sb_dsp_irq_update(void *priv, int set) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_t *dsp = (sb_dsp_t *) priv; - sb_update_status(dsp, 2, set); + sb_update_status(dsp, 2, set); } static int sb_dsp_irq_pending(void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_t *dsp = (sb_dsp_t *) priv; - return dsp->sb_irq401; + return dsp->sb_irq401; } void sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu) { - dsp->mpu = mpu; + dsp->mpu = mpu; - if (mpu != NULL) + if (mpu != NULL) mpu401_irq_attach(mpu, sb_dsp_irq_update, sb_dsp_irq_pending, dsp); } @@ -270,75 +270,77 @@ sb_dsp_set_mpu(sb_dsp_t *dsp, mpu_t *mpu) void sb_dsp_reset(sb_dsp_t *dsp) { - midi_clear_buffer(); + midi_clear_buffer(); - timer_disable(&dsp->output_timer); - timer_disable(&dsp->input_timer); + timer_disable(&dsp->output_timer); + timer_disable(&dsp->input_timer); - dsp->sb_command = 0; + dsp->sb_command = 0; - dsp->sb_8_length = 0xffff; - dsp->sb_8_autolen = 0xffff; + dsp->sb_8_length = 0xffff; + dsp->sb_8_autolen = 0xffff; - dsp->sb_irq8 = 0; - dsp->sb_irq16 = 0; - dsp->sb_irq401 = 0; - dsp->sb_16_pause = 0; - dsp->sb_read_wp = dsp->sb_read_rp = 0; - dsp->sb_data_stat = -1; - dsp->sb_speaker = 0; - dsp->sb_pausetime = -1LL; - dsp->sbe2 = 0xAA; - dsp->sbe2count = 0; + dsp->sb_irq8 = 0; + dsp->sb_irq16 = 0; + dsp->sb_irq401 = 0; + dsp->sb_16_pause = 0; + dsp->sb_read_wp = dsp->sb_read_rp = 0; + dsp->sb_data_stat = -1; + dsp->sb_speaker = 0; + dsp->sb_pausetime = -1LL; + dsp->sbe2 = 0xAA; + dsp->sbe2count = 0; - dsp->sbreset = 0; + dsp->sbreset = 0; - dsp->record_pos_read = 0; - dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN; + dsp->record_pos_read = 0; + dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN; - picintc(1 << dsp->sb_irqnum); + picintc(1 << dsp->sb_irqnum); - dsp->asp_data_len = 0; + dsp->asp_data_len = 0; } void sb_doreset(sb_dsp_t *dsp) { - int c; + int c; - sb_dsp_reset(dsp); + sb_dsp_reset(dsp); - if (IS_AZTECH(dsp)) { + if (IS_AZTECH(dsp)) { + sb_commands[8] = 1; + sb_commands[9] = 1; + } else { + if (dsp->sb_type >= SB16) sb_commands[8] = 1; - sb_commands[9] = 1; - } else { - if ((dsp->sb_type >= SB16) && (dsp->sb_type < SBAWE64)) - sb_commands[8] = 1; - else + else sb_commands[8] = -1; - } + } - for (c = 0; c < 256; c++) + dsp->sb_asp_mode = 0; + dsp->sb_asp_ram_index = 0; + for (c = 0; c < 256; c++) dsp->sb_asp_regs[c] = 0; - dsp->sb_asp_regs[5] = 0x01; - dsp->sb_asp_regs[9] = 0xf8; + dsp->sb_asp_regs[5] = 0x01; + dsp->sb_asp_regs[9] = 0xf8; } void sb_dsp_speed_changed(sb_dsp_t *dsp) { - if (dsp->sb_timeo < 256) + if (dsp->sb_timeo < 256) dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); - else + else dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); - if (dsp->sb_timei < 256) + if (dsp->sb_timei < 256) dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); - else + else dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); } @@ -346,17 +348,17 @@ sb_dsp_speed_changed(sb_dsp_t *dsp) void sb_add_data(sb_dsp_t *dsp, uint8_t v) { - dsp->sb_read_data[dsp->sb_read_wp++] = v; - dsp->sb_read_wp &= 0xff; + dsp->sb_read_data[dsp->sb_read_wp++] = v; + dsp->sb_read_wp &= 0xff; } void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { - dsp->sb_pausetime = -1; + dsp->sb_pausetime = -1; - if (dma8) { + if (dma8) { dsp->sb_8_length = len; dsp->sb_8_format = format; dsp->sb_8_autoinit = autoinit; @@ -370,7 +372,7 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); dsp->sbleftright = 0; dsp->sbdacpos = 0; - } else { + } else { dsp->sb_16_length = len; dsp->sb_16_format = format; dsp->sb_16_autoinit = autoinit; @@ -380,14 +382,14 @@ sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_output = 1; if (!timer_is_enabled(&dsp->output_timer)) timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); - } + } } void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { - if (dma8) { + if (dma8) { dsp->sb_8_length = len; dsp->sb_8_format = format; dsp->sb_8_autoinit = autoinit; @@ -398,7 +400,7 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_8_output = 0; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); - } else { + } else { dsp->sb_16_length = len; dsp->sb_16_format = format; dsp->sb_16_autoinit = autoinit; @@ -409,76 +411,83 @@ sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) dsp->sb_16_output = 0; if (!timer_is_enabled(&dsp->input_timer)) timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); - } + } - memset(dsp->record_buffer,0,sizeof(dsp->record_buffer)); + memset(dsp->record_buffer,0,sizeof(dsp->record_buffer)); } int sb_8_read_dma(sb_dsp_t *dsp) { - return dma_channel_read(dsp->sb_8_dmanum); + return dma_channel_read(dsp->sb_8_dmanum); } void sb_8_write_dma(sb_dsp_t *dsp, uint8_t val) { - dma_channel_write(dsp->sb_8_dmanum, val); + dma_channel_write(dsp->sb_8_dmanum, val); } int sb_16_read_dma(sb_dsp_t *dsp) { - return dma_channel_read(dsp->sb_16_dmanum); + return dma_channel_read(dsp->sb_16_dmanum); } int sb_16_write_dma(sb_dsp_t *dsp, uint16_t val) { - int ret = dma_channel_write(dsp->sb_16_dmanum, val); + int ret = dma_channel_write(dsp->sb_16_dmanum, val); - return (ret == DMA_NODATA); + return (ret == DMA_NODATA); } void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { - dsp->sb_irqnum = irq; + dsp->sb_irqnum = irq; } void sb_dsp_setdma8(sb_dsp_t *dsp, int dma) { - dsp->sb_8_dmanum = dma; + dsp->sb_8_dmanum = dma; } void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) { - dsp->sb_16_dmanum = dma; + dsp->sb_16_dmanum = dma; } void sb_exec_command(sb_dsp_t *dsp) { - int temp, c; + int temp, c; - sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command); + sb_dsp_log("sb_exec_command : SB command %02X\n", dsp->sb_command); - switch (dsp->sb_command) { + + /* Update 8051 ram with the current DSP command. + See https://github.com/joncampbell123/dosbox-x/issues/1044 */ + if (dsp->sb_type >= SB16) + dsp->sb_8051_ram[0x20] = dsp->sb_command; + + switch (dsp->sb_command) { case 0x01: /* ???? */ if (dsp->sb_type >= SB16) dsp->asp_data_len = dsp->sb_data[0] + (dsp->sb_data[1] << 8) + 1; break; case 0x03: /* ASP status */ - sb_add_data(dsp, 0); + if (dsp->sb_type >= SB16) + sb_add_data(dsp, 0); break; case 0x10: /* 8-bit direct mode */ sb_dsp_update(dsp); @@ -581,6 +590,8 @@ sb_exec_command(sb_dsp_t *dsp) dsp->sb_timei = dsp->sb_timeo; if (dsp->sb_freq != temp && dsp->sb_type >= SB16) recalc_sb16_filter(0, dsp->sb_freq); + dsp->sb_8051_ram[0x13] = dsp->sb_freq & 0xff; + dsp->sb_8051_ram[0x14] = (dsp->sb_freq >> 8) & 0xff; } break; case 0x48: /* Set DSP block transfer size */ @@ -767,7 +778,7 @@ sb_exec_command(sb_dsp_t *dsp) break; case 0x07: case 0xFF: /* No, that's not how you program auto-init DMA */ break; - case 0x08: /* ASP get version */ + case 0x08: /* ASP get version / AZTECH type/EEPROM access */ if (IS_AZTECH(dsp)) { if ((dsp->sb_data[0] == 0x05 || dsp->sb_data[0] == 0x55)&& dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ @@ -791,36 +802,76 @@ sb_exec_command(sb_dsp_t *dsp) sb_dsp_log("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); /* 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen */ break; } - if (dsp->sb_type >= SB16) + if (dsp->sb_type == SBAWE64) /* AWE64 has no ASP or a socket for it */ + sb_add_data(dsp, 0xFF); + else if (dsp->sb_type >= SB16) sb_add_data(dsp, 0x18); break; case 0x0E: /* ASP set register */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; + + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory write */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_ram[dsp->sb_asp_ram_index] = dsp->sb_data[1]; + + if (dsp->sb_asp_mode & 2) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } + sb_dsp_log("SB16 ASP write reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_data[1]); + } break; case 0x0F: /* ASP get register */ - if (dsp->sb_type >= SB16) + if (dsp->sb_type >= SB16) { + if ((dsp->sb_data[0] == 0x83) && (dsp->sb_asp_mode & 128) && (dsp->sb_asp_mode & 8)) { /* ASP memory read */ + if (dsp->sb_asp_mode & 8) + dsp->sb_asp_ram_index = 0; + + dsp->sb_asp_regs[0x83] = dsp->sb_asp_ram[dsp->sb_asp_ram_index]; + + if (dsp->sb_asp_mode & 1) { + dsp->sb_asp_ram_index++; + if (dsp->sb_asp_ram_index >= 2048) + dsp->sb_asp_ram_index = 0; + } + } else if (dsp->sb_data[0] == 0x83) { + dsp->sb_asp_regs[0x83] = 0x18; + } sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); + sb_dsp_log("SB16 ASP read reg %02X, val %02X\n", dsp->sb_data[0], dsp->sb_asp_regs[dsp->sb_data[0]]); + } break; case 0xF8: if (dsp->sb_type < SB16) sb_add_data(dsp, 0); break; - case 0xF9: - if (dsp->sb_type >= SB16) { - sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); - } + case 0xF9: /* SB16 8051 RAM read */ + if (dsp->sb_type >= SB16) + sb_add_data(dsp, dsp->sb_8051_ram[dsp->sb_data[0]]); break; - case 0xFA: - if(dsp->sb_type >= SB16) - { + case 0xFA: /* SB16 8051 RAM write */ + if (dsp->sb_type >= SB16) dsp->sb_8051_ram[dsp->sb_data[0]] = dsp->sb_data[1]; + break; + case 0x04: /* ASP set mode register */ + if (dsp->sb_type >= SB16) { + dsp->sb_asp_mode = dsp->sb_data[0]; + if (dsp->sb_asp_mode & 4) + dsp->sb_asp_ram_index = 0; + sb_dsp_log("SB16 ASP set mode %02X\n", dsp->sb_asp_mode); } break; - case 0x04: case 0x05: + case 0x05: /* ASP set codec parameter */ + if (dsp->sb_type >= SB16) + sb_dsp_log("SB16 ASP unknown codec params %02X, %02X\n", dsp->sb_data[0], dsp->sb_data[1]); break; - case 0x09: /*AZTECH mode set*/ + case 0x09: /* AZTECH mode set */ if (IS_AZTECH(dsp)) { if (dsp->sb_data[0] == 0x00) { sb_dsp_log("AZT2316A: WSS MODE!\n"); @@ -846,22 +897,22 @@ sb_exec_command(sb_dsp_t *dsp) * 0FCh DSP Auxiliary Status SB16 * 0FDh DSP Command Status SB16 */ - } - if(dsp->sb_type >= SB16) - { - //Update 8051 ram with the last DSP command. - //See https://github.com/joncampbell123/dosbox-x/issues/1044 - dsp->sb_8051_ram[0x30] = dsp->sb_command; - } + } + + + /* Update 8051 ram with the last DSP command. + See https://github.com/joncampbell123/dosbox-x/issues/1044 */ + if (dsp->sb_type >= SB16) + dsp->sb_8051_ram[0x30] = dsp->sb_command; } void sb_write(uint16_t a, uint8_t v, void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; + sb_dsp_t *dsp = (sb_dsp_t *) priv; - switch (a & 0xF) { + switch (a & 0xF) { case 6: /* Reset */ if (!dsp->uart_midi) { if (!(v & 1) && (dsp->sbreset & 1)) { @@ -913,17 +964,17 @@ sb_write(uint16_t a, uint8_t v, void *priv) } } break; - } + } } uint8_t sb_read(uint16_t a, void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *) priv; - uint8_t ret = 0x00; + sb_dsp_t *dsp = (sb_dsp_t *) priv; + uint8_t ret = 0x00; - switch (a & 0xf) { + switch (a & 0xf) { case 0xA: /* Read data */ if (dsp->mpu && dsp->uart_midi) { ret = MPU401_ReadData(dsp->mpu); @@ -978,134 +1029,136 @@ sb_read(uint16_t a, void *priv) sb_dsp_log("SB 16-bit ACK read 0xFF\n"); ret = 0xff; break; - } + } - return ret; + return ret; } void sb_dsp_input_msg(void *p, uint8_t *msg) { - sb_dsp_t *dsp = (sb_dsp_t *) p; - uint8_t len = msg[3], i = 0; + sb_dsp_t *dsp = (sb_dsp_t *) p; + uint8_t len = msg[3], i = 0; - sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]); + sb_dsp_log("MIDI in sysex = %d, uart irq = %d, msg = %d\n", dsp->midi_in_sysex, dsp->uart_irq, msg[3]); - if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) { + if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) { MPU401_InputMsg(dsp->mpu, msg); return; - } + } - if (dsp->midi_in_sysex) + if (dsp->midi_in_sysex) return; - if (dsp->uart_irq) { + if (dsp->uart_irq) { for (i = 0; i < len; i++) sb_add_data(dsp, msg[i]); sb_irq(dsp, 1); - } else if (dsp->midi_in_poll) { + } else if (dsp->midi_in_poll) { for (i = 0; i < len; i++) sb_add_data(dsp, msg[i]); - } + } } int sb_dsp_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) { - sb_dsp_t *dsp = (sb_dsp_t *) p; - uint32_t i; + sb_dsp_t *dsp = (sb_dsp_t *) p; + uint32_t i; - if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) + if (!dsp->uart_irq && !dsp->midi_in_poll && (dsp->mpu != NULL)) return MPU401_InputSysex(dsp->mpu, buffer, len, abort); - if (abort) { + if (abort) { dsp->midi_in_sysex = 0; return 0; - } + } - dsp->midi_in_sysex = 1; + dsp->midi_in_sysex = 1; - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) { if (dsp->sb_read_rp == dsp->sb_read_wp) { sb_dsp_log("Length sysex SB = %d\n", len - i); return (len - i); } sb_add_data(dsp, buffer[i]); - } + } - dsp->midi_in_sysex = 0; + dsp->midi_in_sysex = 0; - return 0; + return 0; } void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) { - dsp->sb_type = type; - dsp->sb_subtype = subtype; - dsp->parent = parent; + dsp->sb_type = type; + dsp->sb_subtype = subtype; + dsp->parent = parent; - /* Default values. Use sb_dsp_setxxx() methods to change. */ - dsp->sb_irqnum = 7; - dsp->sb_8_dmanum = 1; - dsp->sb_16_dmanum = 5; - dsp->mpu = NULL; + /* Default values. Use sb_dsp_setxxx() methods to change. */ + dsp->sb_irqnum = 7; + dsp->sb_8_dmanum = 1; + dsp->sb_16_dmanum = 5; + dsp->mpu = NULL; - sb_doreset(dsp); + sb_doreset(dsp); - timer_add(&dsp->output_timer, pollsb, dsp, 0); - timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); - timer_add(&dsp->wb_timer, NULL, dsp, 0); + timer_add(&dsp->output_timer, pollsb, dsp, 0); + timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); + timer_add(&dsp->wb_timer, NULL, dsp, 0); - /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when - a set frequency command is sent. */ - recalc_sb16_filter(0, 3200*2); - recalc_sb16_filter(1, 44100); + /* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when + a set frequency command is sent. */ + recalc_sb16_filter(0, 3200*2); + recalc_sb16_filter(1, 44100); - // Initialize SB16 8051 RAM - memset(dsp->sb_8051_ram, 0, 256); - dsp->sb_8051_ram[0x0e] = 0xff; - dsp->sb_8051_ram[0x0f] = 0x07; - dsp->sb_8051_ram[0x37] = 0x38; + /* Initialize SB16 8051 RAM and ASP internal RAM */ + memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram)); + dsp->sb_8051_ram[0x0e] = 0xff; + dsp->sb_8051_ram[0x0f] = 0x07; + dsp->sb_8051_ram[0x37] = 0x38; + + memset(dsp->sb_asp_ram, 0xff, sizeof(dsp->sb_asp_ram)); } void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) { - sb_dsp_log("sb_dsp_setaddr : %04X\n", addr); - if (dsp->sb_addr != 0) { + sb_dsp_log("sb_dsp_setaddr : %04X\n", addr); + if (dsp->sb_addr != 0) { io_removehandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - } - dsp->sb_addr = addr; - if (dsp->sb_addr != 0) { + } + dsp->sb_addr = addr; + if (dsp->sb_addr != 0) { io_sethandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); io_sethandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); - } + } } void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo) { - dsp->stereo = stereo; + dsp->stereo = stereo; } void pollsb(void *p) { - sb_dsp_t *dsp = (sb_dsp_t *) p; - int tempi, ref; - int data[2]; + sb_dsp_t *dsp = (sb_dsp_t *) p; + int tempi, ref; + int data[2]; - 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) { + 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); switch (dsp->sb_8_format) { @@ -1294,8 +1347,8 @@ pollsb(void *p) } sb_irq(dsp, 1); } - } - if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) { + } + if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && dsp->sb_16_output) { sb_dsp_update(dsp); switch (dsp->sb_16_format) { @@ -1343,8 +1396,8 @@ pollsb(void *p) } sb_irq(dsp, 0); } - } - if (dsp->sb_pausetime > -1) { + } + if (dsp->sb_pausetime > -1) { dsp->sb_pausetime--; if (dsp->sb_pausetime < 0) { sb_irq(dsp, 1); @@ -1352,19 +1405,19 @@ pollsb(void *p) timer_disable(&dsp->output_timer); sb_dsp_log("SB pause over\n"); } - } + } } void sb_poll_i(void *p) { - sb_dsp_t *dsp = (sb_dsp_t *) p; - int processed = 0; + sb_dsp_t *dsp = (sb_dsp_t *) p; + int processed = 0; - timer_advance_u64(&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) { + if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { switch (dsp->sb_8_format) { case 0x00: /* Mono unsigned As the manual says, only the left channel is recorded */ sb_8_write_dma(dsp, (dsp->record_buffer[dsp->record_pos_read]>>8) ^0x80); @@ -1404,8 +1457,8 @@ sb_poll_i(void *p) sb_irq(dsp, 1); } processed = 1; - } - if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) { + } + if (dsp->sb_16_enable && !dsp->sb_16_pause && (dsp->sb_pausetime < 0LL) && !dsp->sb_16_output) { switch (dsp->sb_16_format) { case 0x00: /* Unsigned mono. As the manual says, only the left channel is recorded */ if (sb_16_write_dma(dsp, dsp->record_buffer[dsp->record_pos_read]^0x8000)) @@ -1449,25 +1502,25 @@ sb_poll_i(void *p) sb_irq(dsp, 0); } processed = 1; - } - /* Assume this is direct mode */ - if (!processed) { + } + /* Assume this is direct mode */ + if (!processed) { dsp->record_pos_read += 2; dsp->record_pos_read &= 0xFFFF; - } + } } void sb_dsp_update(sb_dsp_t *dsp) { - if (dsp->muted) { + if (dsp->muted) { dsp->sbdatl = 0; dsp->sbdatr = 0; - } - for (; dsp->pos < sound_pos_global; dsp->pos++) { + } + for (; dsp->pos < sound_pos_global; dsp->pos++) { dsp->buffer[dsp->pos*2] = dsp->sbdatl; dsp->buffer[dsp->pos*2 + 1] = dsp->sbdatr; - } + } } diff --git a/src/sound/sound.c b/src/sound/sound.c index b223e706a..4ab9cf58e 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -506,7 +506,7 @@ sound_cd_thread_end(void) sound_log("Waiting for CD Audio thread to terminate...\n"); thread_set_event(sound_cd_event); - thread_wait(sound_cd_thread_h, -1); + thread_wait(sound_cd_thread_h); sound_log("CD Audio thread terminated...\n"); if (sound_cd_event) { diff --git a/src/thread.cpp b/src/thread.cpp new file mode 100644 index 000000000..4134befba --- /dev/null +++ b/src/thread.cpp @@ -0,0 +1,127 @@ +#include +#include +#include + +#include <86box/plat.h> + +struct event_cpp11_t +{ + std::condition_variable cond; + std::mutex mutex; + bool state = false; +}; + +extern "C" { + +thread_t * +thread_create(void (*thread_rout)(void *param), void *param) +{ + auto thread = new std::thread([thread_rout, param] { + thread_rout(param); + }); + return thread; +} + +int +thread_wait(thread_t *arg) +{ + auto thread = reinterpret_cast(arg); + thread->join(); + return 0; +} + +mutex_t * +thread_create_mutex(void) +{ + auto mutex = new std::mutex; + return mutex; +} + +int +thread_wait_mutex(mutex_t *_mutex) +{ + if (_mutex == nullptr) + return 0; + + auto mutex = reinterpret_cast(_mutex); + mutex->lock(); + return 1; +} + + +int +thread_release_mutex(mutex_t *_mutex) +{ + if (_mutex == nullptr) + return 0; + + auto mutex = reinterpret_cast(_mutex); + mutex->unlock(); + return 1; +} + + +void +thread_close_mutex(mutex_t *_mutex) +{ + auto mutex = reinterpret_cast(_mutex); + delete mutex; +} + +event_t * +thread_create_event() +{ + auto ev = new event_cpp11_t; + return ev; +} + +int +thread_wait_event(event_t *handle, int timeout) +{ + auto event = reinterpret_cast(handle); + auto lock = std::unique_lock(event->mutex); + + if (timeout < 0) { + event->cond.wait(lock, [event] { return event->state; }); + } else { + auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); + std::cv_status status; + + do { + status = event->cond.wait_until(lock, to); + } while ((status != std::cv_status::timeout) && !event->state); + + if (status == std::cv_status::timeout) { + return 1; + } + } + return 0; +} + +void +thread_set_event(event_t *handle) +{ + auto event = reinterpret_cast(handle); + { + auto lock = std::unique_lock(event->mutex); + event->state = true; + } + event->cond.notify_all(); +} + +void +thread_reset_event(event_t *handle) +{ + auto event = reinterpret_cast(handle); + auto lock = std::unique_lock(event->mutex); + event->state = false; +} + +void +thread_destroy_event(event_t *handle) +{ + auto event = reinterpret_cast(handle); + delete event; +} + +} diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index e21265370..ca0a6a6e4 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -1,33 +1,30 @@ -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - find_package(ALSA) - if (ALSA_FOUND) - set(PLAT_SOURCES linux_midi_alsa.c) - else() - set(PLAT_SOURCES unix_midi.c) - endif() -else() - set(PLAT_SOURCES unix_midi.c) -endif() -add_library(plat STATIC ${PLAT_SOURCES} unix_thread.c) -add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c) -target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) -target_link_libraries(ui dl) +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: Cacodemon345 +# David Hrdlička, +# +# Copyright 2021 Cacodemon345. +# Copyright 2021 David Hrdlička. +# -find_package(SDL2 REQUIRED) -include_directories(${SDL2_INCLUDE_DIRS}) -if(MINGW) - target_link_libraries(ui SDL2::SDL2-static) -else() - if (TARGET SDL2::SDL2) - target_link_libraries(ui SDL2::SDL2) - else() - target_link_libraries(ui ${SDL2_LIBRARIES}) - endif() -endif() -if (ALSA_FOUND) - target_link_libraries(plat ALSA::ALSA) +add_library(plat OBJECT unix.c) + +if (NOT CPPTHREADS) + target_sources(plat PRIVATE unix_thread.c) endif() set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) target_link_libraries(86Box Threads::Threads) + +add_library(ui OBJECT unix_sdl.c unix_cdrom.c) +target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) +target_link_libraries(ui dl) diff --git a/src/unix/linux_midi_alsa.c b/src/unix/linux_midi_alsa.c deleted file mode 100644 index e3b009d6d..000000000 --- a/src/unix/linux_midi_alsa.c +++ /dev/null @@ -1,326 +0,0 @@ -#include -#include <86box/86box.h> -#include <86box/config.h> -#include <86box/midi.h> -#include <86box/plat.h> -#include <86box/plat_midi.h> - -#define MAX_MIDI_DEVICES 128 - -static struct -{ - int card; - int device; - int sub; - char name[50]; -} midi_devices[MAX_MIDI_DEVICES], midi_in_devices[MAX_MIDI_DEVICES]; - -static int midi_device_count = 0, midi_in_device_count = 0; - -static int midi_queried = 0, midi_in_queried = 0; - -static snd_rawmidi_t *midiout = NULL, *midiin = NULL; - -static void plat_midi_query() -{ - int status; - int card = -1; - - midi_queried = 1; - - if ((status = snd_card_next(&card)) < 0) - return; - - if (card < 0) - return; /*No cards*/ - - while (card >= 0) - { - char *shortname; - - if ((status = snd_card_get_name(card, &shortname)) >= 0) - { - snd_ctl_t *ctl; - char name[32]; - - sprintf(name, "hw:%i", card); - - if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) - { - int device = -1; - - do - { - status = snd_ctl_rawmidi_next_device(ctl, &device); - if (status >= 0 && device != -1) - { - snd_rawmidi_info_t *info; - int sub_nr, sub; - - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); - snd_ctl_rawmidi_info(ctl, info); - sub_nr = snd_rawmidi_info_get_subdevices_count(info); - //pclog("sub_nr=%i\n",sub_nr); - - for (sub = 0; sub < sub_nr; sub++) - { - snd_rawmidi_info_set_subdevice(info, sub); - - if (snd_ctl_rawmidi_info(ctl, info) == 0) - { - //pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device,sub); - - midi_devices[midi_device_count].card = card; - midi_devices[midi_device_count].device = device; - midi_devices[midi_device_count].sub = sub; - snprintf(midi_devices[midi_device_count].name, 50, "%s (%i:%i:%i)", shortname, card, device, sub); - midi_device_count++; - if (midi_device_count >= MAX_MIDI_DEVICES) - return; - } - } - } - } while (device >= 0); - } - } - - if (snd_card_next(&card) < 0) - break; - } -} - -void plat_midi_init() -{ - char portname[32]; - int midi_id; - - if (!midi_queried) - plat_midi_query(); - - midi_id = config_get_int(SYSTEM_MIDI_NAME, "midi", 0); - - sprintf(portname, "hw:%i,%i,%i", midi_devices[midi_id].card, - midi_devices[midi_id].device, - midi_devices[midi_id].sub); - //pclog("Opening MIDI port %s\n", portname); - - if (snd_rawmidi_open(NULL, &midiout, portname, SND_RAWMIDI_SYNC) < 0) - { - //pclog("Failed to open MIDI\n"); - return; - } -} - -void plat_midi_close() -{ - if (midiout != NULL) - { - snd_rawmidi_close(midiout); - midiout = NULL; - } -} - -static int midi_pos, midi_len; -static uint8_t midi_command[4]; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; -static int midi_insysex; -static uint8_t midi_sysex_data[65536]; - -int plat_midi_write(uint8_t val) -{ - return 0; -} - -void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{ - if (midiout) - { - snd_rawmidi_write(midiout, (const void*)sysex, (size_t)len); - } -} - -void plat_midi_play_msg(uint8_t *msg) -{ - plat_midi_play_sysex(msg, midi_lengths[(msg[0] >> 4) & 7]); -} - -int plat_midi_get_num_devs() -{ - if (!midi_queried) - plat_midi_query(); - - return midi_device_count; -} - -void plat_midi_get_dev_name(int num, char *s) -{ - strcpy(s, midi_devices[num].name); -} - -static void plat_midi_query_in() -{ - int status; - int card = -1; - - midi_in_queried = 1; - - if ((status = snd_card_next(&card)) < 0) - return; - - if (card < 0) - return; /*No cards*/ - - while (card >= 0) - { - char *shortname; - - if ((status = snd_card_get_name(card, &shortname)) >= 0) - { - snd_ctl_t *ctl; - char name[32]; - - sprintf(name, "hw:%i", card); - - if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) - { - int device = -1; - - do - { - status = snd_ctl_rawmidi_next_device(ctl, &device); - if (status >= 0 && device != -1) - { - snd_rawmidi_info_t *info; - int sub_nr, sub; - - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_INPUT); - snd_ctl_rawmidi_info(ctl, info); - sub_nr = snd_rawmidi_info_get_subdevices_count(info); - //pclog("sub_nr=%i\n",sub_nr); - - for (sub = 0; sub < sub_nr; sub++) - { - snd_rawmidi_info_set_subdevice(info, sub); - - if (snd_ctl_rawmidi_info(ctl, info) == 0) - { - //pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device,sub); - - midi_in_devices[midi_device_count].card = card; - midi_in_devices[midi_device_count].device = device; - midi_in_devices[midi_device_count].sub = sub; - snprintf(midi_in_devices[midi_device_count].name, 50, "%s (%i:%i:%i)", shortname, card, device, sub); - midi_in_device_count++; - if (midi_in_device_count >= MAX_MIDI_DEVICES) - return; - } - } - } - } while (device >= 0); - } - } - - if (snd_card_next(&card) < 0) - break; - } -} -mutex_t* midiinmtx = NULL; - -static void plat_midi_in_thread(void* param) -{ - int sysexpos = 0; - uint8_t midimsg[3]; - while(1) - { - thread_wait_mutex(midiinmtx); - if (midiin == NULL) - { - thread_release_mutex(midiinmtx); - break; - } - if (snd_rawmidi_read(midiin, midimsg, 1) > 0) - { - if (midimsg[0] == 0xF0) - { - MIDI_InSysexBuf[sysexpos++] = 0xF0; - while(1) - { - snd_rawmidi_read(midiin, &MIDI_InSysexBuf[sysexpos++], 1); - if (MIDI_InSysexBuf[sysexpos - 1] == 0xF7) - { - midi_in_sysex(MIDI_InSysexBuf, sysexpos); - } - } - } - else if (midimsg[0] & 0x80) - { - int lengthofmsg = midi_lengths[(midimsg[0] >> 4) & 7] - 1; - snd_rawmidi_read(midiin, midimsg + 1, lengthofmsg); - midi_in_msg(midimsg); - } - } - thread_release_mutex(midiinmtx); - } -} - -void plat_midi_input_init(void) -{ - char portname[32]; - int midi_id; - snd_rawmidi_params_t* params; - int err; - - snd_rawmidi_params_malloc(¶ms); - if (!params) return; - if (!midi_in_queried) - plat_midi_query_in(); - - - midi_id = config_get_int(MIDI_INPUT_NAME, "midi_input", 0); - - sprintf(portname, "hw:%i,%i,%i", midi_in_devices[midi_id].card, - midi_in_devices[midi_id].device, - midi_in_devices[midi_id].sub); - //pclog("Opening MIDI port %s\n", portname); - - if (snd_rawmidi_open(NULL, &midiin, portname, SND_RAWMIDI_NONBLOCK) < 0) - { - //pclog("Failed to open MIDI\n"); - return; - } - midiin = thread_create_mutex(); - thread_create(plat_midi_in_thread, NULL); -} - -void plat_midi_input_close(void) -{ - if (midiinmtx) thread_wait_mutex(midiinmtx); - if (midiin != NULL) - { - snd_rawmidi_close(midiin); - midiin = NULL; - } - if (midiinmtx) - { - thread_release_mutex(midiinmtx); - thread_close_mutex(midiinmtx); - } - midiinmtx = NULL; -} - -int plat_midi_in_get_num_devs(void) -{ - if (!midi_queried) - plat_midi_query_in(); - - return midi_in_device_count; -} - -void plat_midi_in_get_dev_name(int num, char *s) -{ - strcpy(s, midi_in_devices[num].name); -} diff --git a/src/unix/unix.c b/src/unix/unix.c index 2b949ea5f..d7db5cbef 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -18,6 +18,7 @@ #include #include #include +#include #include <86box/86box.h> #include <86box/keyboard.h> @@ -453,6 +454,12 @@ ui_sb_update_panes() } +void +ui_sb_update_text() +{ + +} + void plat_get_dirname(char *dest, const char *path) { @@ -525,12 +532,11 @@ main_thread(void *param) SDL_Delay(1); /* If needed, handle a screen resize. */ - if (doresize && !video_fullscreen && !is_quit) { + if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) { if (vid_resize & 2) plat_resize(fixed_size_x, fixed_size_y); else plat_resize(scrnsz_x, scrnsz_y); - doresize = 0; } } @@ -702,6 +708,9 @@ plat_pause(int p) static wchar_t oldtitle[512]; wchar_t title[512]; + if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) + nvr_time_sync(); + dopause = p; if (p) { wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); diff --git a/src/unix/unix_midi.c b/src/unix/unix_midi.c deleted file mode 100644 index c92820bef..000000000 --- a/src/unix/unix_midi.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -void plat_midi_init(void) -{ - -} - -void plat_midi_close(void) -{ - -} - -void plat_midi_play_msg(uint8_t *msg) -{ - -} - -void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{ - -} - -int plat_midi_write(uint8_t val) -{ - return 0; -} - -int plat_midi_get_num_devs(void) -{ - return 0; -} - -void plat_midi_get_dev_name(int num, char *s) -{ - s[0] = ' '; - s[1] = 0; -} - -void plat_midi_input_init(void) -{ - -} - -void plat_midi_input_close(void) -{ - -} - -int plat_midi_in_get_num_devs(void) -{ - return 0; -} - -void plat_midi_in_get_dev_name(int num, char *s) -{ - s[0] = ' '; - s[1] = 0; -} \ No newline at end of file diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 4c309144f..356305d1c 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -134,9 +134,9 @@ sdl_blit_shim(int x, int y, int w, int h) params.w = w; params.h = h; if (!(!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL))) - video_copy(interpixels, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + video_copy(interpixels, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t)); if (screenshots) - video_screenshot(interpixels, 0, 0, (2048 + 64)); + video_screenshot(interpixels, 0, 0, 2048); blitreq = 1; video_blit_complete(); } @@ -198,7 +198,7 @@ sdl_blit(int x, int y, int w, int h) r_src.y = y; r_src.w = w; r_src.h = h; - SDL_UpdateTexture(sdl_tex, &r_src, interpixels, (2048 + 64) * 4); + SDL_UpdateTexture(sdl_tex, &r_src, interpixels, 2048 * 4); blitreq = 0; sdl_real_blit(&r_src); diff --git a/src/unix/unix_thread.c b/src/unix/unix_thread.c index f045d2820..564b1943b 100644 --- a/src/unix/unix_thread.c +++ b/src/unix/unix_thread.c @@ -53,9 +53,9 @@ thread_create(void (*thread_rout)(void *param), void *param) int -thread_wait(thread_t *arg, int timeout) +thread_wait(thread_t *arg) { - return pthread_join(*(pthread_t*)(arg), NULL) != 0; + return pthread_join(*(pthread_t*)(arg), NULL); } @@ -144,14 +144,6 @@ thread_create_mutex(void) } -mutex_t * -thread_create_mutex_with_spin_count(unsigned int spin_count) -{ - /* Setting spin count of a mutex is not possible with pthreads. */ - return thread_create_mutex(); -} - - int thread_wait_mutex(mutex_t *_mutex) { diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index b42bd21cb..c58b2f054 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -1,55 +1,55 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c - vid_compaq_cga.c vid_mda.c vid_hercules.c vid_herculesplus.c - vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c - vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c - vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c - vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c - vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c - vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c - vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c - vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c - vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c - vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c) + vid_compaq_cga.c vid_mda.c vid_hercules.c vid_herculesplus.c + vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c + vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c + vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c + vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c + vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c + vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c + vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c + vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c + vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c) if(MGA) - target_compile_definitions(vid PRIVATE USE_MGA) - target_sources(vid PRIVATE vid_mga.c) + target_compile_definitions(vid PRIVATE USE_MGA) + target_sources(vid PRIVATE vid_mga.c) endif() if(VGAWONDER) - target_compile_definitions(vid PRIVATE USE_VGAWONDER) + target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() if(XL24) - target_compile_definitions(vid PRIVATE USE_XL24) + target_compile_definitions(vid PRIVATE USE_XL24) endif() add_library(voodoo OBJECT vid_voodoo.c vid_voodoo_banshee.c - vid_voodoo_banshee_blitter.c vid_voodoo_blitter.c vid_voodoo_display.c - vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c vid_voodoo_render.c - vid_voodoo_setup.c vid_voodoo_texture.c) + vid_voodoo_banshee_blitter.c vid_voodoo_blitter.c vid_voodoo_display.c + vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c vid_voodoo_render.c + vid_voodoo_setup.c vid_voodoo_texture.c) if(NOT MSVC AND (ARCH STREQUAL "i386" OR ARCH STREQUAL "x86_64")) - target_compile_options(voodoo PRIVATE "-msse2") + target_compile_options(voodoo PRIVATE "-msse2") endif() # Suppress GCC false positive warnings in vid_voodoo_codegen_x86[-64].h # that cause ~3000 lines to be output into the logs each time if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_compile_options(voodoo PRIVATE "-Wstringop-overflow=0") + target_compile_options(voodoo PRIVATE "-Wstringop-overflow=0") endif() \ No newline at end of file diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 0701df498..1e19adf84 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -3459,7 +3459,7 @@ void mach64_close(void *p) mach64->thread_run = 0; thread_set_event(mach64->wake_fifo_thread); - thread_wait(mach64->fifo_thread, -1); + thread_wait(mach64->fifo_thread); thread_destroy_event(mach64->wake_fifo_thread); thread_destroy_event(mach64->fifo_not_full_event); diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index d971a6af4..99655b551 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -315,8 +315,8 @@ compaq_cga_poll(void *p) compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline, self->cga.firstline ,self->cga.lastline - self->cga.firstline); - if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3); - else x = (self->cga.crtc[1] << 4); + if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16; + else x = (self->cga.crtc[1] << 4) + 16; self->cga.lastline++; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 1e66743ec..43f157f29 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -69,6 +69,9 @@ int egaswitchread, egaswitches=9; int update_overscan = 0; +uint8_t ega_in(uint16_t addr, void *p); + + void ega_out(uint16_t addr, uint8_t val, void *p) { @@ -145,6 +148,9 @@ ega_out(uint16_t addr, uint8_t val, void *p) ega->vidclock = val & 4; ega->miscout = val; ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; + io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + if (!(val & 1)) + io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); if ((o ^ val) & 0x80) ega_recalctimings(ega); break; @@ -237,10 +243,13 @@ ega_out(uint16_t addr, uint8_t val, void *p) } } -uint8_t ega_in(uint16_t addr, void *p) + +uint8_t +ega_in(uint16_t addr, void *p) { ega_t *ega = (ega_t *)p; uint8_t ret = 0xff; + uint16_t port = addr; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -979,6 +988,8 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) break; } } + + io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); } else { for (c = 0; c < 256; c++) { pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); @@ -988,6 +999,8 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) if ((c & 0x17) == 6) pallook16[c] = makecol32(0xaa, 0x55, 0); } + + ega->miscout |= 1; } ega->pallook = pallook16; @@ -1078,7 +1091,7 @@ ega_standalone_init(const device_t *info) ega->vrammask = ega->vram_limit - 1; mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); - io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); if (info->local == EGA_ATI) { io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 3d9102b7c..c3f1f3593 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5036,7 +5036,7 @@ mystique_close(void *p) mystique->thread_run = 0; thread_set_event(mystique->wake_fifo_thread); - thread_wait(mystique->fifo_thread, -1); + thread_wait(mystique->fifo_thread); thread_destroy_event(mystique->wake_fifo_thread); thread_destroy_event(mystique->fifo_not_full_event); thread_close_mutex(mystique->dma.lock); diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 34e5c2d99..32e8b31ac 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2624,7 +2624,7 @@ pgc_close(void *priv) pgc_log("PGC: waiting for thread to stop...\n"); #endif // while (dev->stopped); - thread_wait(dev->pgc_thread, -1); + thread_wait(dev->pgc_thread); #ifdef ENABLE_PGC_LOG pgc_log("PGC: thread stopped, closing up.\n"); #endif diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 5e6e32867..d7a961925 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -158,7 +158,7 @@ enum #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (s3->fifo_write_idx - s3->fifo_read_idx) -#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= (FIFO_SIZE - 4)) #define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx) #define FIFO_TYPE 0xff000000 @@ -337,6 +337,8 @@ typedef struct s3_t fifo_entry_t fifo[FIFO_SIZE]; volatile int fifo_read_idx, fifo_write_idx; + uint8_t fifo_thread_run; + thread_t *fifo_thread; event_t *wake_fifo_thread; event_t *fifo_not_full_event; @@ -426,6 +428,42 @@ dword_remap_l(svga_t *svga, uint32_t in_addr) (in_addr & ~0xffff); } +static __inline void +wake_fifo_thread(s3_t *s3) +{ + thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} + +static void +s3_wait_fifo_idle(s3_t *s3) +{ + while (!FIFO_EMPTY) { + wake_fifo_thread(s3); + thread_wait_event(s3->fifo_not_full_event, 1); + } +} + +static void +s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) +{ + fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; + + if (FIFO_FULL) { + thread_reset_event(s3->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } + + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + s3->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(s3); +} + static void s3_update_irqs(s3_t *s3) { @@ -666,7 +704,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) switch (port) { case 0x8148: case 0x82e8: - s3->accel.draw_fifo_slot++; s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; @@ -678,7 +715,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.poly_cy = s3->accel.cur_y; break; case 0x814a: case 0x82ea: - s3->accel.draw_fifo_slot++; s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; s3->accel.poly_cy2 = s3->accel.cur_y2; break; @@ -688,7 +724,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8548: case 0x86e8: - s3->accel.draw_fifo_slot++; s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.poly_cx = s3->accel.cur_x << 20; @@ -702,7 +737,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x854a: case 0x86ea: - s3->accel.draw_fifo_slot++; s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; break; @@ -713,7 +747,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xcae8: case 0x8948: case 0x8ae8: - s3->accel.draw_fifo_slot++; s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; @@ -725,7 +758,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.point_1_updated = 1; break; case 0x894a: case 0x8aea: - s3->accel.draw_fifo_slot++; s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; s3->accel.point_2_updated = 1; break; @@ -737,7 +769,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x8d48: case 0x8ee8: - s3->accel.draw_fifo_slot++; s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; @@ -748,7 +779,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.point_1_updated = 1; break; case 0x8d4a: case 0x8eea: - s3->accel.draw_fifo_slot++; s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; s3->accel.point_2_updated = 1; break; @@ -758,7 +788,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9148: case 0x92e8: - s3->accel.draw_fifo_slot++; s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; break; case 0x9149: case 0x92e9: @@ -776,7 +805,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9548: case 0x96e8: - s3->accel.draw_fifo_slot++; s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xf00) | val; break; case 0x9459: case 0x96e9: @@ -794,7 +822,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0x9948: case 0x9ae8: - s3->accel.draw_fifo_slot++; s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; s3->data_available = 0; s3->accel.b2e8_pix = 0; @@ -835,7 +862,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa148: case 0xa2e8: - s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); else @@ -872,7 +898,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa548: case 0xa6e8: - s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); else @@ -909,7 +934,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa948: case 0xaae8: - s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); else @@ -946,7 +970,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xad48: case 0xaee8: - s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); else @@ -1019,12 +1042,10 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xb548: case 0xb6e8: - s3->accel.setup_fifo_slot++; s3->accel.bkgd_mix = val; break; case 0xb948: case 0xbae8: - s3->accel.setup_fifo_slot++; s3->accel.frgd_mix = val; break; @@ -1034,25 +1055,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xbd49: case 0xbee9: s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; - switch (s3->accel.multifunc_cntl >> 12) { - case 0: - s3->accel.draw_fifo_slot++; - break; - case 0xa: - s3->accel.setup_fifo_slot++; - break; - } break; case 0xd148: case 0xd2e8: - s3->accel.setup_fifo_slot++; s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; break; case 0xd149: case 0xd2e9: s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); break; case 0xe548: case 0xe6e8: - s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else @@ -1088,21 +1099,18 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) } break; case 0xe948: case 0xeae8: - s3->accel.draw_fifo_slot++; s3->accel.pat_y = (s3->accel.pat_y & 0xf00) | val; break; case 0xe949: case 0xeae9: s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); break; case 0xe94a: case 0xeaea: - s3->accel.draw_fifo_slot++; s3->accel.pat_x = (s3->accel.pat_x & 0xf00) | val; break; case 0xe94b: case 0xeaeb: s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); break; case 0xed48: case 0xeee8: - s3->accel.setup_fifo_slot++; if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else @@ -1297,11 +1305,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) } break; } - - if (s3_enable_fifo(s3) == 0) { - s3->accel.setup_fifo_slot = 0; - s3->accel.draw_fifo_slot = 0; - } } static void @@ -3366,7 +3369,10 @@ s3_accel_out(uint16_t port, uint8_t val, void *p) if (!s3->enable_8514) return; - s3_accel_out_fifo(s3, port, val); + if (s3_enable_fifo(s3)) + s3_queue(s3, port, val, FIFO_OUT_BYTE); + else + s3_accel_out_fifo(s3, port, val); } else { switch (port) { @@ -3406,7 +3412,10 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *p) if (!s3->enable_8514) return; - s3_accel_out_fifo_w(s3, port, val); + if (s3_enable_fifo(s3)) + s3_queue(s3, port, val, FIFO_OUT_WORD); + else + s3_accel_out_fifo_w(s3, port, val); } static void @@ -3417,7 +3426,10 @@ s3_accel_out_l(uint16_t port, uint32_t val, void *p) if (!s3->enable_8514) return; - s3_accel_out_fifo_l(s3, port, val); + if (s3_enable_fifo(s3)) + s3_queue(s3, port, val, FIFO_OUT_DWORD); + else + s3_accel_out_fifo_l(s3, port, val); } static uint8_t @@ -3437,40 +3449,60 @@ s3_accel_in(uint16_t port, void *p) return s3->subsys_cntl; case 0x8148: case 0x82e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.cur_y & 0xff; case 0x8149: case 0x82e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.cur_y >> 8; case 0x8548: case 0x86e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.cur_x & 0xff; case 0x8549: case 0x86e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.cur_x >> 8; case 0x8948: case 0x8ae8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.desty_axstp & 0xff; } break; case 0x8949: case 0x8ae9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.desty_axstp >> 8; } break; case 0x8d48: case 0x8ee8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.destx_distp & 0xff; } break; case 0x8d49: case 0x8ee9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.destx_distp >> 8; } break; case 0x9148: case 0x92e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.err_term & 0xff; case 0x9149: case 0x92e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.err_term >> 8; case 0x9548: case 0x96e8: @@ -3480,6 +3512,8 @@ s3_accel_in(uint16_t port, void *p) break; case 0x9549: case 0x96e9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.maj_axis_pcnt >> 8; } break; @@ -3488,43 +3522,29 @@ s3_accel_in(uint16_t port, void *p) case 0x9948: case 0x9ae8: temp = 0; /* FIFO empty */ if (s3_enable_fifo(s3)) { - if (s3->accel.setup_fifo_slot) { - temp = s3->accel.setup_fifo; - s3->accel.setup_fifo = 0; - } else if (s3->accel.draw_fifo_slot) { - temp = s3->accel.draw_fifo; - s3->accel.draw_fifo = 0; - } + if (!s3->blitter_busy) + wake_fifo_thread(s3); + if (FIFO_FULL) + temp = 0xff; } return temp; case 0x8119: case 0x9949: case 0x9ae9: temp = 0; if (s3_enable_fifo(s3)) { - if ((s3->accel.setup_fifo_slot && s3->accel.draw_fifo_slot) || s3->force_busy) { + if (!s3->blitter_busy) + wake_fifo_thread(s3); + + if (!FIFO_EMPTY || s3->force_busy) temp |= 0x02; /*Hardware busy*/ - } else { + else temp |= 0x04; /*FIFO empty*/ - s3->subsys_stat |= INT_FIFO_EMP; - s3_update_irqs(s3); - } - s3->force_busy = 0; if (s3->chip >= S3_VISION964) { - if (s3->accel.setup_fifo_slot > 8) { - temp |= s3->accel.setup_fifo2; - s3->accel.setup_fifo2 = 0; - } else if (s3->accel.draw_fifo_slot > 8) { - temp |= s3->accel.draw_fifo2; - s3->accel.draw_fifo2 = 0; - } + if (FIFO_FULL) + temp |= 0xf8; /*FIFO full*/ } - - if (s3->accel.setup_fifo_slot) - s3->accel.setup_fifo_slot--; - if (s3->accel.draw_fifo_slot) - s3->accel.draw_fifo_slot--; if (s3->data_available) { temp |= 0x01; /*Read Data available*/ @@ -3544,101 +3564,151 @@ s3_accel_in(uint16_t port, void *p) case 0x9d48: case 0x9ee8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.short_stroke & 0xff; } break; case 0x9d49: case 0x9ee9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.short_stroke >> 8; } break; case 0xa148: case 0xa2e8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.bkgd_color & 0xff; } break; case 0xa149: case 0xa2e9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.bkgd_color >> 8; } break; case 0xa14a: case 0xa2ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.bkgd_color >> 16; case 0xa14b: case 0xa2eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.bkgd_color >> 24; case 0xa548: case 0xa6e8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.frgd_color & 0xff; } break; case 0xa549: case 0xa6e9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.frgd_color >> 8; } break; case 0xa54a: case 0xa6ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.frgd_color >> 16; case 0xa54b: case 0xa6eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.frgd_color >> 24; case 0xa948: case 0xaae8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.wrt_mask & 0xff; } break; case 0xa949: case 0xaae9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.wrt_mask >> 8; } break; case 0xa94a: case 0xaaea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.wrt_mask >> 16; case 0xa94b: case 0xaaeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.wrt_mask >> 24; case 0xad48: case 0xaee8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.rd_mask & 0xff; } break; case 0xad49: case 0xaee9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.rd_mask >> 8; case 0xad4a: case 0xaeea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.rd_mask >> 16; case 0xad4b: case 0xaeeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.rd_mask >> 24; case 0xb148: case 0xb2e8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.color_cmp & 0xff; } break; case 0xb149: case 0xb2e9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.color_cmp >> 8; } break; case 0xb14a: case 0xb2ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.color_cmp >> 16; case 0xb14b: case 0xb2eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.color_cmp >> 24; case 0xb548: case 0xb6e8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.bkgd_mix; } break; case 0xb948: case 0xbae8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.frgd_mix; } break; case 0xbd48: case 0xbee8: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->accel.multifunc[0xf] & 0xf; switch (temp) { @@ -3659,6 +3729,8 @@ s3_accel_in(uint16_t port, void *p) break; case 0xbd49: case 0xbee9: if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->accel.multifunc[0xf] & 0xf; s3->accel.multifunc[0xf]++; switch (temp) @@ -3680,45 +3752,73 @@ s3_accel_in(uint16_t port, void *p) break; case 0xd148: case 0xd2e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.ropmix & 0xff; case 0xd149: case 0xd2e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.ropmix >> 8; case 0xe548: case 0xe6e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color & 0xff; case 0xe549: case 0xe6e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color >> 8; case 0xe54a: case 0xe6ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color >> 16; case 0xe54b: case 0xe6eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_bg_color >> 24; case 0xe948: case 0xeae8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_y & 0xff; case 0xe949: case 0xeae9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_y >> 8; case 0xe94a: case 0xeaea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_x & 0xff; case 0xe94b: case 0xeaeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_x >> 8; case 0xed48: case 0xeee8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color & 0xff; case 0xed49: case 0xeee9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color >> 8; case 0xed4a: case 0xeeea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color >> 16; case 0xed4b: case 0xeeeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.pat_fg_color >> 24; case 0xe148: case 0xe2e8: @@ -3882,6 +3982,8 @@ s3_accel_in_w(uint16_t port, void *p) } } } else { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->accel.short_stroke; } @@ -3950,10 +4052,13 @@ s3_accel_write(uint32_t addr, uint8_t val, void *p) if (!s3->enable_8514) return; - - if (svga->crtc[0x53] & 0x08) - s3_accel_write_fifo(s3, addr & 0x1ffff, val); - else + + if (s3_enable_fifo(s3)) { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); + } else s3_accel_write_fifo(s3, addr & 0xffff, val); } @@ -3966,9 +4071,12 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *p) if (!s3->enable_8514) return; - if (svga->crtc[0x53] & 0x08) - s3_accel_write_fifo_w(s3, addr & 0x1ffff, val); - else + if (s3_enable_fifo(s3)) { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); + } else s3_accel_write_fifo_w(s3, addr & 0xffff, val); } @@ -3981,9 +4089,12 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *p) if (!s3->enable_8514) return; - if (svga->crtc[0x53] & 0x08) - s3_accel_write_fifo_l(s3, addr & 0x1ffff, val); - else + if (s3_enable_fifo(s3)) { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); + } else s3_accel_write_fifo_l(s3, addr & 0xffff, val); } @@ -4068,6 +4179,8 @@ s3_accel_read_w(uint32_t addr, void *p) if (svga->crtc[0x53] & 0x08) { switch (addr & 0x1fffe) { case 0x811c: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); return s3->accel.short_stroke; default: @@ -4077,9 +4190,11 @@ s3_accel_read_w(uint32_t addr, void *p) return 0xffff; } else { if (addr & 0x8000) { - if (addr == 0x811c) + if (addr == 0x811c) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->accel.short_stroke; - else { + } else { temp = s3_accel_read((addr & 0xfffe), p); temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; } @@ -4194,9 +4309,13 @@ s3_accel_read_l(uint32_t addr, void *p) break; case 0x18080: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = 0; break; case 0x18088: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->videoengine.cntl; if (s3->bpp == 1) { /*The actual bpp is decided by the guest when idf is the same as odf*/ if (s3->videoengine.idf == 0 && s3->videoengine.odf == 0) { @@ -4211,18 +4330,28 @@ s3_accel_read_l(uint32_t addr, void *p) } break; case 0x1808c: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->videoengine.stretch_filt_const; break; case 0x18090: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->videoengine.src_dst_step; break; case 0x18094: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->videoengine.crop; break; case 0x18098: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->videoengine.src_base; break; case 0x1809c: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); temp = s3->videoengine.dest_base; if (s3->videoengine.busy) { temp |= (1 << 31); @@ -5002,104 +5131,6 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) } } -static void -s3_fifo_slots(s3_t *s3) -{ - switch (s3->accel.setup_fifo_slot) { - case 1: - s3->accel.setup_fifo |= 1; - break; - case 2: - s3->accel.setup_fifo |= 3; - break; - case 3: - s3->accel.setup_fifo |= 7; - break; - case 4: - s3->accel.setup_fifo |= 0x0f; - break; - case 5: - s3->accel.setup_fifo |= 0x1f; - break; - case 6: - s3->accel.setup_fifo |= 0x3f; - break; - case 7: - s3->accel.setup_fifo |= 0x7f; - break; - case 8: - s3->accel.setup_fifo |= 0xff; /* FIFO full */ - break; - case 9: - s3->accel.setup_fifo |= 0xff; - s3->accel.setup_fifo2 |= 0x08; - break; - case 10: - s3->accel.setup_fifo |= 0xff; - s3->accel.setup_fifo2 |= 0x18; - break; - case 11: - s3->accel.setup_fifo |= 0xff; - s3->accel.setup_fifo2 |= 0x38; - break; - case 12: - s3->accel.setup_fifo |= 0xff; - s3->accel.setup_fifo2 |= 0x78; - break; - case 13: - s3->accel.setup_fifo |= 0xff; - s3->accel.setup_fifo2 |= 0xf8; /* FIFO full */ - break; - } - - switch (s3->accel.draw_fifo_slot) { - case 1: - s3->accel.draw_fifo |= 1; - break; - case 2: - s3->accel.draw_fifo |= 3; - break; - case 3: - s3->accel.draw_fifo |= 7; - break; - case 4: - s3->accel.draw_fifo |= 0x0f; - break; - case 5: - s3->accel.draw_fifo |= 0x1f; - break; - case 6: - s3->accel.draw_fifo |= 0x3f; - break; - case 7: - s3->accel.draw_fifo |= 0x7f; - break; - case 8: - s3->accel.draw_fifo |= 0xff; /* FIFO full */ - break; - case 9: - s3->accel.draw_fifo |= 0xff; - s3->accel.draw_fifo2 |= 0x08; - break; - case 10: - s3->accel.draw_fifo |= 0xff; - s3->accel.draw_fifo2 |= 0x18; - break; - case 11: - s3->accel.draw_fifo |= 0xff; - s3->accel.draw_fifo2 |= 0x38; - break; - case 12: - s3->accel.draw_fifo |= 0xff; - s3->accel.draw_fifo2 |= 0x78; - break; - case 13: - s3->accel.draw_fifo |= 0xff; - s3->accel.draw_fifo2 |= 0xf8; /* FIFO full */ - break; - } -} - void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) { @@ -5107,9 +5138,7 @@ s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_d s3->accel.ssv_len = ssv & 0x0f; s3->accel.ssv_dir = ssv & 0xe0; s3->accel.ssv_draw = ssv & 0x10; - - s3_fifo_slots(s3); - + if (s3_cpu_src(s3)) { return; /*Wait for data from CPU*/ } @@ -5280,9 +5309,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; s3->accel.sy = s3->accel.maj_axis_pcnt; - - s3_fifo_slots(s3); - + if (s3_cpu_src(s3)) { return; /*Wait for data from CPU*/ } @@ -5464,8 +5491,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dest = dstbase + s3->accel.cy * s3->width; - s3_fifo_slots(s3); - if (s3_cpu_src(s3)) { s3->data_available = 0; return; /*Wait for data from CPU*/ @@ -5593,8 +5618,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ polygon_setup(s3); - s3_fifo_slots(s3); - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ end_y1 = s3->accel.desty_axstp; @@ -5707,8 +5730,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) { @@ -5886,8 +5907,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy = s3->accel.dy & 7; s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); - - s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) { @@ -6010,8 +6029,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cy = s3->accel.cur_y; if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; - - s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ @@ -6104,8 +6121,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ polygon_setup(s3); - s3_fifo_slots(s3); - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ end_y1 = s3->accel.desty_axstp; @@ -6217,8 +6232,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); s3->accel.pattern = (s3->accel.py * s3->width); - - s3_fifo_slots(s3); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ @@ -6481,6 +6494,56 @@ s3_pci_write(int func, int addr, uint8_t val, void *p) } } +static void +fifo_thread(void *param) +{ + s3_t *s3 = (s3_t *)param; + uint64_t start_time, end_time; + + while (s3->fifo_thread_run) { + thread_set_event(s3->fifo_not_full_event); + thread_wait_event(s3->wake_fifo_thread, -1); + thread_reset_event(s3->wake_fifo_thread); + s3->blitter_busy = 1; + while (!FIFO_EMPTY) { + start_time = plat_timer_read(); + fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; + + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_WORD: + s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_DWORD: + s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_BYTE: + s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_WORD: + s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_DWORD: + s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } + + s3->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + + if (FIFO_ENTRIES > 0xe000) + thread_set_event(s3->fifo_not_full_event); + + end_time = plat_timer_read(); + s3->blitter_time += (end_time - start_time); + } + s3->blitter_busy = 0; + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); + } +} static int vram_sizes[] = { @@ -7264,6 +7327,11 @@ static void *s3_init(const device_t *info) s3->i2c = i2c_gpio_init("ddc_s3"); s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); + s3->wake_fifo_thread = thread_create_event(); + s3->fifo_not_full_event = thread_create_event(); + s3->fifo_thread_run = 1; + s3->fifo_thread = thread_create(fifo_thread, s3); + return s3; } @@ -7426,6 +7494,12 @@ static void s3_close(void *p) { s3_t *s3 = (s3_t *)p; + s3->fifo_thread_run = 0; + thread_set_event(s3->wake_fifo_thread); + thread_wait(s3->fifo_thread); + thread_destroy_event(s3->fifo_not_full_event); + thread_destroy_event(s3->wake_fifo_thread); + svga_close(&s3->svga); ddc_close(s3->ddc); diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 23033b5b3..e0e8b0e2e 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -189,6 +189,7 @@ typedef struct virge_t int pci; int chip; + int is_agp; int bilinear_enabled; int dithering_enabled; @@ -3711,7 +3712,7 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; - case 0x08: ret = 0; break; /*Revision ID*/ + case 0x08: ret = virge->virge_rev; break; /*Revision ID*/ case 0x09: ret = 0; break; /*Programming interface*/ case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ @@ -3734,6 +3735,8 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x32: ret = virge->pci_regs[0x32]; break; case 0x33: ret = virge->pci_regs[0x33]; break; + case 0x34: ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; break; + case 0x3c: ret = virge->pci_regs[0x3c]; break; case 0x3d: ret = PCI_INTA; break; /*INTA*/ @@ -3741,6 +3744,26 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x3e: ret = 0x04; break; case 0x3f: ret = 0xff; break; + case 0x80: ret = 0x02; break; /* AGP capability */ + case 0x81: ret = 0x00; break; + case 0x82: ret = 0x10; break; /* assumed AGP 1.0 */ + + case 0x84: ret = (virge->chip >= S3_TRIO3D2X) ? 0x03 : 0x01; break; + case 0x87: ret = 0x1f; break; + + case 0x88: ret = virge->pci_regs[0x88]; break; + case 0x89: ret = virge->pci_regs[0x89]; break; + case 0x8a: ret = virge->pci_regs[0x8a]; break; + case 0x8b: ret = virge->pci_regs[0x8b]; break; + + case 0xdc: ret = 0x01; break; /* PCI Power Management capability */ + case 0xdd: ret = virge->is_agp ? 0x80 : 0x00; break; + case 0xde: ret = 0x21; break; + + case 0xe0: ret = virge->pci_regs[0xe0]; break; + case 0xe1: ret = virge->pci_regs[0xe1]; break; + case 0xe2: ret = virge->pci_regs[0xe2]; break; + case 0xe3: ret = virge->pci_regs[0xe3]; break; } return ret; } @@ -3797,6 +3820,26 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) case 0x3c: virge->pci_regs[0x3c] = val; return; + + case 0x88: + virge->pci_regs[0x5c] = val & 0x27; + return; + + case 0x89: + virge->pci_regs[0x89] = val & 0x03; + return; + + case 0x8b: case 0xe1: case 0xe3: + virge->pci_regs[addr] = val; + return; + + case 0xe0: + virge->pci_regs[0xe0] = val & 0x03; + return; + + case 0xe2: + virge->pci_regs[0xe2] = val & 0xc0; + return; } } @@ -3852,7 +3895,7 @@ static void s3_virge_reset(void *priv) } if (virge->chip >= S3_VIRGEGX2) - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); else { switch (virge->memory_size) { case 2: @@ -3865,6 +3908,8 @@ static void s3_virge_reset(void *priv) virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; } + if (virge->local == S3_VIRGE_GX) + virge->svga.crtc[0x36] |= (1 << 2); } virge->svga.crtc[0x37] = 1 | (7 << 5); @@ -3983,6 +4028,7 @@ static void *s3_virge_init(const device_t *info) virge->virge_rev = 0; virge->virge_id = 0xe1; + virge->is_agp = !!(info->flags & DEVICE_AGP); switch(info->local) { case S3_VIRGE_325: @@ -4011,7 +4057,7 @@ static void *s3_virge_init(const device_t *info) virge->svga.crtc[0x59] = 0x70; virge->svga.vblank_start = s3_virge_vblank_start; virge->chip = S3_VIRGEGX2; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, (info->flags & DEVICE_AGP) ? &timing_virge_agp : &timing_virge_dx_pci); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci); break; case S3_TRIO_3D2X: @@ -4023,9 +4069,12 @@ static void *s3_virge_init(const device_t *info) virge->svga.crtc[0x59] = 0x70; virge->svga.vblank_start = s3_virge_vblank_start; virge->chip = S3_TRIO3D2X; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, (info->flags & DEVICE_AGP) ? &timing_virge_agp : &timing_virge_dx_pci); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci); break; + case S3_VIRGE_GX: + virge->virge_rev = 0x01; + /*FALLTHROUGH*/ default: virge->svga.decode_mask = (4 << 20) - 1; virge->virge_id_high = 0x8a; @@ -4042,7 +4091,7 @@ static void *s3_virge_init(const device_t *info) virge->vram_mask = (4 << 20) - 1; virge->svga.vram_mask = (4 << 20) - 1; virge->svga.vram_max = 4 << 20; - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); } else { switch (virge->memory_size) { case 2: @@ -4064,6 +4113,8 @@ static void *s3_virge_init(const device_t *info) virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; } + if (info->local == S3_VIRGE_GX) + virge->svga.crtc[0x36] |= (1 << 2); } virge->svga.crtc[0x37] = 1 | (7 << 5); @@ -4071,7 +4122,7 @@ static void *s3_virge_init(const device_t *info) memset(virge->dmabuffer, 0, 65536); - virge->card = pci_add_card((info->flags & DEVICE_AGP) ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); virge->i2c = i2c_gpio_init("ddc_s3_virge"); virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); @@ -4097,7 +4148,7 @@ static void s3_virge_close(void *p) virge->render_thread_run = 0; thread_set_event(virge->wake_render_thread); - thread_wait(virge->render_thread, -1); + thread_wait(virge->render_thread); thread_destroy_event(virge->not_full_event); thread_destroy_event(virge->wake_main_thread); thread_destroy_event(virge->wake_render_thread); diff --git a/src/video/vid_table.c b/src/video/vid_table.c index cd9f0a785..d89365255 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -274,7 +274,7 @@ void video_pre_reset(int card) { if ((card == VID_NONE) || \ - (card == VID_INTERNAL) || (machines[machine].flags & MACHINE_VIDEO_ONLY)) + (card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY)) video_prepare(); } @@ -287,13 +287,13 @@ video_reset(int card) return; vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n", - card, (machines[machine].flags & MACHINE_VIDEO)?1:0); + card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); loadfont("roms/video/mda/mda.rom", 0); /* Do not initialize internal cards here. */ if (!(card == VID_NONE) && \ - !(card == VID_INTERNAL) && !(machines[machine].flags & MACHINE_VIDEO_ONLY)) { + !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name); video_prepare(); diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index a9b0e52c9..a8697f0e8 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -1048,7 +1048,7 @@ void *voodoo_card_init() voodoo->force_blit_count = 0; voodoo->can_blit = 0; - voodoo->force_blit_mutex = thread_create_mutex_with_spin_count(MUTEX_DEFAULT_SPIN_COUNT); + voodoo->force_blit_mutex = thread_create_mutex(); return voodoo; } @@ -1172,7 +1172,7 @@ void *voodoo_2d3d_card_init(int type) voodoo->force_blit_count = 0; voodoo->can_blit = 0; - voodoo->force_blit_mutex = thread_create_mutex_with_spin_count(MUTEX_DEFAULT_SPIN_COUNT); + voodoo->force_blit_mutex = thread_create_mutex(); return voodoo; } @@ -1241,22 +1241,22 @@ void voodoo_card_close(voodoo_t *voodoo) voodoo->fifo_thread_run = 0; thread_set_event(voodoo->wake_fifo_thread); - thread_wait(voodoo->fifo_thread, -1); + thread_wait(voodoo->fifo_thread); voodoo->render_thread_run[0] = 0; thread_set_event(voodoo->wake_render_thread[0]); - thread_wait(voodoo->render_thread[0], -1); + thread_wait(voodoo->render_thread[0]); if (voodoo->render_threads >= 2) { voodoo->render_thread_run[1] = 0; thread_set_event(voodoo->wake_render_thread[1]); - thread_wait(voodoo->render_thread[1], -1); + thread_wait(voodoo->render_thread[1]); } if (voodoo->render_threads == 4) { voodoo->render_thread_run[2] = 0; thread_set_event(voodoo->wake_render_thread[2]); - thread_wait(voodoo->render_thread[2], -1); + thread_wait(voodoo->render_thread[2]); voodoo->render_thread_run[3] = 0; thread_set_event(voodoo->wake_render_thread[3]); - thread_wait(voodoo->render_thread[3], -1); + thread_wait(voodoo->render_thread[3]); } thread_destroy_event(voodoo->fifo_not_full_event); thread_destroy_event(voodoo->wake_main_thread); diff --git a/src/video/video.c b/src/video/video.c index 5118b886f..532995cb3 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -831,7 +831,7 @@ video_init(void) } /* Account for overscan. */ - buffer32 = create_bitmap(2048 + 64, 2048 + 64); + buffer32 = create_bitmap(2048, 2048); for (c = 0; c < 64; c++) { cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; @@ -889,7 +889,7 @@ video_close(void) { thread_run = 0; thread_set_event(blit_data.wake_blit_thread); - thread_wait(blit_data.blit_thread, -1); + thread_wait(blit_data.blit_thread); thread_destroy_event(blit_data.buffer_not_in_use); thread_destroy_event(blit_data.blit_complete); thread_destroy_event(blit_data.wake_blit_thread); diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 301544798..36c3dc9ac 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -1,49 +1,57 @@ # -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. # -# This file is part of the 86Box distribution. +# This file is part of the 86Box distribution. # -# CMake build script. +# CMake build script. # -# Authors: David Hrdlička, +# Authors: David Hrdlička, # -# Copyright 2020,2021 David Hrdlička. +# Copyright 2020,2021 David Hrdlička. # enable_language(RC) -add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_thread.c - win_keyboard.c win_crashdump.c win_mouse.c) +add_library(plat OBJECT win.c win_dynld.c win_cdrom.c win_keyboard.c + win_crashdump.c win_mouse.c) add_library(ui OBJECT win_ui.c win_icon.c win_stbar.c win_sdl.c win_dialog.c win_about.c - win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c - win_jsconf.c win_media_menu.c win_preferences.c win_discord.c glad.c win_opengl.c - win_opengl_glslp.c 86Box.rc) + win_settings.c win_devconf.c win_snd_gain.c win_specify_dim.c win_new_floppy.c + win_jsconf.c win_media_menu.c win_preferences.c win_discord.c glad.c win_opengl.c + win_opengl_glslp.c 86Box.rc) -if(MSVC) - # MSVC complains when we include the manifest from 86Box.rc... - # On the bright side, CMake supports passing the manifest as a source - # file when using MSVC, so we might just as well do that! - target_compile_definitions(ui PRIVATE NO_INCLUDE_MANIFEST) - target_sources(86Box PRIVATE 86Box.manifest) +if(NOT CPPTHREADS) + target_sources(plat PRIVATE win_thread.c) +endif() - # Append null to resource strings (fixes file dialogs) - set_property(SOURCE 86Box.rc PROPERTY COMPILE_FLAGS -n) +# CMake 3.22 messed this up for clang/clang++ +# See https://gitlab.kitware.com/cmake/cmake/-/issues/22611 +if(MSVC OR (NOT MINGW AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.22)) + # MSVC linker adds its own manifest to the executable, which fails if + # we include ours in 86Box.rc. We therefore need to pass the manifest + # directly as as a source file, so the linker can use that instead. + set_property(SOURCE 86Box.rc PROPERTY COMPILE_DEFINITIONS NO_INCLUDE_MANIFEST) + target_sources(86Box PRIVATE 86Box.manifest) endif() if(NOT MINGW) - target_sources(plat PRIVATE win_opendir.c) + # Append null to resource strings (fixes file dialogs) + set_property(SOURCE 86Box.rc PROPERTY COMPILE_FLAGS -n) + + # `opendir` is only included in MinGW, so include an implementation + # for other builds. + target_sources(plat PRIVATE win_opendir.c) endif() if(DINPUT) - target_sources(plat PRIVATE win_joystick.cpp) - target_link_libraries(86Box dinput8) + target_sources(plat PRIVATE win_joystick.cpp) + target_link_libraries(86Box dinput8) else() - target_sources(plat PRIVATE win_joystick_rawinput.c) + target_sources(plat PRIVATE win_joystick_rawinput.c) endif() target_link_libraries(86Box advapi32 comctl32 comdlg32 gdi32 shell32 iphlpapi - dxguid imm32 hid setupapi uxtheme version winmm psapi) + dxguid imm32 hid setupapi uxtheme version winmm psapi) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index e3199b319..303e13961 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -163,6 +163,9 @@ endif ifndef DYNAREC DYNAREC := y endif +ifndef CPPTHREADS + CPPTHREADS := y +endif ifeq ($(DYNAREC), y) ifeq ($(ARM), y) ifeq ($(NEW_DYNAREC), n) @@ -370,6 +373,12 @@ MUNTOBJ := midi_mt32.o \ Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o endif +ifeq ($(CPPTHREADS), y) +THREADOBJ := thread.o +else +THREADOBJ := win_thread.o +endif + ifeq ($(VNC), y) OPTS += -DUSE_VNC RFLAGS += -DUSE_VNC @@ -465,8 +474,8 @@ 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 \ - usb.o device.o nvr.o nvr_at.o nvr_ps2.o rtmidi_midi.o \ + nmi.o pic.o pit.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 \ $(VNCOBJ) MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o smram.o spd.o sst_flash.o @@ -608,7 +617,7 @@ SNDOBJ := sound.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ - midi.o midi_system.o \ + midi.o midi_rtmidi.o \ snd_speaker.o \ snd_pssj.o \ snd_lpt_dac.o snd_lpt_dss.o \ @@ -672,7 +681,7 @@ VOODOOOBJ := vid_voodoo.o vid_voodoo_banshee.o \ vid_voodoo_texture.o PLATOBJ := win.o \ - win_dynld.o win_thread.o \ + win_dynld.o \ win_cdrom.o win_keyboard.o \ win_crashdump.o \ win_mouse.o @@ -693,7 +702,7 @@ endif OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ - $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) + $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) ifdef EXOBJ OBJ += $(EXOBJ) endif diff --git a/src/win/glad.c b/src/win/glad.c index 7bab35d06..8e2e4ce13 100644 --- a/src/win/glad.c +++ b/src/win/glad.c @@ -1,23 +1,24 @@ /* - OpenGL loader generated by glad 0.1.34 on Tue Apr 27 15:16:07 2021. + OpenGL loader generated by glad 0.1.34 on Sat Dec 4 18:46:02 2021. Language/Generator: C/C++ Specification: gl - APIs: gl=3.3 + APIs: gl=3.0 Profile: core Extensions: GL_ARB_buffer_storage, - GL_ARB_debug_output + GL_ARB_debug_output, + GL_ARB_sync Loader: True Local files: False Omit khrplatform: False Reproducible: False Commandline: - --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_debug_output" + --profile="core" --api="gl=3.0" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_debug_output,GL_ARB_sync" Online: - https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_debug_output + https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D3.0&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_debug_output&extensions=GL_ARB_sync */ #include @@ -265,9 +266,6 @@ int GLAD_GL_VERSION_1_5 = 0; int GLAD_GL_VERSION_2_0 = 0; int GLAD_GL_VERSION_2_1 = 0; int GLAD_GL_VERSION_3_0 = 0; -int GLAD_GL_VERSION_3_1 = 0; -int GLAD_GL_VERSION_3_2 = 0; -int GLAD_GL_VERSION_3_3 = 0; PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; @@ -278,10 +276,8 @@ PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; -PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; -PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; @@ -302,13 +298,8 @@ PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; PFNGLCLEARCOLORPROC glad_glClearColor = NULL; PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; -PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; PFNGLCOLORMASKPROC glad_glColorMask = NULL; PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; -PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; -PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; -PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; -PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; @@ -316,7 +307,6 @@ PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; -PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; @@ -330,9 +320,7 @@ PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; -PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; -PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; @@ -343,27 +331,20 @@ PFNGLDISABLEPROC glad_glDisable = NULL; PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; PFNGLDISABLEIPROC glad_glDisablei = NULL; PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; -PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; -PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; -PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; -PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; -PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; PFNGLENABLEPROC glad_glEnable = NULL; PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; PFNGLENABLEIPROC glad_glEnablei = NULL; PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; PFNGLENDQUERYPROC glad_glEndQuery = NULL; PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; -PFNGLFENCESYNCPROC glad_glFenceSync = NULL; PFNGLFINISHPROC glad_glFinish = NULL; PFNGLFLUSHPROC glad_glFlush = NULL; PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; -PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; @@ -373,21 +354,15 @@ PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; PFNGLGENQUERIESPROC glad_glGenQueries = NULL; PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; -PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; -PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; -PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; -PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; -PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; -PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; @@ -395,32 +370,21 @@ PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; PFNGLGETERRORPROC glad_glGetError = NULL; PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; -PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; -PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; -PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; -PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; -PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; -PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; -PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; -PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; -PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; -PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; PFNGLGETSTRINGPROC glad_glGetString = NULL; PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; -PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; @@ -429,8 +393,6 @@ PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; -PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; -PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; @@ -449,9 +411,7 @@ PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; PFNGLISPROGRAMPROC glad_glIsProgram = NULL; PFNGLISQUERYPROC glad_glIsQuery = NULL; PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; -PFNGLISSAMPLERPROC glad_glIsSampler = NULL; PFNGLISSHADERPROC glad_glIsShader = NULL; -PFNGLISSYNCPROC glad_glIsSync = NULL; PFNGLISTEXTUREPROC glad_glIsTexture = NULL; PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; @@ -461,17 +421,6 @@ PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; -PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; -PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; -PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; -PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; -PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; -PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; -PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; -PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; -PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; -PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; -PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; @@ -481,24 +430,12 @@ PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; PFNGLPOINTSIZEPROC glad_glPointSize = NULL; PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; -PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; -PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; -PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; PFNGLREADPIXELSPROC glad_glReadPixels = NULL; PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; -PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; -PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; -PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; -PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; -PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; -PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; -PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; PFNGLSCISSORPROC glad_glScissor = NULL; -PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; -PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; @@ -506,20 +443,9 @@ PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; PFNGLSTENCILOPPROC glad_glStencilOp = NULL; PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; -PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; -PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; -PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; -PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; -PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; -PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; -PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; -PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; -PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; -PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; -PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; @@ -554,7 +480,6 @@ PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; -PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; @@ -603,7 +528,6 @@ PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; -PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; @@ -625,30 +549,23 @@ PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; -PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; -PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; -PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; -PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; -PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; -PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; -PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; -PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; -PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; -PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; -PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; -PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; -PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; -PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; PFNGLVIEWPORTPROC glad_glViewport = NULL; -PFNGLWAITSYNCPROC glad_glWaitSync = NULL; int GLAD_GL_ARB_buffer_storage = 0; int GLAD_GL_ARB_debug_output = 0; +int GLAD_GL_ARB_sync = 0; PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; +PFNGLFENCESYNCPROC glad_glFenceSync = NULL; +PFNGLISSYNCPROC glad_glIsSync = NULL; +PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; +PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; +PFNGLWAITSYNCPROC glad_glWaitSync = NULL; +PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; +PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; static void load_GL_VERSION_1_0(GLADloadproc load) { if(!GLAD_GL_VERSION_1_0) return; glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); @@ -961,107 +878,6 @@ static void load_GL_VERSION_3_0(GLADloadproc load) { glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays"); glad_glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray"); } -static void load_GL_VERSION_3_1(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_1) return; - glad_glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced"); - glad_glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced"); - glad_glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer"); - glad_glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex"); - glad_glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData"); - glad_glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices"); - glad_glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv"); - glad_glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName"); - glad_glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex"); - glad_glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv"); - glad_glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName"); - glad_glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding"); - glad_glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange"); - glad_glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase"); - glad_glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v"); -} -static void load_GL_VERSION_3_2(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_2) return; - glad_glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex"); - glad_glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex"); - glad_glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex"); - glad_glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex"); - glad_glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex"); - glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); - glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); - glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); - glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); - glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); - glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); - glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); - glad_glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v"); - glad_glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v"); - glad_glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture"); - glad_glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample"); - glad_glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample"); - glad_glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv"); - glad_glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski"); -} -static void load_GL_VERSION_3_3(GLADloadproc load) { - if(!GLAD_GL_VERSION_3_3) return; - glad_glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)load("glBindFragDataLocationIndexed"); - glad_glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)load("glGetFragDataIndex"); - glad_glGenSamplers = (PFNGLGENSAMPLERSPROC)load("glGenSamplers"); - glad_glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)load("glDeleteSamplers"); - glad_glIsSampler = (PFNGLISSAMPLERPROC)load("glIsSampler"); - glad_glBindSampler = (PFNGLBINDSAMPLERPROC)load("glBindSampler"); - glad_glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)load("glSamplerParameteri"); - glad_glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)load("glSamplerParameteriv"); - glad_glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)load("glSamplerParameterf"); - glad_glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)load("glSamplerParameterfv"); - glad_glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)load("glSamplerParameterIiv"); - glad_glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)load("glSamplerParameterIuiv"); - glad_glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)load("glGetSamplerParameteriv"); - glad_glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)load("glGetSamplerParameterIiv"); - glad_glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)load("glGetSamplerParameterfv"); - glad_glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)load("glGetSamplerParameterIuiv"); - glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC)load("glQueryCounter"); - glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)load("glGetQueryObjecti64v"); - glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)load("glGetQueryObjectui64v"); - glad_glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)load("glVertexAttribDivisor"); - glad_glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)load("glVertexAttribP1ui"); - glad_glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)load("glVertexAttribP1uiv"); - glad_glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)load("glVertexAttribP2ui"); - glad_glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)load("glVertexAttribP2uiv"); - glad_glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)load("glVertexAttribP3ui"); - glad_glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)load("glVertexAttribP3uiv"); - glad_glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)load("glVertexAttribP4ui"); - glad_glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)load("glVertexAttribP4uiv"); - glad_glVertexP2ui = (PFNGLVERTEXP2UIPROC)load("glVertexP2ui"); - glad_glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)load("glVertexP2uiv"); - glad_glVertexP3ui = (PFNGLVERTEXP3UIPROC)load("glVertexP3ui"); - glad_glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)load("glVertexP3uiv"); - glad_glVertexP4ui = (PFNGLVERTEXP4UIPROC)load("glVertexP4ui"); - glad_glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)load("glVertexP4uiv"); - glad_glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)load("glTexCoordP1ui"); - glad_glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)load("glTexCoordP1uiv"); - glad_glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)load("glTexCoordP2ui"); - glad_glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)load("glTexCoordP2uiv"); - glad_glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)load("glTexCoordP3ui"); - glad_glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)load("glTexCoordP3uiv"); - glad_glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)load("glTexCoordP4ui"); - glad_glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)load("glTexCoordP4uiv"); - glad_glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)load("glMultiTexCoordP1ui"); - glad_glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)load("glMultiTexCoordP1uiv"); - glad_glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)load("glMultiTexCoordP2ui"); - glad_glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)load("glMultiTexCoordP2uiv"); - glad_glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)load("glMultiTexCoordP3ui"); - glad_glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)load("glMultiTexCoordP3uiv"); - glad_glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)load("glMultiTexCoordP4ui"); - glad_glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)load("glMultiTexCoordP4uiv"); - glad_glNormalP3ui = (PFNGLNORMALP3UIPROC)load("glNormalP3ui"); - glad_glNormalP3uiv = (PFNGLNORMALP3UIVPROC)load("glNormalP3uiv"); - glad_glColorP3ui = (PFNGLCOLORP3UIPROC)load("glColorP3ui"); - glad_glColorP3uiv = (PFNGLCOLORP3UIVPROC)load("glColorP3uiv"); - glad_glColorP4ui = (PFNGLCOLORP4UIPROC)load("glColorP4ui"); - glad_glColorP4uiv = (PFNGLCOLORP4UIVPROC)load("glColorP4uiv"); - glad_glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui"); - glad_glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv"); -} static void load_GL_ARB_buffer_storage(GLADloadproc load) { if(!GLAD_GL_ARB_buffer_storage) return; glad_glBufferStorage = (PFNGLBUFFERSTORAGEPROC)load("glBufferStorage"); @@ -1073,10 +889,21 @@ static void load_GL_ARB_debug_output(GLADloadproc load) { glad_glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)load("glDebugMessageCallbackARB"); glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC)load("glGetDebugMessageLogARB"); } +static void load_GL_ARB_sync(GLADloadproc load) { + if(!GLAD_GL_ARB_sync) return; + glad_glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync"); + glad_glIsSync = (PFNGLISSYNCPROC)load("glIsSync"); + glad_glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync"); + glad_glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync"); + glad_glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync"); + glad_glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v"); + glad_glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv"); +} static int find_extensionsGL(void) { if (!get_exts()) return 0; GLAD_GL_ARB_buffer_storage = has_ext("GL_ARB_buffer_storage"); GLAD_GL_ARB_debug_output = has_ext("GL_ARB_debug_output"); + GLAD_GL_ARB_sync = has_ext("GL_ARB_sync"); free_exts(); return 1; } @@ -1126,12 +953,9 @@ static void find_coreGL(void) { GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; - GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; - if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 3)) { + if (GLVersion.major > 3 || (GLVersion.major >= 3 && GLVersion.minor >= 0)) { max_loaded_major = 3; - max_loaded_minor = 3; + max_loaded_minor = 0; } } @@ -1150,13 +974,11 @@ int gladLoadGLLoader(GLADloadproc load) { load_GL_VERSION_2_0(load); load_GL_VERSION_2_1(load); load_GL_VERSION_3_0(load); - load_GL_VERSION_3_1(load); - load_GL_VERSION_3_2(load); - load_GL_VERSION_3_3(load); if (!find_extensionsGL()) return 0; load_GL_ARB_buffer_storage(load); load_GL_ARB_debug_output(load); + load_GL_ARB_sync(load); return GLVersion.major != 0 || GLVersion.minor != 0; } diff --git a/src/win/languages/cs-CZ.rc b/src/win/languages/cs-CZ.rc index 9b59a8bd9..b63d8a176 100644 --- a/src/win/languages/cs-CZ.rc +++ b/src/win/languages/cs-CZ.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Kazetové nahrávky (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Všechny soubory (*.*)\0*.*\0" IDS_2150 "Cartridge %i: %ls" IDS_2151 "Obrazy cartridge (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Všechny soubory (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/de-DE.rc b/src/win/languages/de-DE.rc index 748fbf715..eaaa28171 100644 --- a/src/win/languages/de-DE.rc +++ b/src/win/languages/de-DE.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3-Kern)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0-Kern)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Kassettenimages (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Alle Dateien (*.*)\0*.*\0" IDS_2150 "Cartridge %i: %ls" IDS_2151 "Cartridgeimages (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Alle Dateien (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/en-GB.rc b/src/win/languages/en-GB.rc index f0c65adab..61749d954 100644 --- a/src/win/languages/en-GB.rc +++ b/src/win/languages/en-GB.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" IDS_2150 "Cartridge %i: %ls" IDS_2151 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/en-US.rc b/src/win/languages/en-US.rc index ade2e1ff9..3bee70556 100644 --- a/src/win/languages/en-US.rc +++ b/src/win/languages/en-US.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Cassette images (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" IDS_2150 "Cartridge %i: %ls" IDS_2151 "Cartridge images (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/es-ES.rc b/src/win/languages/es-ES.rc index 23a1eae81..2232e69c5 100644 --- a/src/win/languages/es-ES.rc +++ b/src/win/languages/es-ES.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Imágenes de Cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0All files (*.*)\0*.*\0" IDS_2150 "Cartucho %i: %ls" IDS_2151 "Imágenes de Cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0All files (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/fi-FI.rc b/src/win/languages/fi-FI.rc index ff0130d0c..56430464d 100644 --- a/src/win/languages/fi-FI.rc +++ b/src/win/languages/fi-FI.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (ohjelmistopohjainen)", IDM_VID_SDL_SW MENUITEM "SDL (&laitteistokiihdytetty)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Kasetti-tiedostot (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Kaikki tiedostot (*.*)\0*.*\0" IDS_2150 "ROM-moduuli %i: %ls" IDS_2151 "ROM-moduulikuvat (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Kaikki tiedostot (*.*)\0*.*\0" + IDS_2152 "Virhe renderöijän alustuksessa" + IDS_2153 "OpenGL (3.0 Core) renderöijän alustus epäonnistui. Käytä toista renderöijää." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/fr-FR.rc b/src/win/languages/fr-FR.rc index fe6cdc865..6b58bd593 100644 --- a/src/win/languages/fr-FR.rc +++ b/src/win/languages/fr-FR.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Logiciel)", IDM_VID_SDL_SW MENUITEM "SDL (&Materiel)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -274,7 +274,7 @@ END #define STR_OK "OK" #define STR_CANCEL "Annuler" -#define STR_GLOBAL "Sauver ces paramètres comme valeurs par défaut &globales" +#define STR_GLOBAL "Sauvegarder ces paramètres comme valeurs par défaut &globales" #define STR_DEFAULT "&Défaut" #define STR_LANGUAGE "Langue:" #define STR_ICONSET "Ensemble d'icônes:" @@ -478,9 +478,9 @@ BEGIN IDS_2118 "Côntrolleur interne" IDS_2119 "Sortir" IDS_2120 "Pas de ROMs trouvées" - IDS_2121 "Voulez-vous sauver les paramètres ?" + IDS_2121 "Voulez-vous sauvegarder les paramètres ?" IDS_2122 "Cela entraînera la réinitialisation complète de la machine émulée." - IDS_2123 "Sauver" + IDS_2123 "Sauvegarder" IDS_2124 "À propos de 86Box" IDS_2125 "86Box v" EMU_VERSION @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Images cassette (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tous les fichiers (*.*)\0*.*\0" IDS_2150 "Cartouche %i: %ls" IDS_2151 "Images cartouche (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tous les fichiers (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/hr-HR.rc b/src/win/languages/hr-HR.rc index df1402995..c6d4c4cc5 100644 --- a/src/win/languages/hr-HR.rc +++ b/src/win/languages/hr-HR.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Softver)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardver)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 jezgra)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 jezgra)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Slike audio kasete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Sve datoteke (*.*)\0*.*\0" IDS_2150 "Kaseta %i: %ls" IDS_2151 "Slike kasete (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Sve datoteke (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/hu-HU.rc b/src/win/languages/hu-HU.rc index 2acad9e18..3a8dfe756 100644 --- a/src/win/languages/hu-HU.rc +++ b/src/win/languages/hu-HU.rc @@ -44,7 +44,7 @@ BEGIN MENUITEM "&SDL (Szoftveres)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardveres)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -532,6 +532,8 @@ BEGIN IDS_2149 "Magnókazetta-képek (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Minden fájl (*.*)\0*.*\0" IDS_2150 "ROM-kazetta %i: %ls" IDS_2151 "ROM-kazetta képek (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Minden fájl (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/it-IT.rc b/src/win/languages/it-IT.rc index 9cff4e642..461b76e71 100644 --- a/src/win/languages/it-IT.rc +++ b/src/win/languages/it-IT.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Immagini cassetta (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tutti i file (*.*)\0*.*\0" IDS_2150 "Cartuccia %i: %ls" IDS_2151 "Immagini cartuccia (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tutti i file (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/ja-JP.rc b/src/win/languages/ja-JP.rc index f7a8f9770..e88e1822c 100644 --- a/src/win/languages/ja-JP.rc +++ b/src/win/languages/ja-JP.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "SDL (ソフトウェア)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (ハードウェア)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.3コア)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0コア)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -524,12 +524,14 @@ BEGIN IDS_2143 "OpenGLシェーダー (*.GLSL)\0*.GLSL\0すべてのファイル (*.*)\0*.*\0" IDS_2144 "OpenGLの設定" IDS_2145 "サポートされていない設定を読み込んでいます" - IDS_2146 "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。 ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" + IDS_2146 "選択したマシンに基づくCPUタイプのフィルタリングは、このエミュレートされたマシンでは無効になっています。\n\nこれにより、選択したマシンと互換性のないCPUが選択できます。ただし、マシンのBIOSまたは他のソフトウェアとの互換性が失われる可能性があります。\n\nこの設定の有効化は公式サポートができません。また、バグレポートが無効として閉じられる場合があります。" IDS_2147 "つづく" IDS_2148 "カセット: %s" IDS_2149 "カセットイメージ (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0すべてのファイル (*.*)\0*.*\0" IDS_2150 "カートリッジ %i: %ls" IDS_2151 "カートリッジイメージ (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0すべてのファイル (*.*)\0*.*\0" + IDS_2152 "レンダラーの初期化エラー" + IDS_2153 "OpenGL(3.0コア)レンダラーが初期化できませんでした。別のレンダラーを使用してください。" END STRINGTABLE DISCARDABLE @@ -539,7 +541,7 @@ BEGIN IDS_4098 "%01i" IDS_4099 "MFM/RLLまたはESDIのCD-ROMドライブが存在しません" IDS_4100 "カスタム..." - IDS_4101 "カスタム(大)..." + IDS_4101 "カスタム(大)..." IDS_4102 "新規のディスクを追加" IDS_4103 "既定のディスクを追加" IDS_4104 "HDIのディスクイメージは4GB以上にはできません。" @@ -555,7 +557,7 @@ BEGIN IDS_4114 "ファイルが存在し、読み取り可能であることを確認します。" IDS_4115 "ファイルが書き込み可能なディレクトリに保存されていることを確認してください。" IDS_4116 "ディスクイメージが大きすぎます" - IDS_4117 "新規ディスクのパーティション設定とフォーマットを必ずしといて下さい。" + IDS_4117 "新規ディスクのパーティション設定とフォーマットを必ずしといてください。" IDS_4118 "選択したファイルは上書きされます。使っていいですか?" IDS_4119 "サポートされていないディスクイメージ" IDS_4120 "上書き" diff --git a/src/win/languages/ko-KR.rc b/src/win/languages/ko-KR.rc index 4562fdbce..a46c8f6d7 100644 --- a/src/win/languages/ko-KR.rc +++ b/src/win/languages/ko-KR.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "SDL (소프트웨어)(&S)", IDM_VID_SDL_SW MENUITEM "SDL (하드웨어)(&H)", IDM_VID_SDL_HW MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL - MENUITEM "OpenGL (3.3 코어)(&G)", IDM_VID_OPENGL_CORE + MENUITEM "OpenGL (3.0 코어)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "VNC(&V)", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "카세트 이미지 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0모든 파일 (*.*)\0*.*\0" IDS_2150 "카트리지 %i: %ls" IDS_2151 "카트리지 이미지 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0모든 파일 (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/pt-BR.rc b/src/win/languages/pt-BR.rc index 79c0b51cf..06a000458 100644 --- a/src/win/languages/pt-BR.rc +++ b/src/win/languages/pt-BR.rc @@ -9,6 +9,8 @@ LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN #pragma code_page(65001) #endif //_WIN32 +#define AUTHORS + ///////////////////////////////////////////////////////////////////////////// // // Menu @@ -42,7 +44,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.3)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -78,12 +80,12 @@ BEGIN POPUP "&Tipo de tela VGA" BEGIN MENUITEM "&Cor RGB", IDM_VID_GRAY_RGB - MENUITEM "Escala de cinza &RGB", IDM_VID_GRAY_MONO + MENUITEM "Tons de cinza &RGB", IDM_VID_GRAY_MONO MENUITEM "Monitor &âmbar", IDM_VID_GRAY_AMBER MENUITEM "Monitor &verde", IDM_VID_GRAY_GREEN MENUITEM "Monitor &branco", IDM_VID_GRAY_WHITE END - POPUP "Tipo de &conversão de escala de cinza" + POPUP "Tipo de &conversão de tons de cinza" BEGIN MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 @@ -531,6 +533,8 @@ BEGIN IDS_2149 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os arquivos (*.*)\0*.*\0" IDS_2150 "Cartucho %i: %ls" IDS_2151 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os arquivos (*.*)\0*.*\0" + IDS_2152 "Erro ao inicializar o renderizador" + IDS_2153 "O renderizador OpenGL (Núcleo 3.0) não pôde ser inicializado. Use outro renderizador." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/pt-PT.rc b/src/win/languages/pt-PT.rc index 9dc41847a..a424ad141 100644 --- a/src/win/languages/pt-PT.rc +++ b/src/win/languages/pt-PT.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Núcleo 3.3)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (Núcleo 3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Imagens de cassete (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Todos os ficheiros (*.*)\0*.*\0" IDS_2150 "Cartucho %i: %ls" IDS_2151 "Imagens de cartucho (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Todos os ficheiros (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 7f80abe87..36ebf4ee3 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Образы кассет (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Все файлы (*.*)\0*.*\0" IDS_2150 "Картридж %i: %ls" IDS_2151 "Образы картриджей (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Все файлы (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/sl-SI.rc b/src/win/languages/sl-SI.rc index cdd9ecba3..fb1c80b8b 100644 --- a/src/win/languages/sl-SI.rc +++ b/src/win/languages/sl-SI.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (programsko)", IDM_VID_SDL_SW MENUITEM "SDL (s&trojno)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (Jedro 3.3)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (Jedro 3.0)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Slike kaset (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Vse datoteke (*.*)\0*.*\0" IDS_2150 "Spominski vložek %i: %ls" IDS_2151 "Slike spominskega vložka (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Vse datoteke (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/tr-TR.rc b/src/win/languages/tr-TR.rc index b1c055ad1..5d2ef2c50 100644 --- a/src/win/languages/tr-TR.rc +++ b/src/win/languages/tr-TR.rc @@ -41,7 +41,7 @@ BEGIN MENUITEM "&SDL (Yazılım)", IDM_VID_SDL_SW MENUITEM "SDL (&Donanım)", IDM_VID_SDL_HW MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "Open&GL (3.0 Core)", IDM_VID_OPENGL_CORE #ifdef USE_VNC MENUITEM "&VNC", IDM_VID_VNC #endif @@ -530,6 +530,8 @@ BEGIN IDS_2149 "Kaset imajları (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0Tüm dosyalar (*.*)\0*.*\0" IDS_2150 "Kartuş %i: %ls" IDS_2151 "Kartuş imajları (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0Tüm dosyalar (*.*)\0*.*\0" + IDS_2152 "Error initializing renderer" + IDS_2153 "OpenGL (3.0 Core) renderer could not be initialized. Use another renderer." END STRINGTABLE DISCARDABLE diff --git a/src/win/languages/zh-CN.rc b/src/win/languages/zh-CN.rc index f999f0478..37c5621ab 100644 --- a/src/win/languages/zh-CN.rc +++ b/src/win/languages/zh-CN.rc @@ -18,63 +18,63 @@ BEGIN POPUP "操作(&A)" BEGIN MENUITEM "键盘需要捕捉(&K)", IDM_ACTION_KBD_REQ_CAPTURE - MENUITEM "右CTRL作为左ALT(&R)", IDM_ACTION_RCTRL_IS_LALT + MENUITEM "将右 CTRL 键映射为左 ALT 键(&R)", IDM_ACTION_RCTRL_IS_LALT MENUITEM SEPARATOR MENUITEM "硬重置(&H)...", IDM_ACTION_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD + MENUITEM "Ctrl+Alt+Del(&C)\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC + MENUITEM "Ctrl+Alt+Esc(&E)", IDM_ACTION_CTRL_ALT_ESC MENUITEM SEPARATOR MENUITEM "暂停(&P)", IDM_ACTION_PAUSE MENUITEM SEPARATOR - MENUITEM "退出(&x)...", IDM_ACTION_EXIT + MENUITEM "退出(&X)...", IDM_ACTION_EXIT END - POPUP "视图(&V)" + POPUP "查看(&V)" BEGIN MENUITEM "隐藏状态栏(&H)", IDM_VID_HIDE_STATUS_BAR MENUITEM SEPARATOR - MENUITEM "窗口可调整大小(&R)", IDM_VID_RESIZE - MENUITEM "记住窗口大小和未知(&e)", IDM_VID_REMEMBER + MENUITEM "窗口大小可调(&R)", IDM_VID_RESIZE + MENUITEM "记住窗口大小和位置(&E)", IDM_VID_REMEMBER MENUITEM SEPARATOR - POPUP "渲染器(&n)" + POPUP "渲染器(&N)" BEGIN - MENUITEM "&SDL (软件)", IDM_VID_SDL_SW - MENUITEM "SDL (硬件 &H)", IDM_VID_SDL_HW - MENUITEM "SDL (&OpenGL)", IDM_VID_SDL_OPENGL - MENUITEM "Open&GL (3.3 Core)", IDM_VID_OPENGL_CORE + MENUITEM "SDL (软件)(&S)", IDM_VID_SDL_SW + MENUITEM "SDL (硬件)(&H)", IDM_VID_SDL_HW + MENUITEM "SDL (OpenGL)(&O)", IDM_VID_SDL_OPENGL + MENUITEM "OpenGL (3.0 核心)(&G)", IDM_VID_OPENGL_CORE #ifdef USE_VNC - MENUITEM "&VNC", IDM_VID_VNC + MENUITEM "VNC(&V)", IDM_VID_VNC #endif END MENUITEM SEPARATOR MENUITEM "指定窗口大小...", IDM_VID_SPECIFY_DIM - MENUITEM "强制 4:3 显示比例(&o)", IDM_VID_FORCE43 - POPUP "窗口缩放比例(&W)" + MENUITEM "强制 4:3 显示比例(&O)", IDM_VID_FORCE43 + POPUP "窗口缩放系数(&W)" BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X + MENUITEM "0.5x(&0)", IDM_VID_SCALE_1X + MENUITEM "1x(&1)", IDM_VID_SCALE_2X + MENUITEM "1.5x(&5)", IDM_VID_SCALE_3X + MENUITEM "2x(&2)", IDM_VID_SCALE_4X END POPUP "过滤方式" BEGIN MENUITEM "邻近(&N)", IDM_VID_FILTER_NEAREST MENUITEM "线性(&L)", IDM_VID_FILTER_LINEAR END - MENUITEM "Hi&DPI 缩放", IDM_VID_HIDPI + MENUITEM "HiDPI 缩放(&D)", IDM_VID_HIDPI MENUITEM SEPARATOR MENUITEM "全屏(&F)\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN - POPUP "全屏拉伸模式(&s)" + POPUP "全屏拉伸模式(&S)" BEGIN MENUITEM "全屏拉伸(&F)", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "4:3(&4)", IDM_VID_FS_43 MENUITEM "保持比例(&S)", IDM_VID_FS_KEEPRATIO - MENUITEM "整数倍放大&I", IDM_VID_FS_INT + MENUITEM "整数比例(&I)", IDM_VID_FS_INT END - POPUP "E&GA/(S)VGA 设置" + POPUP "EGA/(S)VGA 设置(&G)" BEGIN - MENUITEM "反转 VGA 显示器(&I)", IDM_VID_INVERT - POPUP "VGA 屏幕类型(&t)" + MENUITEM "VGA 显示器反色显示(&I)", IDM_VID_INVERT + POPUP "VGA 屏幕类型(&T)" BEGIN MENUITEM "RGB 彩色(&C)", IDM_VID_GRAY_RGB MENUITEM "RGB 灰度(&R)", IDM_VID_GRAY_MONO @@ -82,16 +82,16 @@ BEGIN MENUITEM "绿色单色显示器(&G)", IDM_VID_GRAY_GREEN MENUITEM "白色单色显示器(&W)", IDM_VID_GRAY_WHITE END - POPUP "灰度转换类型(&c)" + POPUP "灰度转换类型(&C)" BEGIN - MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601 - MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709 + MENUITEM "BT601 (NTSC/PAL)(&6)", IDM_VID_GRAYCT_601 + MENUITEM "BT709 (HDTV)(&7)", IDM_VID_GRAYCT_709 MENUITEM "平均(&A)", IDM_VID_GRAYCT_AVE END END MENUITEM SEPARATOR MENUITEM "CGA/PCjr/Tandy/EGA/(S)VGA 过扫描(&G)", IDM_VID_OVERSCAN - MENUITEM "更改灰度显示器对比度(&m)", IDM_VID_CGACON + MENUITEM "更改单色显示对比度(&M)", IDM_VID_CGACON END MENUITEM "介质(&M)", IDM_MEDIA POPUP "工具(&T)" @@ -99,12 +99,12 @@ BEGIN MENUITEM "设置(&S)...", IDM_CONFIG MENUITEM "更新状态栏图标(&U)", IDM_UPDATE_ICONS MENUITEM SEPARATOR - MENUITEM "截图(&c)\tCtrl+F11", IDM_ACTION_SCREENSHOT + MENUITEM "截图(&C)\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR MENUITEM "首选项(&P)...", IDM_PREFERENCES MENUITEM "启用 Discord 集成(&D)", IDM_DISCORD MENUITEM SEPARATOR - MENUITEM "音量增益(&g)...", IDM_SND_GAIN + MENUITEM "音量增益(&G)...", IDM_SND_GAIN #ifdef MTR_ENABLED MENUITEM SEPARATOR MENUITEM "开始追踪\tCtrl+T", IDM_ACTION_BEGIN_TRACE @@ -115,16 +115,16 @@ BEGIN POPUP "记录日志(&L)" BEGIN # ifdef ENABLE_BUSLOGIC_LOG - MENUITEM "启用 总线Logic 日志\tCtrl+F4", IDM_LOG_BUSLOGIC + MENUITEM "启用 BusLogic 日志\tCtrl+F4", IDM_LOG_BUSLOGIC # endif # ifdef ENABLE_CDROM_LOG MENUITEM "启用 CD-ROM 日志\tCtrl+F5", IDM_LOG_CDROM # endif # ifdef ENABLE_D86F_LOG - MENUITEM "启用 软盘(86F) 日志\tCtrl+F6", IDM_LOG_D86F + MENUITEM "启用软盘 (86F) 日志\tCtrl+F6", IDM_LOG_D86F # endif # ifdef ENABLE_FDC_LOG - MENUITEM "启用软驱控制器日志\tCtrl+F7", IDM_LOG_FDC + MENUITEM "启用软盘控制器日志\tCtrl+F7", IDM_LOG_FDC # endif # ifdef ENABLE_IDE_LOG MENUITEM "启用 IDE 日志\tCtrl+F8", IDM_LOG_IDE @@ -143,7 +143,7 @@ BEGIN MENUITEM "日志断点(&L)\tCtrl+F10", IDM_LOG_BREAKPOINT # endif # ifdef ENABLE_VRAM_DUMP - MENUITEM "创建显示内存转储(&v)\tCtrl+F1", IDM_DUMP_VRAM + MENUITEM "创建显卡内存转储(&V)\tCtrl+F1", IDM_DUMP_VRAM # endif # endif END @@ -151,7 +151,7 @@ BEGIN POPUP "帮助(&H)" BEGIN MENUITEM "文档(&D)...", IDM_DOCS - MENUITEM "关于(&A)...", IDM_ABOUT + MENUITEM "关于 86Box(&A)...", IDM_ABOUT END END @@ -167,14 +167,14 @@ BEGIN MENUITEM "新建镜像(&N)...", IDM_CASSETTE_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "打开已存在的镜像(&E)...", IDM_CASSETTE_IMAGE_EXISTING - MENUITEM "写保护打开已存在的镜像(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_CASSETTE_IMAGE_EXISTING_WP MENUITEM SEPARATOR MENUITEM "录制(&R)", IDM_CASSETTE_RECORD MENUITEM "播放(&P)", IDM_CASSETTE_PLAY MENUITEM "倒带至起点(&R)", IDM_CASSETTE_REWIND MENUITEM "快进至终点(&F)", IDM_CASSETTE_FAST_FORWARD MENUITEM SEPARATOR - MENUITEM "弹出(&j)", IDM_CASSETTE_EJECT + MENUITEM "弹出(&J)", IDM_CASSETTE_EJECT END END @@ -184,7 +184,7 @@ BEGIN BEGIN MENUITEM "镜像(&I)...", IDM_CARTRIDGE_IMAGE MENUITEM SEPARATOR - MENUITEM "弹出(&j)", IDM_CARTRIDGE_EJECT + MENUITEM "弹出(&J)", IDM_CARTRIDGE_EJECT END END @@ -195,11 +195,11 @@ BEGIN MENUITEM "新建镜像(&N)...", IDM_FLOPPY_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "打开已存在的镜像(&E)...", IDM_FLOPPY_IMAGE_EXISTING - MENUITEM "写保护打开已存在的镜像(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_FLOPPY_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "导出为86F格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F + MENUITEM "导出为 86F 格式(&x)...", IDM_FLOPPY_EXPORT_TO_86F MENUITEM SEPARATOR - MENUITEM "弹出(&j)", IDM_FLOPPY_EJECT + MENUITEM "弹出(&J)", IDM_FLOPPY_EJECT END END @@ -209,7 +209,7 @@ BEGIN BEGIN MENUITEM "静音(&M)", IDM_CDROM_MUTE MENUITEM SEPARATOR - MENUITEM "空置驱动器(&m)", IDM_CDROM_EMPTY + MENUITEM "空置驱动器(&M)", IDM_CDROM_EMPTY MENUITEM "载入上一个镜像(&R)", IDM_CDROM_RELOAD MENUITEM SEPARATOR MENUITEM "镜像(&I)", IDM_CDROM_IMAGE @@ -223,9 +223,9 @@ BEGIN MENUITEM "新建镜像(&N)...", IDM_ZIP_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "打开已存在的镜像(&E)...", IDM_ZIP_IMAGE_EXISTING - MENUITEM "写保护打开已存在的镜像(&W)...", IDM_ZIP_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_ZIP_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "弹出(&j)", IDM_ZIP_EJECT + MENUITEM "弹出(&J)", IDM_ZIP_EJECT MENUITEM "载入上一个镜像(&R)", IDM_ZIP_RELOAD END END @@ -237,25 +237,25 @@ BEGIN MENUITEM "新建镜像(&N)...", IDM_MO_IMAGE_NEW MENUITEM SEPARATOR MENUITEM "打开已存在的镜像(&E)...", IDM_MO_IMAGE_EXISTING - MENUITEM "写保护打开已存在的镜像(&W)...", IDM_MO_IMAGE_EXISTING_WP + MENUITEM "打开已存在的镜像并写保护(&W)...", IDM_MO_IMAGE_EXISTING_WP MENUITEM SEPARATOR - MENUITEM "弹出(&j)", IDM_MO_EJECT + MENUITEM "弹出(&J)", IDM_MO_EJECT MENUITEM "载入上一个镜像(&R)", IDM_MO_RELOAD END END VidGLSubMenu MENU DISCARDABLE BEGIN - POPUP "目标帧率(&f)" + POPUP "目标帧率(&F)" BEGIN MENUITEM "与视频同步(&S)", IDM_VID_GL_FPS_BLITTER - MENUITEM "&25 fps", IDM_VID_GL_FPS_25 - MENUITEM "&30 fps", IDM_VID_GL_FPS_30 - MENUITEM "&50 fps", IDM_VID_GL_FPS_50 - MENUITEM "&60 fps", IDM_VID_GL_FPS_60 - MENUITEM "&75 fps", IDM_VID_GL_FPS_75 + MENUITEM "25 fps(&2)", IDM_VID_GL_FPS_25 + MENUITEM "30 fps(&3)", IDM_VID_GL_FPS_30 + MENUITEM "50 fps(&5)", IDM_VID_GL_FPS_50 + MENUITEM "60 fps(&6)", IDM_VID_GL_FPS_60 + MENUITEM "75 fps(&7)", IDM_VID_GL_FPS_75 END - MENUITEM "VSync 垂直同步(&V)", IDM_VID_GL_VSYNC + MENUITEM "垂直同步(&V)", IDM_VID_GL_VSYNC MENUITEM "选择着色器(&S)...", IDM_VID_GL_SHADER MENUITEM "移除着色器(&R)", IDM_VID_GL_NOSHADER END @@ -274,7 +274,7 @@ END #define STR_OK "确定" #define STR_CANCEL "取消" -#define STR_GLOBAL "将以上设定存储为全局默认值(&g)" +#define STR_GLOBAL "将以上设置存储为全局默认值(&G)" #define STR_DEFAULT "默认(&D)" #define STR_LANGUAGE "语言:" #define STR_ICONSET "图标集:" @@ -283,30 +283,30 @@ END #define STR_FILE_NAME "文件名:" #define STR_DISK_SIZE "磁盘大小:" -#define STR_RPM_MODE "转速(RPM)模式:" +#define STR_RPM_MODE "转速 (RPM) 模式:" #define STR_PROGRESS "进度:" #define STR_WIDTH "宽度:" #define STR_HEIGHT "高度:" #define STR_LOCK_TO_SIZE "锁定此大小" -#define STR_MACHINE_TYPE "机器种类:" +#define STR_MACHINE_TYPE "机器类型:" #define STR_MACHINE "机型:" #define STR_CONFIGURE "配置" #define STR_CPU_TYPE "CPU 类型:" #define STR_SPEED "速度:" -#define STR_FPU "浮点处理器(FPU):" -#define STR_WAIT_STATES "等待状态(WS):" +#define STR_FPU "浮点处理器 (FPU):" +#define STR_WAIT_STATES "等待状态 (WS):" #define STR_MB "MB" #define STR_MEMORY "内存:" #define STR_TIME_SYNC "时间同步" #define STR_DISABLED "禁用" -#define STR_ENABLED_LOCAL "启用(本地时间)" -#define STR_ENABLED_UTC "启用(UTC)" +#define STR_ENABLED_LOCAL "启用 (本地时间)" +#define STR_ENABLED_UTC "启用 (UTC)" #define STR_DYNAREC "动态重编译器" #define STR_VIDEO "显卡:" -#define STR_VOODOO "Voodoo 显卡" +#define STR_VOODOO "Voodoo Graphics" #define STR_MOUSE "鼠标:" #define STR_JOYSTICK "操纵杆:" @@ -322,11 +322,11 @@ END #define STR_SSI "Innovation SSI-2001" #define STR_CMS "CMS / Game Blaster" #define STR_GUS "Gravis Ultrasound" -#define STR_FLOAT "使用 FLOAT32 音频" +#define STR_FLOAT "使用单精度浮点 (FLOAT32)" #define STR_NET_TYPE "网络类型:" #define STR_PCAP "PCap 设备:" -#define STR_NET "网卡类型:" +#define STR_NET "网络适配器:" #define STR_LPT1 "LPT1 设备:" #define STR_LPT2 "LPT2 设备:" @@ -340,7 +340,7 @@ END #define STR_PARALLEL3 "并口 3" #define STR_HDC "硬盘控制器:" -#define STR_FDC "软驱控制器:" +#define STR_FDC "软盘控制器:" #define STR_IDE_TER "第三 IDE 控制器" #define STR_IDE_QUA "第四 IDE 控制器" #define STR_SCSI "SCSI" @@ -362,28 +362,28 @@ END #define STR_SECTORS "扇区(S):" #define STR_HEADS "磁头(H):" #define STR_CYLS "柱面(C):" -#define STR_SIZE_MB "大小(MB):" +#define STR_SIZE_MB "大小 (MB):" #define STR_TYPE "类型:" #define STR_IMG_FORMAT "镜像格式:" #define STR_BLOCK_SIZE "块大小:" -#define STR_FLOPPY_DRIVES "软驱设备:" +#define STR_FLOPPY_DRIVES "软盘驱动器:" #define STR_TURBO "加速时序" #define STR_CHECKBPB "检查 BPB" -#define STR_CDROM_DRIVES "CD-ROM 设备:" +#define STR_CDROM_DRIVES "光盘驱动器:" -#define STR_MO_DRIVES "MO 设备:" -#define STR_ZIP_DRIVES "ZIP 设备:" +#define STR_MO_DRIVES "磁光盘驱动器:" +#define STR_ZIP_DRIVES "ZIP 驱动器:" #define STR_250 "ZIP 250" -#define STR_ISARTC "ISA RTC:" +#define STR_ISARTC "ISA 实时时钟:" #define STR_ISAMEM "ISA 内存扩充" #define STR_ISAMEM_1 "扩展卡 1:" #define STR_ISAMEM_2 "扩展卡 2:" #define STR_ISAMEM_3 "扩展卡 3:" #define STR_ISAMEM_4 "扩展卡 4:" -#define STR_BUGGER "ISABugger device" -#define STR_POSTCARD "自检卡(POST)" +#define STR_BUGGER "ISABugger 设备" +#define STR_POSTCARD "自检 (POST) 卡" #define FONT_SIZE 9 #define FONT_NAME "Microsoft YaHei" @@ -399,40 +399,40 @@ STRINGTABLE DISCARDABLE BEGIN 2048 "86Box" IDS_2049 "错误" - IDS_2050 "关键错误" - IDS_2051 "<保留>" - IDS_2052 "按 CTRL+ALT+PAGE DOWN 组合键返回窗口模式." + IDS_2050 "致命错误" + IDS_2051 "" + IDS_2052 "按 CTRL+ALT+PAGE DOWN 组合键返回到窗口模式。" IDS_2053 "速度" IDS_2054 "ZIP %03i %i (%s): %ls" IDS_2055 "ZIP 镜像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0" - IDS_2056 "86Box 找不到支持的 ROM 镜像.\n\n请下载ROM包并解压到 ""roms"" 文件夹." + IDS_2056 "86Box 找不到任何可用的 ROM 镜像。\n\n请下载ROM 包并将其解压到 ""roms"" 文件夹。" IDS_2057 "(空)" IDS_2058 "ZIP 镜像 (*.IM?;*.ZDI)\0*.IM?;*.ZDI\0所有文件 (*.*)\0*.*\0" - IDS_2059 "Turbo" + IDS_2059 "加速" IDS_2060 "开" IDS_2061 "关" - IDS_2062 "所以镜像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本扇区镜像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面镜像 (*.86F)\0*.86F\0" - IDS_2063 "由于 roms/machines 文件夹中缺少合适的ROM, ""%hs"" 机型不可用. 将切换到其他可用机型." + IDS_2062 "所有镜像 (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0基本扇区镜像 (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0表面镜像 (*.86F)\0*.86F\0" + IDS_2063 "由于 roms/machines 文件夹中缺少合适的 ROM,机型 ""%hs"" 不可用。将切换到其他可用机型。" END STRINGTABLE DISCARDABLE BEGIN - IDS_2064 "由于 roms/video 文件夹中缺少合适的ROM, ""%hs"" 机型不可用. 将切换到其他可用的显卡." + IDS_2064 "由于 roms/video 文件夹中缺少合适的 ROM,显卡 ""%hs"" 不可用。将切换到其他可用显卡。" IDS_2065 "机型" IDS_2066 "显示" IDS_2067 "输入设备" IDS_2068 "声音" IDS_2069 "网络" - IDS_2070 "端口 (COM 与 LPT)" + IDS_2070 "端口 (COM 和 LPT)" IDS_2071 "存储控制器" IDS_2072 "硬盘" - IDS_2073 "软驱和光驱" - IDS_2074 "其他可移动存储设备" - IDS_2075 "其他附件" + IDS_2073 "软盘/光盘驱动器" + IDS_2074 "其他可移动设备" + IDS_2075 "其他外围设备" IDS_2076 "表面镜像 (*.86F)\0*.86F\0" IDS_2077 "单击窗口捕捉鼠标" IDS_2078 "按 F8+F12 释放鼠标" - IDS_2079 "按 F8+F12 或中键释放鼠标" + IDS_2079 "按 F8+F12 或鼠标中键释放鼠标" END STRINGTABLE DISCARDABLE @@ -446,45 +446,45 @@ BEGIN IDS_2086 "MB" IDS_2087 "检查 BPB" IDS_2088 "KB" - IDS_2089 "无法初始化视频渲染器." + IDS_2089 "无法初始化视频渲染器。" IDS_2090 "默认" - IDS_2091 "%i 等待状态(WS)" + IDS_2091 "%i 等待状态 (WS)" IDS_2092 "类型" IDS_2093 "设置 PCap 失败" IDS_2094 "未找到 PCap 设备" IDS_2095 "无效 PCap 设备" - IDS_2096 "标准 2键操纵杆" - IDS_2097 "标准 4键操纵杆" - IDS_2098 "标准 6键操纵杆" - IDS_2099 "标准 8键操纵杆" + IDS_2096 "标准 2 键操纵杆" + IDS_2097 "标准 4 键操纵杆" + IDS_2098 "标准 6 键操纵杆" + IDS_2099 "标准 8 键操纵杆" IDS_2100 "CH Flightstick Pro" IDS_2101 "Microsoft SideWinder Pad" IDS_2102 "Thrustmaster Flight Control System" IDS_2103 "无" - IDS_2104 "无法加载键盘加速器." - IDS_2105 "无法注册原始(raw)输入." + IDS_2104 "无法加载键盘加速器。" + IDS_2105 "无法注册原始输入。" IDS_2106 "%u" IDS_2107 "%u MB (CHS: %i, %i, %i)" IDS_2108 "软盘 %i (%s): %ls" - IDS_2109 "所有镜像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区镜像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区镜像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux images (*.FDI)\0*.FDI\0表面镜像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" + IDS_2109 "所有镜像 (*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF)\0*.0??;*.1??;*.??0;*.86F;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.JSON;*.TD0;*.*FD?;*.MFM;*.XDF\0高级扇区镜像 (*.IMD;*.JSON;*.TD0)\0*.IMD;*.JSON;*.TD0\0基本扇区镜像 (*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?)\0*.0??;*.1??;*.??0;*.BIN;*.CQ?;*.D??;*.FLP;*.HDM;*.IM?;*.XDF;*.*FD?\0Flux 镜像 (*.FDI)\0*.FDI\0表面镜像 (*.86F;*.MFM)\0*.86F;*.MFM\0所有文件 (*.*)\0*.*\0" IDS_2110 "无法初始化 FreeType" - IDS_2111 "无法初始化 SDL, 需要 SDL2.dll" - IDS_2112 "您确定要硬重置模拟器吗?" - IDS_2113 "您确定要退出 86Box 吗?" + IDS_2111 "无法初始化 SDL,需要 SDL2.dll" + IDS_2112 "确定要硬重置模拟器吗?" + IDS_2113 "确定要退出 86Box 吗?" IDS_2114 "无法初始化 Ghostscript" - IDS_2115 "MO %i (%ls): %ls" - IDS_2116 "MO 镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2117 "欢迎使用 86Box!" + IDS_2115 "磁光盘 %i (%ls): %ls" + IDS_2116 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" + IDS_2117 "欢迎使用 86Box!" IDS_2118 "内部控制器" IDS_2119 "退出" - IDS_2120 "未找到ROM" - IDS_2121 "您要保存设置吗?" - IDS_2122 "此操作将硬重置模拟器." + IDS_2120 "找不到 ROM" + IDS_2121 "要保存设置吗?" + IDS_2122 "此操作将硬重置模拟器。" IDS_2123 "保存" IDS_2124 "关于 86Box" IDS_2125 "86Box v" EMU_VERSION - IDS_2126 "一个旧计算机模拟器\n\n作者: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, Tiseno100, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布. 详情见 LICENSE 文件." + IDS_2126 "一个旧式计算机模拟器\n\n作者: Sarah Walker、Miran Grca、Fred N. van Kempen (waltje)、SA1988、Tiseno100、reenigne、leilei、JohnElliott、greatpsycho 等人。\n\n本软件依据 GNU 通用公共许可证第二版或更新版本发布。详情见 LICENSE 文件。" IDS_2127 "确定" IDS_2128 "硬件不可用" #ifdef _WIN32 @@ -492,44 +492,46 @@ BEGIN #else #define LIB_NAME_PCAP "libpcap" #endif - IDS_2129 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接." + IDS_2129 "请确认 " LIB_NAME_PCAP " 已安装且使用兼容 " LIB_NAME_PCAP " 的网络连接。" IDS_2130 "无效配置" #ifdef _WIN32 #define LIB_NAME_FREETYPE "freetype.dll" #else #define LIB_NAME_FREETYPE "libfreetype" #endif - IDS_2131 "ESC/P 打印机模拟需要." LIB_NAME_FREETYPE + IDS_2131 "ESC/P 打印机模拟需要" LIB_NAME_FREETYPE #ifdef _WIN32 #define LIB_NAME_GS "gsdll32.dll" #else #define LIB_NAME_GS "libgs" #endif - IDS_2132 LIB_NAME_GS "是将 PostScript 文件转换为 PDF所需要的库.\n\n所有通用PostScript打印机打印的文件将被保存为 PostScript (.ps) 文件." + IDS_2132 LIB_NAME_GS " 是将 PostScript 文件转换为 PDF 所需要的库。\n\n使用通用 PostScript 打印机打印的文档将被保存为 PostScript (.ps) 文件。" #ifdef _WIN32 #define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" #else #define LIB_NAME_FLUIDSYNTH "libfluidsynth" #endif IDS_2133 "FluidSynth MIDI 输出需要" LIB_NAME_FLUIDSYNTH - IDS_2134 "即将进入全屏模式" - IDS_2135 "请勿在显示此提示" + IDS_2134 "正在进入全屏模式" + IDS_2135 "不要再显示此消息" IDS_2136 "不退出" IDS_2137 "重置" IDS_2138 "不重置" - IDS_2139 "MO 镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" - IDS_2140 "CD-ROM 镜像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" + IDS_2139 "磁光盘镜像 (*.IM?;*.MDI)\0*.IM?;*.MDI\0所有文件 (*.*)\0*.*\0" + IDS_2140 "光盘镜像 (*.ISO;*.CUE)\0*.ISO;*.CUE\0所有文件 (*.*)\0*.*\0" IDS_2141 "%hs 设备配置" IDS_2142 "显示器处在睡眠状态" IDS_2143 "OpenGL 着色器 (*.GLSL)\0*.GLSL\0所有文件 (*.*)\0*.*\0" IDS_2144 "OpenGL 选项" - IDS_2145 "您正在载入一个不受支持的配置" - IDS_2146 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤. \n\n这使得选择与选定计算机不兼容的 CPU 成为可能. 但是, 您可能会遇到与机器 BIOS 或其他软件不兼容的问题. \n\n官方不支持启用此设置, 并且提交的任何错误报告可能会因无效而关闭." + IDS_2145 "正在载入一个不受支持的配置" + IDS_2146 "此模拟计算机禁用了基于选定计算机的 CPU 类型过滤。\n\n能够选中与所选机器本不兼容的 CPU,但是可能会遇到与机器 BIOS 或其他软件不兼容的问题。\n\n启用此设置不受官方支持,并且提交的任何错误报告可能会视为无效而关闭。" IDS_2147 "继续" IDS_2148 "磁带: %s" IDS_2149 "磁带镜像 (*.PCM;*.RAW;*.WAV;*.CAS)\0*.PCM;*.RAW;*.WAV;*.CAS\0所有文件 (*.*)\0*.*\0" IDS_2150 "卡带 %i: %ls" IDS_2151 "卡带镜像 (*.A;*.B;*.JRC)\0*.A;*.B;*.JRC\0所有文件 (*.*)\0*.*\0" + IDS_2152 "初始化渲染器时出错" + IDS_2153 "无法初始化 OpenGL (3.0 核心) 渲染器。请使用其他渲染器。" END STRINGTABLE DISCARDABLE @@ -537,26 +539,26 @@ BEGIN IDS_4096 "硬盘 (%s)" IDS_4097 "%01i:%01i" IDS_4098 "%01i" - IDS_4099 "没有 MFM/RLL 或 ESDI CD-ROM 驱动器" + IDS_4099 "不存在 MFM/RLL 或 ESDI CD-ROM 驱动器" IDS_4100 "自定义..." - IDS_4101 "自定义 (large)..." + IDS_4101 "自定义 (大容量)..." IDS_4102 "添加新硬盘" IDS_4103 "添加已存在的硬盘" - IDS_4104 "HDI 磁盘镜像不能超过 4 GB." - IDS_4105 "磁盘镜像不能超过 127 GB." + IDS_4104 "HDI 磁盘镜像不能超过 4 GB。" + IDS_4105 "磁盘镜像不能超过 127 GB。" IDS_4106 "硬盘镜像 (*.HD?;*.IM?;*.VHD)\0*.HD?;*.IM?;*.VHD\0所有文件 (*.*)\0*.*\0" IDS_4107 "无法读取文件" IDS_4108 "无法写入文件" - IDS_4109 "不支持非 512 字节扇区的 HDI 或 HDX 镜像." - IDS_4110 "USB 目前还不支持" + IDS_4109 "不支持非 512 字节扇区大小的 HDI 或 HDX 镜像。" + IDS_4110 "尚未支持 USB" IDS_4111 "磁盘镜像文件已存在" - IDS_4112 "请指定有效的文件名." - IDS_4113 "磁盘镜像创建完成" - IDS_4114 "请确定此文件已存在并可读取" - IDS_4115 "请确定此文件保存在可写的文件夹中." + IDS_4112 "请指定有效的文件名。" + IDS_4113 "已创建磁盘镜像" + IDS_4114 "请确定此文件已存在并可读取。" + IDS_4115 "请确定此文件保存在可写目录中。" IDS_4116 "磁盘镜像太大" - IDS_4117 "请记得为新创建的镜像分区并格式化." - IDS_4118 "选定的文件将被覆盖. 您确定继续使用此文件吗?" + IDS_4117 "请记得为新创建的镜像分区并格式化。" + IDS_4118 "选定的文件将被覆盖。确定继续使用此文件吗?" IDS_4119 "不支持的磁盘镜像" IDS_4120 "覆盖" IDS_4121 "不覆盖" @@ -570,9 +572,9 @@ BEGIN IDS_4129 "小块 (512 KB)" IDS_4130 "VHD 文件 (*.VHD)\0*.VHD\0所有文件 (*.*)\0*.*\0" IDS_4131 "选择父 VHD 文件" - IDS_4132 "这可能因为在创建差异镜像后修改了父映像. \n\n如果镜像文件被移动或复制, 或由于创建此磁盘的程序中的错误, 也可能发生这种情况. \n\n是否需要修复时间戳?" - IDS_4133 "父盘与子盘的时间戳不匹配." - IDS_4134 "无法固定 VHD 时间戳." + IDS_4132 "父映像可能在创建差异镜像后被修改。\n\n如果镜像文件被移动或复制,或创建此磁盘的程序中存在错误,也可能发生这种情况。\n\n是否需要修复时间戳?" + IDS_4133 "父盘与子盘的时间戳不匹配" + IDS_4134 "无法修复 VHD 时间戳。" IDS_4135 "%01i:%02i" IDS_4352 "MFM/RLL" @@ -589,7 +591,7 @@ BEGIN IDS_4612 "ATAPI (%01i:%01i)" IDS_4613 "SCSI (%01i:%02i)" - IDS_5120 "CD-ROM %i (%s): %s" + IDS_5120 "光盘 %i (%s): %s" IDS_5376 "禁用" IDS_5381 "ATAPI" @@ -613,21 +615,21 @@ BEGIN IDS_5899 "2.88 MB" IDS_5900 "ZIP 100" IDS_5901 "ZIP 250" - IDS_5902 "3.5"" 128Mb M.O. (ISO 10090)" - IDS_5903 "3.5"" 230Mb M.O. (ISO 13963)" - IDS_5904 "3.5"" 540Mb M.O. (ISO 15498)" - IDS_5905 "3.5"" 640Mb M.O. (ISO 15498)" - IDS_5906 "3.5"" 1.3Gb M.O. (GigaMO)" - IDS_5907 "3.5"" 2.3Gb M.O. (GigaMO 2)" - IDS_5908 "5.25"" 600Mb M.O." - IDS_5909 "5.25"" 650Mb M.O." - IDS_5910 "5.25"" 1Gb M.O." - IDS_5911 "5.25"" 1.3Gb M.O." + IDS_5902 "3.5 英寸 128Mb 磁光盘 (ISO 10090)" + IDS_5903 "3.5 英寸 230Mb 磁光盘 (ISO 13963)" + IDS_5904 "3.5 英寸 540Mb 磁光盘 (ISO 15498)" + IDS_5905 "3.5 英寸 640Mb 磁光盘 (ISO 15498)" + IDS_5906 "3.5 英寸 1.3Gb 磁光盘 (GigaMO)" + IDS_5907 "3.5 英寸 2.3Gb 磁光盘 (GigaMO 2)" + IDS_5908 "5.25 英寸 600Mb 磁光盘" + IDS_5909 "5.25 英寸 650Mb 磁光盘" + IDS_5910 "5.25 英寸 1Gb 磁光盘" + IDS_5911 "5.25 英寸 1.3Gb 磁光盘" - IDS_6144 "完美转速(RPM)" - IDS_6145 "低于完美转速 1%%" - IDS_6146 "低于完美转速 1.5%%" - IDS_6147 "低于完美转速 2%%" + IDS_6144 "标准转速 (RPM)" + IDS_6145 "低于标准转速的 1%%" + IDS_6146 "低于标准转速的 1.5%%" + IDS_6147 "低于标准转速的 2%%" IDS_7168 "(系统默认)" END diff --git a/src/win/win.c b/src/win/win.c index d2a5003ec..7f35f6d0b 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -35,6 +35,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/config.h> @@ -46,7 +47,6 @@ #include <86box/video.h> #define GLOBAL #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/ui.h> #ifdef USE_VNC # include <86box/vnc.h> @@ -249,28 +249,28 @@ has_language_changed(uint32_t id) void set_language(uint32_t id) { - if (id == 0xFFFF) - { - set_language(lang_sys); - lang_id = id; - return; - } - + if (id == 0xFFFF) { + set_language(lang_sys); + lang_id = id; + return; + } + if (lang_id != id) { - /* Set our new language ID. */ - lang_id = id; - SetThreadUILanguage(lang_id); + /* Set our new language ID. */ + lang_id = id; + SetThreadUILanguage(lang_id); - /* Load the strings table for this ID. */ - LoadCommonStrings(); + /* Load the strings table for this ID. */ + LoadCommonStrings(); - /* Reload main menu */ - menuMain = LoadMenu(hinstance, L"MainMenu"); + /* Reload main menu */ + menuMain = LoadMenu(hinstance, L"MainMenu"); + if (hwndMain != NULL) SetMenu(hwndMain, menuMain); - - /* Re-init all the menus */ - ResetAllMenus(); - media_menu_init(); + + /* Re-init all the menus */ + ResetAllMenus(); + media_menu_init(); } } @@ -550,12 +550,11 @@ main_thread(void *param) // Sleep(1); /* If needed, handle a screen resize. */ - if (doresize && !video_fullscreen && !is_quit) { + if (!atomic_flag_test_and_set(&doresize) && !video_fullscreen && !is_quit) { if (vid_resize & 2) plat_resize(fixed_size_x, fixed_size_y); else plat_resize(scrnsz_x, scrnsz_y); - doresize = 0; } } @@ -1162,7 +1161,7 @@ plat_setfullscreen(int on) video_fullscreen &= 1; video_force_resize_set(1); if (!(on & 1)) - doresize = 1; + atomic_flag_clear(&doresize); win_mouse_init(); diff --git a/src/win/win_devconf.c b/src/win/win_devconf.c index 0ca76c8d8..4f4ddc639 100644 --- a/src/win/win_devconf.c +++ b/src/win/win_devconf.c @@ -25,7 +25,7 @@ #include <86box/config.h> #include <86box/device.h> #include <86box/plat.h> -#include <86box/plat_midi.h> +#include <86box/midi_rtmidi.h> #include <86box/ui.h> #include <86box/win.h> #include @@ -97,9 +97,9 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) val_int = config_get_int((char *) config_device.name, (char *) config->name, config->default_int); - num = plat_midi_get_num_devs(); + num = rtmidi_get_num_devs(); for (c = 0; c < num; c++) { - plat_midi_get_dev_name(c, s); + rtmidi_get_dev_name(c, s); mbstowcs(lptsTemp, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); if (val_int == c) @@ -112,9 +112,9 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) val_int = config_get_int((char *) config_device.name, (char *) config->name, config->default_int); - num = plat_midi_in_get_num_devs(); + num = rtmidi_in_get_num_devs(); for (c = 0; c < num; c++) { - plat_midi_in_get_dev_name(c, s); + rtmidi_in_get_dev_name(c, s); mbstowcs(lptsTemp, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); if (val_int == c) diff --git a/src/win/win_dialog.c b/src/win/win_dialog.c index 6f37f46b0..c7d07955d 100644 --- a/src/win/win_dialog.c +++ b/src/win/win_dialog.c @@ -172,6 +172,7 @@ file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, WCHAR *title, int save) * Set lpstrFile[0] to '\0' so that GetOpenFileName does * not use the contents of szFile to initialize itself. */ + memset(ofn.lpstrFile, 0x00, 512 * sizeof(WCHAR)); memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); ofn.nMaxFile = sizeof_w(wopenfilestring); ofn.lpstrFilter = f; diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index cb50a418f..cf7974dd4 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -24,8 +24,8 @@ #include <86box/zip.h> #include <86box/win.h> -#define MACHINE_HAS_IDE (machines[machine].flags & MACHINE_IDE_QUAD) -#define MACHINE_HAS_SCSI (machines[machine].flags & MACHINE_SCSI_DUAL) +#define MACHINE_HAS_IDE (machine_has_flags(machine, MACHINE_IDE_QUAD)) +#define MACHINE_HAS_SCSI (machine_has_flags(machine, MACHINE_SCSI_DUAL)) #define CASSETTE_FIRST 0 #define CARTRIDGE_FIRST CASSETTE_FIRST + 1 @@ -403,7 +403,7 @@ media_menu_load_submenus() static inline int is_valid_cartridge(void) { - return ((machines[machine].flags & MACHINE_CARTRIDGE) ? 1 : 0); + return (machine_has_cartridge(machine)); } @@ -417,7 +417,9 @@ is_valid_fdd(int i) static inline int is_valid_cdrom(int i) { - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !MACHINE_HAS_IDE && + memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && + memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) return 0; if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && @@ -430,7 +432,9 @@ is_valid_cdrom(int i) static inline int is_valid_zip(int i) { - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !MACHINE_HAS_IDE && + memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && + memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) return 0; if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && @@ -443,7 +447,9 @@ is_valid_zip(int i) static inline int is_valid_mo(int i) { - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE && memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !MACHINE_HAS_IDE && + memcmp(hdc_get_internal_name(hdc_current), "xtide", 5) && + memcmp(hdc_get_internal_name(hdc_current), "ide", 3)) return 0; if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !MACHINE_HAS_SCSI && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && diff --git a/src/win/win_opengl.c b/src/win/win_opengl.c index 69190b6b1..4f328c097 100644 --- a/src/win/win_opengl.c +++ b/src/win/win_opengl.c @@ -56,15 +56,16 @@ typedef LONG atomic_flag; #include <86box/plat.h> #include <86box/video.h> #include <86box/win.h> +#include <86box/language.h> #include <86box/win_opengl.h> #include <86box/win_opengl_glslp.h> static const int INIT_WIDTH = 640; static const int INIT_HEIGHT = 400; -static const int BUFFERPIXELS = 4460544; /* Same size as render_buffer, pow(2048+64,2). */ -static const int BUFFERBYTES = 17842176; /* Pixel is 4 bytes. */ +static const int BUFFERPIXELS = 4194304; /* Same size as render_buffer, pow(2048+64,2). */ +static const int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */ static const int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */ -static const int ROW_LENGTH = 2112; /* Source buffer row lenght (including padding) */ +static const int ROW_LENGTH = 2048; /* Source buffer row lenght (including padding) */ /** * @brief A dedicated OpenGL thread. @@ -445,7 +446,9 @@ static void opengl_fail() window = NULL; } - /* TODO: Notify user. */ + wchar_t* message = plat_get_string(IDS_2152); + wchar_t* header = plat_get_string(IDS_2153); + MessageBox(parent, header, message, MB_OK); WaitForSingleObject(sync_objects.closing, INFINITE); @@ -473,10 +476,10 @@ static void opengl_main(void* param) SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); /* Is this actually doing anything...? */ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - if (GLAD_GL_ARB_debug_output) + if (GLAD_GL_ARB_debug_output && log_path[0] != '\0') SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG | SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); else SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); @@ -526,8 +529,8 @@ static void opengl_main(void* param) SDL_GL_DeleteContext(context); opengl_fail(); } - - if (GLAD_GL_ARB_debug_output) + + if (GLAD_GL_ARB_debug_output && log_path[0] != '\0') { glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); glDebugMessageControlARB(GL_DONT_CARE, GL_DEBUG_TYPE_PERFORMANCE_ARB, GL_DONT_CARE, 0, 0, GL_FALSE); @@ -539,6 +542,33 @@ static void opengl_main(void* param) pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + /* Check that the driver actually reports version 3.0 or later */ + GLint major = -1; + glGetIntegerv(GL_MAJOR_VERSION, &major); + if (major < 3) + { + pclog("OpenGL: Minimum OpenGL version 3.0 is required.\n"); + SDL_GL_DeleteContext(context); + opengl_fail(); + } + + /* Check if errors have been generated at this point */ + GLenum gl_error = glGetError(); + if (gl_error != GL_NO_ERROR) + { + /* Log up to 10 errors */ + int i = 0; + do + { + pclog("OpenGL: Error %u\n", gl_error); + i++; + } + while((gl_error = glGetError()) != GL_NO_ERROR && i < 10); + + SDL_GL_DeleteContext(context); + opengl_fail(); + } + gl_identifiers gl = { 0 }; if (!initialize_glcontext(&gl)) @@ -592,14 +622,17 @@ static void opengl_main(void* param) } } - /* Check if commands that use buffers have been completed. */ - for (int i = 0; i < BUFFERCOUNT; i++) + if (GLAD_GL_ARB_sync) { - if (blit_info[i].sync != NULL && glClientWaitSync(blit_info[i].sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_TIMEOUT_EXPIRED) + /* Check if commands that use buffers have been completed. */ + for (int i = 0; i < BUFFERCOUNT; i++) { - glDeleteSync(blit_info[i].sync); - blit_info[i].sync = NULL; - atomic_flag_clear(&blit_info[i].in_use); + if (blit_info[i].sync != NULL && glClientWaitSync(blit_info[i].sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0) != GL_TIMEOUT_EXPIRED) + { + glDeleteSync(blit_info[i].sync); + blit_info[i].sync = NULL; + atomic_flag_clear(&blit_info[i].in_use); + } } } @@ -653,8 +686,17 @@ static void opengl_main(void* param) glPixelStorei(GL_UNPACK_ROW_LENGTH, ROW_LENGTH); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info->w, info->h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); - /* Add fence to track when above gl commands are complete. */ - info->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + if (GLAD_GL_ARB_sync) + { + /* Add fence to track when above gl commands are complete. */ + info->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + } + else + { + /* No sync objects; block until commands are complete. */ + glFinish(); + atomic_flag_clear(&info->in_use); + } read_pos = (read_pos + 1) % BUFFERCOUNT; @@ -788,10 +830,13 @@ static void opengl_main(void* param) SDL_ShowCursor(show_cursor); } - for (int i = 0; i < BUFFERCOUNT; i++) + if (GLAD_GL_ARB_sync) { - if (blit_info[i].sync != NULL) - glDeleteSync(blit_info[i].sync); + for (int i = 0; i < BUFFERCOUNT; i++) + { + if (blit_info[i].sync != NULL) + glDeleteSync(blit_info[i].sync); + } } finalize_glcontext(&gl); @@ -902,7 +947,7 @@ void opengl_close(void) SetEvent(sync_objects.closing); - thread_wait(thread, -1); + thread_wait(thread); thread_close_mutex(resize_info.mutex); thread_close_mutex(options.mutex); diff --git a/src/win/win_opengl_glslp.c b/src/win/win_opengl_glslp.c index 0dff03be9..0537da899 100644 --- a/src/win/win_opengl_glslp.c +++ b/src/win/win_opengl_glslp.c @@ -43,7 +43,7 @@ /** * @brief Default vertex shader. */ -static const GLchar* vertex_shader = "#version 330 core\n\ +static const GLchar* vertex_shader = "#version 130\n\ in vec2 VertexCoord;\n\ in vec2 TexCoord;\n\ out vec2 tex;\n\ @@ -55,7 +55,7 @@ void main(){\n\ /** * @brief Default fragment shader. */ -static const GLchar* fragment_shader = "#version 330 core\n\ +static const GLchar* fragment_shader = "#version 130\n\ in vec2 tex;\n\ uniform sampler2D texsampler;\n\ out vec4 color;\n\ @@ -173,17 +173,45 @@ GLuint load_custom_shaders(const char* path) { int success = 1; - const char* vertex_sources[2] = { "#version 330 core\n#define VERTEX\n", shader }; - const char* fragment_sources[2] = { "#version 330 core\n#define FRAGMENT\n", shader }; + const char* vertex_sources[3] = { "#version 130\n", "#define VERTEX\n", shader }; + const char* fragment_sources[3] = { "#version 130\n", "#define FRAGMENT\n", shader }; + + /* Check if the shader program defines version directive */ + char* version_start = strstr(shader, "#version"); + + /* If the shader program contains a version directive, + it must be captured and placed as the first statement. */ + if (version_start != NULL) + { + /* Version directive found, search the line end */ + char* version_end = strchr(version_start, '\n'); + + if (version_end != NULL) + { + char version[30] = ""; + + size_t version_len = MIN(version_end - version_start + 1, 29); + + strncat(version, version_start, version_len); + + /* replace the default version directive */ + vertex_sources[0] = version; + fragment_sources[0] = version; + } + + /* Comment out the original version directive + as only one is allowed. */ + memset(version_start, '/', 2); + } GLuint vertex_id = glCreateShader(GL_VERTEX_SHADER); GLuint fragment_id = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(vertex_id, 2, vertex_sources, NULL); + glShaderSource(vertex_id, 3, vertex_sources, NULL); glCompileShader(vertex_id); success *= check_status(vertex_id, OPENGL_BUILD_TARGET_VERTEX, path); - glShaderSource(fragment_id, 2, fragment_sources, NULL); + glShaderSource(fragment_id, 3, fragment_sources, NULL); glCompileShader(fragment_id); success *= check_status(fragment_id, OPENGL_BUILD_TARGET_FRAGMENT, path); diff --git a/src/win/win_preferences.c b/src/win/win_preferences.c index 6bec48282..0c3e95892 100644 --- a/src/win/win_preferences.c +++ b/src/win/win_preferences.c @@ -193,8 +193,9 @@ preferences_settings_save(void) /* Update status bar */ config_changed = 1; - ui_sb_set_ready(0); + ui_sb_set_ready(-1); ui_sb_update_panes(); + ui_sb_update_text(); /* Save the language changes */ config_save(); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index af876540d..3a898f43c 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -244,10 +244,10 @@ sdl_blit(int x, int y, int w, int h) SDL_LockTexture(sdl_tex, 0, &pixeldata, &pitch); - video_copy(pixeldata, &(buffer32->line[y][x]), h * (2048 + 64) * sizeof(uint32_t)); + video_copy(pixeldata, &(buffer32->line[y][x]), h * 2048 * sizeof(uint32_t)); if (screenshots) - video_screenshot((uint32_t *) pixeldata, 0, 0, (2048 + 64)); + video_screenshot((uint32_t *) pixeldata, 0, 0, 2048); SDL_UnlockTexture(sdl_tex); @@ -358,7 +358,7 @@ sdl_init_texture(void) sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE); sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, (2048 + 64), (2048 + 64)); + SDL_TEXTUREACCESS_STREAMING, 2048, 2048); } diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 4d253d8f7..2f2324e2e 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -64,7 +64,6 @@ #include <86box/snd_mpu401.h> #include <86box/video.h> #include <86box/plat.h> -#include <86box/plat_midi.h> #include <86box/ui.h> #include <86box/win.h> #include "../disk/minivhd/minivhd.h" @@ -318,7 +317,7 @@ win_settings_init(void) int i = 0; /* Machine category */ - temp_machine_type = machines[machine].type; + temp_machine_type = machine_get_type(machine); temp_machine = machine; temp_cpu_f = cpu_f; temp_wait_states = cpu_waitstates; @@ -786,13 +785,13 @@ win_settings_machine_recalc_machine(HWND hdlg) win_settings_machine_recalc_cpu_m(hdlg); - if ((machines[temp_machine].ram_granularity & 1023)) { + if (machine_get_ram_granularity(temp_machine) & 1023) { /* KB granularity */ h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (machines[temp_machine].min_ram << 16) | machines[temp_machine].max_ram); + SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 16) | machine_get_max_ram(temp_machine)); accel.nSec = 0; - accel.nInc = machines[temp_machine].ram_granularity; + accel.nInc = machine_get_ram_granularity(temp_machine); SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); SendMessage(h, UDM_SETPOS, 0, temp_mem_size); @@ -802,15 +801,10 @@ win_settings_machine_recalc_machine(HWND hdlg) } else { /* MB granularity */ h = GetDlgItem(hdlg, IDC_MEMSPIN); -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - i = MIN(machines[temp_machine].max_ram, 2097152); -#else - i = MIN(machines[temp_machine].max_ram, 3145728); -#endif - SendMessage(h, UDM_SETRANGE, 0, (machines[temp_machine].min_ram << 6) | (i >> 10)); + SendMessage(h, UDM_SETRANGE, 0, (machine_get_min_ram(temp_machine) << 6) | (machine_get_max_ram(temp_machine) >> 10)); accel.nSec = 0; - accel.nInc = machines[temp_machine].ram_granularity >> 10; + accel.nInc = machine_get_ram_granularity(temp_machine) >> 10; SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); @@ -820,8 +814,8 @@ win_settings_machine_recalc_machine(HWND hdlg) SendMessage(h, WM_SETTEXT, 0, win_get_string(IDS_2086)); } - settings_enable_window(hdlg, IDC_MEMSPIN, machines[temp_machine].min_ram != machines[temp_machine].max_ram); - settings_enable_window(hdlg, IDC_MEMTEXT, machines[temp_machine].min_ram != machines[temp_machine].max_ram); + settings_enable_window(hdlg, IDC_MEMSPIN, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); + settings_enable_window(hdlg, IDC_MEMTEXT, machine_get_min_ram(temp_machine) != machine_get_max_ram(temp_machine)); free(lptsTemp); } @@ -844,7 +838,7 @@ machine_type_available(int id) if ((id > 0) && (id < MACHINE_TYPE_MAX)) { while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machines[c].type == id)) + if (machine_available(c) && (machine_get_type(c) == id)) return 1; c++; } @@ -891,8 +885,8 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_reset_content(hdlg, IDC_COMBO_MACHINE); memset(listtomachine, 0x00, sizeof(listtomachine)); while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machines[c].type == temp_machine_type)) { - stransi = (char *)machines[c].name; + if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { + stransi = machine_getname_ex(c); mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); listtomachine[d] = c; @@ -946,8 +940,8 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) c = d = 0; memset(listtomachine, 0x00, sizeof(listtomachine)); while (machine_get_internal_name_ex(c) != NULL) { - if (machine_available(c) && (machines[c].type == temp_machine_type)) { - stransi = (char *)machines[c].name; + if (machine_available(c) && (machine_get_type(c) == temp_machine_type)) { + stransi = machine_getname_ex(c); mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); settings_add_string(hdlg, IDC_COMBO_MACHINE, (LPARAM) lptsTemp); listtomachine[d] = c; @@ -1023,13 +1017,13 @@ win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); wcstombs(stransi, lptsTemp, 512); sscanf(stransi, "%u", &temp_mem_size); - if (!(machines[temp_machine].ram_granularity & 1023)) + if (!(machine_get_ram_granularity(temp_machine) & 1023)) temp_mem_size = temp_mem_size << 10; - temp_mem_size &= ~(machines[temp_machine].ram_granularity - 1); - if (temp_mem_size < machines[temp_machine].min_ram) - temp_mem_size = machines[temp_machine].min_ram; - else if (temp_mem_size > machines[temp_machine].max_ram) - temp_mem_size = machines[temp_machine].max_ram; + temp_mem_size &= ~(machine_get_ram_granularity(temp_machine) - 1); + if (temp_mem_size < machine_get_min_ram(temp_machine)) + temp_mem_size = machine_get_min_ram(temp_machine); + else if (temp_mem_size > machine_get_max_ram(temp_machine)) + temp_mem_size = machine_get_max_ram(temp_machine); free(stransi); free(lptsTemp); @@ -1080,7 +1074,7 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) while (1) { /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !(machines[temp_machine].flags & MACHINE_VIDEO)) { + if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_VIDEO)) { c++; continue; } @@ -1091,7 +1085,7 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; if (video_card_available(c) && - device_is_valid(video_card_getdevice(c), machines[temp_machine].flags)) { + device_is_valid(video_card_getdevice(c), temp_machine)) { if (c == 0) settings_add_string(hdlg, IDC_COMBO_VIDEO, win_get_string(IDS_2103)); else if (c == 1) @@ -1109,12 +1103,12 @@ win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_process_messages(); } - settings_enable_window(hdlg, IDC_COMBO_VIDEO, !(machines[temp_machine].flags & MACHINE_VIDEO_ONLY)); + settings_enable_window(hdlg, IDC_COMBO_VIDEO, !machine_has_flags(temp_machine, MACHINE_VIDEO_ONLY)); e = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_VIDEO)]; settings_enable_window(hdlg, IDC_CONFIGURE_VID, video_card_has_config(e)); - settings_enable_window(hdlg, IDC_CHECK_VOODOO, (machines[temp_machine].flags & MACHINE_BUS_PCI)); + settings_enable_window(hdlg, IDC_CHECK_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI)); settings_set_check(hdlg, IDC_CHECK_VOODOO, temp_voodoo); - settings_enable_window(hdlg, IDC_BUTTON_VOODOO, (machines[temp_machine].flags & MACHINE_BUS_PCI) && temp_voodoo); + settings_enable_window(hdlg, IDC_BUTTON_VOODOO, machine_has_bus(temp_machine, MACHINE_BUS_PCI) && temp_voodoo); return TRUE; case WM_COMMAND: @@ -1157,10 +1151,10 @@ mouse_valid(int num, int m) const device_t *dev; if ((num == MOUSE_TYPE_INTERNAL) && - !(machines[m].flags & MACHINE_MOUSE)) return(0); + !machine_has_flags(m, MACHINE_MOUSE)) return(0); dev = mouse_get_device(num); - return(device_is_valid(dev, machines[m].flags)); + return(device_is_valid(dev, m)); } @@ -1264,6 +1258,9 @@ mpu401_standalone_allow(void) { char *md, *mdin; + if (!machine_has_bus(temp_machine, MACHINE_BUS_ISA) && !machine_has_bus(temp_machine, MACHINE_BUS_MCA)) + return 0; + md = midi_device_get_internal_name(temp_midi_device); mdin = midi_in_device_get_internal_name(temp_midi_input_device); @@ -1294,7 +1291,7 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_reset_content(hdlg, IDC_COMBO_SOUND); while (1) { /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !(machines[temp_machine].flags & MACHINE_SOUND)) { + if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_SOUND)) { c++; continue; } @@ -1307,7 +1304,7 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (sound_card_available(c)) { sound_dev = sound_card_getdevice(c); - if (device_is_valid(sound_dev, machines[temp_machine].flags)) { + if (device_is_valid(sound_dev, temp_machine)) { if (c == 0) settings_add_string(hdlg, IDC_COMBO_SOUND, win_get_string(IDS_2103)); else if (c == 1) @@ -1377,15 +1374,15 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_set_check(hdlg, IDC_CHECK_MPU401, temp_mpu401); settings_enable_window(hdlg, IDC_CHECK_MPU401, mpu401_standalone_allow()); settings_enable_window(hdlg, IDC_CONFIGURE_MPU401, mpu401_standalone_allow() && temp_mpu401); - settings_enable_window(hdlg, IDC_CHECK_CMS, (machines[temp_machine].flags & MACHINE_BUS_ISA)); + settings_enable_window(hdlg, IDC_CHECK_CMS, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); settings_set_check(hdlg, IDC_CHECK_CMS, temp_GAMEBLASTER); - settings_enable_window(hdlg, IDC_CONFIGURE_CMS, (machines[temp_machine].flags & MACHINE_BUS_ISA) && temp_GAMEBLASTER); - settings_enable_window(hdlg, IDC_CHECK_GUS, (machines[temp_machine].flags & MACHINE_BUS_ISA16)); + settings_enable_window(hdlg, IDC_CONFIGURE_CMS, machine_has_bus(temp_machine, MACHINE_BUS_ISA) && temp_GAMEBLASTER); + settings_enable_window(hdlg, IDC_CHECK_GUS, machine_has_bus(temp_machine, MACHINE_BUS_ISA16)); settings_set_check(hdlg, IDC_CHECK_GUS, temp_GUS); - settings_enable_window(hdlg, IDC_CONFIGURE_GUS, (machines[temp_machine].flags & MACHINE_BUS_ISA16) && temp_GUS); - settings_enable_window(hdlg, IDC_CHECK_SSI, (machines[temp_machine].flags & MACHINE_BUS_ISA)); + settings_enable_window(hdlg, IDC_CONFIGURE_GUS, machine_has_bus(temp_machine, MACHINE_BUS_ISA16) && temp_GUS); + settings_enable_window(hdlg, IDC_CHECK_SSI, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); settings_set_check(hdlg, IDC_CHECK_SSI, temp_SSI2001); - settings_enable_window(hdlg, IDC_CONFIGURE_SSI, (machines[temp_machine].flags & MACHINE_BUS_ISA) && temp_SSI2001); + settings_enable_window(hdlg, IDC_CONFIGURE_SSI, machine_has_bus(temp_machine, MACHINE_BUS_ISA) && temp_SSI2001); settings_set_check(hdlg, IDC_CHECK_FLOAT, temp_float); free(lptsTemp); @@ -1440,7 +1437,7 @@ win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case IDC_CONFIGURE_MPU401: - temp_deviceconfig |= deviceconfig_open(hdlg, (machines[temp_machine].flags & MACHINE_MCA) ? + temp_deviceconfig |= deviceconfig_open(hdlg, machine_has_bus(temp_machine, MACHINE_BUS_MCA) ? (void *)&mpu401_mca_device : (void *)&mpu401_device); break; @@ -1589,7 +1586,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) settings_reset_content(hdlg, IDC_COMBO_HDC); while (1) { /* Skip "internal" if machine doesn't have it. */ - if ((c == 1) && !(machines[temp_machine].flags & MACHINE_HDC)) { + if ((c == 1) && !machine_has_flags(temp_machine, MACHINE_HDC)) { c++; continue; } @@ -1602,7 +1599,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (hdc_available(c)) { hdc_dev = hdc_get_device(c); - if (device_is_valid(hdc_dev, machines[temp_machine].flags)) { + if (device_is_valid(hdc_dev, temp_machine)) { if (c == 0) settings_add_string(hdlg, IDC_COMBO_HDC, win_get_string(IDS_2103)); else if (c == 1) @@ -1634,7 +1631,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (fdc_card_available(c)) { fdc_dev = fdc_card_getdevice(c); - if (device_is_valid(fdc_dev, machines[temp_machine].flags)) { + if (device_is_valid(fdc_dev, temp_machine)) { if (c == 0) settings_add_string(hdlg, IDC_COMBO_FDC, win_get_string(IDS_2118)); else @@ -1665,7 +1662,7 @@ win_settings_storage_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (scsi_card_available(c)) { scsi_dev = scsi_card_getdevice(c); - if (device_is_valid(scsi_dev, machines[temp_machine].flags)) { + if (device_is_valid(scsi_dev, temp_machine)) { for (e = 0; e < SCSI_BUS_MAX; e++) { if (c == 0) settings_add_string(hdlg, IDC_COMBO_SCSI_1 + e, win_get_string(IDS_2103)); @@ -1823,7 +1820,7 @@ win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) if (device_name[0] == L'\0') break; - if (network_card_available(c) && device_is_valid(network_card_getdevice(c), machines[temp_machine].flags)) { + if (network_card_available(c) && device_is_valid(network_card_getdevice(c), temp_machine)) { if (c == 0) settings_add_string(hdlg, IDC_COMBO_NET, win_get_string(IDS_2103)); else @@ -4908,21 +4905,25 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa if (!device_name[0]) break; - - if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2103)); - settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0); - } else - settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name); - settings_list_to_device[1][e] = d; - if (d == temp_isartc) - settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e); - e++; + dev = isartc_get_device(d); + if (device_is_valid(dev, temp_machine)) { + if (d == 0) { + settings_add_string(hdlg, IDC_COMBO_ISARTC, win_get_string(IDS_2103)); + settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, 0); + } else + settings_add_string(hdlg, IDC_COMBO_ISARTC, (LPARAM) device_name); + settings_list_to_device[1][e] = d; + if (d == temp_isartc) + settings_set_cur_sel(hdlg, IDC_COMBO_ISARTC, e); + e++; + } } - settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, temp_isartc != 0); + settings_enable_window(hdlg, IDC_COMBO_ISARTC, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); + settings_enable_window(hdlg, IDC_CONFIGURE_ISARTC, ((temp_isartc != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); /* Populate the ISA memory card dropdowns. */ for (c = 0; c < ISAMEM_MAX; c++) { + e = 0; settings_reset_content(hdlg, IDC_COMBO_ISAMEM_1 + c); for (d = 0; ; d++) { generate_device_name(isamem_get_device(d), (char *) isamem_get_internal_name(d), 0); @@ -4930,16 +4931,24 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa if (!device_name[0]) break; - if (d == 0) { - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2103)); - settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0); - } else - settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name); + dev = isamem_get_device(d); + if (device_is_valid(dev, temp_machine)) { + if (d == 0) { + settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, win_get_string(IDS_2103)); + settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, 0); + } else + settings_add_string(hdlg, IDC_COMBO_ISAMEM_1 + c, (LPARAM) device_name); + settings_list_to_device[0][e] = d; + if (d == temp_isamem[c]) + settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, e); + e++; + } } - settings_set_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c, temp_isamem[c]); - settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0); + settings_enable_window(hdlg, IDC_COMBO_ISAMEM_1 + c, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); + settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, ((temp_isamem[c] != 0) && machine_has_bus(temp_machine, MACHINE_BUS_ISA))); } + settings_enable_window(hdlg, IDC_CHECK_BUGGER, machine_has_bus(temp_machine, MACHINE_BUS_ISA)); settings_set_check(hdlg, IDC_CHECK_BUGGER, temp_bugger); settings_set_check(hdlg, IDC_CHECK_POSTCARD, temp_postcard); @@ -4963,21 +4972,23 @@ win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lPa case IDC_COMBO_ISAMEM_1: case IDC_COMBO_ISAMEM_2: case IDC_COMBO_ISAMEM_3: case IDC_COMBO_ISAMEM_4: c = LOWORD(wParam) - IDC_COMBO_ISAMEM_1; - temp_isamem[c] = settings_get_cur_sel(hdlg, LOWORD(wParam)); + temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, LOWORD(wParam))]; settings_enable_window(hdlg, IDC_CONFIGURE_ISAMEM_1 + c, temp_isamem[c] != 0); break; case IDC_CONFIGURE_ISAMEM_1: case IDC_CONFIGURE_ISAMEM_2: case IDC_CONFIGURE_ISAMEM_3: case IDC_CONFIGURE_ISAMEM_4: c = LOWORD(wParam) - IDC_CONFIGURE_ISAMEM_1; - dev = isamem_get_device(temp_isamem[c]); - temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *)dev, c + 1); + temp_deviceconfig |= deviceconfig_inst_open(hdlg, (void *)isamem_get_device(temp_isamem[c]), c + 1); break; } return FALSE; case WM_SAVESETTINGS: temp_isartc = settings_list_to_device[1][settings_get_cur_sel(hdlg, IDC_COMBO_ISARTC)]; + for (c = 0; c < ISAMEM_MAX; c++) { + temp_isamem[c] = settings_list_to_device[0][settings_get_cur_sel(hdlg, IDC_COMBO_ISAMEM_1 + c)]; + } temp_bugger = settings_get_check(hdlg, IDC_CHECK_BUGGER); temp_postcard = settings_get_check(hdlg, IDC_CHECK_POSTCARD); diff --git a/src/win/win_specify_dim.c b/src/win/win_specify_dim.c index d4727c68b..96ae0403c 100644 --- a/src/win/win_specify_dim.c +++ b/src/win/win_specify_dim.c @@ -133,7 +133,7 @@ SpecifyDimensionsDialogProcedure(HWND hdlg, UINT message, WPARAM wParam, LPARAM scrnsz_x = fixed_size_x; scrnsz_y = fixed_size_y; - doresize = 1; + atomic_flag_clear(&doresize); GetWindowRect(hwndMain, &r); diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index 17178a6bf..afc906215 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -485,6 +485,9 @@ StatusBarDestroyTips(void) /* API: mark the status bar as not ready. */ +/* Values: -1 - not ready, but don't clear POST text + 0 - not ready + 1 - ready */ void ui_sb_set_ready(int ready) { @@ -493,6 +496,9 @@ ui_sb_set_ready(int ready) ui_sb_set_text(NULL); } + if (ready == -1) + ready = 0; + sb_ready = ready; } @@ -516,12 +522,12 @@ ui_sb_update_panes(void) sb_ready = 0; } - cart_int = (machines[machine].flags & MACHINE_CARTRIDGE) ? 1 : 0; - mfm_int = (machines[machine].flags & MACHINE_MFM) ? 1 : 0; - xta_int = (machines[machine].flags & MACHINE_XTA) ? 1 : 0; - esdi_int = (machines[machine].flags & MACHINE_ESDI) ? 1 : 0; - ide_int = (machines[machine].flags & MACHINE_IDE_QUAD) ? 1 : 0; - scsi_int = (machines[machine].flags & MACHINE_SCSI_DUAL) ? 1 : 0; + cart_int = machine_has_cartridge(machine) ? 1 : 0; + mfm_int = machine_has_flags(machine, MACHINE_MFM) ? 1 : 0; + xta_int = machine_has_flags(machine, MACHINE_XTA) ? 1 : 0; + esdi_int = machine_has_flags(machine, MACHINE_ESDI) ? 1 : 0; + ide_int = machine_has_flags(machine, MACHINE_IDE_QUAD) ? 1 : 0; + scsi_int = machine_has_flags(machine, MACHINE_SCSI_DUAL) ? 1 : 0; c_mfm = hdd_count(HDD_BUS_MFM); c_esdi = hdd_count(HDD_BUS_ESDI); @@ -567,7 +573,7 @@ ui_sb_update_panes(void) for (i=0; i #include <86box/video.h> #include <86box/vid_ega.h> // for update_overscan -#include <86box/plat_midi.h> #include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/win.h> @@ -54,8 +53,8 @@ /* Platform Public data, specific. */ -HWND hwndMain, /* application main window */ - hwndRender; /* machine render window */ +HWND hwndMain = NULL, /* application main window */ + hwndRender = NULL; /* machine render window */ HMENU menuMain; /* application main menu */ RECT oldclip; /* mouse rect */ int sbar_height = 23; /* statusbar height */ @@ -672,7 +671,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) scrnsz_x = unscaled_size_x; scrnsz_y = unscaled_size_y; - doresize = 1; + atomic_flag_clear(&doresize); config_save(); break; @@ -771,7 +770,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) reset_screen_size(); device_force_redraw(); video_force_resize_set(1); - doresize = 1; + atomic_flag_clear(&doresize); config_save(); break; @@ -786,7 +785,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_VID_HIDPI: dpi_scale = !dpi_scale; CheckMenuItem(hmenu, IDM_VID_HIDPI, dpi_scale ? MF_CHECKED : MF_UNCHECKED); - doresize = 1; + atomic_flag_clear(&doresize); config_save(); break; @@ -947,7 +946,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) else ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); } else if (!user_resize) - doresize = 1; + atomic_flag_clear(&doresize); break; case WM_WINDOWPOSCHANGED: @@ -992,13 +991,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (temp_x != scrnsz_x || temp_y != scrnsz_y) { scrnsz_x = temp_x; scrnsz_y = temp_y; - doresize = 1; + atomic_flag_clear(&doresize); } } else { if (rect.right != scrnsz_x || rect.bottom != scrnsz_y) { scrnsz_x = rect.right; scrnsz_y = rect.bottom; - doresize = 1; + atomic_flag_clear(&doresize); } } @@ -1160,7 +1159,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* If window is not resizable, then tell the main thread to resize it, as sometimes, moves can mess up the window size. */ if (!vid_resize) - doresize = 1; + atomic_flag_clear(&doresize); break; } @@ -1587,6 +1586,10 @@ plat_pause(int p) ui_window_title(oldtitle); } + /* If un-pausing, synchronize the internal clock with the host's time. */ + if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) + nvr_time_sync(); + dopause = p; /* Update the actual menu. */ diff --git a/vcpkg.json b/vcpkg.json index d8ec1d981..cbd8a31ca 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "3.0", + "version-string": "3.1", "homepage": "https://86box.net/", "documentation": "http://86box.readthedocs.io/", "license": "GPL-2.0-only",