diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index aa0368735..120185c0f 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -22,7 +22,7 @@ on: - "!**/Makefile*" jobs: - mingw: + msys2: name: MSYS2 ${{ matrix.build.name }} build (${{ matrix.environment.msystem }}) runs-on: windows-latest @@ -35,15 +35,30 @@ jobs: fail-fast: false matrix: build: - - name: Regular + - name: Regular ODR + slug: -ODR preset: regular target: install/strip - - name: Debug + - name: Debug ODR + slug: -ODR-Debug preset: debug target: install - - name: Dev + - name: Dev ODR + slug: -ODR-Dev preset: experimental target: install + - name: Regular NDR + slug: -NDR + preset: regularndr + target: install/strip + - name: Debug NDR + slug: -NDR-Debug + preset: debugndr + target: install + - name: Dev NDR + slug: -NDR-Dev + preset: experimentalndr + target: install environment: - msystem: MINGW32 prefix: mingw-w64-i686 @@ -51,6 +66,8 @@ jobs: prefix: mingw-w64-x86_64 - msystem: UCRT64 prefix: mingw-w64-ucrt-x86_64 +# - msystem: CLANG32 +# prefix: mingw-w64-clang-i686 - msystem: CLANG64 prefix: mingw-w64-clang-x86_64 @@ -83,71 +100,155 @@ jobs: run: cmake --build build --target ${{ matrix.build.target }} - uses: actions/upload-artifact@v2 with: - name: '86Box-${{ matrix.build.name }}-MSYS2-${{ matrix.environment.msystem }}-${{ github.sha }}' + name: '86Box${{ matrix.build.slug }}-MSYS2-${{ matrix.environment.msystem }}-gha${{ github.run_number }}' path: build/artifacts/** - vs2019: - name: VS2019 ${{ matrix.build.name }} ${{ matrix.target-arch }} build (${{ matrix.toolset }}) + llvm-windows: + name: "Windows vcpkg/LLVM (${{ matrix.build.name }} ${{ matrix.target.name }})" - runs-on: windows-latest + runs-on: windows-2022 + + env: + VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite' strategy: fail-fast: false matrix: build: - - name: Debug + - name: Regular ODR + slug: -ODR + type: Release dev-build: off new-dynarec: off + strip: --strip + - name: Debug ODR + slug: -ODR-Debug + type: Debug + dev-build: off + new-dynarec: off + - name: Dev ODR + slug: -ODR-Dev + type: Debug + dev-build: on + new-dynarec: off + - name: Regular NDR + slug: -NDR + type: Release + strip: --strip + dev-build: off + new-dynarec: on + - name: Debug NDR + slug: -NDR-Debug + type: Debug + dev-build: off + new-dynarec: on + - name: Dev NDR + slug: -NDR-Dev type: Debug - - name: Dev dev-build: on new-dynarec: on - type: Debug - target-arch: ['Win32', 'x64', 'ARM64'] - toolset: ['clangcl'] + target: + - name: x86 + triplet: x86-windows-static + toolchain: cmake/llvm-win32-i686.cmake + vcvars: x64_x86 + - name: x64 + triplet: x64-windows-static + toolchain: cmake/llvm-win32-x86_64.cmake + vcvars: x64 + - name: ARM64 + triplet: arm64-windows-static + toolchain: cmake/llvm-win32-aarch64.cmake + vcvars: x64_arm64 exclude: - - target-arch: 'ARM64' - build: - new-dynarec: off + - build: + new-dynarec: off + target: + name: ARM64 steps: - uses: actions/checkout@v2 - - uses: actions/cache@v2 - with: - path: build/vcpkg_installed - key: vcpkg-${{ hashFiles('vcpkg.json') }}-${{ matrix.target-arch }} + - name: Download Ninja + run: > + Invoke-WebRequest https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip -OutFile ninja-win.zip && + Expand-Archive ninja-win.zip -DestinationPath . + - name: Setup NuGet Credentials + run: > + & (C:/vcpkg/vcpkg fetch nuget | tail -n 2) + sources add + -source "https://nuget.pkg.github.com/86Box/index.json" + -storepasswordincleartext + -name "GitHub" + -username "86Box" + -password "${{ secrets.GITHUB_TOKEN }}" + - name: vcpkg package restore + if: false + run: vcpkg install freetype libpng openal-soft sdl2 rtmidi --triplet ${{ matrix.target.triplet }} - name: Configure CMake - run: >- - cmake -S . -B build - -G "Visual Studio 16 2019" -A ${{ matrix.target-arch }} -T ${{ matrix.toolset }} - -D CMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake - -D CMAKE_INSTALL_PREFIX=./build/artifacts - -D DEV_BRANCH=${{ matrix.build.dev-build }} + run: > + call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" ${{ matrix.target.vcvars }} + + set PATH=C:/Program Files/LLVM/bin;%PATH% + + cmake -S . -B build -G Ninja -D CMAKE_BUILD_TYPE=${{ matrix.build.type }} -D NEW_DYNAREC=${{ matrix.build.new-dynarec }} - -D VNC=OFF + -D CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake + -D VCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{ github.workspace }}/${{ matrix.target.toolchain }} + -D VCPKG_TARGET_TRIPLET=${{ matrix.target.triplet }} + shell: cmd - name: Build - run: cmake --build build --config ${{ matrix.build.type }} --target install + run: | + call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" ${{ matrix.target.vcvars }} + cmake --build build + shell: cmd + - name: Generate package + run: cmake --install build --prefix ./build/artifacts ${{ matrix.build.strip }} - uses: actions/upload-artifact@v2 with: - name: '86Box-${{ matrix.build.name }}-VS2019-${{ matrix.target-arch }}-${{ matrix.toolset }}-${{ github.sha }}' + name: '86Box${{ matrix.build.slug }}-Windows-LLVM-${{ matrix.target.name }}-gha${{ github.run_number }}' path: build/artifacts/** linux: - name: "Linux GCC 11" + name: "Linux GCC 11 (${{ matrix.build.name }} x86_64)" runs-on: ubuntu-latest + strategy: fail-fast: false matrix: build: - - name: Debug + - name: Regular ODR + slug: -ODR + type: Release dev-build: off new-dynarec: off + strip: --strip + - name: Debug ODR + slug: -ODR-Debug + type: Debug + dev-build: off + new-dynarec: off + - name: Dev ODR + slug: -ODR-Dev + type: Debug + dev-build: on + new-dynarec: off + - name: Regular NDR + slug: -NDR + type: Release + strip: --strip + dev-build: off + new-dynarec: on + - name: Debug NDR + slug: -NDR-Debug + type: Debug + dev-build: off + new-dynarec: on + - name: Dev NDR + slug: -NDR-Dev type: Debug - - name: Dev dev-build: on new-dynarec: on - type: Debug steps: - uses: actions/checkout@v2 @@ -163,24 +264,55 @@ jobs: -D CMAKE_BUILD_TYPE=${{ matrix.build.type }} -D CMAKE_C_COMPILER=gcc-11 -D CMAKE_CXX_COMPILER=g++-11 - name: Build - run: cmake --build build --target install + run: cmake --build build + - name: Generate package + run: cmake --install build --prefix ./build/artifacts ${{ matrix.build.strip }} + - uses: actions/upload-artifact@v2 + with: + name: '86Box${{ matrix.build.slug }}-Linux-x86_64-gha${{ github.run_number }}' + path: build/artifacts/** - macos: - name: "macOS 11" + macos11: + name: "macOS 11 (${{ matrix.build.name }} x86_64)" runs-on: macos-11 + strategy: fail-fast: false matrix: build: - - name: Debug + - name: Regular ODR + slug: -ODR + type: Release dev-build: off new-dynarec: off + strip: --strip + - name: Debug ODR + slug: -ODR-Debug + type: Debug + dev-build: off + new-dynarec: off + - name: Dev ODR + slug: -ODR-Dev + type: Debug + dev-build: on + new-dynarec: off + - name: Regular NDR + slug: -NDR + type: Release + strip: --strip + dev-build: off + new-dynarec: on + - name: Debug NDR + slug: -NDR-Debug + type: Debug + dev-build: off + new-dynarec: on + - name: Dev NDR + slug: -NDR-Dev type: Debug - - name: Dev dev-build: on new-dynarec: on - type: Debug steps: - uses: actions/checkout@v2 @@ -189,10 +321,16 @@ jobs: - name: Configure CMake run: >- cmake -S . -B build - -D CMAKE_INSTALL_PREFIX=./build/artifacts + --toolchain cmake/flags-gcc-x86_64.cmake -D DEV_BRANCH=${{ matrix.build.dev-build }} -D NEW_DYNAREC=${{ matrix.build.new-dynarec }} -D VNC=OFF -D CMAKE_BUILD_TYPE=${{ matrix.build.type }} - name: Build - run: cmake --build build --target install + run: cmake --build build + - name: Generate package + run: cmake --install build --prefix ./build/artifacts ${{ matrix.build.strip }} + - uses: actions/upload-artifact@v2 + with: + name: '86Box${{ matrix.build.slug }}-macOS-x86_64-gha${{ github.run_number }}' + path: build/artifacts/** diff --git a/CMakeLists.txt b/CMakeLists.txt index 29e5e1a3a..ecbb4ca6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,8 +100,8 @@ set(CMAKE_CXX_STANDARD 11) # Option Description Def. # ------ ----------- ---- option(RELEASE "Release build" OFF) -option(USB "USB support" OFF) option(DYNAREC "Dynamic recompiler" ON) +option(OPENAL "OpenAL" ON) option(FLUIDSYNTH "FluidSynth" ON) option(MUNT "MUNT" ON) option(VRAMDUMP "Video RAM dumping" OFF) @@ -131,6 +131,7 @@ cmake_dependent_option(VNC "VNC renderer" cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) +cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) # Ditto but for Qt if (QT) diff --git a/CMakePresets.json b/CMakePresets.json index 2cfd8ea4a..8ff0e502c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -34,6 +34,18 @@ "NEW_DYNAREC": "OFF" } }, + { + "name": "regularndr", + "inherits": [ + "flags-base" + ], + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "DEV_BRANCH": "OFF", + "NEW_DYNAREC": "ON" + } + }, { "name": "optimized", "inherits": [ @@ -46,6 +58,18 @@ "NEW_DYNAREC": "OFF" } }, + { + "name": "optimizedndr", + "inherits": [ + "flags-base" + ], + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Optimized", + "DEV_BRANCH": "OFF", + "NEW_DYNAREC": "ON" + } + }, { "name": "debug", "inherits": [ @@ -58,12 +82,36 @@ "NEW_DYNAREC": "OFF" } }, + { + "name": "debugndr", + "inherits": [ + "flags-base" + ], + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "DEV_BRANCH": "OFF", + "NEW_DYNAREC": "ON" + } + }, { "name": "experimental", "inherits": [ "flags-base" ], "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "DEV_BRANCH": "ON", + "NEW_DYNAREC": "OFF" + } + }, + { + "name": "experimentalndr", + "inherits": [ + "flags-base" + ], + "generator": "Ninja", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "DEV_BRANCH": "ON", diff --git a/src/86box.c b/src/86box.c index 4cee64445..bdd5f4ffa 100644 --- a/src/86box.c +++ b/src/86box.c @@ -932,7 +932,9 @@ pc_reset_hard_close(void) scsi_disk_close(); +#ifdef USE_OPENAL closeal(); +#endif video_reset_close(); @@ -1046,8 +1048,12 @@ pc_reset_hard_init(void) atfullspeed = 0; pc_full_speed(); - cycles = cycles_main = 0; - + cycles = 0; + fpu_cycles = 0; +#ifdef USE_DYNAREC + cycles_main = 0; +#endif + update_mouse_msg(); } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37eb815f7..5cb90b61c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,9 +110,11 @@ if(APPLE) target_link_libraries(86Box Freetype::Freetype) endif() -find_package(OpenAL REQUIRED) -include_directories(${OPENAL_INCLUDE_DIR}) -target_link_libraries(86Box ${OPENAL_LIBRARY}) +if(OPENAL) + find_package(OpenAL REQUIRED) + include_directories(${OPENAL_INCLUDE_DIR}) + target_link_libraries(86Box ${OPENAL_LIBRARY}) +endif() find_package(SDL2 REQUIRED) include_directories(${SDL2_INCLUDE_DIRS}) diff --git a/src/cpu/386.c b/src/cpu/386.c index 298cc66fc..2358fd646 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -81,7 +81,20 @@ x386_log(const char *fmt, ...) #define OP_TABLE(name) ops_ ## name -#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES(c) \ + {\ + if (fpu_cycles > 0) {\ + fpu_cycles -= (c);\ + if (fpu_cycles < 0) {\ + cycles += fpu_cycles;\ + }\ + } else {\ + cycles -= (c);\ + }\ + } + +#define CLOCK_CYCLES_FPU(c) cycles -= (c) +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #include "x86_ops.h" diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index d11be000e..88a95637c 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -267,9 +267,22 @@ static void prefetch_flush() #define OP_TABLE(name) ops_ ## name -#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES(c) \ + {\ + if (fpu_cycles > 0) {\ + fpu_cycles -= (c);\ + if (fpu_cycles < 0) {\ + cycles += fpu_cycles;\ + }\ + } else {\ + cycles -= (c);\ + }\ + } +#define CLOCK_CYCLES_FPU(c) cycles -= (c) +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) + #include "386_ops.h" diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index ef18c2558..40aa2db80 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -65,6 +65,8 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) #define OP_TABLE(name) dynarec_ops_ ## name #define CLOCK_CYCLES(c) +#define CLOCK_CYCLES_FPU(c) +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #include "386_ops.h" diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 750335b60..827ec5b1c 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -89,11 +89,32 @@ static int refresh = 0, cycdiff; wait(val, 0); \ } -#define CLOCK_CYCLES(val) \ +#define CLOCK_CYCLES_ALWAYS(val) \ { \ wait(val, 0); \ } +#define CLOCK_CYCLES_FPU(val) \ + { \ + wait(val, 0); \ + } + + +#define CLOCK_CYCLES(val) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (val); \ + if (fpu_cycles < 0) { \ + wait(val, 0); \ + } \ + } else { \ + wait(val, 0); \ + } \ + } + +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) + + typedef int (*OpFn)(uint32_t fetchdat); diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index 543ad8ff5..20452bf88 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -13,8 +13,8 @@ # 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) +add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c + 386_dynarec.c x86seg.c x87.c x87_timings.c) if(AMD_K5) target_compile_definitions(cpu PRIVATE USE_AMD_K5) @@ -25,8 +25,10 @@ if(CYRIX_6X86) endif() if(DYNAREC) + target_sources(cpu PRIVATE 386_dynarec_ops.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 +endif() diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 2004d7336..09d26cf25 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1369,6 +1369,7 @@ cpu_set(void) case FPU_487SX: default: x87_timings = x87_timings_486; + x87_concurrency = x87_concurrency_486; } if (is386) { diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 18962bab0..690869424 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -354,7 +354,7 @@ typedef struct { uint8_t ssegs, ismmx, abrt, _smi_line; - int _cycles, _in_smm; + int _cycles, _fpu_cycles, _in_smm; uint16_t npxs, npxc; @@ -457,6 +457,7 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state_t) <= 128) #define DI cpu_state.regs[7].w #define cycles cpu_state._cycles +#define fpu_cycles cpu_state._fpu_cycles #define cpu_rm cpu_state.rm_data.rm_mod_reg.rm #define cpu_mod cpu_state.rm_data.rm_mod_reg.mod diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 4399fc4d8..7fab0869c 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -2415,7 +2415,9 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; else cpu_cur_status |= CPU_STATUS_NOTFLATDS; +#ifdef USE_DYNAREC codegen_flat_ds = 0; +#endif } if (seg == &cpu_state.seg_ss) { if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) @@ -2423,7 +2425,9 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) else cpu_cur_status |= CPU_STATUS_NOTFLATSS; set_stack32((segdat[3] & 0x40) ? 1 : 0); +#ifdef USE_DYNAREC codegen_flat_ss = 0; +#endif } } } diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 83decd4fd..5e4bfceab 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -12,7 +12,8 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ if ((cpu_state.npxc >> 10) & 3) \ fesetround(FE_TONEAREST); \ FP_TAG_VALID; \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -24,7 +25,8 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -37,7 +39,8 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ x87_pop(); \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -49,7 +52,8 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), ST(0), use_var); \ FP_TAG_VALID; \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -61,7 +65,8 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ x87_div(ST(0), use_var, ST(0)); \ FP_TAG_VALID; \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv ## cycle_postfix) : ((x87_concurrency.fdiv ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -73,7 +78,8 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) *= use_var; \ FP_TAG_VALID; \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul ## cycle_postfix) : ((x87_concurrency.fmul ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -85,7 +91,8 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) -= use_var; \ FP_TAG_VALID; \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } \ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ @@ -97,7 +104,8 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ load_var = get(); if (cpu_state.abrt) return 1; \ ST(0) = use_var - ST(0); \ FP_TAG_VALID; \ - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ return 0; \ } @@ -127,7 +135,8 @@ static int opFADD(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) + ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } static int opFADDr(uint32_t fetchdat) @@ -136,7 +145,8 @@ static int opFADDr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); FP_TAG_VALID_F; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } static int opFADDP(uint32_t fetchdat) @@ -146,7 +156,8 @@ static int opFADDP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } @@ -157,7 +168,8 @@ static int opFCOM(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } @@ -168,7 +180,8 @@ static int opFCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } @@ -187,7 +200,8 @@ static int opFCOMPP(uint32_t fetchdat) x87_pop(); x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -199,7 +213,8 @@ static int opFUCOMPP(uint32_t fetchdat) cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); x87_pop(); x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } @@ -211,7 +226,8 @@ static int opFCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } static int opFCOMIP(uint32_t fetchdat) @@ -223,7 +239,8 @@ static int opFCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); return 0; } #endif @@ -234,7 +251,8 @@ static int opFDIV(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(0), ST(0), ST(fetchdat & 7)); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); return 0; } static int opFDIVr(uint32_t fetchdat) @@ -243,7 +261,8 @@ static int opFDIVr(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); FP_TAG_VALID_F; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); return 0; } static int opFDIVP(uint32_t fetchdat) @@ -253,7 +272,8 @@ static int opFDIVP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); return 0; } @@ -263,7 +283,8 @@ static int opFDIVR(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(0), ST(fetchdat&7), ST(0)); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); return 0; } static int opFDIVRr(uint32_t fetchdat) @@ -272,7 +293,8 @@ static int opFDIVRr(uint32_t fetchdat) cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); FP_TAG_VALID_F; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); return 0; } static int opFDIVRP(uint32_t fetchdat) @@ -282,7 +304,8 @@ static int opFDIVRP(uint32_t fetchdat) x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); return 0; } @@ -292,7 +315,8 @@ static int opFMUL(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); return 0; } static int opFMULr(uint32_t fetchdat) @@ -301,7 +325,8 @@ static int opFMULr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID_F; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); return 0; } static int opFMULP(uint32_t fetchdat) @@ -311,7 +336,8 @@ static int opFMULP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); return 0; } @@ -321,7 +347,8 @@ static int opFSUB(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } static int opFSUBr(uint32_t fetchdat) @@ -330,7 +357,8 @@ static int opFSUBr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID_F; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } static int opFSUBP(uint32_t fetchdat) @@ -340,7 +368,8 @@ static int opFSUBP(uint32_t fetchdat) ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } @@ -350,7 +379,8 @@ static int opFSUBR(uint32_t fetchdat) cpu_state.pc++; ST(0) = ST(fetchdat & 7) - ST(0); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } static int opFSUBRr(uint32_t fetchdat) @@ -359,7 +389,8 @@ static int opFSUBRr(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID_F; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } static int opFSUBRP(uint32_t fetchdat) @@ -369,7 +400,8 @@ static int opFSUBRP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); FP_TAG_VALID_F; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); return 0; } @@ -380,7 +412,8 @@ static int opFUCOM(uint32_t fetchdat) cpu_state.pc++; cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } @@ -391,7 +424,8 @@ static int opFUCOMP(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } @@ -403,7 +437,8 @@ static int opFUCOMI(uint32_t fetchdat) cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } static int opFUCOMIP(uint32_t fetchdat) @@ -415,7 +450,8 @@ static int opFUCOMIP(uint32_t fetchdat) if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); return 0; } #endif diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index 5e754fc90..388e96011 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -23,7 +23,8 @@ static int opFILDiw_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -35,7 +36,8 @@ static int opFILDiw_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); return 0; } #endif @@ -46,7 +48,8 @@ static int opFISTiw_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -56,7 +59,8 @@ static int opFISTiw_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); return cpu_state.abrt; } #endif @@ -68,7 +72,8 @@ static int opFISTPiw_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -79,7 +84,8 @@ static int opFISTPiw_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); return 0; } #endif @@ -95,7 +101,8 @@ static int opFILDiq_a16(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; FP_TAG_DEFAULT; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -110,7 +117,8 @@ static int opFILDiq_a32(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = temp64; FP_TAG_DEFAULT; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); return 0; } #endif @@ -139,7 +147,8 @@ static int FBSTP_a16(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -167,7 +176,7 @@ static int FBSTP_a32(uint32_t fetchdat) if (ST(0) < 0.0) tempc |= 0x80; writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); return 0; } #endif @@ -184,7 +193,8 @@ static int FISTPiq_a16(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -200,7 +210,8 @@ static int FISTPiq_a32(uint32_t fetchdat) temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); return 0; } #endif @@ -213,7 +224,8 @@ static int opFILDil_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -225,7 +237,8 @@ static int opFILDil_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); return 0; } #endif @@ -236,7 +249,8 @@ static int opFISTil_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(x87_fround32(ST(0))); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -246,7 +260,8 @@ static int opFISTil_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(x87_fround32(ST(0))); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); return cpu_state.abrt; } #endif @@ -258,7 +273,8 @@ static int opFISTPil_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -269,7 +285,8 @@ static int opFISTPil_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); return 0; } #endif @@ -282,7 +299,8 @@ static int opFLDe_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -294,7 +312,8 @@ static int opFLDe_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); return 0; } #endif @@ -306,7 +325,8 @@ static int opFSTPe_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -317,7 +337,8 @@ static int opFSTPe_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); x87_st80(ST(0)); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); return 0; } #endif @@ -330,7 +351,8 @@ static int opFLDd_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -342,7 +364,8 @@ static int opFLDd_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); return 0; } #endif @@ -355,7 +378,8 @@ static int opFSTd_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -367,7 +391,8 @@ static int opFSTd_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); t.d = ST(0); seteaq(t.i); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); return cpu_state.abrt; } #endif @@ -381,7 +406,8 @@ static int opFSTPd_a16(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -394,7 +420,8 @@ static int opFSTPd_a32(uint32_t fetchdat) t.d = ST(0); seteaq(t.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); return 0; } #endif @@ -407,7 +434,8 @@ static int opFLDs_a16(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -419,7 +447,8 @@ static int opFLDs_a32(uint32_t fetchdat) SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); return 0; } #endif @@ -432,7 +461,8 @@ static int opFSTs_a16(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -444,7 +474,8 @@ static int opFSTs_a32(uint32_t fetchdat) SEG_CHECK_WRITE(cpu_state.ea_seg); ts.s = (float)ST(0); seteal(ts.i); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); return cpu_state.abrt; } #endif @@ -458,7 +489,8 @@ static int opFSTPs_a16(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -471,7 +503,8 @@ static int opFSTPs_a32(uint32_t fetchdat) ts.s = (float)ST(0); seteal(ts.i); if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); return 0; } #endif diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index ba5e37f7a..7a6dee001 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -15,7 +15,8 @@ static int opFSTSW_AX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; AX = cpu_state.npxs; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); return 0; } #endif @@ -25,7 +26,8 @@ static int opFNOP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); return 0; } @@ -34,7 +36,8 @@ static int opFCLEX(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= 0xff00; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); return 0; } @@ -58,7 +61,8 @@ static int opFINIT(uint32_t fetchdat) #endif cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); CPU_BLOCK_END(); return 0; } @@ -73,7 +77,8 @@ static int opFFREE(uint32_t fetchdat) #else cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; #endif - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); return 0; } @@ -83,7 +88,8 @@ static int opFFREEP(uint32_t fetchdat) cpu_state.pc++; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); return 0; } @@ -93,7 +99,8 @@ static int opFST(uint32_t fetchdat) cpu_state.pc++; ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); return 0; } @@ -104,7 +111,8 @@ static int opFSTP(uint32_t fetchdat) ST(fetchdat & 7) = ST(0); cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); return 0; } @@ -160,7 +168,8 @@ static int FSTOR() #endif cpu_state.ismmx = 1; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); return cpu_state.abrt; } static int opFSTOR_a16(uint32_t fetchdat) @@ -330,7 +339,8 @@ static int FSAVE() cpu_state.TOP = 0; cpu_state.ismmx = 0; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); return cpu_state.abrt; } static int opFSAVE_a16(uint32_t fetchdat) @@ -358,7 +368,8 @@ static int opFSTSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -368,7 +379,8 @@ static int opFSTSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #endif @@ -386,7 +398,8 @@ static int opFLD(uint32_t fetchdat) x87_push(ST(fetchdat&7)); cpu_state.tag[cpu_state.TOP&7] = old_tag; cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); return 0; } @@ -407,7 +420,8 @@ static int opFXCH(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); return 0; } @@ -417,7 +431,8 @@ static int opFCHS(uint32_t fetchdat) cpu_state.pc++; ST(0) = -ST(0); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); return 0; } @@ -427,7 +442,8 @@ static int opFABS(uint32_t fetchdat) cpu_state.pc++; ST(0) = fabs(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); return 0; } @@ -438,7 +454,8 @@ static int opFTST(uint32_t fetchdat) cpu_state.npxs &= ~(C0|C2|C3); if (ST(0) == 0.0) cpu_state.npxs |= C3; else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); return 0; } @@ -455,7 +472,8 @@ static int opFXAM(uint32_t fetchdat) else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); return 0; } @@ -464,7 +482,8 @@ static int opFLD1(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(1.0); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); return 0; } @@ -473,7 +492,8 @@ static int opFLDL2T(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(3.3219280948873623); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; } @@ -482,7 +502,8 @@ static int opFLDL2E(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(1.4426950408889634); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; } @@ -491,7 +512,8 @@ static int opFLDPI(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(3.141592653589793); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; } @@ -500,7 +522,8 @@ static int opFLDEG2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(0.3010299956639812); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; } @@ -509,7 +532,8 @@ static int opFLDLN2(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); return 0; } @@ -519,7 +543,8 @@ static int opFLDZ(uint32_t fetchdat) cpu_state.pc++; x87_push(0.0); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); return 0; } @@ -529,7 +554,8 @@ static int opF2XM1(uint32_t fetchdat) cpu_state.pc++; ST(0) = pow(2.0, ST(0)) - 1.0; FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); return 0; } @@ -540,7 +566,8 @@ static int opFYL2X(uint32_t fetchdat) ST(1) = ST(1) * (log(ST(0)) / log(2.0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); return 0; } @@ -551,7 +578,8 @@ static int opFYL2XP1(uint32_t fetchdat) ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); return 0; } @@ -563,7 +591,8 @@ static int opFPTAN(uint32_t fetchdat) FP_TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); return 0; } @@ -574,7 +603,8 @@ static int opFPATAN(uint32_t fetchdat) ST(1) = atan2(ST(1), ST(0)); FP_TAG_VALID_N; x87_pop(); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); return 0; } @@ -587,7 +617,8 @@ static int opFDECSTP(uint32_t fetchdat) #else cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); return 0; } @@ -600,7 +631,8 @@ static int opFINCSTP(uint32_t fetchdat) #else cpu_state.TOP = (cpu_state.TOP + 1) & 7; #endif - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); return 0; } @@ -616,7 +648,8 @@ static int opFPREM(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -632,7 +665,8 @@ static int opFPREM1(uint32_t fetchdat) if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); return 0; } #endif @@ -643,7 +677,8 @@ static int opFSQRT(uint32_t fetchdat) cpu_state.pc++; ST(0) = sqrt(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); return 0; } @@ -658,7 +693,8 @@ static int opFSINCOS(uint32_t fetchdat) FP_TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); return 0; } #endif @@ -669,7 +705,8 @@ static int opFRNDINT(uint32_t fetchdat) cpu_state.pc++; ST(0) = (double)x87_fround(ST(0)); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); return 0; } @@ -682,7 +719,8 @@ static int opFSCALE(uint32_t fetchdat) if(ST(0) != 0.0) ST(0) = ST(0) * pow(2.0, (double)temp64); FP_TAG_VALID; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); return 0; } @@ -694,7 +732,8 @@ static int opFSIN(uint32_t fetchdat) ST(0) = sin(ST(0)); FP_TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); return 0; } @@ -705,7 +744,8 @@ static int opFCOS(uint32_t fetchdat) ST(0) = cos(ST(0)); FP_TAG_VALID; cpu_state.npxs &= ~C2; - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); return 0; } #endif @@ -733,7 +773,8 @@ static int FLDENV() cpu_state.TOP = (cpu_state.npxs >> 11) & 7; break; } - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); return cpu_state.abrt; } @@ -766,7 +807,8 @@ static int opFLDCW_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); return 0; } #ifndef FPU_8087 @@ -780,7 +822,8 @@ static int opFLDCW_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); return 0; } #endif @@ -826,7 +869,8 @@ static int FSTENV() writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); break; } - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); return cpu_state.abrt; } @@ -855,7 +899,8 @@ static int opFSTCW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(cpu_state.npxc); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 @@ -865,7 +910,8 @@ static int opFSTCW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); seteaw(cpu_state.npxc); - CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); return cpu_state.abrt; } #endif @@ -882,7 +928,7 @@ static int opFSTCW_a32(uint32_t fetchdat) cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ ST(0) = ST(fetchdat & 7); \ } \ - CLOCK_CYCLES(4); \ + CLOCK_CYCLES_FPU(4); \ return 0; \ } diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c index 7443aae72..905ff1c6a 100644 --- a/src/cpu/x87_timings.c +++ b/src/cpu/x87_timings.c @@ -8,6 +8,7 @@ #include "x87_timings.h" x87_timings_t x87_timings; +x87_timings_t x87_concurrency; const x87_timings_t x87_timings_8087 = { @@ -313,3 +314,157 @@ const x87_timings_t x87_timings_486 = .fyl2x = (196 + 329) / 2, .fyl2xp1 = (171 + 326) / 2 }; + +/* this should be used for FPUs with no concurrency. +some pre-486DX Cyrix FPUs reportedly are like this. */ +const x87_timings_t x87_concurrency_none = +{ + .f2xm1 = 0, + .fabs = 0, + .fadd = 0, + .fadd_32 = 0, + .fadd_64 = 0, + .fbld = 0, + .fbstp = 0, + .fchs = 0, + .fclex = 0, + .fcom = 0, + .fcom_32 = 0, + .fcom_64 = 0, + .fcos = 0, + .fincdecstp = 0, + .fdisi_eni = 0, + .fdiv = 0, + .fdiv_32 = 0, + .fdiv_64 = 0, + .ffree = 0, + .fadd_i16 = 0, + .fadd_i32 = 0, + .fcom_i16 = 0, + .fcom_i32 = 0, + .fdiv_i16 = 0, + .fdiv_i32 = 0, + .fild_16 = 0, + .fild_32 = 0, + .fild_64 = 0, + .fmul_i16 = 0, + .fmul_i32 = 0, + .finit = 0, + .fist_16 = 0, + .fist_32 = 0, + .fist_64 = 0, + .fld = 0, + .fld_32 = 0, + .fld_64 = 0, + .fld_80 = 0, + .fld_z1 = 0, + .fld_const = 0, + .fldcw = 0, + .fldenv = 0, + .fmul = 0, + .fmul_32 = 0, + .fmul_64 = 0, + .fnop = 0, + .fpatan = 0, + .fprem = 0, + .fprem1 = 0, + .fptan = 0, + .frndint = 0, + .frstor = 0, + .fsave = 0, + .fscale = 0, + .fsetpm = 0, + .fsin_cos = 0, + .fsincos = 0, + .fsqrt = 0, + .fst = 0, + .fst_32 = 0, + .fst_64 = 0, + .fst_80 = 0, + .fstcw_sw = 0, + .fstenv = 0, + .ftst = 0, + .fucom = 0, + .fwait = 0, + .fxam = 0, + .fxch = 0, + .fxtract = 0, + .fyl2x = 0, + .fyl2xp1 = 0, +}; + +const x87_timings_t x87_concurrency_486 = +{ + .f2xm1 = 2, + .fabs = 0, + .fadd = 7, + .fadd_32 = 7, + .fadd_64 = 7, + .fbld = 8, + .fbstp = 0, + .fchs = 0, + .fclex = 0, + .fcom = 1, + .fcom_32 = 1, + .fcom_64 = 1, + .fcos = 2, + .fincdecstp = 0, + .fdisi_eni = 0, + .fdiv = 70, + .fdiv_32 = 70, + .fdiv_64 = 70, + .ffree = 0, + .fadd_i16 = 7, + .fadd_i32 = 7, + .fcom_i16 = 1, + .fcom_i32 = 1, + .fdiv_i16 = 70, + .fdiv_i32 = 70, + .fild_16 = 4, + .fild_32 = 4, + .fild_64 = 8, + .fmul_i16 = 8, + .fmul_i32 = 8, + .finit = 0, + .fist_16 = 0, + .fist_32 = 0, + .fist_64 = 0, + .fld = 0, + .fld_32 = 0, + .fld_64 = 0, + .fld_80 = 0, + .fld_z1 = 0, + .fld_const = 2, + .fldcw = 0, + .fldenv = 0, + .fmul = 13, + .fmul_32 = 8, + .fmul_64 = 11, + .fnop = 0, + .fpatan = 5, + .fprem = 2, + .fprem1 = 6, + .fptan = 70, + .frndint = 0, + .frstor = 0, + .fsave = 0, + .fscale = 2, + .fsetpm = 0, + .fsin_cos = 2, + .fsincos = 2, + .fsqrt = 70, + .fst = 0, + .fst_32 = 0, + .fst_64 = 0, + .fst_80 = 0, + .fstcw_sw = 0, + .fstenv = 0, + .ftst = 1, + .fucom = 1, + .fwait = 0, + .fxam = 0, + .fxch = 0, + .fxtract = 4, + .fyl2x = 13, + .fyl2xp1 = 13, +}; \ No newline at end of file diff --git a/src/cpu/x87_timings.h b/src/cpu/x87_timings.h index ec4f8ceca..c7dac8270 100644 --- a/src/cpu/x87_timings.h +++ b/src/cpu/x87_timings.h @@ -53,4 +53,7 @@ extern const x87_timings_t x87_timings_287; extern const x87_timings_t x87_timings_387; extern const x87_timings_t x87_timings_486; -extern x87_timings_t x87_timings; \ No newline at end of file +extern const x87_timings_t x87_concurrency_486; + +extern x87_timings_t x87_timings; +extern x87_timings_t x87_concurrency; \ No newline at end of file diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 2b7b34c7b..5d7d2d752 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -29,4 +29,8 @@ endif() if(ISAMEM_IAB) target_compile_definitions(dev PRIVATE USE_ISAMEM_IAB) -endif() \ No newline at end of file +endif() + +if(ISAMEM_BRAT) + target_compile_definitions(dev PRIVATE USE_ISAMEM_BRAT) +endif() diff --git a/src/device/isamem.c b/src/device/isamem.c index b16d5d247..54d78eb24 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -94,6 +94,7 @@ #define ISAMEM_EV159_CARD 10 #define ISAMEM_RAMPAGEXT_CARD 11 #define ISAMEM_ABOVEBOARD_CARD 12 +#define ISAMEM_BRAT_CARD 13 #define ISAMEM_DEBUG 0 @@ -451,6 +452,7 @@ dev->frame_addr = 0xE0000; case ISAMEM_RAMPAGEXT_CARD: /* AST RAMpage/XT */ case ISAMEM_ABOVEBOARD_CARD: /* Intel AboveBoard */ + case ISAMEM_BRAT_CARD: /* BocaRAM/AT */ dev->base_addr = device_get_config_hex16("base"); dev->total_size = device_get_config_int("size"); dev->start_addr = device_get_config_int("start"); @@ -984,6 +986,96 @@ static const device_t ev159_device = { }; +#ifdef USE_ISAMEM_BRAT +static const device_config_t brat_config[] = +{ + { + "base", "Address", CONFIG_HEX16, "", 0x0258, "", { 0 }, + { + { + "208H", 0x0208 + }, + { + "218H", 0x0218 + }, + { + "258H", 0x0258 + }, + { + "268H", 0x0268 + }, + { + "" + } + }, + }, + { + "frame", "Frame Address", CONFIG_HEX20, "", 0, "", { 0 }, + { + { + "Disabled", 0x00000 + }, + { + "D000H", 0xD0000 + }, + { + "E000H", 0xE0000 + }, + { + "" + } + }, + }, + { + "width", "I/O Width", CONFIG_SELECTION, "", 8, "", { 0 }, + { + { + "8-bit", 8 + }, + { + "16-bit", 16 + }, + { + "" + } + }, + }, + { + "speed", "Transfer Speed", CONFIG_SELECTION, "", 0, "", { 0 }, + { + { + "Standard", 0 + }, + { + "High-Speed", 1 + }, + { + "" + } + } + }, + { + "size", "Memory Size", CONFIG_SPINNER, "", 128, + "", + { 0, 8192, 512 }, + { 0 } + }, + { + "", "", -1 + } +}; + +static const device_t brat_device = { + "BocaRAM/AT", + DEVICE_ISA, + ISAMEM_BRAT_CARD, + isamem_init, isamem_close, NULL, + { NULL }, NULL, NULL, + brat_config +}; +#endif + + #ifdef USE_ISAMEM_RAMPAGE static const device_config_t rampage_config[] = { diff --git a/src/dma.c b/src/dma.c index d59160d73..26fe1a6bf 100644 --- a/src/dma.c +++ b/src/dma.c @@ -892,8 +892,10 @@ dma_page_write(uint16_t addr, uint8_t val, void *priv) { uint8_t convert[8] = CHANNELS; +#ifdef USE_DYNAREC if ((addr == 0x84) && cpu_use_dynarec) update_tsc(); +#endif addr &= 0x0f; dmaregs[2][addr] = val; diff --git a/src/include/86box/scsi_buslogic.h b/src/include/86box/scsi_buslogic.h index 203e45e12..27ea5c10b 100644 --- a/src/include/86box/scsi_buslogic.h +++ b/src/include/86box/scsi_buslogic.h @@ -20,12 +20,14 @@ # define SCSI_BUSLOGIC_H -extern const device_t buslogic_542b_1991_device; -extern const device_t buslogic_device; +extern const device_t buslogic_542b_device; extern const device_t buslogic_545s_device; +extern const device_t buslogic_542bh_device; +extern const device_t buslogic_545c_device; extern const device_t buslogic_640a_device; extern const device_t buslogic_445s_device; -extern const device_t buslogic_pci_device; +extern const device_t buslogic_445c_device; +extern const device_t buslogic_958d_pci_device; extern void BuslogicDeviceReset(void *p); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index e21b96c4b..9583123b0 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -99,8 +99,12 @@ extern const device_t gus_device; extern const device_t pas16_device; #endif +/* IBM PS/1 Audio Card */ +extern const device_t ps1snd_device; + /* Tandy PSSJ */ extern const device_t pssj_device; +extern const device_t pssj_isa_device; /* Creative Labs Sound Blaster */ extern const device_t sb_1_device; diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index 708879fdd..c8b1cca8c 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -15,6 +15,8 @@ * Copyright 2008-2018 Sarah Walker. * Copyright 2016-2018 Miran Grca. */ +#ifndef VIDEO_CGA_H +# define VIDEO_CGA_H typedef struct cga_t { @@ -65,3 +67,5 @@ void cga_poll(void *p); extern const device_config_t cga_config[]; extern const device_t cga_device; #endif + +#endif /*VIDEO_CGA_H*/ diff --git a/src/include/86box/vid_cga_comp.h b/src/include/86box/vid_cga_comp.h index 5ce52e61a..6b1dc4062 100644 --- a/src/include/86box/vid_cga_comp.h +++ b/src/include/86box/vid_cga_comp.h @@ -16,6 +16,8 @@ * Copyright 2015-2018 reenigne. * Copyright 2015-2018 Miran Grca. */ +#ifndef VIDEO_CGA_COMP_H +# define VIDEO_CGA_COMP_H #define Bit8u uint8_t #define Bit32u uint32_t @@ -25,3 +27,5 @@ void update_cga16_color(uint8_t cgamode); void cga_comp_init(int revision); Bit32u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit32u *TempLine); + +#endif /*VIDEO_CGA_COMP_H*/ diff --git a/src/include/86box/vid_hercules.h b/src/include/86box/vid_hercules.h new file mode 100644 index 000000000..8d44fdfe1 --- /dev/null +++ b/src/include/86box/vid_hercules.h @@ -0,0 +1,61 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Hercules graphics cards. + * + * + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2021 Jasmine Iwanek. + */ +#ifndef VIDEO_HERCULES_H +# define VIDEO_HERCULES_H + +typedef struct { + mem_mapping_t mapping; + + uint8_t crtc[32], charbuffer[4096]; + int crtcreg; + + uint8_t ctrl, + ctrl2, + stat; + + uint64_t dispontime, + dispofftime; + pc_timer_t timer; + + int firstline, + lastline; + + int linepos, + displine; + int vc, + sc; + uint16_t ma, + maback; + int con, coff, + cursoron; + int dispon, + blink; + int vsynctime; + int vadj; + + int lp_ff; + + int cols[256][2][2]; + + uint8_t *vram; +} hercules_t; + +static void *hercules_init(const device_t *info); + +#endif /*VIDEO_HERCULES_H*/ diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 4380e041b..348677477 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -16,6 +16,8 @@ * Copyright 2008-2020 Sarah Walker. * Copyright 2016-2020 Miran Grca. */ +#ifndef VIDEO_SVGA_H +# define VIDEO_SVGA_H #define FLAG_EXTRA_BANKS 1 @@ -274,6 +276,7 @@ extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, voi extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga); extern void tvp3026_recalctimings(void *p, svga_t *svga); extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); +extern float tvp3026_getclock(int clock, void *p); #ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; @@ -305,3 +308,5 @@ extern const device_t tseng_ics5301_ramdac_device; extern const device_t tseng_ics5341_ramdac_device; extern const device_t tvp3026_ramdac_device; #endif + +#endif /*VIDEO_SVGA_H*/ diff --git a/src/include/86box/vid_vga.h b/src/include/86box/vid_vga.h new file mode 100644 index 000000000..c8a9b132e --- /dev/null +++ b/src/include/86box/vid_vga.h @@ -0,0 +1,34 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the IBM MDA + VGA graphics cards. + * + * + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2018 Sarah Walker. + * Copyright 2016-2018 Miran Grca. + * Copyright 2021 Jasmine Iwanek. + */ +#ifndef VIDEO_VGA_H +# define VIDEO_VGA_H + +typedef struct vga_t +{ + svga_t svga; + + rom_t bios_rom; +} vga_t; + +static video_timings_t timing_vga = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; + +void vga_out(uint16_t addr, uint8_t val, void *p); +uint8_t vga_in(uint16_t addr, void *p); + +#endif /*VIDEO_VGA_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 3e0c74ce9..62d9e3153 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -348,6 +348,7 @@ extern const device_t s3_diamond_stealth_vram_isa_device; extern const device_t s3_ami_86c924_isa_device; extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_device; +extern const device_t s3_spea_mercury_lite_86c928_pci_device; extern const device_t s3_spea_mirage_86c801_isa_device; extern const device_t s3_spea_mirage_86c805_vlb_device; extern const device_t s3_mirocrystal_8s_805_vlb_device; @@ -394,6 +395,7 @@ extern const device_t s3_trio64v2_dx_onboard_pci_device; extern const device_t s3_virge_325_pci_device; extern const device_t s3_diamond_stealth_2000_pci_device; extern const device_t s3_diamond_stealth_3000_pci_device; +extern const device_t s3_stb_velocity_3d_pci_device; extern const device_t s3_virge_375_pci_device; extern const device_t s3_diamond_stealth_2000pro_pci_device; extern const device_t s3_virge_385_pci_device; diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index 4c5c26dbc..47b8121e0 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -60,26 +60,11 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/port_6x.h> -#include <86box/sound.h> -#include <86box/snd_sn76489.h> #include <86box/video.h> #include <86box/machine.h> +#include <86box/sound.h> -typedef struct { - sn76489_t sn76489; - uint8_t status, ctrl; - uint64_t timer_latch; - pc_timer_t timer_count; - int timer_enable; - uint8_t fifo[2048]; - int fifo_read_idx, fifo_write_idx; - int fifo_threshold; - uint8_t dac_val; - int16_t buffer[SOUNDBUFLEN]; - int pos; -} ps1snd_t; - typedef struct { int model; @@ -100,178 +85,6 @@ typedef struct { } ps1_t; -static void -update_irq_status(ps1snd_t *snd) -{ - if (((snd->status & snd->ctrl) & 0x12) && (snd->ctrl & 0x01)) - picint(1 << 7); - else - picintc(1 << 7); -} - - -static uint8_t -snd_read(uint16_t port, void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - uint8_t ret = 0xff; - - switch (port & 7) { - case 0: /* ADC data */ - snd->status &= ~0x10; - update_irq_status(snd); - ret = 0; - break; - - case 2: /* status */ - ret = snd->status; - ret |= (snd->ctrl & 0x01); - if ((snd->fifo_write_idx - snd->fifo_read_idx) >= 2048) - ret |= 0x08; /* FIFO full */ - if (snd->fifo_read_idx == snd->fifo_write_idx) - ret |= 0x04; /* FIFO empty */ - break; - - case 3: /* FIFO timer */ - /* - * The PS/1 Technical Reference says this should return - * thecurrent value, but the PS/1 BIOS and Stunt Island - * expect it not to change. - */ - ret = snd->timer_latch; - break; - - case 4: - case 5: - case 6: - case 7: - ret = 0; - } - - return(ret); -} - - -static void -snd_write(uint16_t port, uint8_t val, void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - - switch (port & 7) { - case 0: /* DAC output */ - if ((snd->fifo_write_idx - snd->fifo_read_idx) < 2048) { - snd->fifo[snd->fifo_write_idx & 2047] = val; - snd->fifo_write_idx++; - } - break; - - case 2: /* control */ - snd->ctrl = val; - if (! (val & 0x02)) - snd->status &= ~0x02; - update_irq_status(snd); - break; - - case 3: /* timer reload value */ - snd->timer_latch = val; - if (val) - timer_set_delay_u64(&snd->timer_count, ((0xff-val) * TIMER_USEC)); - else - timer_disable(&snd->timer_count); - break; - - case 4: /* almost empty */ - snd->fifo_threshold = val * 4; - break; - } -} - - -static void -snd_update(ps1snd_t *snd) -{ - for (; snd->pos < sound_pos_global; snd->pos++) - snd->buffer[snd->pos] = (int8_t)(snd->dac_val ^ 0x80) * 0x20; -} - - -static void -snd_callback(void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - - snd_update(snd); - - if (snd->fifo_read_idx != snd->fifo_write_idx) { - snd->dac_val = snd->fifo[snd->fifo_read_idx & 2047]; - snd->fifo_read_idx++; - } - - if ((snd->fifo_write_idx - snd->fifo_read_idx) == snd->fifo_threshold) - snd->status |= 0x02; /*FIFO almost empty*/ - - snd->status |= 0x10; /*ADC data ready*/ - update_irq_status(snd); - - timer_advance_u64(&snd->timer_count, snd->timer_latch * TIMER_USEC); -} - - -static void -snd_get_buffer(int32_t *buffer, int len, void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - int c; - - snd_update(snd); - - for (c = 0; c < len * 2; c++) - buffer[c] += snd->buffer[c >> 1]; - - snd->pos = 0; -} - - -static void * -snd_init(const device_t *info) -{ - ps1snd_t *snd; - - snd = malloc(sizeof(ps1snd_t)); - memset(snd, 0x00, sizeof(ps1snd_t)); - - sn76489_init(&snd->sn76489, 0x0205, 0x0001, SN76496, 4000000); - - io_sethandler(0x0200, 1, snd_read,NULL,NULL, snd_write,NULL,NULL, snd); - io_sethandler(0x0202, 6, snd_read,NULL,NULL, snd_write,NULL,NULL, snd); - - timer_add(&snd->timer_count, snd_callback, snd, 0); - - sound_add_handler(snd_get_buffer, snd); - - return(snd); -} - - -static void -snd_close(void *priv) -{ - ps1snd_t *snd = (ps1snd_t *)priv; - - free(snd); -} - - -static const device_t snd_device = { - "PS/1 Audio Card", - 0, 0, - snd_init, snd_close, NULL, - { NULL }, - NULL, - NULL -}; - - static void recalc_memory(ps1_t *ps) { @@ -470,7 +283,7 @@ ps1_setup(int model) lpt2_remove(); - device_add(&snd_device); + device_add(&ps1snd_device); device_add(&fdc_at_ps1_device); @@ -499,7 +312,7 @@ ps1_setup(int model) device_add(&ide_isa_device); - device_add(&snd_device); + device_add(&ps1snd_device); } } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 4005d5f57..d3b0a91e6 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -64,9 +64,10 @@ static SCSI_CARD scsi_cards[] = { { "aha154xc", &aha154xc_device, }, { "aha154xcf", &aha154xcf_device, }, { "aha154xcp", &aha154xcp_device, }, - { "bt542b", &buslogic_542b_1991_device, }, - { "bt542bh", &buslogic_device, }, + { "bt542b", &buslogic_542b_device, }, + { "bt542bh", &buslogic_542bh_device, }, { "bt545s", &buslogic_545s_device, }, + { "bt545c", &buslogic_545c_device, }, { "lcs6821n", &scsi_lcs6821n_device, }, { "rt1000b", &scsi_rt1000b_device, }, { "t128", &scsi_t128_device, }, @@ -78,7 +79,7 @@ static SCSI_CARD scsi_cards[] = { { "bt640a", &buslogic_640a_device, }, { "ncr53c90", &ncr53c90_mca_device, }, { "spock", &spock_device, }, - { "bt958d", &buslogic_pci_device, }, + { "bt958d", &buslogic_958d_pci_device, }, { "ncr53c810", &ncr53c810_pci_device, }, { "ncr53c815", &ncr53c815_pci_device, }, { "ncr53c820", &ncr53c820_pci_device, }, @@ -87,6 +88,7 @@ static SCSI_CARD scsi_cards[] = { { "ncr53c875", &ncr53c875_pci_device, }, { "dc390", &dc390_pci_device, }, { "bt445s", &buslogic_445s_device, }, + { "bt445c", &buslogic_445c_device, }, { "", NULL, }, }; diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index fcc19a1d6..2ea041aaa 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -231,13 +231,14 @@ typedef struct { enum { - CHIP_BUSLOGIC_ISA_542_1991, - CHIP_BUSLOGIC_ISA_542, - CHIP_BUSLOGIC_ISA, - CHIP_BUSLOGIC_MCA, - CHIP_BUSLOGIC_EISA, - CHIP_BUSLOGIC_VLB, - CHIP_BUSLOGIC_PCI + CHIP_BUSLOGIC_ISA_542B_1991_12_14, + CHIP_BUSLOGIC_ISA_545S_1992_10_05, + CHIP_BUSLOGIC_ISA_542BH_1993_05_23, + CHIP_BUSLOGIC_ISA_545C_1994_12_01, + CHIP_BUSLOGIC_VLB_445S_1993_11_16, + CHIP_BUSLOGIC_VLB_445C_1994_12_01, + CHIP_BUSLOGIC_MCA_640A_1993_05_23, + CHIP_BUSLOGIC_PCI_958D_1995_12_30 }; @@ -266,17 +267,21 @@ BuslogicGetNVRFileName(buslogic_data_t *bl) { switch(bl->chip) { - case CHIP_BUSLOGIC_ISA_542_1991: + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: return "bt542b.nvr"; - case CHIP_BUSLOGIC_ISA_542: - return "bt542bh.nvr"; - case CHIP_BUSLOGIC_ISA: + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: return "bt545s.nvr"; - case CHIP_BUSLOGIC_MCA: - return "bt640a.nvr"; - case CHIP_BUSLOGIC_VLB: + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + return "bt542bh.nvr"; + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + return "bt545c.nvr"; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: return "bt445s.nvr"; - case CHIP_BUSLOGIC_PCI: + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: + return "bt445c.nvr"; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: + return "bt640a.nvr"; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: return "bt958d.nvr"; default: fatal("Unrecognized BusLogic chip: %i\n", bl->chip); @@ -303,30 +308,36 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) HALR->structured.autoSCSIData.aHostAdaptertype[0] = ' '; HALR->structured.autoSCSIData.aHostAdaptertype[5] = ' '; switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542_1991: + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542B", 4); break; - case CHIP_BUSLOGIC_ISA_542: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542BH", 5); - break; - case CHIP_BUSLOGIC_ISA: + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545S", 4); break; - case CHIP_BUSLOGIC_MCA: - memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4); + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "542BH", 5); break; - case CHIP_BUSLOGIC_VLB: + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "545C", 4); + break; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445S", 4); break; - case CHIP_BUSLOGIC_PCI: + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "445C", 4); + break; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: + memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "640A", 4); + break; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: memcpy(&(HALR->structured.autoSCSIData.aHostAdaptertype[1]), "958D", 4); break; } - HALR->structured.autoSCSIData.fLevelSensitiveInterrupt = (bl->chip == CHIP_BUSLOGIC_PCI) ? 1 : 0; + HALR->structured.autoSCSIData.fLevelSensitiveInterrupt = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; HALR->structured.autoSCSIData.uSystemRAMAreForBIOS = 6; - if (bl->chip != CHIP_BUSLOGIC_PCI) { + if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { switch(dev->DmaChannel) { case 5: HALR->structured.autoSCSIData.uDMAChannel = 1; @@ -342,9 +353,9 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) break; } } - HALR->structured.autoSCSIData.fDMAAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 1; + HALR->structured.autoSCSIData.fDMAAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 1; - if (bl->chip != CHIP_BUSLOGIC_PCI) { + if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { switch(dev->Irq) { case 9: HALR->structured.autoSCSIData.uIrqChannel = 1; @@ -369,14 +380,14 @@ BuslogicAutoSCSIRamSetDefaults(x54x_t *dev, uint8_t safe) break; } } - HALR->structured.autoSCSIData.fIrqAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 1; + HALR->structured.autoSCSIData.fIrqAutoConfiguration = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 1; - HALR->structured.autoSCSIData.uDMATransferRate = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 1; + HALR->structured.autoSCSIData.uDMATransferRate = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 1; HALR->structured.autoSCSIData.uSCSIId = 7; HALR->structured.autoSCSIData.uSCSIConfiguration = 0x3F; - HALR->structured.autoSCSIData.uBusOnDelay = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 7; - HALR->structured.autoSCSIData.uBusOffDelay = (bl->chip == CHIP_BUSLOGIC_PCI) ? 0 : 4; + HALR->structured.autoSCSIData.uBusOnDelay = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 7; + HALR->structured.autoSCSIData.uBusOffDelay = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 0 : 4; HALR->structured.autoSCSIData.uBIOSConfiguration = (bl->has_bios) ? 0x33 : 0x32; if (!safe) HALR->structured.autoSCSIData.uBIOSConfiguration |= 0x04; @@ -416,7 +427,7 @@ BuslogicInitializeAutoSCSIRam(x54x_t *dev) fatal("BuslogicInitializeAutoSCSIRam(): Error reading data\n"); fclose(f); f = NULL; - if (bl->chip == CHIP_BUSLOGIC_PCI) { + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { x54x_io_remove(dev, dev->Base, 4); switch(HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { case 0: @@ -472,7 +483,10 @@ buslogic_get_host_id(void *p) HALocalRAM *HALR = &bl->LocalRAM; - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_ISA_542_1991)) + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || + (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || + (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || + (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) return dev->HostID; else return HALR->structured.autoSCSIData.uSCSIId; @@ -489,7 +503,11 @@ buslogic_get_irq(void *p) HALocalRAM *HALR = &bl->LocalRAM; - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_ISA_542_1991) || (bl->chip == CHIP_BUSLOGIC_PCI)) + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || + (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || + (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || + (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || + (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30)) return dev->Irq; else return bl_irq[HALR->structured.autoSCSIData.uIrqChannel]; @@ -506,9 +524,12 @@ buslogic_get_dma(void *p) HALocalRAM *HALR = &bl->LocalRAM; - if (bl->chip == CHIP_BUSLOGIC_PCI) + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) return (dev->Base ? 7 : 0); - else if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_ISA_542_1991)) + else if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || + (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || + (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || + (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16)) return dev->DmaChannel; else return bl_dma[HALR->structured.autoSCSIData.uDMAChannel]; @@ -543,15 +564,15 @@ buslogic_param_len(void *p) case 0xFB: return 3; case 0x93: /* Valid only for VLB */ - return (bl->chip == CHIP_BUSLOGIC_VLB) ? 1 : 0; + return (bl->chip == CHIP_BUSLOGIC_VLB_445C_1994_12_01 || bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) ? 1 : 0; case 0x95: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI) ? 1 : 0; + return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; case 0x97: /* Valid only for PCI */ case 0xA7: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI) ? 10 : 0; + return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 10 : 0; case 0xA8: /* Valid only for PCI */ case 0xA9: /* Valid only for PCI */ - return (bl->chip == CHIP_BUSLOGIC_PCI) ? 4 : 0; + return (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 4 : 0; default: return 0; } @@ -690,6 +711,8 @@ buslogic_cmds(void *p) BuslogicPCIInformation_t *ReplyPI; int cCharsToTransfer; + buslogic_log("Buslogic cmds = 0x%02x\n", dev->Command); + switch (dev->Command) { case 0x20: dev->DataReplyLeft = 0; @@ -754,7 +777,7 @@ buslogic_cmds(void *p) case 0x84: dev->DataBuf[0] = dev->fw_rev[4]; dev->DataReplyLeft = 1; - break; + break; case 0x85: if (strlen(dev->fw_rev) == 6) dev->DataBuf[0] = dev->fw_rev[5]; @@ -763,7 +786,7 @@ buslogic_cmds(void *p) dev->DataReplyLeft = 1; break; case 0x86: - if (bl->chip == CHIP_BUSLOGIC_PCI) { + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { ReplyPI = (BuslogicPCIInformation_t *) dev->DataBuf; memset(ReplyPI, 0, sizeof(BuslogicPCIInformation_t)); ReplyPI->InformationIsValid = 0; @@ -801,7 +824,7 @@ buslogic_cmds(void *p) /* The reply length is set by the guest and is found in the first byte of the command buffer. */ dev->DataReplyLeft = dev->CmdBuf[0]; memset(dev->DataBuf, 0, dev->DataReplyLeft); - if (bl->chip == CHIP_BUSLOGIC_ISA_542) + if (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) i = 5; else i = 4; @@ -819,16 +842,18 @@ buslogic_cmds(void *p) memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); switch (bl->chip) { - case CHIP_BUSLOGIC_ISA_542_1991: - case CHIP_BUSLOGIC_ISA_542: - case CHIP_BUSLOGIC_ISA: - case CHIP_BUSLOGIC_VLB: + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: ReplyIESI->uBusType = 'A'; /* ISA style */ break; - case CHIP_BUSLOGIC_MCA: + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: ReplyIESI->uBusType = 'M'; /* MCA style */ break; - case CHIP_BUSLOGIC_PCI: + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: ReplyIESI->uBusType = 'E'; /* PCI style */ break; } @@ -836,17 +861,19 @@ buslogic_cmds(void *p) ReplyIESI->u16ScatterGatherLimit = 8192; ReplyIESI->cMailbox = dev->MailboxCount; ReplyIESI->uMailboxAddressBase = dev->MailboxOutAddr; - ReplyIESI->fHostWideSCSI = 1; /* This should be set for the BT-542B as well. */ - if ((bl->chip != CHIP_BUSLOGIC_ISA_542) && (bl->chip != CHIP_BUSLOGIC_ISA_542_1991) && (bl->chip != CHIP_BUSLOGIC_MCA)) + ReplyIESI->fHostWideSCSI = (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ? 1 : 0; + if ((bl->chip != CHIP_BUSLOGIC_ISA_542B_1991_12_14) && (bl->chip != CHIP_BUSLOGIC_ISA_545S_1992_10_05) && + (bl->chip != CHIP_BUSLOGIC_ISA_542BH_1993_05_23) && (bl->chip != CHIP_BUSLOGIC_MCA_640A_1993_05_23) && + (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16)) ReplyIESI->fLevelSensitiveInterrupt = bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; - if (bl->chip == CHIP_BUSLOGIC_PCI) + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) ReplyIESI->fHostUltraSCSI = 1; memcpy(ReplyIESI->aFirmwareRevision, &(dev->fw_rev[strlen(dev->fw_rev) - 3]), sizeof(ReplyIESI->aFirmwareRevision)); buslogic_log("Return Extended Setup Information: %d\n", dev->CmdBuf[0]); break; case 0x8F: bl->fAggressiveRoundRobinMode = dev->CmdBuf[0] & 1; - + buslogic_log("Aggressive Round Robin Mode = %d\n", bl->fAggressiveRoundRobinMode); dev->DataReplyLeft = 0; break; case 0x90: @@ -866,13 +893,16 @@ buslogic_cmds(void *p) dev->DataReply = 0; break; case 0x93: - if (bl->chip != CHIP_BUSLOGIC_VLB) { + if ((bl->chip != CHIP_BUSLOGIC_VLB_445C_1994_12_01) && (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16)) { dev->DataReplyLeft = 0; dev->Status |= STAT_INVCMD; break; } case 0x92: - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_ISA_542_1991) || (bl->chip == CHIP_BUSLOGIC_MCA)) { + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || + (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || + (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || + (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { dev->DataReplyLeft = 0; dev->Status |= STAT_INVCMD; break; @@ -901,7 +931,7 @@ buslogic_cmds(void *p) break; } - if ((bl->chip == CHIP_BUSLOGIC_PCI) && !(dev->Status & STAT_INVCMD)) { + if ((bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) && !(dev->Status & STAT_INVCMD)) { x54x_io_remove(dev, dev->Base, 4); switch(HALR->structured.autoSCSIData.uHostAdapterIoPortAddress) { case 0: @@ -918,7 +948,8 @@ buslogic_cmds(void *p) } break; case 0x94: - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_ISA_542_1991) || (bl->chip == CHIP_BUSLOGIC_MCA)) { + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23) || + (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23)) { dev->DataReplyLeft = 0; dev->Status |= STAT_INVCMD; break; @@ -937,7 +968,7 @@ buslogic_cmds(void *p) } break; case 0x95: - if (bl->chip == CHIP_BUSLOGIC_PCI) { + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { if (dev->Base != 0) x54x_io_remove(dev, dev->Base, 4); if (dev->CmdBuf[0] < 6) { @@ -966,7 +997,7 @@ buslogic_cmds(void *p) dev->DataReplyLeft = 0; break; case 0xA8: - if (bl->chip != CHIP_BUSLOGIC_PCI) { + if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { dev->DataReplyLeft = 0; dev->Status |= STAT_INVCMD; break; @@ -985,7 +1016,7 @@ buslogic_cmds(void *p) dev->DataReply = 0; break; case 0xA9: - if (bl->chip != CHIP_BUSLOGIC_PCI) { + if (bl->chip != CHIP_BUSLOGIC_PCI_958D_1995_12_30) { dev->DataReplyLeft = 0; dev->Status |= STAT_INVCMD; break; @@ -1038,18 +1069,20 @@ buslogic_setup_data(void *p) bl_setup->uCharacterD = 'D'; /* BusLogic model. */ switch(bl->chip) { - case CHIP_BUSLOGIC_ISA_542_1991: - case CHIP_BUSLOGIC_ISA_542: - case CHIP_BUSLOGIC_ISA: + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: bl_setup->uHostBusType = 'A'; break; - case CHIP_BUSLOGIC_MCA: + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: bl_setup->uHostBusType = 'B'; break; - case CHIP_BUSLOGIC_VLB: + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: bl_setup->uHostBusType = 'E'; break; - case CHIP_BUSLOGIC_PCI: + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: bl_setup->uHostBusType = 'F'; break; } @@ -1062,6 +1095,8 @@ buslogic_is_aggressive_mode(void *p) x54x_t *dev = (x54x_t *)p; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; + buslogic_log("Buslogic: Aggressive mode = %d\n", bl->fAggressiveRoundRobinMode); + return bl->fAggressiveRoundRobinMode; } @@ -1072,7 +1107,8 @@ buslogic_interrupt_type(void *p) x54x_t *dev = (x54x_t *)p; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; - if ((bl->chip == CHIP_BUSLOGIC_ISA_542) || (bl->chip == CHIP_BUSLOGIC_ISA_542_1991) || (bl->chip == CHIP_BUSLOGIC_MCA)) + if ((bl->chip == CHIP_BUSLOGIC_ISA_542B_1991_12_14) || (bl->chip == CHIP_BUSLOGIC_ISA_545S_1992_10_05) || (bl->chip == CHIP_BUSLOGIC_ISA_542BH_1993_05_23) || + (bl->chip == CHIP_BUSLOGIC_VLB_445S_1993_11_16) || (bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23)) return 0; else return !!bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt; @@ -1302,7 +1338,7 @@ static void BuslogicInitializeLocalRAM(buslogic_data_t *bl) { memset(bl->LocalRAM.u8View, 0, sizeof(HALocalRAM)); - if (bl->chip == CHIP_BUSLOGIC_PCI) { + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; } else { bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 0; @@ -1582,92 +1618,115 @@ buslogic_init(const device_t *info) bl->fAggressiveRoundRobinMode = 1; - switch(bl->chip) - { - case CHIP_BUSLOGIC_ISA_542_1991: - strcpy(dev->name, "BT-542B"); - bios_rom_name = "roms/scsi/buslogic/BT-542B_BIOS.ROM"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA221"; - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_ISA_542: - strcpy(dev->name, "BT-542BH"); - bios_rom_name = "roms/scsi/buslogic/BT-542BH_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "AA335"; - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_ISA: - default: - strcpy(dev->name, "BT-545S"); - bios_rom_name = "roms/scsi/buslogic/BT-545S_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = "roms/scsi/buslogic/BT-545S_AutoSCSI.rom"; - autoscsi_rom_size = 0x4000; - has_scam_rom = 0; - dev->fw_rev = "AA421E"; - dev->ha_bps = 10000000.0; /* fast SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_MCA: - strcpy(dev->name, "BT-640A"); - bios_rom_name = "roms/scsi/buslogic/BT-640A_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 0; - has_scam_rom = 0; - dev->fw_rev = "BA150"; - dev->flags |= X54X_32BIT; - dev->pos_regs[0] = 0x08; /* MCA board ID */ - dev->pos_regs[1] = 0x07; - mca_add(buslogic_mca_read, buslogic_mca_write, buslogic_mca_feedb, NULL, dev); - dev->ha_bps = 5000000.0; /* normal SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_VLB: - strcpy(dev->name, "BT-445S"); - bios_rom_name = "roms/scsi/buslogic/BT-445S_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = "roms/scsi/buslogic/BT-445S_AutoSCSI.rom"; - autoscsi_rom_size = 0x8000; - has_scam_rom = 1; - scam_rom_name = "roms/scsi/buslogic/BT-445S_SCAM.rom"; - scam_rom_size = 0x0200; - dev->fw_rev = "AA507B"; - dev->flags |= X54X_32BIT; - dev->ha_bps = 10000000.0; /* fast SCSI */ - dev->max_id = 7; /* narrow SCSI */ - break; - case CHIP_BUSLOGIC_PCI: - strcpy(dev->name, "BT-958D"); - bios_rom_name = "roms/scsi/buslogic/BT-958D_BIOS.rom"; - bios_rom_size = 0x4000; - bios_rom_mask = 0x3fff; - has_autoscsi_rom = 1; - autoscsi_rom_name = "roms/scsi/buslogic/BT-958D_AutoSCSI.rom"; - autoscsi_rom_size = 0x8000; - has_scam_rom = 1; - scam_rom_name = "roms/scsi/buslogic/BT-958D_SCAM.rom"; - scam_rom_size = 0x0200; - dev->fw_rev = "AA507B"; - dev->flags |= (X54X_CDROM_BOOT | X54X_32BIT); - dev->ha_bps = 20000000.0; /* ultra SCSI */ - dev->max_id = 15; /* wide SCSI */ - break; - } + bios_rom_name = NULL; + has_autoscsi_rom = 0; + has_scam_rom = 0; + + switch (bl->chip) { + case CHIP_BUSLOGIC_ISA_542B_1991_12_14: /*Dated December 14th, 1991*/ + strcpy(dev->name, "BT-542B"); + bios_rom_name = "roms/scsi/buslogic/BT-542B_BIOS.ROM"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA221"; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_ISA_545S_1992_10_05: /*Dated October 5th, 1992*/ + strcpy(dev->name, "BT-545S"); + bios_rom_name = "roms/scsi/buslogic/BT-545S_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA331"; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_ISA_542BH_1993_05_23: /*Dated May 23rd, 1993*/ + strcpy(dev->name, "BT-542BH"); + bios_rom_name = "roms/scsi/buslogic/BT-542BH_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA335"; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_ISA_545C_1994_12_01: /*Dated December 1st, 1994*/ + strcpy(dev->name, "BT-545C"); + bios_rom_name = "roms/scsi/buslogic/BT-545C_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 1; + autoscsi_rom_name = "roms/scsi/buslogic/BT-545C_AutoSCSI.rom"; + autoscsi_rom_size = 0x4000; + has_scam_rom = 0; + dev->fw_rev = "AA425J"; + dev->ha_bps = 10000000.0; /* fast SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_MCA_640A_1993_05_23: /*Dated May 23rd, 1993*/ + strcpy(dev->name, "BT-640A"); + bios_rom_name = "roms/scsi/buslogic/BT-640A_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "BA335"; + dev->flags |= X54X_32BIT; + dev->pos_regs[0] = 0x08; /* MCA board ID */ + dev->pos_regs[1] = 0x07; + mca_add(buslogic_mca_read, buslogic_mca_write, buslogic_mca_feedb, NULL, dev); + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_VLB_445S_1993_11_16: /*Dated November 16th, 1993*/ + strcpy(dev->name, "BT-445S"); + bios_rom_name = "roms/scsi/buslogic/BT-445S_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 0; + has_scam_rom = 0; + dev->fw_rev = "AA335"; + dev->flags |= X54X_32BIT; + dev->ha_bps = 5000000.0; /* normal SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_VLB_445C_1994_12_01: /*Dated December 1st, 1994*/ + strcpy(dev->name, "BT-445C"); + bios_rom_name = "roms/scsi/buslogic/BT-445C_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 1; + autoscsi_rom_name = "roms/scsi/buslogic/BT-445C_AutoSCSI.rom"; + autoscsi_rom_size = 0x4000; + has_scam_rom = 0; + dev->fw_rev = "AA425J"; + dev->flags |= X54X_32BIT; + dev->ha_bps = 10000000.0; /* fast SCSI */ + dev->max_id = 7; /* narrow SCSI */ + break; + case CHIP_BUSLOGIC_PCI_958D_1995_12_30: /*Dated December 30th, 1995*/ + strcpy(dev->name, "BT-958D"); + bios_rom_name = "roms/scsi/buslogic/BT-958D_BIOS.rom"; + bios_rom_size = 0x4000; + bios_rom_mask = 0x3fff; + has_autoscsi_rom = 1; + autoscsi_rom_name = "roms/scsi/buslogic/BT-958D_AutoSCSI.rom"; + autoscsi_rom_size = 0x8000; + has_scam_rom = 1; + scam_rom_name = "roms/scsi/buslogic/BT-958D_SCAM.rom"; + scam_rom_size = 0x0200; + dev->fw_rev = "AA507B"; + dev->flags |= (X54X_CDROM_BOOT | X54X_32BIT); + dev->ha_bps = 20000000.0; /* ultra SCSI */ + dev->max_id = 15; /* wide SCSI */ + break; + } if ((dev->Base != 0) && !(dev->card_bus & DEVICE_MCA) && !(dev->card_bus & DEVICE_PCI)) { x54x_io_set(dev, dev->Base, 4); @@ -1709,7 +1768,7 @@ buslogic_init(const device_t *info) bl->bios_mask = 0; } - if (bl->chip == CHIP_BUSLOGIC_PCI) { + if (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30) { dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, dev); buslogic_pci_bar[0].addr_regs[0] = 1; @@ -1727,14 +1786,15 @@ buslogic_init(const device_t *info) x54x_mem_disable(dev); } - if ((bl->chip == CHIP_BUSLOGIC_MCA) || (bl->chip == CHIP_BUSLOGIC_PCI)) + if ((bl->chip == CHIP_BUSLOGIC_MCA_640A_1993_05_23) || (bl->chip == CHIP_BUSLOGIC_PCI_958D_1995_12_30)) mem_mapping_disable(&bl->bios.mapping); buslogic_log("Buslogic on port 0x%04X\n", dev->Base); x54x_device_reset(dev); - if ((bl->chip != CHIP_BUSLOGIC_ISA_542) && (bl->chip != CHIP_BUSLOGIC_ISA_542_1991) && (bl->chip != CHIP_BUSLOGIC_MCA)) { + if ((bl->chip != CHIP_BUSLOGIC_ISA_542B_1991_12_14) && (bl->chip != CHIP_BUSLOGIC_ISA_545S_1992_10_05) && (bl->chip != CHIP_BUSLOGIC_ISA_542BH_1993_05_23) && + (bl->chip != CHIP_BUSLOGIC_VLB_445S_1993_11_16) && (bl->chip != CHIP_BUSLOGIC_MCA_640A_1993_05_23)) { BuslogicInitializeLocalRAM(bl); BuslogicInitializeAutoSCSIRam(dev); } @@ -1848,19 +1908,10 @@ static const device_config_t BT958D_Config[] = { } }; -const device_t buslogic_542b_1991_device = { +const device_t buslogic_542b_device = { "BusLogic BT-542B ISA", DEVICE_ISA | DEVICE_AT, - CHIP_BUSLOGIC_ISA_542_1991, - buslogic_init, x54x_close, NULL, - { NULL }, NULL, NULL, - BT_ISA_Config -}; - -const device_t buslogic_device = { - "BusLogic BT-542BH ISA", - DEVICE_ISA | DEVICE_AT, - CHIP_BUSLOGIC_ISA_542, + CHIP_BUSLOGIC_ISA_542B_1991_12_14, buslogic_init, x54x_close, NULL, { NULL }, NULL, NULL, BT_ISA_Config @@ -1869,7 +1920,25 @@ const device_t buslogic_device = { const device_t buslogic_545s_device = { "BusLogic BT-545S ISA", DEVICE_ISA | DEVICE_AT, - CHIP_BUSLOGIC_ISA, + CHIP_BUSLOGIC_ISA_545S_1992_10_05, + buslogic_init, x54x_close, NULL, + { NULL }, NULL, NULL, + BT_ISA_Config +}; + +const device_t buslogic_542bh_device = { + "BusLogic BT-542BH ISA", + DEVICE_ISA | DEVICE_AT, + CHIP_BUSLOGIC_ISA_542BH_1993_05_23, + buslogic_init, x54x_close, NULL, + { NULL }, NULL, NULL, + BT_ISA_Config +}; + +const device_t buslogic_545c_device = { + "BusLogic BT-545C ISA", + DEVICE_ISA | DEVICE_AT, + CHIP_BUSLOGIC_ISA_545C_1994_12_01, buslogic_init, x54x_close, NULL, { NULL }, NULL, NULL, BT_ISA_Config @@ -1878,7 +1947,7 @@ const device_t buslogic_545s_device = { const device_t buslogic_640a_device = { "BusLogic BT-640A MCA", DEVICE_MCA, - CHIP_BUSLOGIC_MCA, + CHIP_BUSLOGIC_MCA_640A_1993_05_23, buslogic_init, x54x_close, NULL, { NULL }, NULL, NULL, NULL @@ -1887,16 +1956,25 @@ const device_t buslogic_640a_device = { const device_t buslogic_445s_device = { "BusLogic BT-445S VLB", DEVICE_VLB, - CHIP_BUSLOGIC_VLB, + CHIP_BUSLOGIC_VLB_445S_1993_11_16, buslogic_init, x54x_close, NULL, { NULL }, NULL, NULL, BT_ISA_Config }; -const device_t buslogic_pci_device = { +const device_t buslogic_445c_device = { + "BusLogic BT-445C VLB", + DEVICE_VLB, + CHIP_BUSLOGIC_VLB_445C_1994_12_01, + buslogic_init, x54x_close, NULL, + { NULL }, NULL, NULL, + BT_ISA_Config +}; + +const device_t buslogic_958d_pci_device = { "BusLogic BT-958D PCI", DEVICE_PCI, - CHIP_BUSLOGIC_PCI, + CHIP_BUSLOGIC_PCI_958D_1995_12_30, buslogic_init, x54x_close, NULL, { NULL }, NULL, NULL, BT958D_Config diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index e3420ac01..464e5c45a 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -13,12 +13,17 @@ # Copyright 2020,2021 David Hrdlička. # -add_library(snd OBJECT sound.c openal.c snd_opl.c snd_opl_nuked.c snd_resid.cc +add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_resid.cc 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_lpt_dss.c snd_ps1.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(OPENAL) + target_compile_definitions(snd PRIVATE USE_OPENAL) + target_sources(snd PRIVATE openal.c) +endif() + if(FLUIDSYNTH) target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) target_sources(snd PRIVATE midi_fluidsynth.c) diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index a93618cd4..1a3ae2764 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -40,8 +40,10 @@ enum fluid_interp { }; +#ifdef USE_OPENAL extern void givealbuffer_midi(void *buf, uint32_t size); extern void al_set_midi(int freq, int buf_size); +#endif static void *fluidsynth_handle; /* handle to FluidSynth DLL */ @@ -150,7 +152,9 @@ static void fluidsynth_thread(void *param) buf_pos += buf_size; if (buf_pos >= data->buf_size) { +#ifdef USE_OPENAL givealbuffer_midi(data->buffer, data->buf_size / sizeof(float)); +#endif buf_pos = 0; } } @@ -163,7 +167,9 @@ static void fluidsynth_thread(void *param) buf_pos += buf_size; if (buf_pos >= data->buf_size) { +#ifdef USE_OPENAL givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t)); +#endif buf_pos = 0; } } @@ -314,7 +320,9 @@ void* fluidsynth_init(const device_t *info) data->buffer_int16 = malloc(data->buf_size); } +#ifdef USE_OPENAL al_set_midi(data->samplerate, data->buf_size); +#endif dev = malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 8ade99b51..ed87411cc 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -13,8 +13,10 @@ #include <86box/midi.h> +#ifdef USE_OPENAL extern void givealbuffer_midi(void *buf, uint32_t size); extern void al_set_midi(int freq, int buf_size); +#endif static const mt32emu_report_handler_i_v0 handler_v0 = { /** Returns the actual interface version ID */ @@ -136,7 +138,9 @@ static void mt32_thread(void *param) buf_pos += bsize; if (buf_pos >= buf_size) { +#ifdef USE_OPENAL givealbuffer_midi(buffer, buf_size / sizeof(float)); +#endif buf_pos = 0; } } @@ -148,7 +152,9 @@ static void mt32_thread(void *param) buf_pos += bsize; if (buf_pos >= buf_size) { +#ifdef USE_OPENAL givealbuffer_midi(buffer_int16, buf_size / sizeof(int16_t)); +#endif buf_pos = 0; } } @@ -200,7 +206,9 @@ void* mt32emu_init(char *control_rom, char *pcm_rom) mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo")); mt32emu_set_nice_amp_ramp_enabled(context, device_get_config_int("nice_ramp")); +#ifdef USE_OPENAL al_set_midi(samplerate, buf_size); +#endif dev = malloc(sizeof(midi_device_t)); memset(dev, 0, sizeof(midi_device_t)); diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index da8c66c93..fea4052d2 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -40,7 +40,7 @@ typedef struct adgold_t int adgold_mma_intpos[2]; pc_timer_t adgold_mma_timer_count; - + uint8_t adgold_midi_ctrl, midi_queue[16]; int midi_r, midi_w; int uart_in, uart_out, sysex; @@ -57,7 +57,7 @@ typedef struct adgold_t opl_t opl; ym7128_t ym7128; - + int fm_vol_l, fm_vol_r; int samp_vol_l, samp_vol_r; int aux_vol_l, aux_vol_r; @@ -85,7 +85,7 @@ static int bass_attenuation[0x10] = (int)(0.708 * 16384), /*3 dB*/ (int)(0 * 16384), /*0 dB*/ (int)(0.708 * 16384), /*3 dB*/ - (int)(1 * 16384), /*6 dB*/ + (int)(1 * 16384), /*6 dB*/ (int)(1.413 * 16384), /*9 dB*/ (int)(1.995 * 16384), /*12 dB*/ (int)(2.819 * 16384), /*15 dB*/ @@ -115,7 +115,7 @@ static int treble_attenuation[0x10] = (int)(0.708 * 16384), /*3 dB*/ (int)(0 * 16384), /*0 dB*/ (int)(0.708 * 16384), /*3 dB*/ - (int)(1 * 16384), /*6 dB*/ + (int)(1 * 16384), /*6 dB*/ (int)(1.413 * 16384), /*9 dB*/ (int)(1.995 * 16384), /*12 dB*/ (int)(1.995 * 16384), @@ -171,10 +171,10 @@ void adgold_update_irq_status(adgold_t *adgold) void adgold_getsamp_dma(adgold_t *adgold, int channel) { int temp; - + if ((adgold->adgold_mma_regs[channel][0xc] & 0x60) && (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= 127)) return; - + temp = dma_channel_read(1); if (temp == DMA_NODATA) return; adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; @@ -184,7 +184,7 @@ void adgold_getsamp_dma(adgold_t *adgold, int channel) temp = dma_channel_read(1); adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; - } + } if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) >= adgold->adgold_mma_intpos[channel]) { adgold->adgold_mma_status &= ~(0x01 << channel); @@ -208,7 +208,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) return; } if (val == 0xfe) - { + { adgold->adgold_38x_state = 0; return; } @@ -229,7 +229,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) if (val & 2) memcpy(adgold->adgold_eeprom, adgold->adgold_38x_regs, 0x1a); break; - + case 0x04: /*Final output volume left*/ adgold->adgold_38x_regs[0x04] = val; adgold->vol_l = attenuation[val & 0x3f]; @@ -246,7 +246,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) adgold->adgold_38x_regs[0x07] = val; adgold->treble = val & 0xf; break; - + case 0x09: /*FM volume left*/ adgold->adgold_38x_regs[0x09] = val; adgold->fm_vol_l = (int)(int8_t)(val - 128); @@ -271,12 +271,12 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) adgold->adgold_38x_regs[0x0e] = val; adgold->aux_vol_r = (int)(int8_t)(val - 128); break; - + case 0x18: /*Surround*/ adgold->adgold_38x_regs[0x18] = val; ym7128_write(&adgold->ym7128, val); break; - + default: adgold->adgold_38x_regs[adgold->adgold_38x_addr] = val; break; @@ -311,11 +311,11 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) case 0x7: adgold->adgold_mma.timer2_latch = (adgold->adgold_mma.timer2_latch & 0xff) | (val << 8); break; - + case 0x8: if ((val & 1) && !(adgold->adgold_mma_regs[0][8] & 1)) /*Reload timer 0*/ adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; - + if ((val & 2) && !(adgold->adgold_mma_regs[0][8] & 2)) /*Reload timer 1*/ adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; @@ -325,7 +325,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) if ((val & 8) && !(adgold->adgold_mma_regs[0][8] & 8)) /*Reload base timer*/ adgold->adgold_mma.timerbase_count = adgold->adgold_mma.timerbase_latch; break; - + case 0x9: switch (val & 0x18) { @@ -345,7 +345,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) { if (!(adgold->adgold_mma_regs[0][0x9] & 1)) adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; - + if (adgold->adgold_mma_regs[0][0xc] & 1) { if (adgold->adgold_mma_regs[0][0xc] & 0x80) @@ -385,7 +385,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) } adgold->adgold_mma_enable[0] = val & 0x01; break; - + case 0xb: if (((adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255) < 128) { @@ -398,14 +398,14 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) } } break; - + case 0xc: adgold->adgold_mma_intpos[0] = (7 - ((val >> 2) & 7)) * 8; break; - + case 0xd: adgold->adgold_midi_ctrl = val & 0x3f; - + if ((adgold->adgold_midi_ctrl & 0x0f) != 0x0f) { if ((adgold->adgold_midi_ctrl & 0x0f) == 0x00) { adgold->uart_out = 0; @@ -432,7 +432,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) adgold_update_irq_status(adgold); break; - + case 0xe: if (adgold->uart_out) { midi_raw_out_byte(val); @@ -468,7 +468,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) { if (!(adgold->adgold_mma_regs[1][0x9] & 1)) adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; - + if (adgold->adgold_mma_regs[1][0xc] & 1) { while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) @@ -479,7 +479,7 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) } adgold->adgold_mma_enable[1] = val & 0x01; break; - + case 0xb: if (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) { @@ -506,7 +506,7 @@ uint8_t adgold_read(uint16_t addr, void *p) { adgold_t *adgold = (adgold_t *)p; uint8_t temp = 0; - + switch (addr & 7) { case 0: case 1: @@ -519,7 +519,7 @@ uint8_t adgold_read(uint16_t addr, void *p) else temp = opl3_read(addr, &adgold->opl); break; - + case 3: if (adgold->adgold_38x_state) { @@ -535,7 +535,7 @@ uint8_t adgold_read(uint16_t addr, void *p) default: temp = adgold->adgold_38x_regs[adgold->adgold_38x_addr]; - } + } } else temp = opl3_read(addr, &adgold->opl); @@ -592,7 +592,7 @@ void adgold_update(adgold_t *adgold) for (; adgold->pos < sound_pos_global; adgold->pos++) { adgold->mma_buffer[0][adgold->pos] = adgold->mma_buffer[1][adgold->pos] = 0; - + if (adgold->adgold_mma_regs[0][9] & 0x20) adgold->mma_buffer[0][adgold->pos] += adgold->adgold_mma_out[0] / 2; if (adgold->adgold_mma_regs[0][9] & 0x40) @@ -620,11 +620,11 @@ void adgold_mma_poll(adgold_t *adgold, int channel) adgold->adgold_mma_out[channel] = dat; adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; break; - + case 0x40: /*12-bit sensible format*/ if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < 2) return; - + dat = adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] & 0xf0; adgold->adgold_mma_fifo_start[channel] = (adgold->adgold_mma_fifo_start[channel] + 1) & 255; dat |= (adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_start[channel]] << 8); @@ -632,7 +632,7 @@ void adgold_mma_poll(adgold_t *adgold, int channel) adgold->adgold_mma_out[channel] = dat; break; } - + if (adgold->adgold_mma_regs[channel][0xc] & 1) { adgold_getsamp_dma(adgold, channel); @@ -652,9 +652,9 @@ void adgold_mma_poll(adgold_t *adgold, int channel) void adgold_timer_poll(void *p) { adgold_t *adgold = (adgold_t *)p; - + timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t)((double)TIMER_USEC * 1.88964)); - + if (adgold->adgold_midi_ctrl & 0x3f) { if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) { if (adgold->uart_out) @@ -729,7 +729,7 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *p) adgold_t *adgold = (adgold_t *)p; int16_t* adgold_buffer = malloc(sizeof(int16_t) * len * 2); if (adgold_buffer == NULL) fatal("adgold_buffer = NULL"); - + int c; opl3_update(&adgold->opl); @@ -745,7 +745,7 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *p) if (adgold->surround_enabled) ym7128_apply(&adgold->ym7128, adgold_buffer, len); - + switch (adgold->adgold_38x_regs[0x8] & 6) { case 0: @@ -763,7 +763,7 @@ static void adgold_get_buffer(int32_t *buffer, int len, void *p) case 6: /*Left and right channels*/ break; } - + switch (adgold->adgold_38x_regs[0x8] & 0x18) { case 0x00: /*Forced mono*/ @@ -855,10 +855,10 @@ static void adgold_input_msg(void *p, uint8_t *msg, uint32_t len) { adgold_t *adgold = (adgold_t *)p; uint8_t i; - + if (adgold->sysex) return; - + if (adgold->uart_in) { adgold->adgold_mma_status |= 0x04; @@ -866,7 +866,7 @@ static void adgold_input_msg(void *p, uint8_t *msg, uint32_t len) adgold->midi_queue[adgold->midi_w++] = msg[i]; adgold->midi_w &= 0x0f; } - + adgold_update_irq_status(adgold); } } @@ -875,7 +875,7 @@ static int adgold_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort) { adgold_t *adgold = (adgold_t *)p; uint32_t i; - + if (abort) { adgold->sysex = 0; return 0; @@ -903,7 +903,7 @@ void *adgold_init(const device_t *info) adgold->surround_enabled = device_get_config_int("surround"); adgold->gameport_enabled = device_get_config_int("gameport"); - + opl3_init(&adgold->opl); if (adgold->surround_enabled) ym7128_init(&adgold->ym7128); @@ -917,6 +917,33 @@ void *adgold_init(const device_t *info) for (; c >= 0; c--) attenuation[c] = 0; + adgold->adgold_eeprom[0x00] = 0x00; + adgold->adgold_eeprom[0x01] = 0x00; + adgold->adgold_eeprom[0x02] = 0x7f; + adgold->adgold_eeprom[0x03] = 0x7f; + adgold->adgold_eeprom[0x04] = 0xf8; /* vol_l */ + adgold->adgold_eeprom[0x05] = 0xf8; /* vol_r */ + adgold->adgold_eeprom[0x06] = 0xf6; /* bass */ + adgold->adgold_eeprom[0x07] = 0xf6; /* treble */ + adgold->adgold_eeprom[0x08] = 0xce; + adgold->adgold_eeprom[0x09] = 0xff; /* fm_vol_l */ + adgold->adgold_eeprom[0x0a] = 0xff; /* fm_vol_r */ + adgold->adgold_eeprom[0x0b] = 0xff; /* samp_vol_l */ + adgold->adgold_eeprom[0x0c] = 0xff; /* samp_vol_r */ + adgold->adgold_eeprom[0x0d] = 0xff; /* aux_vol_l */ + adgold->adgold_eeprom[0x0e] = 0xff; /* aux_vol_r */ + adgold->adgold_eeprom[0x0f] = 0xff; + adgold->adgold_eeprom[0x10] = 0xff; + adgold->adgold_eeprom[0x11] = 0x20; + adgold->adgold_eeprom[0x12] = 0x00; + adgold->adgold_eeprom[0x13] = 0x0b; /* IRQ 1, DMA1 */ + adgold->adgold_eeprom[0x14] = 0x00; /* DMA2 */ + adgold->adgold_eeprom[0x15] = 0x71; /* Port */ + adgold->adgold_eeprom[0x16] = 0x00; + adgold->adgold_eeprom[0x17] = 0x68; + adgold->adgold_eeprom[0x18] = 0x00; /* Surround */ + adgold->adgold_eeprom[0x19] = 0x00; + f = nvr_fopen("adgold.bin", "rb"); if (f) { @@ -927,8 +954,9 @@ void *adgold_init(const device_t *info) adgold->adgold_status = 0xf; adgold->adgold_38x_addr = 0; - adgold->adgold_eeprom[0x13] = 3 | (1 << 4); /*IRQ 7, DMA 1*/ - adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3*/ + adgold->adgold_eeprom[0x13] = 3 | (1 << 3); /*IRQ 7, DMA 1*/ +// adgold->adgold_eeprom[0x14] = 3 << 4; /*DMA 3 - Double check this */ + adgold->adgold_eeprom[0x14] = 0x00; /*DMA ?*/ adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; @@ -940,25 +968,25 @@ void *adgold_init(const device_t *info) adgold->samp_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0b] - 128); adgold->samp_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0c] - 128); adgold->aux_vol_l = (int)(int8_t)(adgold->adgold_eeprom[0x0d] - 128); - adgold->aux_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0e] - 128); + adgold->aux_vol_r = (int)(int8_t)(adgold->adgold_eeprom[0x0e] - 128); adgold->adgold_mma_enable[0] = 0; adgold->adgold_mma_fifo_start[0] = adgold->adgold_mma_fifo_end[0] = 0; - + /*388/389 are handled by adlib_init*/ io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); - + if (adgold->gameport_enabled) gameport_remap(gameport_add(&gameport_201_device), 0x201); - + timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1); sound_add_handler(adgold_get_buffer, adgold); sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold); - + if (device_get_config_int("receive_input")) midi_in_handler(1, adgold_input_msg, adgold_input_sysex, adgold); - + return adgold; } @@ -966,7 +994,7 @@ void adgold_close(void *p) { FILE *f; adgold_t *adgold = (adgold_t *)p; - + f = nvr_fopen("adgold.bin", "wb"); if (f) { diff --git a/src/sound/snd_ps1.c b/src/sound/snd_ps1.c new file mode 100644 index 000000000..e9455a327 --- /dev/null +++ b/src/sound/snd_ps1.c @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/pic.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/sound.h> +#include <86box/snd_sn76489.h> + + +typedef struct { + sn76489_t sn76489; + uint8_t status, ctrl; + uint64_t timer_latch; + pc_timer_t timer_count; + int timer_enable; + uint8_t fifo[2048]; + int fifo_read_idx, fifo_write_idx; + int fifo_threshold; + uint8_t dac_val; + int16_t buffer[SOUNDBUFLEN]; + int pos; +} ps1snd_t; + + +static void +ps1snd_update_irq_status(ps1snd_t *snd) +{ + if (((snd->status & snd->ctrl) & 0x12) && (snd->ctrl & 0x01)) + picint(1 << 7); + else + picintc(1 << 7); +} + + +static uint8_t +ps1snd_read(uint16_t port, void *priv) +{ + ps1snd_t *ps1snd = (ps1snd_t *)priv; + uint8_t ret = 0xff; + + switch (port & 7) { + case 0: /* ADC data */ + ps1snd->status &= ~0x10; + ps1snd_update_irq_status(ps1snd); + ret = 0; + break; + + case 2: /* status */ + ret = ps1snd->status; + ret |= (ps1snd->ctrl & 0x01); + if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) >= 2048) + ret |= 0x08; /* FIFO full */ + if (ps1snd->fifo_read_idx == ps1snd->fifo_write_idx) + ret |= 0x04; /* FIFO empty */ + break; + + case 3: /* FIFO timer */ + /* + * The PS/1 Technical Reference says this should return + * thecurrent value, but the PS/1 BIOS and Stunt Island + * expect it not to change. + */ + ret = ps1snd->timer_latch; + break; + + case 4: + case 5: + case 6: + case 7: + ret = 0; + } + + return(ret); +} + + +static void +ps1snd_write(uint16_t port, uint8_t val, void *priv) +{ + ps1snd_t *ps1snd = (ps1snd_t *)priv; + + switch (port & 7) { + case 0: /* DAC output */ + if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) < 2048) { + ps1snd->fifo[ps1snd->fifo_write_idx & 2047] = val; + ps1snd->fifo_write_idx++; + } + break; + + case 2: /* control */ + ps1snd->ctrl = val; + if (! (val & 0x02)) + ps1snd->status &= ~0x02; + ps1snd_update_irq_status(ps1snd); + break; + + case 3: /* timer reload value */ + ps1snd->timer_latch = val; + if (val) + timer_set_delay_u64(&ps1snd->timer_count, ((0xff-val) * TIMER_USEC)); + else + timer_disable(&ps1snd->timer_count); + break; + + case 4: /* almost empty */ + ps1snd->fifo_threshold = val * 4; + break; + } +} + + +static void +ps1snd_update(ps1snd_t *ps1snd) +{ + for (; ps1snd->pos < sound_pos_global; ps1snd->pos++) + ps1snd->buffer[ps1snd->pos] = (int8_t)(ps1snd->dac_val ^ 0x80) * 0x20; +} + + +static void +ps1snd_callback(void *priv) +{ + ps1snd_t *ps1snd = (ps1snd_t *)priv; + + ps1snd_update(ps1snd); + + if (ps1snd->fifo_read_idx != ps1snd->fifo_write_idx) { + ps1snd->dac_val = ps1snd->fifo[ps1snd->fifo_read_idx & 2047]; + ps1snd->fifo_read_idx++; + } + + if ((ps1snd->fifo_write_idx - ps1snd->fifo_read_idx) == ps1snd->fifo_threshold) + ps1snd->status |= 0x02; /*FIFO almost empty*/ + + ps1snd->status |= 0x10; /*ADC data ready*/ + ps1snd_update_irq_status(ps1snd); + + timer_advance_u64(&ps1snd->timer_count, ps1snd->timer_latch * TIMER_USEC); +} + + +static void +ps1snd_get_buffer(int32_t *buffer, int len, void *priv) +{ + ps1snd_t *ps1snd = (ps1snd_t *)priv; + int c; + + ps1snd_update(ps1snd); + + for (c = 0; c < len * 2; c++) + buffer[c] += ps1snd->buffer[c >> 1]; + + ps1snd->pos = 0; +} + + +static void * +ps1snd_init(const device_t *info) +{ + ps1snd_t *ps1snd = malloc(sizeof(ps1snd_t)); + memset(ps1snd, 0x00, sizeof(ps1snd_t)); + + sn76489_init(&ps1snd->sn76489, 0x0205, 0x0001, SN76496, 4000000); + + io_sethandler(0x0200, 1, ps1snd_read,NULL,NULL, ps1snd_write,NULL,NULL, ps1snd); + io_sethandler(0x0202, 6, ps1snd_read,NULL,NULL, ps1snd_write,NULL,NULL, ps1snd); + + timer_add(&ps1snd->timer_count, ps1snd_callback, ps1snd, 0); + + sound_add_handler(ps1snd_get_buffer, ps1snd); + + return(ps1snd); +} + + +static void +ps1snd_close(void *priv) +{ + ps1snd_t *ps1snd = (ps1snd_t *)priv; + + free(ps1snd); +} + + +const device_t ps1snd_device = { + "IBM PS/1 Audio Card", + 0, 0, + ps1snd_init, ps1snd_close, + NULL, + { NULL }, + NULL, + NULL, + NULL +}; diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 4eab5c856..6ef24c679 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -15,233 +15,289 @@ typedef struct pssj_t { - sn76489_t sn76489; - - uint8_t ctrl; - uint8_t wave; - uint8_t dac_val; - uint16_t freq; - int amplitude; - - int irq; - pc_timer_t timer_count; - int enable; - - int wave_pos; - int pulse_width; + sn76489_t sn76489; - int16_t buffer[SOUNDBUFLEN]; - int pos; + uint8_t ctrl; + uint8_t wave; + uint8_t dac_val; + uint16_t freq; + int amplitude; + + int irq; + pc_timer_t timer_count; + int enable; + + int wave_pos; + int pulse_width; + + int16_t buffer[SOUNDBUFLEN]; + int pos; } pssj_t; static void pssj_update_irq(pssj_t *pssj) { - if (pssj->irq && (pssj->ctrl & 0x10) && (pssj->ctrl & 0x08)) - picint(1 << 7); + if (pssj->irq && (pssj->ctrl & 0x10) && (pssj->ctrl & 0x08)) + picint(1 << 7); } static void pssj_write(uint16_t port, uint8_t val, void *p) { - pssj_t *pssj = (pssj_t *)p; + pssj_t *pssj = (pssj_t *)p; - switch (port & 3) - { - case 0: - pssj->ctrl = val; - if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3))) - timer_set_delay_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); - pssj->enable = (val & 4) && (pssj->ctrl & 3); - if (!pssj->enable) - timer_disable(&pssj->timer_count); - sn74689_set_extra_divide(&pssj->sn76489, val & 0x40); - if (!(val & 8)) - pssj->irq = 0; - pssj_update_irq(pssj); - break; - case 1: - switch (pssj->ctrl & 3) - { - case 1: /*Sound channel*/ - pssj->wave = val; - pssj->pulse_width = val & 7; - break; - case 3: /*Direct DAC*/ - pssj->dac_val = val; - break; - } - break; - case 2: - pssj->freq = (pssj->freq & 0xf00) | val; - break; - case 3: - pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8); - pssj->amplitude = val >> 4; - break; - } + switch (port & 3) + { + case 0: + pssj->ctrl = val; + if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3))) + timer_set_delay_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); + pssj->enable = (val & 4) && (pssj->ctrl & 3); + if (!pssj->enable) + timer_disable(&pssj->timer_count); + sn74689_set_extra_divide(&pssj->sn76489, val & 0x40); + if (!(val & 8)) + pssj->irq = 0; + pssj_update_irq(pssj); + break; + case 1: + switch (pssj->ctrl & 3) + { + case 1: /*Sound channel*/ + pssj->wave = val; + pssj->pulse_width = val & 7; + break; + case 3: /*Direct DAC*/ + pssj->dac_val = val; + break; + } + break; + case 2: + pssj->freq = (pssj->freq & 0xf00) | val; + break; + case 3: + pssj->freq = (pssj->freq & 0x0ff) | ((val & 0xf) << 8); + pssj->amplitude = val >> 4; + break; + } } static uint8_t pssj_read(uint16_t port, void *p) { - pssj_t *pssj = (pssj_t *)p; - - switch (port & 3) - { - case 0: - return (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0); - case 1: - switch (pssj->ctrl & 3) - { - case 0: /*Joystick*/ - return 0; - case 1: /*Sound channel*/ - return pssj->wave; - case 2: /*Successive approximation*/ - return 0x80; - case 3: /*Direct DAC*/ - return pssj->dac_val; - } - break; - case 2: - return pssj->freq & 0xff; - case 3: - return (pssj->freq >> 8) | (pssj->amplitude << 4); - default: - return 0xff; - } + pssj_t *pssj = (pssj_t *)p; - return 0xff; + switch (port & 3) + { + case 0: + return (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0); + case 1: + switch (pssj->ctrl & 3) + { + case 0: /*Joystick*/ + return 0; + case 1: /*Sound channel*/ + return pssj->wave; + case 2: /*Successive approximation*/ + return 0x80; + case 3: /*Direct DAC*/ + return pssj->dac_val; + } + break; + case 2: + return pssj->freq & 0xff; + case 3: + return (pssj->freq >> 8) | (pssj->amplitude << 4); + default: + return 0xff; + } + + return 0xff; } static void pssj_update(pssj_t *pssj) { - for (; pssj->pos < sound_pos_global; pssj->pos++) - pssj->buffer[pssj->pos] = (((int8_t)(pssj->dac_val ^ 0x80) * 0x20) * pssj->amplitude) / 15; + for (; pssj->pos < sound_pos_global; pssj->pos++) + pssj->buffer[pssj->pos] = (((int8_t)(pssj->dac_val ^ 0x80) * 0x20) * pssj->amplitude) / 15; } static void pssj_callback(void *p) { - pssj_t *pssj = (pssj_t *)p; - int data; + pssj_t *pssj = (pssj_t *)p; + int data; - pssj_update(pssj); - if (pssj->ctrl & 2) + pssj_update(pssj); + if (pssj->ctrl & 2) + { + if ((pssj->ctrl & 3) == 3) { - if ((pssj->ctrl & 3) == 3) - { - data = dma_channel_read(1); + data = dma_channel_read(1); - if (data != DMA_NODATA) - { - pssj->dac_val = data & 0xff; - } - } - else - { - data = dma_channel_write(1, 0x80); - } - - if ((data & DMA_OVER) && data != DMA_NODATA) - { - if (pssj->ctrl & 0x08) - { - pssj->irq = 1; - pssj_update_irq(pssj); - } - } + if (data != DMA_NODATA) + { + pssj->dac_val = data & 0xff; + } } else { - switch (pssj->wave & 0xc0) - { - case 0x00: /*Pulse*/ - pssj->dac_val = (pssj->wave_pos > (pssj->pulse_width << 1)) ? 0xff : 0; - break; - case 0x40: /*Ramp*/ - pssj->dac_val = pssj->wave_pos << 3; - break; - case 0x80: /*Triangle*/ - if (pssj->wave_pos & 16) - pssj->dac_val = (pssj->wave_pos ^ 31) << 4; - else - pssj->dac_val = pssj->wave_pos << 4; - break; - case 0xc0: - pssj->dac_val = 0x80; - break; - } - pssj->wave_pos = (pssj->wave_pos + 1) & 31; + data = dma_channel_write(1, 0x80); } - timer_advance_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); + if ((data & DMA_OVER) && data != DMA_NODATA) + { + if (pssj->ctrl & 0x08) + { + pssj->irq = 1; + pssj_update_irq(pssj); + } + } + } + else + { + switch (pssj->wave & 0xc0) + { + case 0x00: /*Pulse*/ + pssj->dac_val = (pssj->wave_pos > (pssj->pulse_width << 1)) ? 0xff : 0; + break; + case 0x40: /*Ramp*/ + pssj->dac_val = pssj->wave_pos << 3; + break; + case 0x80: /*Triangle*/ + if (pssj->wave_pos & 16) + pssj->dac_val = (pssj->wave_pos ^ 31) << 4; + else + pssj->dac_val = pssj->wave_pos << 4; + break; + case 0xc0: + pssj->dac_val = 0x80; + break; + } + pssj->wave_pos = (pssj->wave_pos + 1) & 31; + } + + timer_advance_u64(&pssj->timer_count, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); } static void pssj_get_buffer(int32_t *buffer, int len, void *p) { - pssj_t *pssj = (pssj_t *)p; - int c; - - pssj_update(pssj); - - for (c = 0; c < len * 2; c++) - buffer[c] += pssj->buffer[c >> 1]; + pssj_t *pssj = (pssj_t *)p; + int c; - pssj->pos = 0; + pssj_update(pssj); + + for (c = 0; c < len * 2; c++) + buffer[c] += pssj->buffer[c >> 1]; + + pssj->pos = 0; } void *pssj_init(const device_t *info) { - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); + pssj_t *pssj = malloc(sizeof(pssj_t)); + memset(pssj, 0, sizeof(pssj_t)); - sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); + sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); - io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); - timer_add(&pssj->timer_count, pssj_callback, pssj, pssj->enable); - sound_add_handler(pssj_get_buffer, pssj); - - return pssj; + io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); + timer_add(&pssj->timer_count, pssj_callback, pssj, pssj->enable); + sound_add_handler(pssj_get_buffer, pssj); + + return pssj; } void *pssj_1e0_init(const device_t *info) { - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); + pssj_t *pssj = malloc(sizeof(pssj_t)); + memset(pssj, 0, sizeof(pssj_t)); - sn76489_init(&pssj->sn76489, 0x01e0, 0x0004, PSSJ, 3579545); + sn76489_init(&pssj->sn76489, 0x01e0, 0x0004, PSSJ, 3579545); - io_sethandler(0x01E4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); - timer_add(&pssj->timer_count, pssj_callback, pssj, pssj->enable); - sound_add_handler(pssj_get_buffer, pssj); - - return pssj; + io_sethandler(0x01E4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); + timer_add(&pssj->timer_count, pssj_callback, pssj, pssj->enable); + sound_add_handler(pssj_get_buffer, pssj); + + return pssj; +} + +void *pssj_isa_init(const device_t *info) +{ + pssj_t *pssj = malloc(sizeof(pssj_t)); + memset(pssj, 0, sizeof(pssj_t)); + + sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); + + uint16_t addr = device_get_config_hex16("base"); + + io_sethandler(addr, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); + timer_add(&pssj->timer_count, pssj_callback, pssj, pssj->enable); + sound_add_handler(pssj_get_buffer, pssj); + + return pssj; } void pssj_close(void *p) { - pssj_t *pssj = (pssj_t *)p; + pssj_t *pssj = (pssj_t *)p; - free(pssj); + free(pssj); } +static const device_config_t pssj_isa_config[] = +{ + { + "base", "Address", CONFIG_HEX16, "", 0xC0, "", { 0 }, + { + { + "0xC0", 0xC0 + }, + { + "0x1E0", 0x1E0 + }, + { + "0x2C0", 0x2C0 + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + const device_t pssj_device = { - "Tandy PSSJ", - 0, 0, - pssj_init, - pssj_close, - NULL, - { NULL }, - NULL, - NULL + "Tandy PSSJ", + 0, + 0, + pssj_init, + pssj_close, + NULL, + { NULL }, + NULL, + NULL }; const device_t pssj_1e0_device = { - "Tandy PSSJ (port 1e0h)", - 0, 0, - pssj_1e0_init, - pssj_close, - NULL, - { NULL }, - NULL, - NULL + "Tandy PSSJ (port 1e0h)", + 0, + 0, + pssj_1e0_init, + pssj_close, + NULL, + { NULL }, + NULL, + NULL +}; + +const device_t pssj_isa_device = +{ + "Tandy PSSJ (ISA Clone)", + DEVICE_ISA, + 0, + pssj_isa_init, + pssj_close, + NULL, + { NULL }, + NULL, + NULL, + pssj_isa_config }; diff --git a/src/sound/sound.c b/src/sound/sound.c index 4ab9cf58e..892f6a689 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -85,6 +85,7 @@ static const SOUND_CARD sound_cards[] = { { "none", NULL }, { "internal", NULL }, + { "pssj_isa", &pssj_isa_device }, { "adlib", &adlib_device }, { "adlibgold", &adgold_device }, { "azt2316a", &azt2316a_device }, @@ -323,10 +324,12 @@ sound_cd_thread(void *param) } } +#ifdef USE_OPENAL if (sound_is_float) givealbuffer_cd(cd_out_buffer); else givealbuffer_cd(cd_out_buffer_int16); +#endif } } @@ -430,10 +433,12 @@ sound_poll(void *priv) } } +#ifdef USE_OPENAL if (sound_is_float) givealbuffer(outbuffer_ex); else givealbuffer(outbuffer_ex_int16); +#endif if (cd_thread_enable) { cd_buf_update--; @@ -462,7 +467,9 @@ sound_reset(void) midi_device_init(); midi_in_device_init(); +#ifdef USE_OPENAL inital(); +#endif timer_add(&sound_poll_timer, sound_poll, NULL, 1); diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 6c9660bb8..1dd60a3e4 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -31,45 +31,9 @@ #include <86box/pit.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/vid_hercules.h> -typedef struct { - mem_mapping_t mapping; - - uint8_t crtc[32], charbuffer[4096]; - int crtcreg; - - uint8_t ctrl, - ctrl2, - stat; - - uint64_t dispontime, - dispofftime; - pc_timer_t timer; - - int firstline, - lastline; - - int linepos, - displine; - int vc, - sc; - uint16_t ma, - maback; - int con, coff, - cursoron; - int dispon, - blink; - int vsynctime; - int vadj; - - int lp_ff; - - int cols[256][2][2]; - - uint8_t *vram; -} hercules_t; - static video_timings_t timing_hercules = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index d7a961925..1796e9049 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -41,6 +41,7 @@ #define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" #define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" #define ROM_METHEUS_86C928 "roms/video/s3/928.VBI" +#define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" #define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" #define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" #define ROM_MIROCRYSTAL8S_805 "roms/video/s3/S3_805VL_ATT20C491_miroCRYSTAL_8s_ver1.4.BIN" @@ -104,7 +105,8 @@ enum S3_PHOENIX_VISION968, S3_MIROCRYSTAL8S_805, S3_NUMBER9_9FX_531, - S3_NUMBER9_9FX_771 + S3_NUMBER9_9FX_771, + S3_SPEA_MERCURY_LITE_PCI }; @@ -113,22 +115,24 @@ enum S3_86C911 = 0x00, S3_86C924 = 0x02, S3_86C928 = 0x04, - S3_86C801 = 0x06, - S3_86C805 = 0x07, - S3_VISION964 = 0x08, - S3_VISION968 = 0x10, - S3_VISION864 = 0x18, - S3_VISION868 = 0x20, - S3_TRIO32 = 0x28, - S3_TRIO64 = 0x30, - S3_TRIO64V = 0x38, - S3_TRIO64V2 = 0x40 + S3_86C928PCI = 0x06, + S3_86C801 = 0x07, + S3_86C805 = 0x08, + S3_VISION964 = 0x18, + S3_VISION968 = 0x20, + S3_VISION864 = 0x28, + S3_VISION868 = 0x30, + S3_TRIO32 = 0x38, + S3_TRIO64 = 0x40, + S3_TRIO64V = 0x48, + S3_TRIO64V2 = 0x50 }; static video_timings_t timing_s3_86c911 = {VIDEO_ISA, 4, 4, 5, 20, 20, 35}; static video_timings_t timing_s3_86c801 = {VIDEO_ISA, 4, 4, 5, 20, 20, 35}; static video_timings_t timing_s3_86c805 = {VIDEO_BUS, 4, 4, 5, 20, 20, 35}; +static video_timings_t timing_s3_86c928pci = {VIDEO_PCI, 2, 2, 4, 26, 26, 42}; static video_timings_t timing_s3_stealth64_vlb = {VIDEO_BUS, 2, 2, 4, 26, 26, 42}; static video_timings_t timing_s3_stealth64_pci = {VIDEO_PCI, 2, 2, 4, 26, 26, 42}; static video_timings_t timing_s3_vision864_vlb = {VIDEO_BUS, 4, 4, 5, 20, 20, 35}; @@ -563,7 +567,7 @@ static void s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) { svga_t *svga = &s3->svga; - + if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: @@ -1173,7 +1177,8 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) else s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); } else { - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); + if (s3->chip != S3_86C928PCI) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); } break; } @@ -1197,7 +1202,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) } break; case 0x200: - /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928*/ + /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928 ISA/VLB*/ if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) @@ -1205,7 +1210,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) else s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); } else { - if (s3->chip == S3_86C928) + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); else { if (s3->accel.cmd & 0x1000) @@ -1214,6 +1219,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); } } + } else { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); + else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } } break; case 0x400: @@ -1261,7 +1275,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); break; case 0x200: - /*Windows 95's built-in driver expects the upper 16 bits to be loaded instead of the whole 32-bit one, regardless of the byte swap bit (0xE2EB) in the 86c928*/ + /*Windows 95's built-in driver expects the upper 16 bits to be loaded instead of the whole 32-bit one, regardless of the byte swap bit (0xE2EB) in the 86c928 ISA/VLB card*/ if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { if (s3->accel.cmd & 0x1000) @@ -1269,7 +1283,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) else s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); } else { - if (s3->chip == S3_86C928) + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); else { if (s3->accel.cmd & 0x1000) @@ -1278,6 +1292,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); } } + } else { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); + else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } } break; case 0x400: @@ -1360,7 +1383,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) if ((addr >= 0x08000) && (addr <= 0x0803f)) s3_pci_write(0, addr & 0xff, val, s3); } - + switch (addr & 0x1fffe) { case 0x8100: addr = 0x82e8; break; /*ALT_CURXY*/ case 0x8102: addr = 0x86e8; break; @@ -2405,8 +2428,10 @@ s3_out(uint16_t addr, uint8_t val, void *p) { case 0x3c2: if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { - if (((val >> 2) & 3) != 3) - icd2061_write(svga->clock_gen, (val >> 2) & 3); + if ((s3->card_type != S3_SPEA_MERCURY_P64V) && (s3->card_type != S3_MIROVIDEO40SV_ERGO_968)) { + if (((val >> 2) & 3) != 3) + icd2061_write(svga->clock_gen, (val >> 2) & 3); + } } break; @@ -2472,6 +2497,8 @@ s3_out(uint16_t addr, uint8_t val, void *p) sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); } else if (s3->card_type == S3_NUMBER9_9FX_531) att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); else sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); return; @@ -2760,6 +2787,8 @@ s3_in(uint16_t addr, void *p) return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); else if (s3->card_type == S3_NUMBER9_9FX_531) return att498_ramdac_in(addr, rs2, svga->ramdac, svga); + else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) + return sc1502x_ramdac_in(addr, svga->ramdac, svga); else return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); break; @@ -2880,7 +2909,7 @@ static void s3_recalctimings(svga_t *svga) if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || - s3->card_type == S3_NUMBER9_9FX_531) { + s3->card_type == S3_NUMBER9_9FX_531 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { if (!(svga->crtc[0x5e] & 0x04)) svga->vblankstart = svga->dispend; if (svga->bpp != 32) { @@ -3006,7 +3035,8 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp = s3->width; } - if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805) + if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || + s3->card_type == S3_SPEA_MERCURY_LITE_PCI) svga->hdisp = s3->width; break; case 16: @@ -3034,7 +3064,8 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp = s3->width; } - if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805) + if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || + s3->card_type == S3_SPEA_MERCURY_LITE_PCI) svga->hdisp = s3->width; break; case 24: @@ -3044,6 +3075,15 @@ static void s3_recalctimings(svga_t *svga) svga->hdisp /= 3; else svga->hdisp = (svga->hdisp * 2) / 3; + + if (s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { + if (s3->width == 2048) + switch (svga->dispend) { + case 480: + svga->hdisp = 640; + break; + } + } } else { if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) @@ -3085,7 +3125,7 @@ static void s3_recalctimings(svga_t *svga) s3->width = 800; svga->hdisp = 800; break; - } + } } } } @@ -3292,6 +3332,7 @@ s3_updatemapping(s3_t *s3) case S3_TRIO64V: case S3_TRIO64V2: case S3_86C928: + case S3_86C928PCI: s3->linear_size = 0x400000; break; default: @@ -3842,8 +3883,9 @@ s3_accel_in(uint16_t port, void *p) s3_accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); else s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else + } else { s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } break; } } @@ -5235,7 +5277,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -6129,8 +6170,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { int y = s3->accel.poly_cy; @@ -6278,7 +6317,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ ROPMIX - if (s3->accel.cmd & 0x10) { + if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, out); } } @@ -6615,6 +6654,7 @@ static void s3_reset(void *priv) break; case S3_METHEUS_86C928: + case S3_SPEA_MERCURY_LITE_PCI: svga->crtc[0x5a] = 0x0a; break; @@ -6763,6 +6803,11 @@ static void *s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_SPEA_MERCURY_LITE_PCI: + bios_fn = ROM_SPEA_MERCURY_LITE_PCI; + chip = S3_86C928PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); + break; case S3_MIROCRYSTAL20SD_864: bios_fn = ROM_MIROCRYSTAL20SD_864_VLB; chip = S3_VISION864; @@ -7159,7 +7204,20 @@ static void *s3_init(const device_t *info) svga->ramdac = device_add(&bt485_ramdac_device); svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; - break; + break; + + case S3_SPEA_MERCURY_LITE_PCI: + svga->decode_mask = (4 << 20) - 1; + stepping = 0xb0; /*86C928PCI*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + break; case S3_PARADISE_BAHAMAS64: case S3_PHOENIX_VISION864: @@ -7219,13 +7277,15 @@ static void *s3_init(const device_t *info) } if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || - info->local == S3_NUMBER9_9FX_771) + info->local == S3_NUMBER9_9FX_771) { svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - else + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + } else { svga->ramdac = device_add(&tvp3026_ramdac_device); - - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; + svga->clock_gen = svga->ramdac; + svga->getclock = tvp3026_getclock; + } break; case S3_NUMBER9_9FX_531: @@ -7380,6 +7440,11 @@ static int s3_metheus_86c928_available(void) return rom_present(ROM_METHEUS_86C928); } +static int s3_spea_mercury_lite_pci_available(void) +{ + return rom_present(ROM_SPEA_MERCURY_LITE_PCI); +} + static int s3_bahamas64_available(void) { return rom_present(ROM_PARADISE_BAHAMAS64); @@ -7796,6 +7861,20 @@ const device_t s3_metheus_86c928_vlb_device = s3_standard_config }; +const device_t s3_spea_mercury_lite_86c928_pci_device = +{ + "S3 86c928 PCI (SPEA Mercury Lite)", + DEVICE_PCI, + S3_SPEA_MERCURY_LITE_PCI, + s3_init, + s3_close, + s3_reset, + { s3_spea_mercury_lite_pci_available }, + s3_speed_changed, + s3_force_redraw, + s3_standard_config +}; + const device_t s3_mirocrystal_20sd_864_vlb_device = { "S3 Vision864 VLB (MiroCRYSTAL 20SD)", diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index e0e8b0e2e..fb589677f 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -61,7 +61,7 @@ static int dither[4][4] = #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= (FIFO_SIZE - 4)) #define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) #define FIFO_TYPE 0xff000000 @@ -70,6 +70,7 @@ static int dither[4][4] = #define ROM_VIRGE_325 "roms/video/s3virge/86c325.bin" #define ROM_DIAMOND_STEALTH3D_2000 "roms/video/s3virge/s3virge.bin" #define ROM_DIAMOND_STEALTH3D_3000 "roms/video/s3virge/diamondstealth3000.vbi" +#define ROM_STB_VELOCITY_3D "roms/video/s3virge/stb_velocity3d_110.BIN" #define ROM_VIRGE_DX "roms/video/s3virge/86c375_1.bin" #define ROM_DIAMOND_STEALTH3D_2000PRO "roms/video/s3virge/virgedxdiamond.vbi" #define ROM_VIRGE_GX "roms/video/s3virge/86c375_4.bin" @@ -82,6 +83,7 @@ enum S3_VIRGE_325, S3_DIAMOND_STEALTH3D_2000, S3_DIAMOND_STEALTH3D_3000, + S3_STB_VELOCITY_3D, S3_VIRGE_DX, S3_DIAMOND_STEALTH3D_2000PRO, S3_VIRGE_GX, @@ -288,7 +290,6 @@ typedef struct virge_t int sec_x, sec_y, sec_w, sec_h; } streams; - int fifo_slot; uint8_t cmd_dma; uint8_t dma_bs; uint32_t cmd_dma_base; @@ -302,6 +303,10 @@ typedef struct virge_t fifo_entry_t fifo[FIFO_SIZE]; volatile int fifo_read_idx, fifo_write_idx; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; + int virge_busy, local; uint8_t subsys_stat, subsys_cntl, advfunc_cntl; @@ -417,6 +422,11 @@ s3_virge_tri_timer(void *p) thread_set_event(virge->wake_render_thread); /*Wake up FIFO thread if moving from idle*/ } +static __inline void +wake_fifo_thread(virge_t *virge) +{ + thread_set_event(virge->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ +} static void queue_triangle(virge_t *virge) @@ -970,7 +980,8 @@ static void s3_virge_updatemapping(virge_t *virge) mem_mapping_disable(&virge->new_mmio_mapping); } -static void s3_virge_vblank_start(svga_t *svga) +static void +s3_virge_vblank_start(svga_t *svga) { virge_t *virge = (virge_t *)svga->p; @@ -978,6 +989,16 @@ static void s3_virge_vblank_start(svga_t *svga) s3_virge_update_irqs(virge); } +static void +s3_virge_wait_fifo_idle(virge_t *virge) +{ + while (!FIFO_EMPTY) + { + wake_fifo_thread(virge); + thread_wait_event(virge->fifo_not_full_event, 1); + } +} + static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { @@ -989,14 +1010,12 @@ s3_virge_mmio_read(uint32_t addr, void *p) switch (addr & 0xffff) { case 0x8505: - ret = 0; - if (virge->s3d_busy || virge->fifo_slot) { - ret = 0x10; - } else { - ret = 0x30; - } - if (virge->fifo_slot) - virge->fifo_slot--; + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) + ret = 0x10; + else + ret = 0x10 | (1 << 5); + if (!virge->virge_busy) + wake_fifo_thread(virge); return ret; case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: @@ -1014,6 +1033,7 @@ s3_virge_mmio_read(uint32_t addr, void *p) return s3_virge_in(addr & 0x3ff, virge); case 0x859c: + s3_virge_wait_fifo_idle(virge); return virge->cmd_dma; case 0xff20: case 0xff21: @@ -1030,22 +1050,21 @@ static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { virge_t *virge = (virge_t *)p; - uint32_t ret = 0xffff; + uint16_t ret = 0xffff; s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); switch (addr & 0xfffe) { case 0x8504: - if (!virge->fifo_slot) + if (FIFO_EMPTY) virge->subsys_stat |= INT_FIFO_EMP; ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; ret |= 0x30; /*A bit of a workaround at the moment.*/ s3_virge_update_irqs(virge); - return ret; + return ret; case 0x859c: + s3_virge_wait_fifo_idle(virge); return virge->cmd_dma; default: @@ -1134,78 +1153,91 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) break; case 0x8504: - if (virge->s3d_busy || virge->fifo_slot) { + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) ret = (0x10 << 8); - } else { + else ret = (0x10 << 8) | (1 << 13); - if (!virge->s3d_busy) - virge->subsys_stat |= INT_3DF_EMP; - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; - } ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; - s3_virge_update_irqs(virge); + if (!virge->virge_busy) + wake_fifo_thread(virge); dmahdr->dblword_read = 0; dmahdr->dblword_write = 0; break; case 0x8590: + s3_virge_wait_fifo_idle(virge); ret = virge->cmd_dma_base; break; case 0x8594: + s3_virge_wait_fifo_idle(virge); break; case 0x8598: + s3_virge_wait_fifo_idle(virge); ret = virge->dma_ptr; break; case 0x859c: + s3_virge_wait_fifo_idle(virge); ret = virge->cmd_dma; break; case 0xa4d4: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_base; break; case 0xa4d8: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.dest_base; break; case 0xa4dc: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; break; case 0xa4e0: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; break; case 0xa4e4: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; break; case 0xa4e8: case 0xace8: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.mono_pat_0; break; case 0xa4ec: case 0xacec: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.mono_pat_1; break; case 0xa4f0: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pat_bg_clr; break; case 0xa4f4: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.pat_fg_clr; break; case 0xa4f8: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_bg_clr; break; case 0xa4fc: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.src_fg_clr; break; case 0xa500: + s3_virge_wait_fifo_idle(virge); ret = virge->s3d.cmd_set; break; case 0xa504: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; break; case 0xa508: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; break; case 0xa50c: + s3_virge_wait_fifo_idle(virge); ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; break; @@ -1242,14 +1274,96 @@ s3_virge_mmio_read_l(uint32_t addr, void *p) return ret; } +static void +fifo_thread(void *param) +{ + virge_t *virge = (virge_t *)param; -static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) + while (virge->fifo_thread_run) + { + thread_set_event(virge->fifo_not_full_event); + thread_wait_event(virge->wake_fifo_thread, -1); + thread_reset_event(virge->wake_fifo_thread); + virge->virge_busy = 1; + while (!FIFO_EMPTY) + { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + uint32_t addr, val; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; + addr = fifo->addr_type & FIFO_ADDR; + val = fifo->val; + + switch (fifo->addr_type & FIFO_TYPE) + { + case FIFO_WRITE_BYTE: + if ((addr & 0xfffc) < 0x8000) + s3_virge_bitblt(virge, 8, val); + break; + case FIFO_WRITE_WORD: + if ((addr & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } + break; + case FIFO_WRITE_DWORD: + if ((addr & 0xfffc) < 0x8000) + { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } + break; + } + + virge->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + + if (FIFO_ENTRIES > 0xe000) + thread_set_event(virge->fifo_not_full_event); + + end_time = plat_timer_read(); + virge_time += end_time - start_time; + } + virge->virge_busy = 0; + virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; + s3_virge_update_irqs(virge); + } +} + +static void +s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) +{ + fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; + + if (FIFO_FULL) + { + thread_reset_event(virge->fifo_not_full_event); + if (FIFO_FULL) + thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; + + virge->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(virge); +} + +static void +s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; s3_virge_log("MMIO WriteB addr = %04x, val = %02x\n", addr & 0xffff, val); if ((addr & 0xffff) < 0x8000) { - s3_virge_bitblt(virge, 8, val); + s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); } else { switch (addr & 0xffff) { case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: @@ -1286,10 +1400,7 @@ s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) s3_virge_log("[%04X:%08X]: MMIO WriteW addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffe, val); if ((addr & 0xfffe) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); + s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); } else { if ((addr & 0xfffe) == 0x83d4) { s3_virge_mmio_write(addr, val, virge); @@ -1310,17 +1421,19 @@ s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) s3_virge_log("MMIO WriteL addr = %04x, val = %08x\n", addr & 0xfffc, val); if ((addr & 0xfffc) < 0x8000) { + if ((addr & 0xe000) == 0) { if (virge->s3d.cmd_set & CMD_SET_MS) s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); else - s3_virge_bitblt(virge, 32, val); + s3_virge_bitblt(virge, 32, val); + } else { + s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); + } if (virge->cmd_dma) { dmahdr->datatype = 1; } } else { - if ((addr & 0xfffc) >= 0xa000) - virge->fifo_slot++; if (virge->cmd_dma) { dmahdr->datatype = 0; } @@ -3875,6 +3988,7 @@ static void s3_virge_reset(void *priv) virge->svga.crtc[0x59] = 0x70; break; case S3_DIAMOND_STEALTH3D_3000: + case S3_STB_VELOCITY_3D: virge->svga.crtc[0x59] = 0x70; break; case S3_VIRGE_GX2: @@ -3950,6 +4064,9 @@ static void *s3_virge_init(const device_t *info) case S3_DIAMOND_STEALTH3D_3000: bios_fn = ROM_DIAMOND_STEALTH3D_3000; break; + case S3_STB_VELOCITY_3D: + bios_fn = ROM_STB_VELOCITY_3D; + break; case S3_VIRGE_DX: bios_fn = ROM_VIRGE_DX; break; @@ -4041,6 +4158,7 @@ static void *s3_virge_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_2000_pci); break; case S3_DIAMOND_STEALTH3D_3000: + case S3_STB_VELOCITY_3D: virge->svga.decode_mask = (8 << 20) - 1; virge->virge_id_high = 0x88; virge->virge_id_low = 0x3d; @@ -4135,6 +4253,11 @@ static void *s3_virge_init(const device_t *info) virge->render_thread_run = 1; virge->render_thread = thread_create(render_thread, virge); + virge->wake_fifo_thread = thread_create_event(); + virge->fifo_not_full_event = thread_create_event(); + virge->fifo_thread_run = 1; + virge->fifo_thread = thread_create(fifo_thread, virge); + timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0); virge->local = info->local; @@ -4153,6 +4276,12 @@ static void s3_virge_close(void *p) thread_destroy_event(virge->wake_main_thread); thread_destroy_event(virge->wake_render_thread); + virge->fifo_thread_run = 0; + thread_set_event(virge->wake_fifo_thread); + thread_wait(virge->fifo_thread); + thread_destroy_event(virge->wake_fifo_thread); + thread_destroy_event(virge->fifo_not_full_event); + svga_close(&virge->svga); ddc_close(virge->ddc); @@ -4176,6 +4305,11 @@ static int s3_virge_988_diamond_available(void) return rom_present(ROM_DIAMOND_STEALTH3D_3000); } +static int s3_virge_988_stb_available(void) +{ + return rom_present(ROM_STB_VELOCITY_3D); +} + static int s3_virge_375_available(void) { return rom_present(ROM_VIRGE_DX); @@ -4302,6 +4436,20 @@ const device_t s3_diamond_stealth_3000_pci_device = s3_virge_config }; +const device_t s3_stb_velocity_3d_pci_device = +{ + "S3 ViRGE/VX (STB Velocity 3D) PCI", + DEVICE_PCI, + S3_STB_VELOCITY_3D, + s3_virge_init, + s3_virge_close, + s3_virge_reset, + { s3_virge_988_stb_available }, + s3_virge_speed_changed, + s3_virge_force_redraw, + s3_virge_config +}; + const device_t s3_virge_375_pci_device = { "S3 ViRGE/DX (375) PCI", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index d89365255..4cccea754 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -138,6 +138,7 @@ video_cards[] = { { "cl_gd5480_pci", &gd5480_pci_device }, { "ctl3d_banshee_pci", &creative_voodoo_banshee_device }, { "stealth32_pci", &et4000w32p_pci_device }, + { "spea_mercurylite_pci", &s3_spea_mercury_lite_86c928_pci_device }, { "stealth64v_pci", &s3_diamond_stealth64_964_pci_device }, { "elsawin2kprox_964_pci", &s3_elsa_winner2000_pro_x_964_pci_device }, { "mirocrystal20sv_pci", &s3_mirocrystal_20sv_964_pci_device }, @@ -160,6 +161,7 @@ video_cards[] = { { "virge325_pci", &s3_virge_325_pci_device }, { "stealth3d_2000_pci", &s3_diamond_stealth_2000_pci_device }, { "stealth3d_3000_pci", &s3_diamond_stealth_3000_pci_device }, + { "stb_velocity3d_pci", &s3_stb_velocity_3d_pci_device }, { "virge375_pci", &s3_virge_375_pci_device }, { "stealth3d_2000pro_pci", &s3_diamond_stealth_2000pro_pci_device }, { "virge385_pci", &s3_virge_385_pci_device }, diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 4c081e1a7..bd05fea46 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -1249,7 +1249,8 @@ enum TGUI_BITBLT = 1, TGUI_SCANLINE = 3, TGUI_BRESENHAMLINE = 4, - TGUI_SHORTVECTOR = 5 + TGUI_SHORTVECTOR = 5, + TGUI_FASTLINE = 6 }; enum @@ -1480,7 +1481,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.right >>= 2; } } - + switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) { case TGUI_SRCCPU: @@ -1572,31 +1573,36 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } while (count--) { - src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); - if (tgui->accel.bpp == 0) - src_dat &= 0xff; - else if (tgui->accel.bpp == 1) - src_dat &= 0xffff; + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && + tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); + if (tgui->accel.bpp == 0) + src_dat &= 0xff; + else if (tgui->accel.bpp == 1) + src_dat &= 0xffff; - READ(tgui->accel.dst, dst_dat); + READ(tgui->accel.dst, dst_dat); - pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; + pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; - if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { - MIX(); + if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { + MIX(); - WRITE(tgui->accel.dst, out); + WRITE(tgui->accel.dst, out); + } } cpu_dat <<= 1; tgui->accel.src += xdir; tgui->accel.dst += xdir; tgui->accel.pat_x += xdir; + if (tgui->type >= TGUI_9660) + tgui->accel.dx += xdir; tgui->accel.x++; if (tgui->accel.x > tgui->accel.size_x) { @@ -1605,6 +1611,11 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) tgui->accel.pat_x = tgui->accel.dst_x; tgui->accel.pat_y += ydir; + if (tgui->type >= TGUI_9660) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy += ydir; + } + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); @@ -1891,6 +1902,88 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } break; + + case TGUI_FASTLINE: + { + if (tgui->type < TGUI_9660) + break; + + int16_t dx, dy; + + dx = tgui->accel.dst_x & 0xfff; + dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } + + while (count--) { + READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && + dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { + READ(dx + (dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(dx + (dy * tgui->accel.pitch), out); + } + + if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) + break; + + switch ((tgui->accel.size_y >> 8) & 0xe0) { + case 0x00: + dx++; + break; + case 0x20: + dx++; + dy--; + break; + case 0x40: + dy--; + break; + case 0x60: + dx--; + dy--; + break; + case 0x80: + dx--; + break; + case 0xa0: + dx--; + dy++; + break; + case 0xc0: + dy++; + break; + case 0xe0: + dx++; + dy++; + break; + } + + tgui->accel.y++; + } + } + break; } } diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 926921946..c3fc85655 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -47,6 +47,12 @@ typedef struct uint8_t misc; uint8_t type; uint8_t mode; + uint8_t pll_addr; + uint8_t clock_sel; + struct + { + uint8_t m, n, p; + } pix, mem, loop; } tvp3026_ramdac_t; static void @@ -96,7 +102,6 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); - switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ ramdac->ind_idx = val; @@ -152,7 +157,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64; svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; - svga->dac_hwcursor.ena = ((val & 0x03) != 0); + svga->dac_hwcursor.ena = !!(val & 0x03); ramdac->mode = val & 0x03; } break; @@ -163,7 +168,7 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 64; svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.xsize; svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.ysize; - svga->dac_hwcursor.ena = ((val & 0x03) != 0); + svga->dac_hwcursor.ena = !!(val & 0x03); ramdac->mode = val & 0x03; break; case 0x0f: /* Latch Control */ @@ -177,6 +182,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t ramdac->mcr = val; tvp3026_set_bpp(ramdac, svga); break; + case 0x1a: /* Clock Selection */ + ramdac->clock_sel = val; + break; case 0x1c: /* Palette-Page Register */ ramdac->ppr = val; break; @@ -187,6 +195,51 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t ramdac->misc = val; svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; break; + case 0x2c: /* PLL Address */ + ramdac->pll_addr = val; + break; + case 0x2d: /* Pixel clock PLL data */ + switch (ramdac->pll_addr & 3) { + case 0: + ramdac->pix.n = val; + break; + case 1: + ramdac->pix.m = val; + break; + case 2: + ramdac->pix.p = val; + break; + } + ramdac->pll_addr = ((ramdac->pll_addr + 1) & 3) | (ramdac->pll_addr & 0xfc); + break; + case 0x2e: /* Memory Clock PLL Data */ + switch ((ramdac->pll_addr >> 2) & 3) { + case 0: + ramdac->mem.n = val; + break; + case 1: + ramdac->mem.m = val; + break; + case 2: + ramdac->mem.p = val; + break; + } + ramdac->pll_addr = ((ramdac->pll_addr + 4) & 0x0c) | (ramdac->pll_addr & 0xf3); + break; + case 0x2f: /* Loop Clock PLL Data */ + switch ((ramdac->pll_addr >> 4) & 3) { + case 0: + ramdac->loop.n = val; + break; + case 1: + ramdac->loop.m = val; + break; + case 2: + ramdac->loop.p = val; + break; + } + ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf); + break; case 0x39: /* MCLK/Loop Clock Control */ ramdac->mclk = val; break; @@ -292,6 +345,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x19: /* Multiplex Control */ temp = ramdac->mcr; break; + case 0x1a: /* Clock Selection */ + temp = ramdac->clock_sel; + break; case 0x1c: /* Palette-Page Register */ temp = ramdac->ppr; break; @@ -301,6 +357,54 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) case 0x1e: /* Miscellaneous Control */ temp = ramdac->misc; break; + case 0x2c: /* PLL Address */ + temp = ramdac->pll_addr; + break; + case 0x2d: /* Pixel clock PLL data */ + switch (ramdac->pll_addr & 3) { + case 0: + temp = ramdac->pix.n; + break; + case 1: + temp = ramdac->pix.m; + break; + case 2: + temp = ramdac->pix.p; + break; + case 3: + temp = 0x40; /*PLL locked to frequency*/ + break; + } + break; + case 0x2e: /* Memory Clock PLL Data */ + switch ((ramdac->pll_addr >> 2) & 3) { + case 0: + temp = ramdac->mem.n; + break; + case 1: + temp = ramdac->mem.m; + break; + case 2: + temp = ramdac->mem.p; + break; + case 3: + temp = 0x40; /*PLL locked to frequency*/ + break; + } + break; + case 0x2f: /* Loop Clock PLL Data */ + switch ((ramdac->pll_addr >> 4) & 3) { + case 0: + temp = ramdac->loop.n; + break; + case 1: + temp = ramdac->loop.m; + break; + case 2: + temp = ramdac->loop.p; + break; + } + break; case 0x39: /* MCLK/Loop Clock Control */ temp = ramdac->mclk; break; @@ -436,6 +540,29 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) } +float +tvp3026_getclock(int clock, void *p) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + int n, m, pl; + float f_vco, f_pll; + + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + +/*Fvco = 8 x Fref x (65 - M) / (65 - N)*/ +/*Fpll = Fvco / 2^P*/ + n = ramdac->pix.n & 0x3f; + m = ramdac->pix.m & 0x3f; + pl = ramdac->pix.p & 0x03; + f_vco = 8.0 * 14318184 * (float)(65 - m) / (float)(65 - n); + f_pll = f_vco / (float)(1 << pl); + + return f_pll; +} + void * tvp3026_ramdac_init(const device_t *info) { @@ -447,6 +574,7 @@ tvp3026_ramdac_init(const device_t *info) ramdac->latch_cntl = 0x06; ramdac->true_color = 0x80; ramdac->mcr = 0x98; + ramdac->clock_sel = 0x07; ramdac->mclk = 0x18; return ramdac; diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 3c872705b..b9f18348b 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -29,16 +29,9 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/vid_vga.h> -typedef struct vga_t -{ - svga_t svga; - - rom_t bios_rom; -} vga_t; - -static video_timings_t timing_vga = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; static video_timings_t timing_ps1_svga_isa = {VIDEO_ISA, 6, 8, 16, 6, 8, 16}; static video_timings_t timing_ps1_svga_mca = {VIDEO_MCA, 6, 8, 16, 6, 8, 16}; diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 9ee608c4f..cfcef28ab 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -75,6 +75,9 @@ ifeq ($(DEV_BUILD), y) ifndef ISAMEM_IAB ISAMEM_IAB := y endif + ifndef ISAMEM_BRAT + ISAMEM_BRAT := y + endif ifndef OLIVETTI OLIVETTI := y endif @@ -130,6 +133,9 @@ else ifndef ISAMEM_IAB ISAMEM_IAB := n endif + ifndef ISAMEM_BRAT + ISAMEM_BRAT := n + endif ifndef OLIVETTI OLIVETTI := n endif @@ -470,6 +476,10 @@ ifeq ($(ISAMEM_IAB), y) OPTS += -DUSE_ISAMEM_IAB endif +ifeq ($(ISAMEM_BRAT), y) +OPTS += -DUSE_ISAMEM_BRAT +endif + ifeq ($(OLIVETTI), y) OPTS += -DUSE_OLIVETTI DEVBROBJ += olivetti_eva.o @@ -640,6 +650,7 @@ SNDOBJ := sound.o \ midi.o midi_rtmidi.o \ snd_speaker.o \ snd_pssj.o \ + snd_ps1.o \ snd_lpt_dac.o snd_lpt_dss.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \ snd_ac97_codec.o snd_ac97_via.o \ diff --git a/src/win/languages/ru-RU.rc b/src/win/languages/ru-RU.rc index 43289dbfc..82530c400 100644 --- a/src/win/languages/ru-RU.rc +++ b/src/win/languages/ru-RU.rc @@ -37,7 +37,7 @@ BEGIN MENUITEM "&Изменяемый размер окна", IDM_VID_RESIZE MENUITEM "&Запомнить размер и положение", IDM_VID_REMEMBER MENUITEM SEPARATOR - POPUP "&Рендерер" + POPUP "&Рендеринг" BEGIN MENUITEM "&SDL (Software)", IDM_VID_SDL_SW MENUITEM "SDL (&Hardware)", IDM_VID_SDL_HW @@ -144,7 +144,7 @@ BEGIN MENUITEM "&Точка останова журнала\tCtrl+F10", IDM_LOG_BREAKPOINT # endif # ifdef ENABLE_VRAM_DUMP - MENUITEM "&Выгрузка дампа видео-ОЗУ\tCtrl+F1", IDM_DUMP_VRAM + MENUITEM "&Выгрузка дампа видеопамяти\tCtrl+F1", IDM_DUMP_VRAM # endif # endif END