From 206c34ed2747138adb120861462e2e7a855dc687 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 15 Sep 2021 00:01:18 +0200 Subject: [PATCH 1/6] CMakeList.txt now uses libpthread. --- src/CMakeLists.txt | 2 ++ src/unix/CMakeLists.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a3cbc2e76..0930c5de0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,6 +75,8 @@ else() target_link_libraries(86Box SDL2::SDL2) endif() +target_link_libraries(plat pthread) + find_package(PNG REQUIRED) include_directories(${PNG_INCLUDE_DIRS}) target_link_libraries(86Box PNG::PNG) diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 10cc8c53e..193de96c0 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -12,7 +12,6 @@ add_library(plat STATIC ${PLAT_SOURCES}) add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c) target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64) target_link_libraries(ui dl) -target_link_libraries(plat pthread) if (ALSA_FOUND) target_link_libraries(plat ALSA::ALSA) endif() \ No newline at end of file From 719d155393f256c5733b6d518a6f1860aa4fad65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 15 Sep 2021 12:49:52 +0200 Subject: [PATCH 2/6] cmake: fix pthread linking on Windows --- .github/workflows/c-cpp.yml | 1 + .github/workflows/cmake.yml | 5 ++++- CMakeLists.txt | 4 ++++ src/CMakeLists.txt | 14 +++++++++++++- src/win/CMakeLists.txt | 4 ++++ vcpkg.json | 3 ++- 6 files changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 36b9010e3..619d2c871 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -57,6 +57,7 @@ jobs: ${{ matrix.environment.prefix }}-zlib ${{ matrix.environment.prefix }}-libpng ${{ matrix.environment.prefix }}-libvncserver + ${{ matrix.environment.prefix }}-winpthreads - uses: actions/checkout@v2 - name: make run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} X64=${{ matrix.environment.x64 }} CLANG=${{ matrix.clang }} VNC=n diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 294442bf4..2b9abeaa8 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -62,13 +62,16 @@ jobs: msystem: ${{ matrix.environment.msystem }} install: >- ${{ matrix.environment.prefix }}-ninja - ${{ matrix.environment.prefix }}-toolchain + ${{ matrix.environment.prefix }}-gcc + ${{ matrix.environment.prefix }}-clang + ${{ matrix.environment.prefix }}-pkg-config ${{ matrix.environment.prefix }}-openal ${{ matrix.environment.prefix }}-freetype ${{ matrix.environment.prefix }}-SDL2 ${{ matrix.environment.prefix }}-zlib ${{ matrix.environment.prefix }}-libpng ${{ matrix.environment.prefix }}-libvncserver + ${{ matrix.environment.prefix }}-winpthreads - uses: actions/checkout@v2 - name: Configure CMake run: >- diff --git a/CMakeLists.txt b/CMakeLists.txt index 68b9e760e..1e565b001 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,10 @@ CMAKE_DEPENDENT_OPTION(VNC "VNC renderer" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) CMAKE_DEPENDENT_OPTION(VECT486VL "HP Vectra 486VL" ON "DEV_BRANCH" OFF) +if(WIN32) + option(PTHREAD "Use POSIX threads (pthreads) instead of Win32 threads" ON) +endif() + # HACK: Avoid a MSVC2019 compiler bug on ARM64 Debug builds if(MSVC_TOOLSET_VERSION GREATER_EQUAL 142 AND ARCH STREQUAL "arm64") # Define a cache option in case somebody wants to disable this workaround diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0930c5de0..116bc1e45 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,7 +16,7 @@ # WIN32 marks us as a GUI app on Windows add_executable(86Box WIN32 86box.c config.c random.c timer.c io.c acpi.c apm.c dma.c ddma.c nmi.c pic.c pit.c port_92.c ppi.c pci.c mca.c usb.c - device.c nvr.c nvr_at.c nvr_ps2.c thread.c) + device.c nvr.c nvr_at.c nvr_ps2.c) if(NEW_DYNAREC) add_compile_definitions(USE_NEW_DYNAREC) @@ -44,6 +44,18 @@ if(VNC) target_link_libraries(86Box vnc vncserver ws2_32) endif() +if(NOT WIN32 OR PTHREAD) + target_sources(86Box PRIVATE thread.c) + if(WIN32 AND VCPKG_TOOLCHAIN) + find_package(pthreads REQUIRED) + target_link_libraries(86Box pthreads) + else() + set(THREADS_PREFER_PTHREAD_FLAG TRUE) + find_package(Threads REQUIRED) + target_link_libraries(86Box Threads::Threads) + endif() +endif() + target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd net print scsi sio snd vid voodoo plat ui) diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt index 75d3daf4a..527f64f51 100644 --- a/src/win/CMakeLists.txt +++ b/src/win/CMakeLists.txt @@ -58,5 +58,9 @@ if(OPENGL) target_sources(ui PRIVATE glad.c win_opengl.c win_opengl_glslp.c) endif() +if(NOT PTHREAD) + target_sources(plat PRIVATE win_thread.c) +endif() + target_link_libraries(86Box advapi32 comctl32 comdlg32 gdi32 shell32 iphlpapi dxguid imm32 hid setupapi uxtheme version winmm psapi) diff --git a/vcpkg.json b/vcpkg.json index 9fba60a48..eb9ed9b1d 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -8,6 +8,7 @@ "freetype", "libpng", "openal-soft", - "sdl2" + "sdl2", + "pthreads" ] } \ No newline at end of file From 0e2cf677fbeccea76b0ef20890ac4dabfd1da022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 15 Sep 2021 13:05:00 +0200 Subject: [PATCH 3/6] cmake: fix pthread linking, take 2 --- src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 116bc1e45..c1ffaabd2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,8 +87,6 @@ else() target_link_libraries(86Box SDL2::SDL2) endif() -target_link_libraries(plat pthread) - find_package(PNG REQUIRED) include_directories(${PNG_INCLUDE_DIRS}) target_link_libraries(86Box PNG::PNG) From d9123cad4ad56702f0b8f974d610e76bd21782e6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Sep 2021 02:17:25 +0200 Subject: [PATCH 4/6] Fixed 16-bit and 32-bit FISTP(P) instruction, fixes OpenStep 4.2 font on interpreter and old recompiler, closes #1204. --- src/codegen/codegen_ops_x86-64.h | 4 +- src/cpu/x87_ops.h | 64 +++++++++++++++++++++++++++++++- src/cpu/x87_ops_loadstore.h | 32 ++++------------ 3 files changed, 73 insertions(+), 27 deletions(-) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index a68dee7ae..906b07dc6 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -4363,7 +4363,7 @@ static inline int FP_LOAD_REG_INT_W(int reg) addbyte(0xc5); addbyte((uint8_t)cpu_state_offset(ST)); - CALL_FUNC((uintptr_t)x87_fround); + CALL_FUNC((uintptr_t)x87_fround16_64); addbyte(0x93); /*XCHG EBX, EAX*/ @@ -4393,7 +4393,7 @@ static inline int FP_LOAD_REG_INT(int reg) addbyte(0xc5); addbyte((uint8_t)cpu_state_offset(ST)); - CALL_FUNC((uintptr_t)x87_fround); + CALL_FUNC((uintptr_t)x87_fround32_64); addbyte(0x93); /*XCHG EBX, EAX*/ diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 17861fa57..9e06a343e 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -152,10 +152,72 @@ static __inline double x87_pop() return t; } +static __inline int16_t x87_fround16(double b) +{ + int16_t a, c; + + switch ((cpu_state.npxc >> 10) & 3) + { + case 0: /*Nearest*/ + a = (int16_t)floor(b); + c = (int16_t)floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int16_t)floor(b); + case 2: /*Up*/ + return (int16_t)ceil(b); + case 3: /*Chop*/ + return (int16_t)b; + } + + return 0; +} + +static __inline int64_t x87_fround16_64(double b) +{ + return (int64_t) x87_fround16(b); +} + +static __inline int32_t x87_fround32(double b) +{ + int32_t a, c; + + switch ((cpu_state.npxc >> 10) & 3) + { + case 0: /*Nearest*/ + a = (int32_t)floor(b); + c = (int32_t)floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int32_t)floor(b); + case 2: /*Up*/ + return (int32_t)ceil(b); + case 3: /*Chop*/ + return (int32_t)b; + } + + return 0; +} + +static __inline int64_t x87_fround32_64(double b) +{ + return (int64_t) x87_fround32(b); +} + static __inline int64_t x87_fround(double b) { int64_t a, c; - + switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index f742196ea..5e754fc90 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -42,24 +42,20 @@ static int opFILDiw_a32(uint32_t fetchdat) static int opFISTiw_a16(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteaw((int16_t)temp64); + seteaw(x87_fround16(ST(0))); CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 static int opFISTiw_a32(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteaw((int16_t)temp64); + seteaw(x87_fround16(ST(0))); CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); return cpu_state.abrt; } @@ -67,12 +63,10 @@ static int opFISTiw_a32(uint32_t fetchdat) static int opFISTPiw_a16(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; + 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)); return 0; @@ -80,12 +74,10 @@ static int opFISTPiw_a16(uint32_t fetchdat) #ifndef FPU_8087 static int opFISTPiw_a32(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteaw((int16_t)temp64); if (cpu_state.abrt) return 1; + 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)); return 0; @@ -240,24 +232,20 @@ static int opFILDil_a32(uint32_t fetchdat) static int opFISTil_a16(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteal((int32_t)temp64); + seteal(x87_fround32(ST(0))); CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); return cpu_state.abrt; } #ifndef FPU_8087 static int opFISTil_a32(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteal((int32_t)temp64); + seteal(x87_fround32(ST(0))); CLOCK_CYCLES((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); return cpu_state.abrt; } @@ -265,12 +253,10 @@ static int opFISTil_a32(uint32_t fetchdat) static int opFISTPil_a16(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteal((int32_t)temp64); if (cpu_state.abrt) return 1; + 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)); return 0; @@ -278,12 +264,10 @@ static int opFISTPil_a16(uint32_t fetchdat) #ifndef FPU_8087 static int opFISTPil_a32(uint32_t fetchdat) { - int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - temp64 = x87_fround(ST(0)); - seteal((int32_t)temp64); if (cpu_state.abrt) return 1; + 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)); return 0; From ef6d3d01db0bf120a4daa65a6f41619e1ca8a8fe Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Sep 2021 02:18:23 +0200 Subject: [PATCH 5/6] More correct implementation of the FDC FIFO. --- src/floppy/fdc.c | 67 ++++++++++++++++++++++++++++++-------------- src/floppy/fdd_86f.c | 4 +-- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 4da50795e..3c81dd02e 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1892,9 +1892,10 @@ fdc_is_verify(fdc_t *fdc) int -fdc_data(fdc_t *fdc, uint8_t data) +fdc_data(fdc_t *fdc, uint8_t data, int last) { - int result = 0; + int i, result = 0; + int n; if (fdc->deleted & 2) { /* We're in a VERIFY command, so return with 0. */ @@ -1924,27 +1925,39 @@ fdc_data(fdc_t *fdc, uint8_t data) } } } else { - result = dma_channel_write(fdc->dma_ch, data); - if (fdc->tc) return -1; - if (result & DMA_OVER) { - fdc->data_ready = 1; - fdc->stat = 0xd0; - fdc->tc = 1; - return -1; - } - if (!fdc->fifo || (fdc->tfifo < 1)) { + dma_channel_write(fdc->dma_ch, data); + fdc->data_ready = 1; fdc->stat = 0xd0; + + if (result & DMA_OVER) { + fdc->tc = 1; + return -1; + } } else { - fdc_fifo_buf_advance(fdc); - if (fdc->fifobufpos == 0) { + /* FIFO enabled */ + fdc_fifo_buf_write(fdc, data); + if (last || (fdc->fifobufpos == 0)) { /* We have wrapped around, means FIFO is over */ fdc->data_ready = 1; fdc->stat = 0xd0; + + n = (fdc->fifobufpos > 0) ? (fdc->fifobufpos - 1) : fdc->tfifo; + if (fdc->fifobufpos > 0) + fdc->fifobufpos = 0; + + for (i = 0; i <= n; i++) { + result = dma_channel_write(fdc->dma_ch, fdc->fifobuf[i]); + + if (result & DMA_OVER) { + fdc->tc = 1; + return -1; + } + } } } } @@ -2057,10 +2070,10 @@ fdc_writeprotect(fdc_t *fdc) int fdc_getdata(fdc_t *fdc, int last) { - int data; + int i, data = 0; if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->dma) { - if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo) { + if ((fdc->flags & FDC_FLAG_PCJR) || !fdc->fifo || (fdc->tfifo < 1)) { data = fdc->dat; if (!last) @@ -2072,20 +2085,32 @@ int fdc_getdata(fdc_t *fdc, int last) fdc->stat = 0xb0; } } else { - data = dma_channel_read(fdc->dma_ch); + if (!fdc->fifo || (fdc->tfifo < 1)) { + data = dma_channel_read(fdc->dma_ch); + + if (data & DMA_OVER) + fdc->tc = 1; - if (!fdc->fifo) { if (!last) fdc->stat = 0x90; } else { - fdc_fifo_buf_advance(fdc); + if (fdc->fifobufpos == 0) { + for (i = 0; i <= fdc->tfifo; i++) { + data = dma_channel_read(fdc->dma_ch); + fdc->fifobuf[i] = data; + + if (data & DMA_OVER) { + fdc->tc = 1; + break; + } + } + } + + data = fdc_fifo_buf_read(fdc); if (!last && (fdc->fifobufpos == 0)) fdc->stat = 0x90; } - - if (data & DMA_OVER) - fdc->tc = 1; } return data & 0xff; diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index 5ff02adb3..ebd7d6f7c 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -1577,7 +1577,7 @@ d86f_read_sector_data(int drive, int side) } else { if (dev->data_find.bytes_obtained < d86f_get_data_len(drive)) { if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, data); + read_status = fdc_data(d86f_fdc, data, dev->data_find.bytes_obtained == ((d86f_get_data_len(drive)) - 1)); if (read_status == -1) dev->dma_over++; } @@ -2139,7 +2139,7 @@ d86f_turbo_read(int drive, int side) } else { if (dev->data_find.bytes_obtained < (128UL << dev->last_sector.id.n)) { if (dev->state != STATE_16_VERIFY_DATA) { - read_status = fdc_data(d86f_fdc, dat); + read_status = fdc_data(d86f_fdc, dat, dev->data_find.bytes_obtained == ((128UL << dev->last_sector.id.n) - 1)); if (read_status == -1) dev->dma_over++; } From c35b7e21bac51e35c6a8dfe839c11142705770d0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Sep 2021 02:42:52 +0200 Subject: [PATCH 6/6] And the forgotten fdc.h. --- src/include/86box/fdc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 5e2d50d06..87404e174 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -157,7 +157,7 @@ extern void fdc_set_base(fdc_t *fdc, int base); extern void fdc_set_irq(fdc_t *fdc, int irq); extern void fdc_set_dma_ch(fdc_t *fdc, int dma_ch); extern int fdc_getdata(fdc_t *fdc, int last); -extern int fdc_data(fdc_t *fdc, uint8_t data); +extern int fdc_data(fdc_t *fdc, uint8_t data, int last); extern void fdc_sectorid(fdc_t *fdc, uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1,