diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..89f2cffe5 --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,102 @@ +name: CMake + +on: + + push: + paths: + - src/** + - .github/workflows/** + - vcpkg.json + + pull_request: + paths: + - src/** + - .github/workflows/** + - vcpkg.json + +env: + BUILD_TYPE: Release + +jobs: + mingw: + name: ${{ matrix.target-arch.msystem }} build (DEV_BUILD=${{ matrix.dev-build }}, NEW_DYNAREC=${{ matrix.new-dynarec }}) + + runs-on: windows-latest + + defaults: + run: + shell: msys2 {0} + + strategy: + matrix: + dev-build: ['ON', 'OFF'] + new-dynarec: ['ON', 'OFF'] + target-arch: + - msystem: MINGW32 + prefix: mingw-w64-i686 + - msystem: MINGW64 + prefix: mingw-w64-x86_64 + + steps: + - uses: msys2/setup-msys2@v2 + with: + path-type: inherit + update: true + msystem: ${{ matrix.target-arch.msystem }} + install: >- + ${{ matrix.target-arch.prefix }}-toolchain + ${{ matrix.target-arch.prefix }}-openal + ${{ matrix.target-arch.prefix }}-freetype + ${{ matrix.target-arch.prefix }}-SDL2 + ${{ matrix.target-arch.prefix }}-zlib + ${{ matrix.target-arch.prefix }}-libpng + ${{ matrix.target-arch.prefix }}-libvncserver + - uses: actions/checkout@v2 + - name: Configure CMake + run: >- + cmake -S . -B build + -G "MSYS Makefiles" + -D CMAKE_BUILD_TYPE=$BUILD_TYPE + -D DEV_BRANCH=${{ matrix.dev-build }} + -D NEW_DYNAREC=${{ matrix.new-dynarec }} + -D VNC=OFF + - name: Build + run: cmake --build build --config $BUILD_TYPE + + clang: + name: VS2019 ${{ matrix.toolset }} ${{ matrix.target-arch }} build (DEV_BUILD=${{ matrix.dev-build }}, NEW_DYNAREC=${{ matrix.new-dynarec }}) + + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + dev-build: ['ON', 'OFF'] + new-dynarec: ['ON', 'OFF'] + target-arch: ['Win32', 'x64', 'ARM', 'ARM64'] + toolset: ['clangcl', 'v141'] + exclude: + - target-arch: 'ARM' + new-dynarec: 'OFF' + - target-arch: 'ARM64' + new-dynarec: 'OFF' + - target-arch: 'ARM' + toolset: 'clangcl' + + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: build/vcpkg_installed + key: vcpkg-${{ hashFiles('vcpkg.json') }}-${{ matrix.target-arch }} + - 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_BUILD_TYPE=$BUILD_TYPE + -D DEV_BRANCH=${{ matrix.dev-build }} + -D NEW_DYNAREC=${{ matrix.new-dynarec }} + -D VNC=OFF + - name: Build + run: cmake --build build --config $BUILD_TYPE diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..f37195cc3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,67 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +cmake_minimum_required(VERSION 3.16) + +project(86Box + VERSION 2.10 + DESCRIPTION "Emulator of x86-based systems" + HOMEPAGE_URL "https://86box.github.io/" + LANGUAGES C CXX) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(TargetArch) +target_architecture(CMAKE_TARGET_ARCHITECTURES) + +include(CMakeDependentOption) + +add_compile_definitions(CMAKE) + +option(RELEASE "Release build" OFF) +option(USB "USB support" OFF) +option(DYNAREC "Dynamic recompiler" ON) +option(FLUIDSYNTH "FluidSynth" ON) +option(MUNT "MUNT" ON) +option(VRAMDUMP "Video RAM dumping" OFF) +option(DINPUT "DirectInput" OFF) +option(DISCORD "Discord integration" ON) + +option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) + +option(DEV_BRANCH "Development branch" OFF) +CMAKE_DEPENDENT_OPTION(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(CL5422 "Cirrus Logic CL-GD 5402/5420/5422" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(HEDAKA "Hedaka HED-919" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(NO_SIO "Machines without emulated Super I/O chips" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(PAS16 "Pro Audio Spectrum 16" OFF "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(PS1M2133 "IBM PS/1 model 2133" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(PS2M70T4 "IBM PS/2 model 70 (type 4)" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(S3TRIO3D2X "S3 Trio3D/2X" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(STPC "STPC machines" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(M1489 "ALi M1489" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(M6117 "ALi M6117" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(VGAWONDER "ATI VGA Wonder (ATI-18800)" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(VNC "VNC renderer" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(VECT486VL "HP Vectra 486VL" ON "DEV_BRANCH" OFF) +CMAKE_DEPENDENT_OPTION(DELLS4 "Dell Dimension XPS P60; Dell OptiPlex 560/L" ON "DEV_BRANCH" OFF) + +add_subdirectory(src) diff --git a/cmake/TargetArch.cmake b/cmake/TargetArch.cmake new file mode 100644 index 000000000..c8eb27735 --- /dev/null +++ b/cmake/TargetArch.cmake @@ -0,0 +1,141 @@ +# Based on the Qt 5 processor detection code, so should be very accurate +# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h +# Currently handles arm (v5, v6, v7, v8), x86 (32/64), ia64, and ppc (32/64) + +# Regarding POWER/PowerPC, just as is noted in the Qt source, +# "There are many more known variants/revisions that we do not handle/detect." + +set(archdetect_c_code " +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) + #if defined(__ARM64_ARCH_8__) \\ + || defined(__aarch64__) \\ + || defined(__ARMv8__) \\ + || defined(__ARMv8_A__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 8) \\ + || (defined(_M_ARM64) && _M_ARM64 >= 1) + #error cmake_ARCH armv8 + #elif defined(__ARM_ARCH_7__) \\ + || defined(__ARM_ARCH_7A__) \\ + || defined(__ARM_ARCH_7R__) \\ + || defined(__ARM_ARCH_7M__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) \\ + || (defined(_M_ARM) && _M_ARM >= 7) + #error cmake_ARCH armv7 + #elif defined(__ARM_ARCH_6__) \\ + || defined(__ARM_ARCH_6J__) \\ + || defined(__ARM_ARCH_6T2__) \\ + || defined(__ARM_ARCH_6Z__) \\ + || defined(__ARM_ARCH_6K__) \\ + || defined(__ARM_ARCH_6ZK__) \\ + || defined(__ARM_ARCH_6M__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) + #error cmake_ARCH armv6 + #elif defined(__ARM_ARCH_5TEJ__) \\ + || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) + #error cmake_ARCH armv5 + #else + #error cmake_ARCH arm + #endif +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) + #error cmake_ARCH i386 +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) + #error cmake_ARCH x86_64 +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + #error cmake_ARCH ia64 +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\ + || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\ + || defined(_M_MPPC) || defined(_M_PPC) + #if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) + #error cmake_ARCH ppc64 + #else + #error cmake_ARCH ppc + #endif +#endif +#error cmake_ARCH unknown +") + +# Set ppc_support to TRUE before including this file or ppc and ppc64 +# will be treated as invalid architectures since they are no longer supported by Apple + +function(target_architecture output_var) + if(APPLE AND CMAKE_OSX_ARCHITECTURES) + # On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set + # First let's normalize the order of the values + + # Note that it's not possible to compile PowerPC applications if you are using + # the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we + # disable it by default + # See this page for more information: + # http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4 + + # Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime. + # On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise. + + foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES}) + if("${osx_arch}" STREQUAL "ppc" AND ppc_support) + set(osx_arch_ppc TRUE) + elseif("${osx_arch}" STREQUAL "i386") + set(osx_arch_i386 TRUE) + elseif("${osx_arch}" STREQUAL "x86_64") + set(osx_arch_x86_64 TRUE) + elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support) + set(osx_arch_ppc64 TRUE) + else() + message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}") + endif() + endforeach() + + # Now add all the architectures in our normalized order + if(osx_arch_ppc) + list(APPEND ARCH ppc) + endif() + + if(osx_arch_i386) + list(APPEND ARCH i386) + endif() + + if(osx_arch_x86_64) + list(APPEND ARCH x86_64) + endif() + + if(osx_arch_ppc64) + list(APPEND ARCH ppc64) + endif() + else() + file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}") + + enable_language(C) + + # Detect the architecture in a rather creative way... + # This compiles a small C program which is a series of ifdefs that selects a + # particular #error preprocessor directive whose message string contains the + # target architecture. The program will always fail to compile (both because + # file is not a valid C program, and obviously because of the presence of the + # #error preprocessor directives... but by exploiting the preprocessor in this + # way, we can detect the correct target architecture even when cross-compiling, + # since the program itself never needs to be run (only the compiler/preprocessor) + try_run( + run_result_unused + compile_result_unused + "${CMAKE_BINARY_DIR}" + "${CMAKE_BINARY_DIR}/arch.c" + COMPILE_OUTPUT_VARIABLE ARCH + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + ) + + # Parse the architecture name from the compiler output + string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}") + + # Get rid of the value marker leaving just the architecture name + string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}") + + # If we are compiling with an unknown architecture this variable should + # already be set to "unknown" but in the case that it's empty (i.e. due + # to a typo in the code), then set it to unknown + if (NOT ARCH) + set(ARCH unknown) + endif() + endif() + + set(${output_var} "${ARCH}" PARENT_SCOPE) +endfunction() \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 000000000..b5e9746a8 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,109 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +# WIN32 marks us as a GUI app on Windows +add_executable(86Box WIN32 pc.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) + +if(NEW_DYNAREC) + add_compile_definitions(USE_NEW_DYNAREC) +endif() + +if(RELEASE) + add_compile_definitions(RELEASE_BUILD) +endif() + +if(DYNAREC) + add_compile_definitions(USE_DYNAREC) +endif() + +if(VRAMDUMP) + add_compile_definitions(ENABLE_VRAM_DUMP) +endif() + +if(DEV_BRANCH) + add_compile_definitions(DEV_BRANCH) +endif() + +if(VNC) + add_compile_definitions(USE_VNC) + add_library(vnc OBJECT vnc.c vnc_keymap.c) + target_link_libraries(86Box vnc vncserver ws2_32) +endif() + +if(STPC) + add_compile_definitions(USE_STPC) +endif() + +target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd + net print scsi sio snd vid plat ui) + +find_package(Freetype REQUIRED) +include_directories(${FREETYPE_INCLUDE_DIRS}) + +find_package(OpenAL CONFIG REQUIRED) +include_directories(${OPENAL_INCLUDE_DIRS}) +target_link_libraries(86Box OpenAL::OpenAL) + +find_package(SDL2 CONFIG REQUIRED) +include_directories(${SDL2_INCLUDE_DIRS}) +target_link_libraries(86Box SDL2::SDL2) + +find_package(PNG REQUIRED) +include_directories(${PNG_INCLUDE_DIRS}) +target_link_libraries(86Box PNG::PNG) + +if(CMAKE_TARGET_ARCHITECTURES STREQUAL "i386") + if(MSVC) + set_target_properties(86Box PROPERTIES LINK_FLAGS "/LARGEADDRESSAWARE") + elseif(MINGW) + set_target_properties(86Box PROPERTIES LINK_FLAGS "-Wl,--large-address-aware") + endif() +endif() + +configure_file(include/86box/version.h.in include/86box/version.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) + +include_directories(include) +if(NEW_DYNAREC) + include_directories(cpu codegen_new) +else() + include_directories(cpu codegen) +endif() + +add_subdirectory(cdrom) +add_subdirectory(chipset) + +add_subdirectory(cpu) +if(NEW_DYNAREC) + add_subdirectory(codegen_new) +else() + add_subdirectory(codegen) +endif() + +add_subdirectory(device) +add_subdirectory(disk) +add_subdirectory(floppy) +add_subdirectory(game) +add_subdirectory(machine) +add_subdirectory(mem) +add_subdirectory(network) +add_subdirectory(printer) +add_subdirectory(sio) +add_subdirectory(scsi) +add_subdirectory(sound) +add_subdirectory(video) +add_subdirectory(win) \ No newline at end of file diff --git a/src/cdrom/CMakeLists.txt b/src/cdrom/CMakeLists.txt new file mode 100644 index 000000000..6b6c89022 --- /dev/null +++ b/src/cdrom/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image.c) \ No newline at end of file diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 4b4e74d55..5db9365bc 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -733,11 +733,6 @@ track_type_is_valid(uint8_t id, int type, int flags, int audio, int mode2) } if ((type != 1) && !audio) { - if (!(flags & 0x70)) { /* 0x00/0x08/0x80/0x88 are illegal modes */ - cdrom_log("CD-ROM %i: [Any Data Mode] 0x00/0x08/0x80/0x88 are illegal modes\n", id); - return 0; - } - if ((flags & 0x06) == 0x06) { cdrom_log("CD-ROM %i: [Any Data Mode] Invalid error flags\n", id); return 0; diff --git a/src/chipset/CMakeLists.txt b/src/chipset/CMakeLists.txt new file mode 100644 index 000000000..9b7cd39ad --- /dev/null +++ b/src/chipset/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(chipset OBJECT acc2168.c cs8230.c ali1429.c headland.c intel_82335.c + cs4031.c intel_420ex.c intel_4x0.c intel_sio.c intel_piix.c ../ioapic.c + neat.c opti495.c opti895.c opti5x7.c scamp.c scat.c via_vt82c49x.c + via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c + opti283.c opti291.c umc491.c via_apollo.c via_pipc.c wd76c10.c + vl82c480.c) + +if(STPC) + target_sources(chipset PRIVATE stpc.c) +endif() + +if(M1489) + target_sources(chipset PRIVATE ali1489.c) +endif() + +if(M6117) + target_sources(chipset PRIVATE ali6117.c) +endif() \ No newline at end of file diff --git a/src/chipset/acc2168.c b/src/chipset/acc2168.c index 5461cb71a..b30a7951e 100644 --- a/src/chipset/acc2168.c +++ b/src/chipset/acc2168.c @@ -6,19 +6,23 @@ * * This file is part of the 86Box distribution. * - * Implementation of the ACC 2168 chipset + * Implementation of the ACC 2046/2168 chipset * * * * Authors: Sarah Walker, + * Tiseno100 * * Copyright 2019 Sarah Walker. + * Copyright 2021 Tiseno100. */ -#include +#include #include +#include #include #include #include +#define HAVE_STDARG_H #include <86box/86box.h> #include "cpu.h" #include <86box/timer.h> @@ -28,84 +32,174 @@ #include <86box/port_92.h> #include <86box/chipset.h> -#define enabled_shadow (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) -#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY) +#define ENABLED_SHADOW (MEM_READ_INTERNAL | ((dev->regs[0x02] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL)) +#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) +#define SHADOW_ADDR ((i <= 1) ? (0xc0000 + (i << 15)) : (0xd0000 + ((i - 2) << 16))) +#define SHADOW_SIZE ((i <= 1) ? 0x8000 : 0x10000) +#define SHADOW_RECALC ((dev->regs[0x02] & (1 << i)) ? ENABLED_SHADOW : DISABLED_SHADOW) + +#ifdef ENABLE_ACC2168_LOG +int acc2168_do_log = ENABLE_ACC2168_LOG; +static void +acc2168_log(const char *fmt, ...) +{ + va_list ap; + + if (acc2168_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define acc2168_log(fmt, ...) +#endif typedef struct acc2168_t { - int reg_idx; - uint8_t regs[256]; + uint8_t reg_idx, regs[256]; } acc2168_t; -static void +static void acc2168_shadow_recalc(acc2168_t *dev) { -mem_set_mem_state_both(0xc0000, 0x8000, ((dev->regs[0x02] & 0x01) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xc8000, 0x8000, ((dev->regs[0x02] & 0x02) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xd0000, 0x10000, ((dev->regs[0x02] & 0x04) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xe0000, 0x10000, ((dev->regs[0x02] & 0x08) ? enabled_shadow : disabled_shadow)); -mem_set_mem_state_both(0xf0000, 0x10000, ((dev->regs[0x02] & 0x10) ? enabled_shadow : disabled_shadow)); + for (uint32_t i = 0; i < 5; i++) + mem_set_mem_state_both(SHADOW_ADDR, SHADOW_SIZE, SHADOW_RECALC); } -static void +static void acc2168_write(uint16_t addr, uint8_t val, void *p) { acc2168_t *dev = (acc2168_t *)p; - if (!(addr & 1)) - dev->reg_idx = val; - else { - dev->regs[dev->reg_idx] = val; + switch (addr) + { + case 0xf2: + dev->reg_idx = val; + break; + case 0xf3: + acc2168_log("ACC2168: dev->regs[%02x] = %02x\n", dev->reg_idx, val); + switch (dev->reg_idx) + { + case 0x00: + dev->regs[dev->reg_idx] = val; + break; - switch (dev->reg_idx) { - case 0x02: - acc2168_shadow_recalc(dev); - break; - } + case 0x01: + dev->regs[dev->reg_idx] = val & 0xd3; + cpu_update_waitstates(); + break; + + case 0x02: + dev->regs[dev->reg_idx] = val & 0x7f; + acc2168_shadow_recalc(dev); + break; + + case 0x03: + dev->regs[dev->reg_idx] = val & 0x1f; + break; + + case 0x04: + dev->regs[dev->reg_idx] = val; + cpu_cache_ext_enabled = !!(val & 0x01); + cpu_update_waitstates(); + break; + + case 0x05: + dev->regs[dev->reg_idx] = val & 0xf3; + break; + + case 0x06: + case 0x07: + dev->regs[dev->reg_idx] = val & 0x1f; + break; + + case 0x08: + dev->regs[dev->reg_idx] = val & 0x0f; + break; + + case 0x09: + dev->regs[dev->reg_idx] = val & 0x03; + break; + + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x10: + case 0x11: + dev->regs[dev->reg_idx] = val; + break; + + case 0x12: + dev->regs[dev->reg_idx] = val & 0xbb; + break; + + case 0x18: + dev->regs[dev->reg_idx] = val & 0x77; + break; + + case 0x19: + dev->regs[dev->reg_idx] = val & 0xfb; + break; + + case 0x1a: + dev->regs[dev->reg_idx] = val; + cpu_cache_int_enabled = !(val & 0x40); + cpu_update_waitstates(); + break; + + case 0x1b: + dev->regs[dev->reg_idx] = val & 0xef; + break; + + default: /* ACC 2168 has way more registers which we haven't documented */ + dev->regs[dev->reg_idx] = val; + break; + + } + break; } } - -static uint8_t +static uint8_t acc2168_read(uint16_t addr, void *p) { acc2168_t *dev = (acc2168_t *)p; - if (!(addr & 1)) - return dev->reg_idx; - - return dev->regs[dev->reg_idx]; + return (addr == 0xf3) ? dev->regs[dev->reg_idx] : dev->reg_idx; } static void acc2168_close(void *priv) { - acc2168_t *dev = (acc2168_t *) priv; + acc2168_t *dev = (acc2168_t *)priv; free(dev); } - static void * acc2168_init(const device_t *info) { acc2168_t *dev = (acc2168_t *)malloc(sizeof(acc2168_t)); memset(dev, 0, sizeof(acc2168_t)); - - io_sethandler(0x00f2, 0x0002, - acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev); - device_add(&port_92_inv_device); + device_add(&port_92_device); + io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev); return dev; } - const device_t acc2168_device = { - "ACC 2168", + "ACC 2046/2168", 0, 0, - acc2168_init, acc2168_close, NULL, - { NULL }, NULL, NULL, - NULL -}; + acc2168_init, + acc2168_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 180db433d..9bf301abc 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -28,19 +28,19 @@ #include <86box/timer.h> #include <86box/io.h> #include <86box/device.h> -#include <86box/keyboard.h> -#include <86box/mem.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/pci.h> -#include <86box/dma.h> -#include <86box/smram.h> + +#include <86box/apm.h> #include <86box/hdc_ide.h> +#include <86box/hdc.h> +#include <86box/mem.h> +#include <86box/pci.h> #include <86box/port_92.h> +#include <86box/smram.h> + #include <86box/chipset.h> -#define disabled_shadow (MEM_READ_EXTANY | MEM_WRITE_EXTANY) -#define ENABLE_ALI1489_LOG 0 +#define DEFINE_SHADOW_PROCEDURE (((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)) +#define DISABLED_SHADOW (MEM_READ_EXTANY | MEM_WRITE_EXTANY) #ifdef ENABLE_ALI1489_LOG int ali1489_do_log = ENABLE_ALI1489_LOG; @@ -49,10 +49,11 @@ ali1489_log(const char *fmt, ...) { va_list ap; - if (ali1489_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + if (ali1489_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else @@ -61,18 +62,23 @@ ali1489_log(const char *fmt, ...) typedef struct { - uint8_t index, ide_index, ide_chip_id, - regs[256], pci_conf[256], ide_regs[256]; - port_92_t * port_92; - smram_t * smram; + uint8_t index, ide_index, ide_chip_id, + regs[256], pci_conf[256], ide_regs[256]; + + uint8_t pci_slot; + + apm_t *apm; + port_92_t *port_92; + smram_t *smram; } ali1489_t; static void ali1489_defaults(void *priv) { - ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; /* IDE registers */ + dev->ide_regs[0x00] = 0x57; dev->ide_regs[0x01] = 0x02; dev->ide_regs[0x08] = 0xff; dev->ide_regs[0x09] = 0x41; @@ -104,266 +110,264 @@ ali1489_defaults(void *priv) dev->regs[0x3c] = 0x03; dev->regs[0x3d] = 0x01; dev->regs[0x40] = 0x03; - } static void ali1489_shadow_recalc(ali1489_t *dev) { + for (uint32_t i = 0; i < 8; i++) + { + if (dev->regs[0x13] & (1 << i)) + mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DEFINE_SHADOW_PROCEDURE); + else + mem_set_mem_state_both(0xc0000 + (i << 14), 0x4000, DISABLED_SHADOW); + } -uint32_t base, i; + for (uint32_t i = 0; i < 4; i++) + { + shadowbios = (dev->regs[0x14] & 0x10); + shadowbios_write = (dev->regs[0x14] & 0x20); + if (dev->regs[0x14] & (1 << i)) + mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DEFINE_SHADOW_PROCEDURE); + else + mem_set_mem_state_both(0xe0000 + (i << 15), 0x8000, DISABLED_SHADOW); + } -for(i = 0; i < 8; i++){ - -base = 0xc0000 + (i << 14); -if(dev->regs[0x13] & (1 << i)) -mem_set_mem_state_both(base, 0x4000, ((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); -else -mem_set_mem_state_both(base, 0x4000, disabled_shadow); - -} - - -for(i = 0; i < 4; i++){ -base = 0xe0000 + (i << 15); - -shadowbios = (dev->regs[0x14] & 0x10); -shadowbios_write = (dev->regs[0x14] & 0x20); - -if(dev->regs[0x14] & (1 << i)) -mem_set_mem_state_both(base, 0x8000, ((dev->regs[0x14] & 0x10) ? MEM_READ_INTERNAL : MEM_READ_EXTANY) | ((dev->regs[0x14] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY)); -else -mem_set_mem_state_both(base, 0x8000, disabled_shadow); -} - -flushmmucache(); + flushmmucache(); } static void ali1489_smram_recalc(ali1489_t *dev) { -/* The datasheet documents SMM behavior quite terribly. + /* The datasheet documents SMM behavior quite terribly. Everything were done according to the M1489 programming guide. */ -switch(dev->regs[0x19] & 0x30) { -case 0: -smram_disable_all(); -break; -case 1: -smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, (dev->regs[0x19] & 0x08), !(dev->regs[0x19] & 0x08)); -break; -case 2: -smram_enable(dev->smram, 0xe0000, 0xe0000, 0x10000, (dev->regs[0x19] & 0x08), !(dev->regs[0x19] & 0x08)); -break; -case 3: -smram_enable(dev->smram, 0x30000, 0xa0000, 0x20000, (dev->regs[0x19] & 0x08), !(dev->regs[0x19] & 0x08)); -break; + switch (dev->regs[0x19] & 0x30) + { + case 0: + smram_disable_all(); + break; + case 1: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x20000, (dev->regs[0x19] & 0x08), 1); + break; + case 2: + if (dev->regs[0x14] == 0) + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x10000, (dev->regs[0x19] & 0x08), 1); + break; + case 3: + smram_enable(dev->smram, 0x30000, 0xa0000, 0x20000, (dev->regs[0x19] & 0x08), 1); + break; + } } + +static void +ali1489_ide_handler(ali1489_t *dev) +{ + ide_set_base(0, 0x1f0); + ide_set_side(0, 0x3f6); + ide_pri_enable(); + if (dev->ide_regs[0x35] & 0x01) + { + ide_set_base(1, 0x170); + ide_set_side(1, 0x376); + ide_sec_enable(); + if (dev->ide_regs[0x35] & 0x04) + ide_sec_disable(); + } } static void ali1489_write(uint16_t addr, uint8_t val, void *priv) { - ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; - switch (addr) { - case 0x22: - dev->index = val; - break; - case 0x23: + switch (addr) + { + case 0x22: + dev->index = val; + break; + case 0x23: dev->regs[dev->index] = val; - if(dev->regs[0x03] == 0xc5) /* Check if the configuration registers are unlocked */ + if (dev->regs[0x03] == 0xc5) /* Check if the configuration registers are unlocked */ { - switch(dev->index){ + switch (dev->index) + { case 0x10: /* DRAM Configuration Register I */ case 0x11: /* DRAM Configuration Register II */ case 0x12: /* ROM Function Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x13: /* Shadow Region Register */ case 0x14: /* Shadow Control Register */ - if(dev->index == 0x14) - dev->regs[dev->index] = (val & 0xbf); - else - { - dev->regs[dev->index] = val; - } + if (dev->index == 0x14) + dev->regs[dev->index] = (val & 0xbf); + else + { + dev->regs[dev->index] = val; + } - ali1489_shadow_recalc(dev); - break; + ali1489_shadow_recalc(dev); + break; case 0x15: /* Cycle Check Point Control Register */ - dev->regs[dev->index] = (val & 0xf1); - break; + dev->regs[dev->index] = (val & 0xf1); + break; case 0x16: /* Cache Control Register I */ - dev->regs[dev->index] = val; - cpu_cache_int_enabled = (val & 0x01); - cpu_cache_ext_enabled = (val & 0x02); - break; + dev->regs[dev->index] = val; + cpu_cache_int_enabled = (val & 0x01); + cpu_cache_ext_enabled = (val & 0x02); + cpu_update_waitstates(); + break; case 0x17: /* Cache Control Register II */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x19: /* SMM Control Register */ - dev->regs[dev->index] = val; - ali1489_smram_recalc(dev); - break; + dev->regs[dev->index] = val; + ali1489_smram_recalc(dev); + break; case 0x1a: /* EDO DRAM Configuration Register */ case 0x1b: /* DRAM Timing Control Register */ case 0x1c: /* Memory Data Buffer Direction Control Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x1e: /* Linear Wrapped Burst Order Mode Control Register */ - dev->regs[dev->index] = (val & 0x40); - break; + dev->regs[dev->index] = (val & 0x40); + break; case 0x20: /* CPU to PCI Buffer Control Register */ case 0x21: /* DEVSELJ Check Point Setting Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x22: /* PCI to CPU W/R Buffer Configuration Register */ - dev->regs[dev->index] = (val & 0xfd); - break; + dev->regs[dev->index] = (val & 0xfd); + break; case 0x25: /* GP/MEM Address Definition Register I */ case 0x26: /* GP/MEM Address Definition Register II */ case 0x27: /* GP/MEM Address Definition Register III */ case 0x28: /* PCI Arbiter Control Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x29: /* System Clock Register */ - dev->regs[dev->index] = val; + dev->regs[dev->index] = val; - if(val & 0x10) - port_92_add(dev->port_92); - else - port_92_remove(dev->port_92); - break; + if (val & 0x10) + port_92_add(dev->port_92); + else + port_92_remove(dev->port_92); + break; case 0x2a: /* I/O Recovery Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x2b: /* Turbo Function Register */ - dev->regs[dev->index] = (val & 0xbf); - break; + dev->regs[dev->index] = (val & 0xbf); + break; case 0x30: /* Power Management Unit Control Register */ + dev->regs[dev->index] = val; + apm_set_do_smi(dev->apm, val & 0x1c); + break; + case 0x31: /* Mode Timer Monitoring Events Selection Register I */ case 0x32: /* Mode Timer Monitoring Events Selection Register II */ case 0x33: /* SMI Triggered Events Selection Register I */ case 0x34: /* SMI Triggered Events Selection Register II */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x35: /* SMI Status Register */ - dev->regs[dev->index] = val; - if(dev->regs[dev->index] & 0x30) - smi_line = 1; - break; + dev->regs[dev->index] = val; + break; case 0x36: /* IRQ Channel Group Selected Control Register I */ - dev->regs[dev->index] = (val & 0xe5); - break; + dev->regs[dev->index] = (val & 0xe5); + break; case 0x37: /* IRQ Channel Group Selected Control Register II */ - dev->regs[dev->index] = (val & 0xef); - break; + dev->regs[dev->index] = (val & 0xef); + break; case 0x38: /* DRQ Channel Selected Control Register */ case 0x39: /* Mode Timer Setting Register */ case 0x3a: /* Input_device Timer Setting Register */ case 0x3b: /* GP/MEM Timer Setting Register */ case 0x3c: /* LED Flash Control Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x3d: /* Miscellaneous Register I */ - dev->regs[dev->index] = (val & 0x07); - break; + dev->regs[dev->index] = (val & 0x07); + break; case 0x3f: /* Shadow Port 70h Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x40: /* Clock Generator Control Feature Register */ - dev->regs[dev->index] = (val & 0x3f); - break; + dev->regs[dev->index] = (val & 0x3f); + break; case 0x41: /* Power Control Output Register */ - dev->regs[dev->index] = val; - break; + dev->regs[dev->index] = val; + break; case 0x42: /* PCI INTx Routing Table Mapping Register I */ - if((val & 0x0f) != 0) - pci_set_irq(PCI_INTA, (val & 0x0f)); - else - pci_set_irq(PCI_INTA, PCI_IRQ_DISABLED); - - if(((val & 0x0f) << 4) != 0) - pci_set_irq(PCI_INTB, ((val & 0x0f) << 4)); - else - pci_set_irq(PCI_INTB, PCI_IRQ_DISABLED); - break; + pci_set_irq_routing(PCI_INTA, ((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTB, ((val & 0xf0) != 0) ? (val & 0xf0) : PCI_IRQ_DISABLED); + break; case 0x43: /* PCI INTx Routing Table Mapping Register II */ - if((val & 0x0f) != 0) - pci_set_irq(PCI_INTC, (val & 0x0f)); - else - pci_set_irq(PCI_INTC, PCI_IRQ_DISABLED); - - if(((val & 0x0f) << 4) != 0) - pci_set_irq(PCI_INTD, ((val & 0x0f) << 4)); - else - pci_set_irq(PCI_INTD, PCI_IRQ_DISABLED); - break; + pci_set_irq_routing(PCI_INTC, ((val & 0x0f) != 0) ? (val & 0x0f) : PCI_IRQ_DISABLED); + pci_set_irq_routing(PCI_INTD, ((val & 0xf0) != 0) ? (val & 0xf0) : PCI_IRQ_DISABLED); + break; case 0x44: /* PCI INTx Sensitivity Register */ - dev->regs[dev->index] = val; - break; - + dev->regs[dev->index] = val; + break; + } + + if (dev->index != 0x03) + { + ali1489_log("M1489: dev->regs[%02x] = %02x\n", dev->index, val); + } } - if(dev->index != 0x03) - { - ali1489_log("M1489: dev->regs[%02x] = %02x\n", dev->index, val); - } - - } - - break; + break; } } - static uint8_t ali1489_read(uint16_t addr, void *priv) { uint8_t ret = 0xff; - ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; - switch (addr) { - case 0x23: + switch (addr) + { + case 0x23: - if(((dev->index == 0x20) || (dev->index >= 0xc0)) && cpu_iscyrix) /* Avoid conflict with Cyrix CPU registers */ - ret = 0xff; + if (((dev->index == 0x20) || (dev->index >= 0xc0)) && cpu_iscyrix) /* Avoid conflict with Cyrix CPU registers */ + ret = 0xff; else { - ret = dev->regs[dev->index]; + ret = dev->regs[dev->index]; } - break; + break; } - + ali1489_log("M1489: dev->regs[%02x] (%02x)\n", dev->index, ret); return ret; } @@ -371,33 +375,32 @@ static void ali1489_pci_write(int func, int addr, uint8_t val, void *priv) { -ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; -ali1489_log("M1489-PCI: dev->regs[%02x] = %02x\n", addr, val); + ali1489_log("M1489-PCI: dev->pci_conf[%02x] = %02x\n", addr, val); -switch (addr) -{ + switch (addr) + { /* Dummy PCI Config */ case 0x04: - dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x07) | (val & 0x07); - break; + dev->pci_conf[0x04] = (dev->pci_conf[0x04] & ~0x07) | (val & 0x07); + break; /* Dummy PCI Status */ case 0x07: - dev->pci_conf[0x07] &= ~(val & 0xfe); - break; -} - + dev->pci_conf[0x07] &= ~(val & 0xfe); + break; + } } static uint8_t ali1489_pci_read(int func, int addr, void *priv) { - ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; uint8_t ret = 0xff; - - ret = dev->pci_conf[addr]; + ret = dev->pci_conf[addr]; + ali1489_log("M1489-PCI: dev->pci_conf[%02x] (%02x)\n", addr, ret); return ret; } @@ -405,40 +408,29 @@ static void ali1489_ide_write(uint16_t addr, uint8_t val, void *priv) { -ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; - switch (addr) { + switch (addr) + { case 0xf4: /* Usually it writes 30h here */ dev->ide_chip_id = val; break; - case 0xf8: - dev->ide_index = val; - break; - - case 0xfc: - ali1489_log("M1489-IDE: dev->regs[%02x] = %02x\n", dev->ide_index, val); - dev->ide_regs[dev->ide_index] = val; + case 0xf8: + dev->ide_index = val; + break; - ide_pri_disable(); - ide_sec_disable(); - - if(dev->ide_regs[0x01] & 0x01){ /*The datasheet doesn't clearly explain the channel selection */ - ide_pri_enable(); /*So we treat it according to the chipset programming manual. */ - ide_set_base(0, 0x1f0); - ide_set_side(0, 0x3f6); - - if(!(dev->ide_regs[0x35] & 0x41)){ - ide_sec_enable(); - ide_set_base(1, 0x170); - ide_set_side(1, 0x376); + case 0xfc: + dev->ide_regs[dev->ide_index] = val; + if (dev->ide_regs[0x01] & 0x01) // Internal IDE Enabled + { + ali1489_log("M1489-IDE: dev->regs[%02x] = %02x\n", dev->ide_index, val); + ide_pri_disable(); + ide_sec_disable(); + ali1489_ide_handler(dev); } - - } - break; } - } static uint8_t @@ -446,15 +438,17 @@ ali1489_ide_read(uint16_t addr, void *priv) { uint8_t ret = 0xff; - ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; - switch (addr) { + switch (addr) + { case 0xf4: ret = dev->ide_chip_id; break; - case 0xfc: - ret = dev->ide_regs[dev->ide_index]; - break; + case 0xfc: + ret = dev->ide_regs[dev->ide_index]; + ali1489_log("M1489-IDE: dev->regs[%02x] (%02x)\n", dev->ide_index, ret); + break; } return ret; @@ -464,34 +458,29 @@ static void ali1489_reset(void *priv) { -ali1489_t *dev = (ali1489_t *) priv; + ali1489_t *dev = (ali1489_t *)priv; -ide_pri_disable(); -ide_sec_disable(); - -pci_set_irq(PCI_INTA, PCI_IRQ_DISABLED); -pci_set_irq(PCI_INTB, PCI_IRQ_DISABLED); -pci_set_irq(PCI_INTC, PCI_IRQ_DISABLED); -pci_set_irq(PCI_INTD, PCI_IRQ_DISABLED); - -ali1489_defaults(dev); + pci_set_irq(PCI_INTA, PCI_IRQ_DISABLED); + pci_set_irq(PCI_INTB, PCI_IRQ_DISABLED); + pci_set_irq(PCI_INTC, PCI_IRQ_DISABLED); + pci_set_irq(PCI_INTD, PCI_IRQ_DISABLED); + ali1489_defaults(dev); } static void ali1489_close(void *priv) { - ali1489_t *dev = (ali1489_t *) priv; - + ali1489_t *dev = (ali1489_t *)priv; + smram_del(dev->smram); free(dev); } - static void * ali1489_init(const device_t *info) { - ali1489_t *dev = (ali1489_t *) malloc(sizeof(ali1489_t)); + ali1489_t *dev = (ali1489_t *)malloc(sizeof(ali1489_t)); memset(dev, 0, sizeof(ali1489_t)); /* @@ -512,11 +501,13 @@ ali1489_init(const device_t *info) io_sethandler(0x0fc, 0x0001, ali1489_ide_read, NULL, NULL, ali1489_ide_write, NULL, NULL, dev); /* Dummy M1489 PCI device */ - pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev); + dev->pci_slot = pci_add_card(PCI_ADD_NORTHBRIDGE, ali1489_pci_read, ali1489_pci_write, dev); ide_pri_disable(); ide_sec_disable(); + dev->apm = device_add(&apm_pci_device); + device_add(&ide_pci_2ch_device); dev->port_92 = device_add(&port_92_pci_device); dev->smram = smram_add(); @@ -532,7 +523,6 @@ ali1489_init(const device_t *info) return dev; } - const device_t ali1489_device = { "ALi M1489", 0, @@ -540,8 +530,7 @@ const device_t ali1489_device = { ali1489_init, ali1489_close, ali1489_reset, - { NULL }, + {NULL}, NULL, NULL, - NULL -}; + NULL}; diff --git a/src/chipset/cs8230.c b/src/chipset/cs8230.c index 90432e271..e7ae64134 100644 --- a/src/chipset/cs8230.c +++ b/src/chipset/cs8230.c @@ -32,124 +32,131 @@ typedef struct { - int idx; - uint8_t regs[256]; + int idx; + uint8_t regs[256]; } cs8230_t; + static void shadow_control(uint32_t addr, uint32_t size, int state) { - switch (state) { - case 0x00: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x01: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 0x10: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 0x11: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - } - flushmmucache_nopc(); + switch (state) { + case 0x00: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x01: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 0x11: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + } + + flushmmucache_nopc(); } static void rethink_shadow_mappings(cs8230_t *cs8230) { - int c; + int c; - for (c = 0; c < 4*8; c++) { /*Addresses 40000-bffff in 16k blocks*/ - if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7))) - mem_set_mem_state(0x40000 + c*0x4000, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /*IO channel*/ - else - mem_set_mem_state(0x40000 + c*0x4000, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /*System board*/ - } - for (c = 0; c < 2*8; c++) { /*Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here*/ - if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7))) - mem_set_mem_state(0xc0000 + c*0x4000, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /*IO channel*/ - else - shadow_control(0xc0000 + c*0x4000, 0x4000, (cs8230->regs[9] >> (3-(c >> 2))) & 0x11); - } + for (c = 0; c < 32; c++) { + /* Addresses 40000-bffff in 16k blocks */ + if (cs8230->regs[0xa + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /* I/O channel */ + else + mem_set_mem_state(0x40000 + (c << 14), 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /* System board */ + } + + for (c = 0; c < 16; c++) { + /* Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here */ + if (cs8230->regs[0xe + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0xc0000 + (c << 14), 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); /* I/O channel */ + else + shadow_control(0xc0000 + (c << 14), 0x4000, (cs8230->regs[9] >> (3 - (c >> 2))) & 0x11); + } } + static uint8_t cs8230_read(uint16_t port, void *p) { - cs8230_t *cs8230 = (cs8230_t *)p; - uint8_t ret = 0xff; + cs8230_t *cs8230 = (cs8230_t *) p; + uint8_t ret = 0xff; - if (port & 1) { - switch (cs8230->idx) { - case 0x04: /*82C301 ID/version*/ - ret = cs8230->regs[cs8230->idx] & ~0xe3; - break; + if (port & 1) { + switch (cs8230->idx) { + case 0x04: /* 82C301 ID/version */ + ret = cs8230->regs[cs8230->idx] & ~0xe3; + break; - case 0x08: /*82C302 ID/Version*/ - ret = cs8230->regs[cs8230->idx] & ~0xe0; - break; - - case 0x05: case 0x06: /*82C301 registers*/ - case 0x09: case 0x0a: case 0x0b: case 0x0c: /*82C302 registers*/ - case 0x0d: case 0x0e: case 0x0f: - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x28: case 0x29: case 0x2a: - ret = cs8230->regs[cs8230->idx]; - break; - } + case 0x08: /* 82C302 ID/Version */ + ret = cs8230->regs[cs8230->idx] & ~0xe0; + break; + + case 0x05: case 0x06: /* 82C301 registers */ + case 0x09: case 0x0a: case 0x0b: case 0x0c: /* 82C302 registers */ + case 0x0d: case 0x0e: case 0x0f: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x28: case 0x29: case 0x2a: + ret = cs8230->regs[cs8230->idx]; + break; } + } - return ret; + return ret; } + static void cs8230_write(uint16_t port, uint8_t val, void *p) { - cs8230_t *cs8230 = (cs8230_t *)p; - - if (!(port & 1)) - cs8230->idx = val; - else { - cs8230->regs[cs8230->idx] = val; - switch (cs8230->idx) { - case 0x09: /*RAM/ROM Configuration in boot area*/ - case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /*Address maps*/ - rethink_shadow_mappings(cs8230); - break; - } + cs8230_t *cs8230 = (cs8230_t *)p; + + if (!(port & 1)) + cs8230->idx = val; + else { + cs8230->regs[cs8230->idx] = val; + switch (cs8230->idx) { + case 0x09: /* RAM/ROM Configuration in boot area */ + case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* Address maps */ + rethink_shadow_mappings(cs8230); + break; } + } } + static void cs8230_close(void *priv) { - cs8230_t *cs8230 = (cs8230_t *)priv; - - free(cs8230); + cs8230_t *cs8230 = (cs8230_t *)priv; + + free(cs8230); } + static void *cs8230_init(const device_t *info) { - cs8230_t *cs8230 = (cs8230_t *)malloc(sizeof(cs8230_t)); - memset(cs8230, 0, sizeof(cs8230_t)); + cs8230_t *cs8230 = (cs8230_t *)malloc(sizeof(cs8230_t)); + memset(cs8230, 0, sizeof(cs8230_t)); - io_sethandler(0x0022, 0x0002, - cs8230_read, NULL, NULL, - cs8230_write, NULL, NULL, - cs8230); + io_sethandler(0x0022, 0x0002, cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, cs8230); - if (mem_size > 768) { - mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); - } + if (mem_size > 768) { + mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); + } - return cs8230; + return cs8230; } + const device_t cs8230_device = { "C&T CS8230 (386/AT)", 0, @@ -157,4 +164,4 @@ const device_t cs8230_device = { cs8230_init, cs8230_close, NULL, { NULL }, NULL, NULL, NULL -}; \ No newline at end of file +}; diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 222b483f9..ea9b68d9a 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -34,28 +34,6 @@ #include <86box/port_92.h> #include <86box/chipset.h> -typedef struct { - void *parent; - int bank; -} ram_struct_t; - -typedef struct { - int cfg_index; - uint8_t cfg_regs[256]; - int cfg_enable; - - int ram_config; - - mem_mapping_t ram_mapping[2]; - - ram_struct_t ram_struct[3]; - - uint32_t ram_virt_base[2], ram_phys_base[2]; - uint32_t ram_mask[2]; - int row_virt_shift[2], row_phys_shift[2]; - int ram_interleaved[2]; - int ibank_shift[2]; -} scamp_t; #define CFG_ID 0x00 #define CFG_SLTPTR 0x02 @@ -71,697 +49,745 @@ typedef struct { #define RAMMAP_REMP386 (1 << 4) +#define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) + + /*Commodore SL386SX requires proper memory slot decoding to detect memory size. Therefore we emulate the SCAMP memory address decoding, and therefore are limited to the DRAM combinations supported by the actual chip*/ enum { - BANK_NONE, - BANK_256K, - BANK_256K_INTERLEAVED, - BANK_1M, - BANK_1M_INTERLEAVED, - BANK_4M, - BANK_4M_INTERLEAVED + BANK_NONE, + BANK_256K, + BANK_256K_INTERLEAVED, + BANK_1M, + BANK_1M_INTERLEAVED, + BANK_4M, + BANK_4M_INTERLEAVED }; + +typedef struct { + void * parent; + int bank; +} ram_struct_t; + +typedef struct { + int cfg_index; + uint8_t cfg_regs[256]; + int cfg_enable, ram_config; + + mem_mapping_t ram_mapping[2]; + ram_struct_t ram_struct[2]; + + uint32_t ram_virt_base[2], ram_phys_base[2]; + uint32_t ram_mask[2]; + int row_virt_shift[2], row_phys_shift[2]; + int ram_interleaved[2], ibank_shift[2]; + + port_92_t * port_92; +} scamp_t; + static const struct { - int size_kb; - int rammap; - int bank[2]; + int size_kb; + int rammap; + int bank[2]; } ram_configs[] = { - {512, 0x0, {BANK_256K, BANK_NONE}}, - {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}}, - {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}}, - {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}}, - {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}}, - {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}}, - {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}}, - {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}}, - {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}}, - {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}}, - {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}}, + {512, 0x0, {BANK_256K, BANK_NONE}}, + {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}}, + {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}}, + {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}}, + {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}}, + {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}}, + {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}}, + {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}}, + {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}}, }; static const struct { - int bank[2]; - int remapped; + int bank[2]; + int remapped; } rammap[16] = { - {{BANK_256K, BANK_NONE}, 0}, - {{BANK_256K_INTERLEAVED, BANK_NONE}, 0}, - {{BANK_256K_INTERLEAVED, BANK_256K}, 0}, - {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0}, + {{BANK_256K, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0}, - {{BANK_1M, BANK_NONE}, 0}, - {{BANK_1M_INTERLEAVED, BANK_NONE}, 0}, - {{BANK_1M_INTERLEAVED, BANK_1M}, 0}, - {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + {{BANK_1M, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, - {{BANK_4M, BANK_NONE}, 0}, - {{BANK_4M_INTERLEAVED, BANK_NONE}, 0}, - {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/ - {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/ + {{BANK_4M, BANK_NONE}, 0}, + {{BANK_4M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/ + {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/ - {{BANK_256K_INTERLEAVED, BANK_1M}, 0}, - {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, - {{BANK_1M_INTERLEAVED, BANK_4M}, 0}, - {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/ + {{BANK_256K_INTERLEAVED, BANK_1M}, 0}, + {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/ }; -/*The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous, - so we use separate routines for that special case*/ + +/* The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous, + so we use separate routines for that special case */ static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return 0xff; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return 0xff; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } - return ram[addr + dev->ram_phys_base[bank]]; + return ram[addr + dev->ram_phys_base[bank]]; } + + static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } - ram[addr + dev->ram_phys_base[bank]] = val; + ram[addr + dev->ram_phys_base[bank]] = val; } + /*Read/write handlers for interleaved memory banks. We must keep CPU and ram array mapping linear, otherwise we won't be able to execute code from interleaved banks*/ static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return 0xff; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return 0xff; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; - - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; - return ram[addr + dev->ram_phys_base[bank]]; + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } + + return ram[addr + dev->ram_phys_base[bank]]; } + + static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - if (!dev->ram_interleaved[bank]) { - if (addr & 0x400) - return; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + if (!dev->ram_interleaved[bank]) { + if (addr & 0x400) + return; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - } - else { - column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); - row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((dev->ram_mask[bank] << 1) | 1); + row = (addr >> (dev->row_virt_shift[bank]+1)) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); - } + addr = byte | (column << 1) | (row << (dev->row_phys_shift[bank]+1)); + } - ram[addr + dev->ram_phys_base[bank]] = val; + ram[addr + dev->ram_phys_base[bank]] = val; } + static uint8_t ram_mirrored_read(uint32_t addr, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; - - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - return ram[addr + dev->ram_phys_base[bank]]; + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + + return ram[addr + dev->ram_phys_base[bank]]; } + + static void ram_mirrored_write(uint32_t addr, uint8_t val, void *priv) { - ram_struct_t *rs = (ram_struct_t *) priv; - scamp_t *dev = rs->parent; - int bank = rs->bank; - int row, column, byte; + ram_struct_t *rs = (ram_struct_t *) priv; + scamp_t *dev = rs->parent; + int bank = rs->bank, byte; + int row, column; - addr -= dev->ram_virt_base[bank]; - byte = addr & 1; - column = (addr >> 1) & dev->ram_mask[bank]; - row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; - addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); + addr -= dev->ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & dev->ram_mask[bank]; + row = (addr >> dev->row_virt_shift[bank]) & dev->ram_mask[bank]; + addr = byte | (column << 1) | (row << dev->row_phys_shift[bank]); - ram[addr + dev->ram_phys_base[bank]] = val; + ram[addr + dev->ram_phys_base[bank]] = val; } + static void recalc_mappings(void *priv) { - scamp_t *dev = (scamp_t *) priv; - int c; - uint32_t virt_base = 0; - uint8_t cur_rammap = dev->cfg_regs[CFG_RAMMAP] & 0xf; - int bank_nr = 0; + scamp_t *dev = (scamp_t *) priv; + int c; + uint32_t virt_base = 0, old_virt_base; + uint8_t cur_rammap = dev->cfg_regs[CFG_RAMMAP] & 0xf; + int bank_nr = 0, phys_bank; + + mem_set_mem_state_both((1 << 20), (16256 - 1024) * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + for (c = 0; c < 2; c++) + mem_mapping_disable(&dev->ram_mapping[c]); + + /* Once the BIOS programs the correct DRAM configuration, switch to regular + linear memory mapping */ + if (cur_rammap == ram_configs[dev->ram_config].rammap) { + mem_mapping_set_handler(&ram_low_mapping, + mem_read_ram, mem_read_ramw, mem_read_raml, + mem_write_ram, mem_write_ramw, mem_write_raml); + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + if (mem_size > 1024) + mem_set_mem_state_both((1 << 20), (mem_size - 1024) << 10, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_enable(&ram_high_mapping); + return; + } else { + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_low_mapping); + } + + if (rammap[cur_rammap].bank[0] == BANK_NONE) + bank_nr = 1; - for (c = 0; c < 2; c++) - mem_mapping_disable(&dev->ram_mapping[c]); + for (; bank_nr < 2; bank_nr++) { + old_virt_base = virt_base; + phys_bank = ram_configs[dev->ram_config].bank[bank_nr]; - /*Once the BIOS programs the correct DRAM configuration, switch to regular - linear memory mapping*/ - if (cur_rammap == ram_configs[dev->ram_config].rammap) { - mem_mapping_set_handler(&ram_low_mapping, - mem_read_ram, mem_read_ramw, mem_read_raml, - mem_write_ram, mem_write_ramw, mem_write_raml); - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_enable(&ram_high_mapping); - return; - } else { - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - mem_mapping_disable(&ram_low_mapping); - } - - if (rammap[cur_rammap].bank[0] == BANK_NONE) - bank_nr = 1; + dev->ram_virt_base[bank_nr] = virt_base; -/* pclog("Bank remap, cur_rammap=%x\n", cur_rammap); */ - - for (; bank_nr < 2; bank_nr++) { - uint32_t old_virt_base = virt_base; - int phys_bank = ram_configs[dev->ram_config].bank[bank_nr]; - -/* pclog(" Bank %i: phys_bank=%i rammap_bank=%i virt_base=%08x phys_base=%08x\n", bank_nr, phys_bank, rammap[cur_rammap].bank[bank_nr], virt_base, dev->ram_phys_base[bank_nr]); */ - dev->ram_virt_base[bank_nr] = virt_base; + if (virt_base == 0) { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + fatal(" Bank %i is empty!\n }\n}\n", bank_nr); + break; - if (virt_base == 0) { - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_NONE: - fatal("Bank 0 is empty!\n"); - break; + case BANK_256K: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); + } + virt_base += (1 << 19); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); - mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); - } - virt_base += 512*1024; - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); + } + virt_base += (1 << 20); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); - } - virt_base += 512*1024*2; - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 21); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x100000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 2048*1024; - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (3 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 22); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x300000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 2048*1024*2; - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (7 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 23); + dev->row_virt_shift[bank_nr] = 12; + break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0x700000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 8192*1024; - dev->row_virt_shift[bank_nr] = 12; - break; + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); + mem_set_mem_state_both((1 << 20), (15 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 24); + dev->row_virt_shift[bank_nr] = 12; + break; + } + } else { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + break; - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)&dev->ram_struct[bank_nr]); - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], 0x100000, 0xf00000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 8192*1024*2; - dev->row_virt_shift[bank_nr] = 12; - break; - } - } else { - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_NONE: - break; + case BANK_256K: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x80000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 19), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 19); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x80000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 512*1024; - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 20), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 20); + dev->row_virt_shift[bank_nr] = 10; + break; - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x100000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 512*1024*2; - dev->row_virt_shift[bank_nr] = 10; - break; + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 21), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 21); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x200000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 2048*1024; - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 22), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 22); + dev->row_virt_shift[bank_nr] = 11; + break; - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x400000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 2048*1024*2; - dev->row_virt_shift[bank_nr] = 11; - break; + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 23), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 23); + dev->row_virt_shift[bank_nr] = 12; + break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x800000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 8192*1024; - dev->row_virt_shift[bank_nr] = 12; - break; - - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000); - mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); - } - virt_base += 8192*1024*2; - dev->row_virt_shift[bank_nr] = 12; - break; - } - } - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_256K: case BANK_1M: case BANK_4M: - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&dev->ram_mapping[bank_nr], virt_base, 0x1000000); + mem_mapping_set_exec(&dev->ram_mapping[bank_nr], &ram[dev->ram_phys_base[bank_nr]]); + mem_set_mem_state_both(virt_base, (1 << 24), MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } + virt_base += (1 << 24); + dev->row_virt_shift[bank_nr] = 12; + break; + } + } + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_256K: case BANK_1M: case BANK_4M: + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); - /*pclog(" not interleaved\n");*/ - break; + break; - case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED: - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + case BANK_256K_INTERLEAVED: case BANK_1M_INTERLEAVED: + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], ram_mirrored_interleaved_read, NULL, NULL, ram_mirrored_interleaved_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_interleaved_read, NULL, NULL, ram_mirrored_interleaved_write, NULL, NULL); - /*pclog(" interleaved\n");*/ - break; + break; - case BANK_4M_INTERLEAVED: - if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + case BANK_4M_INTERLEAVED: + if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], ram_mirrored_256k_in_4mi_read, NULL, NULL, ram_mirrored_256k_in_4mi_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_256k_in_4mi_read, NULL, NULL, ram_mirrored_256k_in_4mi_write, NULL, NULL); - /*pclog(" 256k in 4mi\n");*/ - } else { - mem_mapping_set_handler(&dev->ram_mapping[bank_nr], + } else { + mem_mapping_set_handler(&dev->ram_mapping[bank_nr], ram_mirrored_interleaved_read, NULL, NULL, ram_mirrored_interleaved_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_interleaved_read, NULL, NULL, ram_mirrored_interleaved_write, NULL, NULL); - /*pclog(" interleaved\n");*/ - } - break; - } - } + } + break; + } + } } -#define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) - static void shadow_control(uint32_t addr, uint32_t size, int state) { -/* pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); */ - switch (state) { - case 0: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - break; - case 1: - mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); - break; - case 2: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); - break; - case 3: - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); + switch (state) { + case 0: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + break; + case 1: + mem_set_mem_state(addr, size, MEM_READ_EXTANY | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTANY); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + + flushmmucache_nopc(); } + static void scamp_write(uint16_t addr, uint8_t val, void *priv) { - scamp_t *dev = (scamp_t *) priv; - -/* pclog("scamp_write: addr=%04x val=%02x\n", addr, val); */ - switch (addr) { - case 0xec: - if (dev->cfg_enable) - dev->cfg_index = val; - break; - - case 0xed: - if (dev->cfg_enable) { - if (dev->cfg_index >= 0x02 && dev->cfg_index <= 0x16) { - dev->cfg_regs[dev->cfg_index] = val; -/* pclog("SCAMP CFG[%02x]=%02x\n", dev->cfg_index, val); */ - switch (dev->cfg_index) { - case CFG_SLTPTR: - break; + scamp_t *dev = (scamp_t *) priv; - case CFG_RAMMAP: - recalc_mappings(dev); - mem_mapping_disable(&ram_remapped_mapping); - if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) { - /*Enabling remapping will disable all shadowing*/ - mem_remap_top(384); - shadow_control(0xa0000, 0x60000, 0); - } else { - shadow_control(0xa0000, 0x8000, dev->cfg_regs[CFG_ABAXS] & 3); - shadow_control(0xa8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 2) & 3); - shadow_control(0xb0000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 4) & 3); - shadow_control(0xb8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 6) & 3); + switch (addr) { + case 0xec: + if (dev->cfg_enable) + dev->cfg_index = val; + break; - shadow_control(0xc0000, 0x4000, dev->cfg_regs[CFG_CAXS] & 3); - shadow_control(0xc4000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 2) & 3); - shadow_control(0xc8000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 4) & 3); - shadow_control(0xcc000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 6) & 3); + case 0xed: + if (dev->cfg_enable && (dev->cfg_index >= 0x02) && (dev->cfg_index <= 0x16)) { + dev->cfg_regs[dev->cfg_index] = val; + switch (dev->cfg_index) { + case CFG_SLTPTR: + break; - shadow_control(0xd0000, 0x4000, dev->cfg_regs[CFG_DAXS] & 3); - shadow_control(0xd4000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 2) & 3); - shadow_control(0xd8000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 4) & 3); - shadow_control(0xdc000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 6) & 3); + case CFG_RAMMAP: + recalc_mappings(dev); + mem_mapping_disable(&ram_remapped_mapping); + if (dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) { + /* Enabling remapping will disable all shadowing */ + mem_remap_top(384); + shadow_control(0xa0000, 0x60000, 0); + } else { + shadow_control(0xa0000, 0x8000, dev->cfg_regs[CFG_ABAXS] & 3); + shadow_control(0xa8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 2) & 3); + shadow_control(0xb0000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 4) & 3); + shadow_control(0xb8000, 0x8000, (dev->cfg_regs[CFG_ABAXS] >> 6) & 3); - shadow_control(0xe0000, 0x8000, dev->cfg_regs[CFG_FEAXS] & 3); - shadow_control(0xe8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 2) & 3); - shadow_control(0xf0000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 4) & 3); - shadow_control(0xf8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 6) & 3); - } - break; + shadow_control(0xc0000, 0x4000, dev->cfg_regs[CFG_CAXS] & 3); + shadow_control(0xc4000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 2) & 3); + shadow_control(0xc8000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 4) & 3); + shadow_control(0xcc000, 0x4000, (dev->cfg_regs[CFG_CAXS] >> 6) & 3); - case CFG_ABAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xa0000, 0x8000, val & 3); - shadow_control(0xa8000, 0x8000, (val >> 2) & 3); - shadow_control(0xb0000, 0x8000, (val >> 4) & 3); - shadow_control(0xb8000, 0x8000, (val >> 6) & 3); - } - break; - - case CFG_CAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xc0000, 0x4000, val & 3); - shadow_control(0xc4000, 0x4000, (val >> 2) & 3); - shadow_control(0xc8000, 0x4000, (val >> 4) & 3); - shadow_control(0xcc000, 0x4000, (val >> 6) & 3); - } - break; - - case CFG_DAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xd0000, 0x4000, val & 3); - shadow_control(0xd4000, 0x4000, (val >> 2) & 3); - shadow_control(0xd8000, 0x4000, (val >> 4) & 3); - shadow_control(0xdc000, 0x4000, (val >> 6) & 3); - } - break; - - case CFG_FEAXS: - if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { - shadow_control(0xe0000, 0x8000, val & 3); - shadow_control(0xe8000, 0x8000, (val >> 2) & 3); - shadow_control(0xf0000, 0x8000, (val >> 4) & 3); - shadow_control(0xf8000, 0x8000, (val >> 6) & 3); - } - break; + shadow_control(0xd0000, 0x4000, dev->cfg_regs[CFG_DAXS] & 3); + shadow_control(0xd4000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 2) & 3); + shadow_control(0xd8000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 4) & 3); + shadow_control(0xdc000, 0x4000, (dev->cfg_regs[CFG_DAXS] >> 6) & 3); + + shadow_control(0xe0000, 0x8000, dev->cfg_regs[CFG_FEAXS] & 3); + shadow_control(0xe8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 2) & 3); + shadow_control(0xf0000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 4) & 3); + shadow_control(0xf8000, 0x8000, (dev->cfg_regs[CFG_FEAXS] >> 6) & 3); } - } - } - break; + break; - case 0xee: - if (dev->cfg_enable && mem_a20_alt) - outb(0x92, inb(0x92) & ~2); - break; - } + case CFG_ABAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xa0000, 0x8000, val & 3); + shadow_control(0xa8000, 0x8000, (val >> 2) & 3); + shadow_control(0xb0000, 0x8000, (val >> 4) & 3); + shadow_control(0xb8000, 0x8000, (val >> 6) & 3); + } + break; + + case CFG_CAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xc0000, 0x4000, val & 3); + shadow_control(0xc4000, 0x4000, (val >> 2) & 3); + shadow_control(0xc8000, 0x4000, (val >> 4) & 3); + shadow_control(0xcc000, 0x4000, (val >> 6) & 3); + } + break; + + case CFG_DAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xd0000, 0x4000, val & 3); + shadow_control(0xd4000, 0x4000, (val >> 2) & 3); + shadow_control(0xd8000, 0x4000, (val >> 4) & 3); + shadow_control(0xdc000, 0x4000, (val >> 6) & 3); + } + break; + + case CFG_FEAXS: + if (!(dev->cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386)) { + shadow_control(0xe0000, 0x8000, val & 3); + shadow_control(0xe8000, 0x8000, (val >> 2) & 3); + shadow_control(0xf0000, 0x8000, (val >> 4) & 3); + shadow_control(0xf8000, 0x8000, (val >> 6) & 3); + } + break; + } + } + break; + + case 0xee: + if (dev->cfg_enable && mem_a20_alt) { + dev->port_92->reg &= 0xfd; + mem_a20_alt = 0; + mem_a20_recalc(); + } + break; + } } static uint8_t scamp_read(uint16_t addr, void *priv) { - uint8_t ret = 0xff; - - switch (addr) { - case 0xee: - if (!mem_a20_alt) - outb(0x92, inb(0x92) | 2); - break; - - case 0xef: - softresetx86(); - cpu_set_edx(); - break; - } + scamp_t *dev = (scamp_t *) priv; + uint8_t ret = 0xff; -/* pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret); */ - return ret; + switch (addr) { + case 0xed: + if (dev->cfg_enable && (dev->cfg_index >= 0x00) && (dev->cfg_index <= 0x16)) + ret = (dev->cfg_regs[dev->cfg_index]); + break; + + case 0xee: + if (!mem_a20_alt) { + dev->port_92->reg |= 0x02; + mem_a20_alt = 1; + mem_a20_recalc(); + } + break; + + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } + + return ret; } + static void scamp_close(void *priv) { - scamp_t *dev = (scamp_t *) priv; + scamp_t *dev = (scamp_t *) priv; - free(dev); + free(dev); } static void * scamp_init(const device_t *info) { - uint32_t addr; - int c; - scamp_t *dev = (scamp_t *)malloc(sizeof(scamp_t)); - memset(dev, 0, sizeof(scamp_t)); + uint32_t addr; + int c; + scamp_t *dev = (scamp_t *)malloc(sizeof(scamp_t)); + memset(dev, 0x00, sizeof(scamp_t)); - dev->cfg_regs[CFG_ID] = ID_VL82C311; - dev->cfg_enable = 1; - - io_sethandler(0x00e8, 0x0001, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00ea, 0x0006, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00f4, 0x0002, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00f9, 0x0001, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - io_sethandler(0x00fb, 0x0001, - scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - - dev->ram_config = 0; + dev->cfg_regs[CFG_ID] = ID_VL82C311; + dev->cfg_enable = 1; - /*Find best fit configuration for the requested memory size*/ - for (c = 0; c < NR_ELEMS(ram_configs); c++) { - if (mem_size < ram_configs[c].size_kb) - break; - - dev->ram_config = c; - } + io_sethandler(0x00e8, 0x0001, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00ea, 0x0006, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00f4, 0x0002, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00f9, 0x0001, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); + io_sethandler(0x00fb, 0x0001, + scamp_read, NULL, NULL, scamp_write, NULL, NULL, dev); - mem_mapping_set_handler(&ram_low_mapping, + dev->ram_config = 0; + + /* Find best fit configuration for the requested memory size */ + for (c = 0; c < NR_ELEMS(ram_configs); c++) { + if (mem_size < ram_configs[c].size_kb) + break; + + dev->ram_config = c; + } + + mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[0]); + mem_mapping_set_handler(&ram_low_mapping, + ram_mirrored_read, NULL, NULL, + ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_high_mapping); + + addr = 0; + for (c = 0; c < 2; c++) { + dev->ram_struct[c].parent = dev; + dev->ram_struct[c].bank = c; + mem_mapping_add(&dev->ram_mapping[c], 0, 0, ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - dev->ram_struct[2].parent = dev; - dev->ram_struct[2].bank = 0; - mem_mapping_set_p(&ram_low_mapping, (void *) &dev->ram_struct[2]); - mem_mapping_disable(&ram_high_mapping); + ram_mirrored_write, NULL, NULL, + &ram[addr], MEM_MAPPING_INTERNAL, (void *) &dev->ram_struct[c]); + mem_mapping_disable(&dev->ram_mapping[c]); - addr = 0; - for (c = 0; c < 2; c++) { - dev->ram_struct[c].parent = dev; - dev->ram_struct[c].bank = c; - mem_mapping_add(&dev->ram_mapping[c], 0, 0, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL, - &ram[addr], MEM_MAPPING_INTERNAL, (void *) &dev->ram_struct[c]); - mem_mapping_disable(&dev->ram_mapping[c]); - - dev->ram_phys_base[c] = addr; -/* pclog("Bank calc : %i = %08x\n", c ,addr);*/ - - switch (ram_configs[dev->ram_config].bank[c]) { - case BANK_NONE: - dev->ram_mask[c] = 0; - dev->ram_interleaved[c] = 0; - break; - - case BANK_256K: - addr += 512*1024; - dev->ram_mask[c] = 0x1ff; - dev->row_phys_shift[c] = 10; - dev->ram_interleaved[c] = 0; - break; - - case BANK_256K_INTERLEAVED: - addr += 512*1024*2; - dev->ram_mask[c] = 0x1ff; - dev->row_phys_shift[c] = 10; - dev->ibank_shift[c] = 19; - dev->ram_interleaved[c] = 1; - break; + dev->ram_phys_base[c] = addr; - case BANK_1M: - addr += 2048*1024; - dev->ram_mask[c] = 0x3ff; - dev->row_phys_shift[c] = 11; - dev->ram_interleaved[c] = 0; - break; - - case BANK_1M_INTERLEAVED: - addr += 2048*1024*2; - dev->ram_mask[c] = 0x3ff; - dev->row_phys_shift[c] = 11; - dev->ibank_shift[c] = 21; - dev->ram_interleaved[c] = 1; - break; + switch (ram_configs[dev->ram_config].bank[c]) { + case BANK_NONE: + dev->ram_mask[c] = 0; + dev->ram_interleaved[c] = 0; + break; - case BANK_4M: - addr += 8192*1024; - dev->ram_mask[c] = 0x7ff; - dev->row_phys_shift[c] = 12; - dev->ram_interleaved[c] = 0; - break; + case BANK_256K: + addr += (1 << 19); + dev->ram_mask[c] = 0x1ff; + dev->row_phys_shift[c] = 10; + dev->ram_interleaved[c] = 0; + break; - case BANK_4M_INTERLEAVED: - addr += 8192*1024*2; - dev->ram_mask[c] = 0x7ff; - dev->row_phys_shift[c] = 12; - dev->ibank_shift[c] = 23; - dev->ram_interleaved[c] = 1; - break; - } - } - - mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - - return dev; + case BANK_256K_INTERLEAVED: + addr += (1 << 20); + dev->ram_mask[c] = 0x1ff; + dev->row_phys_shift[c] = 10; + dev->ibank_shift[c] = 19; + dev->ram_interleaved[c] = 1; + break; + + case BANK_1M: + addr += (1 << 21); + dev->ram_mask[c] = 0x3ff; + dev->row_phys_shift[c] = 11; + dev->ram_interleaved[c] = 0; + break; + + case BANK_1M_INTERLEAVED: + addr += (1 << 22); + dev->ram_mask[c] = 0x3ff; + dev->row_phys_shift[c] = 11; + dev->ibank_shift[c] = 21; + dev->ram_interleaved[c] = 1; + break; + + case BANK_4M: + addr += (1 << 23); + dev->ram_mask[c] = 0x7ff; + dev->row_phys_shift[c] = 12; + dev->ram_interleaved[c] = 0; + break; + + case BANK_4M_INTERLEAVED: + addr += (1 << 24); + dev->ram_mask[c] = 0x7ff; + dev->row_phys_shift[c] = 12; + dev->ibank_shift[c] = 23; + dev->ram_interleaved[c] = 1; + break; + } + } + + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + dev->port_92 = device_add(&port_92_device); + + return dev; } @@ -772,4 +798,4 @@ const device_t vlsi_scamp_device = { scamp_init, scamp_close, NULL, { NULL }, NULL, NULL, NULL -}; \ No newline at end of file +}; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c new file mode 100644 index 000000000..69cc13ace --- /dev/null +++ b/src/chipset/sis_5571.c @@ -0,0 +1,632 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SiS 5571 Chipset. + * + * + * + * Authors: Tiseno100, + * + * Copyright 2020 Tiseno100. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/timer.h> + +#include <86box/apm.h> +#include <86box/dma.h> +#include <86box/mem.h> +#include <86box/pci.h> +#include <86box/port_92.h> +#include <86box/hdc_ide.h> +#include <86box/hdc_ide_sff8038i.h> +#include <86box/smram.h> +#include <86box/usb.h> + +#include <86box/chipset.h> + +#ifdef ENABLE_SIS_5571_LOG +int sis_5571_do_log = ENABLE_SIS_5571_LOG; +static void +sis_5571_log(const char *fmt, ...) +{ + va_list ap; + + if (sis_5571_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define sis_5571_log(fmt, ...) +#endif + +typedef struct sis_5571_t +{ + uint8_t pci_conf[256], pci_conf_sb[3][256], + sb_pci_slot; + + apm_t *apm; + port_92_t *port_92; + sff8038i_t *bm[2]; + uint32_t bus_master_base, program_status_pri, program_status_sec; + smram_t *smram; + usb_t *usb; + +} sis_5571_t; + +static void +sis_5571_shadow_recalc(sis_5571_t *dev) +{ + uint32_t i, can_read, can_write; + + for (i = 0; i < 6; i++) + { + can_read = (dev->pci_conf[0x70 + (i & 0x07)] & 0x08) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + can_write = (dev->pci_conf[0x70 + (i & 0x07)] & 0x02) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xc0000 + (0x8000 * (i & 0x07)), 0x4000, can_read | can_write); + can_read = (dev->pci_conf[0x70 + (i & 0x07)] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + can_write = (dev->pci_conf[0x70 + (i & 0x07)] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + mem_set_mem_state_both(0xc4000 + (0x8000 * (i & 0x07)), 0x4000, can_read | can_write); + } + + can_read = (dev->pci_conf[0x76] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTANY; + can_write = (dev->pci_conf[0x76] & 0x20) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTANY; + shadowbios = (dev->pci_conf[0x76] & 0x80); + shadowbios_write = (dev->pci_conf[0x76] & 0x20); + mem_set_mem_state_both(0xf0000, 0x10000, can_read | can_write); + + flushmmucache(); +} + +static void +sis_5571_smm_recalc(sis_5571_t *dev) +{ + switch (dev->pci_conf[0xa3] & 0xc0) + { + case 0x00: + if (!dev->pci_conf[0x74]) + smram_enable(dev->smram, 0xe0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x01: + if (!dev->pci_conf[0x74]) + smram_enable(dev->smram, 0xa0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x02: + if (!dev->pci_conf[0x74]) + smram_enable(dev->smram, 0xb0000, 0xe0000, 0x8000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + case 0x03: + smram_enable(dev->smram, 0xa0000, 0xa0000, 0x10000, (dev->pci_conf[0xa3] & 0x10), 1); + break; + } + + flushmmucache(); +} + +static void +sis_5571_ide_handler(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + uint32_t base, side; + + /* IDE IRQ remap */ + if (!(dev->pci_conf_sb[0][0x63] & 0x80)) + { + sff_set_irq_line(dev->bm[0], dev->pci_conf_sb[0][0x63] & 0x0f); + sff_set_irq_line(dev->bm[1], dev->pci_conf_sb[0][0x63] & 0x0f); + } + + /* Compatibility(0)/Native(1) Mode Status Programming */ + if (dev->pci_conf_sb[1][0x08]) + dev->program_status_sec = dev->pci_conf_sb[1][0x09] & 0x04; + + if (dev->pci_conf_sb[1][0x02]) + dev->program_status_pri = dev->pci_conf_sb[1][0x09] & 0x01; + + /* Setting Base/Side */ + if (dev->program_status_pri) + { + base = ((dev->pci_conf_sb[1][0x13]) | (dev->pci_conf_sb[1][0x12] << 4) | (dev->pci_conf_sb[1][0x11] << 8) | (dev->pci_conf_sb[1][0x10]) << 12); + side = ((dev->pci_conf_sb[1][0x17]) | (dev->pci_conf_sb[1][0x16] << 4) | (dev->pci_conf_sb[1][0x15] << 8) | (dev->pci_conf_sb[1][0x14]) << 12); + } + else + { + base = 0x1f0; + side = 0x3f6; + } + ide_set_base(0, base); + ide_set_side(0, side); + + if (dev->program_status_sec) + { + base = ((dev->pci_conf_sb[1][0x1b]) | (dev->pci_conf_sb[1][0x1a] << 4) | (dev->pci_conf_sb[1][0x19] << 8) | (dev->pci_conf_sb[1][0x18]) << 12); + side = ((dev->pci_conf_sb[1][0x1f]) | (dev->pci_conf_sb[1][0x1e] << 4) | (dev->pci_conf_sb[1][0x1d] << 8) | (dev->pci_conf_sb[1][0x1c]) << 12); + } + else + { + base = 0x170; + side = 0x376; + } + ide_set_base(1, base); + ide_set_side(1, side); + + /* Enable/Disable(Default is Enabled) */ + ide_pri_disable(); + ide_sec_disable(); + + if (dev->pci_conf_sb[1][0x4a] & 0x02) + ide_pri_enable(); + + if (dev->pci_conf_sb[1][0x4a] & 0x04) + ide_sec_enable(); + + /* Bus Mastering */ + dev->bus_master_base = ((dev->pci_conf_sb[1][0x23]) | (dev->pci_conf_sb[1][0x22] << 4) | (dev->pci_conf_sb[1][0x21] << 8) | (dev->pci_conf_sb[1][0x20]) << 12); + sff_bus_master_handler(dev->bm[0], dev->pci_conf_sb[1][0x09] & 0x80, dev->bus_master_base); + sff_bus_master_handler(dev->bm[1], dev->pci_conf_sb[1][0x09] & 0x80, dev->bus_master_base + 8); +} + +static void +sis_5571_usb_handler(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + + /* USB Memory Base */ + ohci_update_mem_mapping(dev->usb, dev->pci_conf_sb[2][0x11], dev->pci_conf_sb[2][0x12], dev->pci_conf_sb[2][0x13], dev->pci_conf_sb[0][0x68] & 0x40); + + /* USB I/O Base*/ + uhci_update_io_mapping(dev->usb, dev->pci_conf_sb[2][0x14], dev->pci_conf_sb[2][0x17], dev->pci_conf_sb[0][0x68] & 0x40); +} + +static void +memory_pci_bridge_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + + switch (addr) + { + case 0x07: /* Status */ + dev->pci_conf[addr] = val & 0xbe; + break; + + case 0x50: + dev->pci_conf[addr] = val & 0xec; + break; + + case 0x51: /* Cache */ + dev->pci_conf[addr] = val; + cpu_cache_ext_enabled = (val & 0x40); + cpu_update_waitstates(); + break; + + case 0x52: + dev->pci_conf[addr] = val & 0xd0; + break; + + case 0x53: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x55: + dev->pci_conf[addr] = val & 0xe0; + break; + + case 0x56: + case 0x57: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x5a: + dev->pci_conf[addr] = val & 0x03; + break; + + case 0x70: /* Shadow RAM */ + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + dev->pci_conf[addr] = val & ((addr != 0x76) ? 0xee : 0xe8); + sis_5571_shadow_recalc(dev); + sis_5571_smm_recalc(dev); + break; + + case 0x77: + dev->pci_conf[addr] = val & 0x0f; + break; + + case 0x80: + dev->pci_conf[addr] = val & 0xfe; + break; + + case 0x81: + dev->pci_conf[addr] = val & 0xcc; + break; + + case 0x83: + dev->pci_conf[addr] = val; + port_92_set_features(dev->port_92, (val & 0x40), (val & 0x80)); + break; + + case 0x87: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x93: /* APM SMI */ + dev->pci_conf[addr] = val; + apm_set_do_smi(dev->apm, ((dev->pci_conf[0x9b] & 0x01) && (val & 0x02))); + break; + + case 0x94: + dev->pci_conf[addr] = val & 0xf8; + break; + + case 0x95: + case 0x96: + dev->pci_conf[addr] = val & 0xfb; + break; + + case 0xa3: /* SMRAM */ + dev->pci_conf[addr] = val & 0xd0; + sis_5571_smm_recalc(dev); + break; + + default: + dev->pci_conf[addr] = val; + break; + } + sis_5571_log("Memory/PCI Bridge: dev->pci_conf[%02x] = %02x\n", addr, val); +} + +static uint8_t +memory_pci_bridge_read(int func, int addr, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + sis_5571_log("Memory/PCI Bridge: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf[addr]); + return dev->pci_conf[addr]; +} + +static void +pci_isa_bridge_write(int func, int addr, uint8_t val, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + switch (func) + { + case 0: /* Bridge */ + switch (addr) + { + case 0x04: + dev->pci_conf_sb[0][addr] = val & 0x0f; + break; + + case 0x40: + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x41: /* PCI IRQ Routing*/ + case 0x42: + case 0x43: + case 0x44: + dev->pci_conf_sb[0][addr] = val & 0x8f; + pci_set_irq_routing(PCI_INTA + (val & 0x07), !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x45: + case 0x46: + dev->pci_conf_sb[0][addr] = val & 0xec; + break; + + case 0x47: + dev->pci_conf_sb[0][addr] = val & 0x3e; + break; + + case 0x5f: + dev->pci_conf_sb[0][addr] = val & 0x3f; + break; + + case 0x61: /* MIRQ */ + dev->pci_conf_sb[0][addr] = val; + pci_set_mirq_routing(PCI_MIRQ0, !(val & 0x80) ? (val & 0x0f) : PCI_IRQ_DISABLED); + break; + + case 0x62: /* DMA */ + dev->pci_conf_sb[0][addr] = val & 0x0f; + dma_set_drq((val & 0x07), 1); + break; + + case 0x63: /* IDE IRQ Remap */ + dev->pci_conf_sb[0][addr] = val & 0x8f; + sis_5571_ide_handler(dev); + break; + + case 0x64: + dev->pci_conf_sb[0][addr] = val & 0xef; + break; + + case 0x65: + dev->pci_conf_sb[0][addr] = val & 0x1b; + break; + + case 0x68: /* USB IRQ Remap */ + dev->pci_conf_sb[0][addr] = val & 0x1b; + sis_5571_usb_handler(dev); + break; + + case 0x6a: + dev->pci_conf_sb[0][addr] = val & 0xfc; + break; + + case 0x6c: + dev->pci_conf_sb[0][addr] = val & 0x03; + break; + + case 0x70: + dev->pci_conf_sb[0][addr] = val & 0xde; + break; + + case 0x71: + dev->pci_conf_sb[0][addr] = val & 0xfe; + break; + + case 0x72: + case 0x73: + dev->pci_conf_sb[0][addr] = (addr == 0x72) ? val & 0xfe : val; + break; + + default: + dev->pci_conf_sb[0][addr] = val; + break; + } + sis_5571_log("PCI to ISA Bridge: dev->pci_conf[%02x] = %02x\n", addr, val); + break; + + case 1: /* IDE Controller */ + switch (addr) + { + case 0x04: + dev->pci_conf_sb[1][addr] = val & 0x05; + break; + + case 0x09: + dev->pci_conf_sb[1][addr] = val & 0xcf; + break; + + default: + dev->pci_conf_sb[1][addr] = val; + break; + } + sis_5571_log("IDE Controller: dev->pci_conf[%02x] = %02x\n", addr, val); + + if ((addr == 0x09) || ((addr >= 0x10) && (addr <= 0x23)) || (addr == 0x4a)) + sis_5571_ide_handler(dev); + break; + + case 2: /* USB Controller */ + switch (addr) + { + case 0x05: + dev->pci_conf_sb[2][addr] = val & 0x03; + break; + + case 0x06: + dev->pci_conf_sb[2][addr] = val & 0xc0; + break; + + default: + dev->pci_conf_sb[2][addr] = val; + break; + } + sis_5571_log("USB Controller: dev->pci_conf[%02x] = %02x\n", addr, val); + + if ((addr >= 0x11) && (addr <= 0x17)) + sis_5571_usb_handler(dev); + break; + } +} + +static uint8_t +pci_isa_bridge_read(int func, int addr, void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + + switch (func) + { + case 0: + sis_5571_log("PCI to ISA Bridge: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[0][addr]); + return dev->pci_conf_sb[0][addr]; + case 1: + sis_5571_log("IDE Controller: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[1][addr]); + return dev->pci_conf_sb[1][addr]; + case 2: + sis_5571_log("USB Controller: dev->pci_conf[%02x] (%02x)\n", addr, dev->pci_conf_sb[2][addr]); + return dev->pci_conf_sb[2][addr]; + default: + return 0xff; + } +} + +static void +sis_5571_reset(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + + /* Memory/PCI Bridge */ + dev->pci_conf[0x00] = 0x39; + dev->pci_conf[0x01] = 0x10; + dev->pci_conf[0x02] = 0x71; + dev->pci_conf[0x03] = 0x55; + dev->pci_conf[0x04] = 0xfd; + dev->pci_conf[0x05] = 0x00; + dev->pci_conf[0x06] = 0x00; + dev->pci_conf[0x07] = 0x00; + dev->pci_conf[0x08] = 0x00; + dev->pci_conf[0x09] = 0x00; + dev->pci_conf[0x0a] = 0x00; + dev->pci_conf[0x0b] = 0x06; + dev->pci_conf[0x0c] = 0x00; + dev->pci_conf[0x0d] = 0x00; + dev->pci_conf[0x0e] = 0x00; + dev->pci_conf[0x0f] = 0x00; + + memory_pci_bridge_write(0, 0x51, 0x00, dev); + memory_pci_bridge_write(0, 0x70, 0x00, dev); + memory_pci_bridge_write(0, 0x71, 0x00, dev); + memory_pci_bridge_write(0, 0x72, 0x00, dev); + memory_pci_bridge_write(0, 0x73, 0x00, dev); + memory_pci_bridge_write(0, 0x74, 0x00, dev); + memory_pci_bridge_write(0, 0x75, 0x00, dev); + memory_pci_bridge_write(0, 0x76, 0x00, dev); + memory_pci_bridge_write(0, 0x93, 0x00, dev); + memory_pci_bridge_write(0, 0xa3, 0x00, dev); + + /* PCI to ISA bridge */ + dev->pci_conf_sb[0][0x00] = 0x39; + dev->pci_conf_sb[0][0x01] = 0x10; + dev->pci_conf_sb[0][0x02] = 0x08; + dev->pci_conf_sb[0][0x03] = 0x00; + dev->pci_conf_sb[0][0x04] = 0xfd; + dev->pci_conf_sb[0][0x05] = 0x00; + dev->pci_conf_sb[0][0x06] = 0x00; + dev->pci_conf_sb[0][0x07] = 0x00; + dev->pci_conf_sb[0][0x08] = 0x01; + dev->pci_conf_sb[0][0x09] = 0x00; + dev->pci_conf_sb[0][0x0a] = 0x01; + dev->pci_conf_sb[0][0x0b] = 0x06; + dev->pci_conf_sb[0][0x0c] = 0x00; + dev->pci_conf_sb[0][0x0d] = 0x00; + dev->pci_conf_sb[0][0x0e] = 0x00; + dev->pci_conf_sb[0][0x0f] = 0x00; + + pci_isa_bridge_write(0, 0x41, 0x80, dev); + pci_isa_bridge_write(0, 0x42, 0x80, dev); + pci_isa_bridge_write(0, 0x43, 0x80, dev); + pci_isa_bridge_write(0, 0x44, 0x80, dev); + pci_isa_bridge_write(0, 0x61, 0x80, dev); + pci_isa_bridge_write(0, 0x62, 0x80, dev); + dev->pci_conf_sb[0][0x63] = 0x80; + + /* IDE Controller */ + dev->pci_conf_sb[1][0x00] = 0x39; + dev->pci_conf_sb[1][0x01] = 0x10; + dev->pci_conf_sb[1][0x02] = 0x13; + dev->pci_conf_sb[1][0x03] = 0x55; + dev->pci_conf_sb[1][0x04] = 0x00; + dev->pci_conf_sb[1][0x05] = 0x00; + dev->pci_conf_sb[1][0x06] = 0x00; + dev->pci_conf_sb[1][0x07] = 0x00; + dev->pci_conf_sb[1][0x08] = 0xc0; + dev->pci_conf_sb[1][0x09] = 0x00; + dev->pci_conf_sb[1][0x0a] = 0x01; + dev->pci_conf_sb[1][0x0b] = 0x01; + dev->pci_conf_sb[1][0x0c] = 0x00; + dev->pci_conf_sb[1][0x0d] = 0x00; + dev->pci_conf_sb[1][0x0e] = 0x80; + dev->pci_conf_sb[1][0x0f] = 0x00; + dev->pci_conf_sb[1][0x4a] = 0x06; + + sff_bus_master_reset(dev->bm[0], dev->bus_master_base); + sff_bus_master_reset(dev->bm[1], dev->bus_master_base + 8); + + sff_set_slot(dev->bm[0], dev->sb_pci_slot); + sff_set_irq_pin(dev->bm[0], PCI_INTA); + + sff_set_slot(dev->bm[1], dev->sb_pci_slot); + sff_set_irq_pin(dev->bm[1], PCI_INTA); + + sis_5571_ide_handler(dev); + + /* USB Controller */ + dev->pci_conf_sb[2][0x00] = 0x39; + dev->pci_conf_sb[2][0x01] = 0x10; + dev->pci_conf_sb[2][0x02] = 0x01; + dev->pci_conf_sb[2][0x03] = 0x70; + dev->pci_conf_sb[2][0x04] = 0x00; + dev->pci_conf_sb[2][0x05] = 0x00; + dev->pci_conf_sb[2][0x06] = 0x00; + dev->pci_conf_sb[2][0x07] = 0x00; + dev->pci_conf_sb[2][0x08] = 0xb0; + dev->pci_conf_sb[2][0x09] = 0x10; + dev->pci_conf_sb[2][0x0a] = 0x03; + dev->pci_conf_sb[2][0x0b] = 0xc0; + dev->pci_conf_sb[2][0x0c] = 0x00; + dev->pci_conf_sb[2][0x0d] = 0x00; + dev->pci_conf_sb[2][0x0e] = 0x80; + dev->pci_conf_sb[2][0x0f] = 0x00; + dev->pci_conf_sb[2][0x14] = 0x01; + dev->pci_conf_sb[2][0x3d] = 0x01; + + sis_5571_usb_handler(dev); +} + +static void +sis_5571_close(void *priv) +{ + sis_5571_t *dev = (sis_5571_t *)priv; + + smram_del(dev->smram); + free(dev); +} + +static void * +sis_5571_init(const device_t *info) +{ + sis_5571_t *dev = (sis_5571_t *)malloc(sizeof(sis_5571_t)); + memset(dev, 0x00, sizeof(sis_5571_t)); + + pci_add_card(PCI_ADD_NORTHBRIDGE, memory_pci_bridge_read, memory_pci_bridge_write, dev); + dev->sb_pci_slot = pci_add_card(PCI_ADD_SOUTHBRIDGE, pci_isa_bridge_read, pci_isa_bridge_write, dev); + pci_enable_mirq(1); + + /* APM */ + dev->apm = device_add(&apm_pci_device); + + /* DMA */ + dma_alias_set(); + + /* SFF IDE */ + dev->bm[0] = device_add_inst(&sff8038i_device, 1); + dev->bm[1] = device_add_inst(&sff8038i_device, 2); + dev->program_status_pri = 0; + dev->program_status_sec = 0; + + /* Port 92 & SMRAM */ + dev->port_92 = device_add(&port_92_pci_device); + dev->smram = smram_add(); + + /* USB */ + dev->usb = device_add(&usb_device); + + sis_5571_reset(dev); + + return dev; +} + +const device_t sis_5571_device = { + "SiS 5571", + DEVICE_PCI, + 0, + sis_5571_init, + sis_5571_close, + sis_5571_reset, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt new file mode 100644 index 000000000..7ee69bf3b --- /dev/null +++ b/src/codegen/CMakeLists.txt @@ -0,0 +1,32 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +if(DYNAREC) + add_library(dynarec OBJECT codegen.c codegen_ops.c) + + if(CMAKE_TARGET_ARCHITECTURES STREQUAL "i386") + target_sources(dynarec PRIVATE codegen_x86.c + codegen_accumulate_x86.c) + elseif(CMAKE_TARGET_ARCHITECTURES STREQUAL "x86_64") + target_sources(dynarec PRIVATE codegen_x86-64.c + codegen_accumulate_x86-64.c) + else() + message(SEND_ERROR + "Dynarec is incompatible with target platform " + ${CMAKE_TARGET_ARCHITECTURES}) + endif() + + target_link_libraries(86Box dynarec cgt) +endif() \ No newline at end of file diff --git a/src/codegen_new/CMakeLists.txt b/src/codegen_new/CMakeLists.txt new file mode 100644 index 000000000..0a6db2827 --- /dev/null +++ b/src/codegen_new/CMakeLists.txt @@ -0,0 +1,52 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +if(DYNAREC) + add_library(dynarec OBJECT codegen.c codegen_accumulate.c + codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c + codegen_ops_3dnow.c codegen_ops_branch.c codegen_ops_arith.c + codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c + codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c + codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c + codegen_ops_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c + codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c + codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_mov.c + codegen_ops_shift.c codegen_ops_stack.c codegen_reg.c) + + if(CMAKE_TARGET_ARCHITECTURES STREQUAL "i386") + target_sources(dynarec PRIVATE codegen_backend_x86.c + codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c + codegen_backend_x86_ops_sse.c + codegen_backend_x86_uops.c) + elseif(CMAKE_TARGET_ARCHITECTURES STREQUAL "x86_64") + target_sources(dynarec PRIVATE codegen_backend_x86-64.c + codegen_backend_x86-64_ops.c + codegen_backend_x86-64_ops_sse.c + codegen_backend_x86-64_uops.c) + elseif(CMAKE_TARGET_ARCHITECTURES STREQUAL "armv8") + target_sources(dynarec PRIVATE codegen_backend_arm64.c + codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c + codegen_backend_arm64_imm.c) + elseif(CMAKE_TARGET_ARCHITECTURES MATCHES "arm") + target_sources(dynarec PRIVATE codegen_backend_arm.c + codegen_backend_arm_ops.c codegen_backend_arm_uops.c) + else() + message(SEND_ERROR + "Dynarec is incompatible with target platform " + ${CMAKE_TARGET_ARCHITECTURES}) + endif() + + target_link_libraries(86Box dynarec cgt) +endif() \ No newline at end of file diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index a62ac4f04..5ae3304bf 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1760,7 +1760,7 @@ sysexit(uint32_t fetchdat) int -syscall(uint32_t fetchdat) +syscall_op(uint32_t fetchdat) { #ifdef ENABLE_386_COMMON_LOG x386_common_log("SYSCALL called\n"); diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt new file mode 100644 index 000000000..6fe97a35c --- /dev/null +++ b/src/cpu/CMakeLists.txt @@ -0,0 +1,32 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(cpu OBJECT cpu.c cpu_table.c 808x.c 386.c 386_common.c 386_dynarec.c + 386_dynarec_ops.c x86seg.c x87.c x87_timings.c) + +if(AMD_K5) + target_compile_definitions(cpu PRIVATE USE_AMD_K5) +endif() + +if(CYRIX_6X86) + target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86) +endif() + +if(DYNAREC) + add_library(cgt OBJECT codegen_timing_486.c codegen_timing_686.c + codegen_timing_common.c codegen_timing_k6.c + codegen_timing_pentium.c codegen_timing_p6.c + codegen_timing_winchip.c codegen_timing_winchip2.c) +endif() \ No newline at end of file diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 6e13695ab..ffe4c129e 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -155,7 +155,7 @@ typedef struct { typedef struct { const uint32_t package; const char *manufacturer; - const char *name; + const char *name; const char *internal_name; const CPU *cpus; } cpu_family_t; @@ -578,7 +578,7 @@ extern void update_tsc(void); extern int sysenter(uint32_t fetchdat); extern int sysexit(uint32_t fetchdat); -extern int syscall(uint32_t fetchdat); +extern int syscall_op(uint32_t fetchdat); extern int sysret(uint32_t fetchdat); extern cpu_family_t *cpu_get_family(const char *internal_name); diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index e95eab849..73b7169bd 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -835,10 +835,12 @@ const cpu_family_t cpu_families[] = { .name = "Pentium Pro", .internal_name = "pentiumpro", .cpus = (const CPU[]) { - {"50", CPU_PENTIUMPRO, fpus_internal, 50000000, 1.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"60", CPU_PENTIUMPRO, fpus_internal, 60000000, 1.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"66", CPU_PENTIUMPRO, fpus_internal, 66666666, 1.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"75", CPU_PENTIUMPRO, fpus_internal, 75000000, 1.5, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"60", CPU_PENTIUMPRO, fpus_internal, 60000000, 1.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 1, 1, 7}, /* out of spec */ + {"66", CPU_PENTIUMPRO, fpus_internal, 66666666, 1.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 1, 1, 8}, /* out of spec */ + {"90", CPU_PENTIUMPRO, fpus_internal, 90000000, 1.5, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 3, 3, 11}, /* out of spec */ + {"100", CPU_PENTIUMPRO, fpus_internal, 100000000, 1.5, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 3, 3, 12}, /* out of spec */ + {"120", CPU_PENTIUMPRO, fpus_internal, 120000000, 2.0, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 5, 5, 14}, /* out of spec */ + {"133", CPU_PENTIUMPRO, fpus_internal, 133333333, 2.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 5, 5, 16}, /* out of spec */ {"150", CPU_PENTIUMPRO, fpus_internal, 150000000, 2.5, 3100, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2}, {"166", CPU_PENTIUMPRO, fpus_internal, 166666666, 2.5, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, {"180", CPU_PENTIUMPRO, fpus_internal, 180000000, 3.0, 3300, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21}, @@ -851,17 +853,14 @@ const cpu_family_t cpu_families[] = { .name = "Pentium II OverDrive", .internal_name = "pentium2_od", .cpus = (const CPU[]) { - {"50", CPU_PENTIUM2D, fpus_internal, 50000000, 1.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 4, 4, 3, 3, 6}, - {"60", CPU_PENTIUM2D, fpus_internal, 60000000, 1.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 7}, - {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, - {"75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 7, 7, 4, 4, 9}, - {"210", CPU_PENTIUM2D, fpus_internal, 210000000, 3.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 17,17, 7, 7, 25}, - {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 21,21,10,10, 28}, - {"240", CPU_PENTIUM2D, fpus_internal, 240000000, 4.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 24,24,12,12, 29}, - {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 24,24,12,12, 32}, - {"270", CPU_PENTIUM2D, fpus_internal, 270000000, 4.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 25,25,12,12, 33}, - {"300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 25,25,12,12, 36}, - {"300/60", CPU_PENTIUM2D, fpus_internal, 300000000, 5.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 36}, + {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* out of spec */ + {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 9, 9, 4, 4, 12}, /* out of spec */ + {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12, 6, 6, 16}, /* out of spec */ + {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15, 7, 7, 20}, /* out of spec */ + {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 18,18, 9, 9, 24}, /* out of spec */ + {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 21,21,10,10, 28}, /* out of spec */ + {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 24,24,12,12, 32}, /* out of spec */ + {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 5.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 36}, {"333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 3300, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 40}, {"", 0} } @@ -871,13 +870,14 @@ const cpu_family_t cpu_families[] = { .name = "Pentium II (Klamath)", .internal_name = "pentium2_klamath", .cpus = (const CPU[]) { - {"50", CPU_PENTIUM2, fpus_internal, 50000000, 1.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"60", CPU_PENTIUM2, fpus_internal, 60000000, 1.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"66", CPU_PENTIUM2, fpus_internal, 66666666, 1.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"75", CPU_PENTIUM2, fpus_internal, 75000000, 1.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"66", CPU_PENTIUM2, fpus_internal, 66666666, 1.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, /* out of spec */ + {"100", CPU_PENTIUM2, fpus_internal, 100000000, 1.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12}, /* out of spec */ + {"133", CPU_PENTIUM2, fpus_internal, 133333333, 2.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, /* out of spec */ + {"166", CPU_PENTIUM2, fpus_internal, 166666666, 2.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, /* out of spec */ + {"200", CPU_PENTIUM2, fpus_internal, 200000000, 3.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, /* out of spec */ {"233", CPU_PENTIUM2, fpus_internal, 233333333, 3.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28}, {"266", CPU_PENTIUM2, fpus_internal, 266666666, 4.0, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"300/66", CPU_PENTIUM2, fpus_internal, 300000000, 4.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"300", CPU_PENTIUM2, fpus_internal, 300000000, 4.5, 2800, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, {"", 0} } }, { @@ -886,12 +886,14 @@ const cpu_family_t cpu_families[] = { .name = "Pentium II (Deschutes)", .internal_name = "pentium2_deschutes", .cpus = (const CPU[]) { - {"50", CPU_PENTIUM2D, fpus_internal, 50000000, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6}, - {"60", CPU_PENTIUM2D, fpus_internal, 60000000, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, + {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, /* out of spec */ + {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 5, 5, 12}, /* out of spec */ + {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, /* out of spec */ + {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, /* out of spec */ + {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24}, /* out of spec */ + {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,11,11, 28}, /* out of spec */ {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32}, - {"300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, + {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36}, {"333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40}, {"350", CPU_PENTIUM2D, fpus_internal, 350000000, 3.5, 2050, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,11,11, 42}, {"400", CPU_PENTIUM2D, fpus_internal, 400000000, 4.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, @@ -904,10 +906,12 @@ const cpu_family_t cpu_families[] = { .name = "Pentium II Xeon", .internal_name = "pentium2_xeon", .cpus = (const CPU[]) { - {"75", CPU_PENTIUM2D, fpus_internal, 75000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9}, - {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12}, - {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16}, - {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20}, + {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 3, 3, 12}, /* out of spec */ + {"150", CPU_PENTIUM2D, fpus_internal, 150000000, 1.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 14,14, 4, 4, 18}, /* out of spec */ + {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 2.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 6, 6, 24}, /* out of spec */ + {"250", CPU_PENTIUM2D, fpus_internal, 250000000, 2.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 22,22, 7, 7, 30}, /* out of spec */ + {"300", CPU_PENTIUM2D, fpus_internal, 300000000, 3.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27, 9, 9, 36}, /* out of spec */ + {"350", CPU_PENTIUM2D, fpus_internal, 350000000, 3.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 32,32,10,10, 42}, /* out of spec */ {"400", CPU_PENTIUM2D, fpus_internal, 400000000, 4.0, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 36,36,12,12, 48}, {"450", CPU_PENTIUM2D, fpus_internal, 450000000, 4.5, 2050, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 41,41,14,14, 54}, {"", 0} @@ -918,11 +922,14 @@ const cpu_family_t cpu_families[] = { .name = "Celeron (Mendocino)", .internal_name = "celeron_mendocino", .cpus = (const CPU[]) { - {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, - {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 10,10, 6, 6, 12}, - {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 12,12, 6, 6, 16}, - {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 15,15, 7, 7, 20}, - {"300/66", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 25,25,12,12, 36}, + {"66", CPU_PENTIUM2D, fpus_internal, 66666666, 1.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* out of spec */ + {"100", CPU_PENTIUM2D, fpus_internal, 100000000, 1.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 8, 8, 4, 4, 12}, /* out of spec */ + {"133", CPU_PENTIUM2D, fpus_internal, 133333333, 2.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 11,11, 5, 5, 16}, /* out of spec */ + {"166", CPU_PENTIUM2D, fpus_internal, 166666666, 2.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 14,14, 7, 7, 20}, /* out of spec */ + {"200", CPU_PENTIUM2D, fpus_internal, 200000000, 3.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 17,17, 8, 8, 24}, /* out of spec */ + {"233", CPU_PENTIUM2D, fpus_internal, 233333333, 3.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 19,19, 9, 9, 28}, /* out of spec */ + {"266", CPU_PENTIUM2D, fpus_internal, 266666666, 4.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 22,22,11,11, 32}, /* out of spec */ + {"300A", CPU_PENTIUM2D, fpus_internal, 300000000, 4.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 25,25,12,12, 36}, {"333", CPU_PENTIUM2D, fpus_internal, 333333333, 5.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 27,27,13,13, 40}, {"366", CPU_PENTIUM2D, fpus_internal, 366666666, 5.5, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 33,33,17,17, 44}, {"400", CPU_PENTIUM2D, fpus_internal, 400000000, 6.0, 2050, 0x665, 0x665, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC | CPU_FIXED_MULTIPLIER, 36,36,12,12, 48}, @@ -938,24 +945,29 @@ const cpu_family_t cpu_families[] = { .name = "Cyrix III", .internal_name = "c3_samuel", .cpus = (const CPU[]) { - {"66", CPU_CYRIX3S, fpus_internal, 66666666, 1.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* not in multiplier range */ - {"233", CPU_CYRIX3S, fpus_internal, 233333333, 3.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 21, 21, 9, 9, 28}, /* not in multiplier range */ - {"266", CPU_CYRIX3S, fpus_internal, 266666666, 4.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 24, 24, 12, 12, 32}, /* not in multiplier range */ - {"300", CPU_CYRIX3S, fpus_internal, 300000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 27, 27, 13, 13, 36}, /* not specified */ - {"333", CPU_CYRIX3S, fpus_internal, 333333333, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 30, 30, 15, 15, 40}, /* not specified */ - {"366", CPU_CYRIX3S, fpus_internal, 366666666, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 33, 33, 16, 16, 44}, /* not specified */ + {"66", CPU_CYRIX3S, fpus_internal, 66666666, 1.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 6, 6, 3, 3, 8}, /* out of multiplier range */ + {"100", CPU_CYRIX3S, fpus_internal, 100000000, 1.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 9, 9, 4, 4, 12}, /* out of multiplier range */ + {"133", CPU_CYRIX3S, fpus_internal, 133333333, 2.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 12, 12, 6, 6, 16}, /* out of multiplier range */ + {"166", CPU_CYRIX3S, fpus_internal, 166666666, 2.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 15, 15, 7, 7, 20}, /* out of multiplier range */ + {"200", CPU_CYRIX3S, fpus_internal, 200000000, 3.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 18, 18, 8, 8, 24}, /* out of multiplier range */ + {"233", CPU_CYRIX3S, fpus_internal, 233333333, 3.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 21, 21, 9, 9, 28}, /* out of multiplier range */ + {"266", CPU_CYRIX3S, fpus_internal, 266666666, 4.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 24, 24, 12, 12, 32}, /* out of multiplier range */ + {"300", CPU_CYRIX3S, fpus_internal, 300000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 27, 27, 13, 13, 36}, /* out of spec */ + {"333", CPU_CYRIX3S, fpus_internal, 333333333, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 30, 30, 15, 15, 40}, /* out of spec */ + {"366", CPU_CYRIX3S, fpus_internal, 366666666, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 33, 33, 16, 16, 44}, /* out of spec */ {"400", CPU_CYRIX3S, fpus_internal, 400000000, 6.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 36, 36, 17, 17, 48}, - {"433", CPU_CYRIX3S, fpus_internal, 433333333, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 39, 39, 18, 18, 52}, /* not specified */ + {"433", CPU_CYRIX3S, fpus_internal, 433333333, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 39, 39, 18, 18, 52}, /* out of spec */ {"450", CPU_CYRIX3S, fpus_internal, 450000000, 4.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 41, 41, 14, 14, 54}, - {"466", CPU_CYRIX3S, fpus_internal, 466666666, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 42, 42, 14, 14, 56}, /* not specified */ + {"466", CPU_CYRIX3S, fpus_internal, 466666666, 6.5, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 42, 42, 14, 14, 56}, /* out of spec */ {"500", CPU_CYRIX3S, fpus_internal, 500000000, 5.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 45, 45, 15, 15, 60}, - {"533", CPU_CYRIX3S, fpus_internal, 533333333, 8.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 48, 48, 15, 15, 64}, /* not specified */ + {"533", CPU_CYRIX3S, fpus_internal, 533333333, 8.0, 2050, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 48, 48, 15, 15, 64}, /* out of spec */ {"550", CPU_CYRIX3S, fpus_internal, 550000000, 5.5, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 50, 50, 17, 17, 66}, {"600/100", CPU_CYRIX3S, fpus_internal, 600000000, 6.0, 2050, 0x662, 0x662, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 18, 18, 72}, {"600/133", CPU_CYRIX3S, fpus_internal, 600000000, 4.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 54, 54, 13, 13, 72}, {"650", CPU_CYRIX3S, fpus_internal, 650000000, 6.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 58, 58, 20, 20, 78}, {"667", CPU_CYRIX3S, fpus_internal, 666666667, 5.0, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 60, 60, 16, 16, 80}, {"700", CPU_CYRIX3S, fpus_internal, 700000000, 7.0, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 63, 63, 21, 21, 84}, + {"733", CPU_CYRIX3S, fpus_internal, 733333333, 5.5, 2050, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_FIXED_MULTIPLIER, 66, 66, 18, 18, 88}, {"", 0} } }, { diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index 439cb2a43..0674c8187 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -20,7 +20,7 @@ opSYSCALL(uint32_t fetchdat) ILLEGAL_ON(!(amd_efer & 0x0000000000000001)); - ret = syscall(fetchdat); + ret = syscall_op(fetchdat); if (ret <= 1) { CLOCK_CYCLES(20); diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt new file mode 100644 index 000000000..85339108a --- /dev/null +++ b/src/device/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(dev OBJECT bugger.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c + hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c + postcard.c serial.c vpc2007.c clock_ics9xxx.c i2c.c i2c_gpio.c + smbus_piix4.c keyboard.c keyboard_xt.c keyboard_at.c mouse.c mouse_bus.c + mouse_serial.c mouse_ps2.c phoenix_486_jumper.c) + +if(LASERXT) + target_compile_definitions(dev PRIVATE USE_LASERXT) +endif() \ No newline at end of file diff --git a/src/device/keyboard_at.c b/src/device/keyboard_at.c index ac59b3036..28fbc490a 100644 --- a/src/device/keyboard_at.c +++ b/src/device/keyboard_at.c @@ -89,7 +89,8 @@ #define KBC_VEN_ACER 0x1c #define KBC_VEN_INTEL_AMI 0x20 #define KBC_VEN_OLIVETTI 0x24 -#define KBC_VEN_NCR 0x28 +#define KBC_VEN_NCR 0x28 +#define KBC_VEN_SAMSUNG 0x2c #define KBC_VEN_MASK 0x3c @@ -1058,7 +1059,7 @@ write_output(atkbd_t *dev, uint8_t val) if ((dev->output_port ^ val) & 0x01) { /*Reset*/ if (! (val & 0x01)) { /* Pin 0 selected. */ - softresetx86(); /*Pulse reset!*/ + resetx86(); /*Pulse reset!*/ cpu_set_edx(); } } @@ -1749,7 +1750,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) add_data_kbd_direct(dev, 0xfa); if (val == 0) { kbd_log("Get scan code set: %02X\n", keyboard_mode & 3); - add_data_kbd(keyboard_mode & 3); + add_data_kbd_direct(dev, keyboard_mode & 3); } else { if ((val <= 3) && (val != 1)) { keyboard_mode &= 0xfc; @@ -1955,7 +1956,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xaa: /* self-test */ kbd_log("ATkbc: self-test\n"); - if (kbc_ven == KBC_VEN_TOSHIBA) + if ((kbc_ven == KBC_VEN_TOSHIBA) || (kbc_ven == KBC_VEN_SAMSUNG)) dev->status |= STAT_IFULL; if (! dev->initialized) { kbd_log("ATkbc: self-test reinitialization\n"); @@ -2298,6 +2299,7 @@ kbd_init(const device_t *info) case KBC_VEN_AMI: case KBC_VEN_INTEL_AMI: + case KBC_VEN_SAMSUNG: dev->write60_ven = write60_ami; dev->write64_ven = write64_ami; break; @@ -2344,6 +2346,16 @@ const device_t keyboard_at_ami_device = { { NULL }, NULL, NULL, NULL }; +const device_t keyboard_at_samsung_device = { + "PC/AT Keyboard (Samsung)", + 0, + KBC_TYPE_ISA | KBC_VEN_SAMSUNG, + kbd_init, + kbd_close, + kbd_reset, + { NULL }, NULL, NULL, NULL +}; + const device_t keyboard_at_toshiba_device = { "PC/AT Keyboard (Toshiba)", 0, diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index 5b846d986..eff3e93bc 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -39,7 +39,7 @@ #define AGP_BRIDGE_VIA_597 0x11068597 #define AGP_BRIDGE_VIA_598 0x11068598 #define AGP_BRIDGE_VIA_691 0x11068691 -#define AGP_BRIDGE_VIA_8601 0x11068601 +#define AGP_BRIDGE_VIA_8601 0x11068601 #define AGP_BRIDGE_INTEL(x) (((x) >> 16) == 0x8086) #define AGP_BRIDGE_VIA(x) (((x) >> 16) == 0x1106) @@ -90,10 +90,12 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x08: case 0x09: case 0x0a: - case 0x0b: case 0x0e: case 0x1e: case 0x34: - case 0x3d: case 0x67: case 0xdc: case 0xdd: - case 0xde: case 0xdf: case 0xe0: case 0xe1: - case 0xe2: case 0xe3: + case 0x0b: case 0x0e: case 0x0f: case 0x10: + case 0x11: case 0x12: case 0x13: case 0x14: + case 0x15: case 0x16: case 0x17: case 0x1e: + case 0x34: case 0x3d: case 0x67: case 0xdc: + case 0xdd: case 0xde: case 0xdf: case 0xe0: + case 0xe1: case 0xe2: case 0xe3: return; case 0x04: @@ -116,17 +118,19 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) dev->regs[addr] &= ~(val & 0x40); return; - case 0x0d: - if (AGP_BRIDGE_INTEL(dev->local)) - val &= 0xf8; - break; - - case 0x18: - /* Parent bus number is always 0 on AGP bridges. */ + case 0x0c: case 0x18: + /* Parent bus number (0x18) is always 0 on AGP bridges. */ if (AGP_BRIDGE(dev->local)) return; break; + case 0x0d: + if (AGP_BRIDGE_VIA(dev->local)) + return; + else if (AGP_BRIDGE_INTEL(dev->local)) + val &= 0xf8; + break; + case 0x19: /* Set our bus number. */ pci_bridge_log("PCI Bridge %d: remapping from bus %02X to %02X\n", dev->bus_index, dev->regs[addr], val); diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt new file mode 100644 index 000000000..f0ec758fe --- /dev/null +++ b/src/disk/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(hdd OBJECT hdd.c hdd_image.c hdd_table.c hdc.c hdc_st506_xt.c + hdc_st506_at.c hdc_xta.c hdc_esdi_at.c hdc_esdi_mca.c hdc_xtide.c + hdc_ide.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_sff8038i.c) + +add_library(zip OBJECT zip.c) + +add_library(mo OBJECT mo.c) + +add_subdirectory(minivhd) +target_link_libraries(86Box minivhd) \ No newline at end of file diff --git a/src/disk/minivhd/CMakeLists.txt b/src/disk/minivhd/CMakeLists.txt new file mode 100644 index 000000000..8afcd4265 --- /dev/null +++ b/src/disk/minivhd/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(minivhd STATIC cwalk.c libxml2_encoding.c minivhd_convert.c + minivhd_create.c minivhd_io.c minivhd_manage.c minivhd_struct_rw.c + minivhd_util.c) \ No newline at end of file diff --git a/src/disk/mo.c b/src/disk/mo.c index 87b67c4b4..bdb5d2824 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -15,7 +15,9 @@ * Miran Grca, * Fred N. van Kempen, * - * Copyright 2020 Miran Grca. + * Copyright 2020,2021 Natalia Portillo. + * Copyright 2020,2021 Miran Grca. + * Copyright 2020,2021 Fred N. van Kempen */ #include #include @@ -1039,15 +1041,16 @@ mo_insert(mo_t *dev) void mo_format(mo_t *dev) { - unsigned long size; + long size; int ret; int fd; mo_log("MO %i: Formatting media...\n", dev->id); fseek(dev->drv->f, 0, SEEK_END); - size = (uint32_t) ftello64(dev->drv->f); + size = ftell(dev->drv->f); +#ifdef _WIN32 HANDLE fh; LARGE_INTEGER liSize; @@ -1058,14 +1061,14 @@ mo_format(mo_t *dev) ret = (int)SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - if (!ret) { + if(!ret) { mo_log("MO %i: Failed seek to start of image file\n", dev->id); return; } ret = (int)SetEndOfFile(fh); - if (!ret) { + if(!ret) { mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); return; } @@ -1073,17 +1076,34 @@ mo_format(mo_t *dev) liSize.QuadPart = size; ret = (int)SetFilePointerEx(fh, liSize, NULL, FILE_BEGIN); - if (!ret) { + if(!ret) { mo_log("MO %i: Failed seek to end of image file\n", dev->id); return; } ret = (int)SetEndOfFile(fh); - if (!ret) { + if(!ret) { mo_log("MO %i: Failed to truncate image file to %llu\n", dev->id, size); return; } +#else + fd = fileno(dev->drv->f); + + ret = ftruncate(fd, 0); + + if(ret) { + mo_log("MO %i: Failed to truncate image file to 0\n", dev->id); + return; + } + + ret = ftruncate(fd, size); + + if(ret) { + mo_log("MO %i: Failed to truncate image file to %llu", dev->id, size); + return; + } +#endif } static int @@ -1887,8 +1907,8 @@ mo_phase_data_out(scsi_common_t *sc) { mo_t *dev = (mo_t *) sc; - uint16_t block_desc_len; - uint16_t pos; + uint16_t block_desc_len, pos; + uint16_t param_list_len; uint8_t error = 0; uint8_t page, page_len; @@ -1914,10 +1934,15 @@ mo_phase_data_out(scsi_common_t *sc) break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->drv->bus_type == MO_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { @@ -1935,7 +1960,7 @@ mo_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { mo_log("MO %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/disk/zip.c b/src/disk/zip.c index 39ea4dc2a..2de8a2c0d 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -2081,8 +2081,8 @@ zip_phase_data_out(scsi_common_t *sc) { zip_t *dev = (zip_t *) sc; - uint16_t block_desc_len; - uint16_t pos; + uint16_t block_desc_len, pos; + uint16_t param_list_len; uint8_t error = 0; uint8_t page, page_len; @@ -2143,10 +2143,15 @@ zip_phase_data_out(scsi_common_t *sc) break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->drv->bus_type == ZIP_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { @@ -2164,7 +2169,7 @@ zip_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { zip_log("ZIP %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/floppy/CMakeLists.txt b/src/floppy/CMakeLists.txt new file mode 100644 index 000000000..a3039ddd5 --- /dev/null +++ b/src/floppy/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(fdd OBJECT fdd.c fdc.c fdc_pii15xb.c fdi2raw.c fdd_common.c + fdd_86f.c fdd_fdi.c fdd_imd.c fdd_img.c fdd_json.c fdd_mfm.c fdd_td0.c) \ No newline at end of file diff --git a/src/floppy/fdd_imd.c b/src/floppy/fdd_imd.c index a52a35c38..37c2b41da 100644 --- a/src/floppy/fdd_imd.c +++ b/src/floppy/fdd_imd.c @@ -268,14 +268,17 @@ sector_to_buffer(int drive, int track, int side, uint8_t *buffer, int sector, in { imd_t *dev = imd[drive]; int type = dev->buffer[dev->tracks[track][side].sector_data_offs[sector]]; + uint8_t fill_char; if (type == 0) memset(buffer, 0x00, len); else { if (type & 1) memcpy(buffer, &(dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1]), len); - else - memset(buffer, dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1], len); + else { + fill_char = dev->buffer[dev->tracks[track][side].sector_data_offs[sector] + 1]; + memset(buffer, fill_char, len); + } } } @@ -398,6 +401,7 @@ imd_seek(int drive, int track) ssize = 128 << ((uint32_t) id[3]); sector_to_buffer(drive, track, side, data, actual_sector, ssize); + current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, 22, track_gap3, flags); track_buf_pos[side] += ssize; @@ -551,9 +555,12 @@ poll_read_data(int drive, int side, uint16_t pos) imd_t *dev = imd[drive]; int type = dev->current_data[side][0]; - if (! (type & 1)) return(0xf6); /* Should never happen. */ + if ((type == 0) || (type > 8)) return(0xf6); /* Should never happen. */ - return(dev->current_data[side][pos + 1]); + if (type & 1) + return(dev->current_data[side][pos + 1]); + else + return(dev->current_data[side][1]); } @@ -565,7 +572,7 @@ poll_write_data(int drive, int side, uint16_t pos, uint8_t data) if (writeprot[drive]) return; - if (! (type & 1)) return; /* Should never happen. */ + if ((type & 1) || (type == 0) || (type > 8)) return; /* Should never happen. */ dev->current_data[side][pos + 1] = data; } @@ -720,7 +727,6 @@ imd_load(int drive, wchar_t *fn) track_spt = buffer2[3]; sector_size = buffer2[4]; - pclog("%02X %02X %02X %02X\n", buffer2[1], buffer2[2], buffer2[3], buffer2[4]); if ((track_spt == 15) && (sector_size == 2)) dev->tracks[track][side].side_flags |= 0x20; if ((track_spt == 16) && (sector_size == 2)) @@ -737,7 +743,7 @@ imd_load(int drive, wchar_t *fn) dev->tracks[track][side].max_sector_size = 5; if (!mfm) dev->tracks[track][side].max_sector_size--; - /* imd_log("Side flags for (%02i)(%01i): %02X\n", track, side, dev->tracks[track][side].side_flags); */ + imd_log("Side flags for (%02i)(%01i): %02X\n", track, side, dev->tracks[track][side].side_flags); dev->tracks[track][side].is_present = 1; dev->tracks[track][side].file_offs = (buffer2 - buffer); memcpy(dev->tracks[track][side].params, buffer2, 5); diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt new file mode 100644 index 000000000..06f700cca --- /dev/null +++ b/src/game/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(game OBJECT gameport.c joystick_standard.c + joystick_ch_flightstick_pro.c joystick_sw_pad.c joystick_tm_fcs.c) \ No newline at end of file diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index e68084678..7b2923809 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -96,6 +96,9 @@ extern const device_t sis_85c471_device; extern const device_t sis_85c496_device; extern const device_t sis_85c496_ls486e_device; extern const device_t sis_85c50x_device; +#if defined(DEV_BRANCH) && defined(USE_SIS_5571) +extern const device_t sis_5571_device; +#endif /* ST */ #if defined(DEV_BRANCH) && defined(USE_STPC) diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 0d5b397e6..6cf841df4 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -72,6 +72,7 @@ extern const device_t keyboard_xt_olivetti_device; extern const device_t keyboard_xt_zenith_device; extern const device_t keyboard_at_device; extern const device_t keyboard_at_ami_device; +extern const device_t keyboard_at_samsung_device; extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_ncr_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f8dd959b7..31baeee20 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -251,12 +251,15 @@ extern int machine_at_gw286ct_init(const machine_t *); extern int machine_at_super286tr_init(const machine_t *); extern int machine_at_spc4200p_init(const machine_t *); extern int machine_at_spc4216p_init(const machine_t *); +extern int machine_at_spc4620p_init(const machine_t *); extern int machine_at_kmxc02_init(const machine_t *); extern int machine_at_deskmaster286_init(const machine_t *); extern int machine_at_shuttle386sx_init(const machine_t *); extern int machine_at_adi386sx_init(const machine_t *); -extern int machine_at_commodore_sl386sx_init(const machine_t *); +extern int machine_at_commodore_sl386sx16_init(const machine_t *); +extern int machine_at_commodore_sl386sx25_init(const machine_t *); +extern int machine_at_spc6033p_init(const machine_t *); extern int machine_at_wd76c10_init(const machine_t *); extern int machine_at_olim290_init(const machine_t *); @@ -271,14 +274,16 @@ extern int machine_at_pja511m_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_ama932j_get_device(void); -extern const device_t *at_commodore_sl386sx_get_device(void); +extern const device_t *at_commodore_sl386sx25_get_device(void); +extern const device_t *at_spc4620p_get_device(void); +extern const device_t *at_spc6033p_get_device(void); #endif /* m_at_386dx_486.c */ - extern int machine_at_acc386_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); extern int machine_at_ecs386_init(const machine_t *); +extern int machine_at_spc6000a_init(const machine_t *); extern int machine_at_ustechnologies386_init(const machine_t *); extern int machine_at_micronics386_init(const machine_t *); @@ -304,6 +309,7 @@ extern int machine_at_vect486vl_init(const machine_t *); extern int machine_at_403tg_init(const machine_t *); extern int machine_at_pc330_6571_init(const machine_t *); +extern int machine_at_mvi486_init(const machine_t *); extern int machine_at_sis401_init(const machine_t *); extern int machine_at_av4_init(const machine_t *); @@ -414,6 +420,7 @@ extern int machine_at_p65up5_cp55t2d_init(const machine_t *); extern int machine_at_p55tvp4_init(const machine_t *); extern int machine_at_p55va_init(const machine_t *); extern int machine_at_i430vx_init(const machine_t *); +extern int machine_at_5ivg_init(const machine_t *); extern int machine_at_brio80xx_init(const machine_t *); extern int machine_at_8500tvxa_init(const machine_t *); extern int machine_at_presario4500_init(const machine_t *); @@ -429,6 +436,11 @@ extern int machine_at_an430tx_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_p5mms98_init(const machine_t *); +#if defined(DEV_BRANCH) && defined(USE_SIS_5571) +extern int machine_at_r534f_init(const machine_t *); +extern int machine_at_ms5146_init(const machine_t *); +#endif + extern int machine_at_ficva502_init(const machine_t *); extern int machine_at_ficpa2012_init(const machine_t *); @@ -479,6 +491,7 @@ extern int machine_at_ergox365_init(const machine_t *); extern int machine_at_ficka6130_init(const machine_t *); extern int machine_at_p3v133_init(const machine_t *); extern int machine_at_p3v4x_init(const machine_t *); +extern int machine_at_vei8_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t *at_tsunamiatx_get_device(void); diff --git a/src/include/86box/sio.h b/src/include/86box/sio.h index 3c4702ffa..81dc8976e 100644 --- a/src/include/86box/sio.h +++ b/src/include/86box/sio.h @@ -32,6 +32,8 @@ extern const device_t fdc37c931apm_compaq_device; extern const device_t fdc37c932fr_device; extern const device_t fdc37c932qf_device; extern const device_t fdc37c935_device; +extern const device_t fdc37m60x_device; +extern const device_t fdc37m60x_370_device; extern const device_t i82091aa_device; extern const device_t i82091aa_398_device; extern const device_t i82091aa_ide_device; @@ -41,9 +43,13 @@ extern const device_t pc87307_15c_device; extern const device_t pc87307_both_device; extern const device_t pc87309_device; extern const device_t pc87309_15c_device; +extern const device_t pc87311_device; +extern const device_t pc87311_ide_device; extern const device_t pc87332_device; extern const device_t pc87332_ps1_device; extern const device_t pc97307_device; +extern const device_t prime3c_device; +extern const device_t prime3c_ide_device; extern const device_t ps1_m2133_sio; extern const device_t sio_detect_device; extern const device_t um8669f_device; diff --git a/src/include/86box/version.h.in b/src/include/86box/version.h.in new file mode 100644 index 000000000..67832258d --- /dev/null +++ b/src/include/86box/version.h.in @@ -0,0 +1,31 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for project version, branding, and external links. + * + * Authors: Miran Grca, + * + * Copyright 2020 Miran Grca. + */ + +/* Version info. */ +#define EMU_NAME "@CMAKE_PROJECT_NAME@" +#define EMU_NAME_W L"@CMAKE_PROJECT_NAME@" + +#define EMU_VERSION "@CMAKE_PROJECT_VERSION@" +#define EMU_VERSION_W L"@CMAKE_PROJECT_VERSION@" +#define EMU_VERSION_EX "@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@0" +#define EMU_VERSION_MAJ @CMAKE_PROJECT_VERSION_MAJOR@ +#define EMU_VERSION_MIN @CMAKE_PROJECT_VERSION_MINOR@ + +#define COPYRIGHT_YEAR "2020" + +/* Web URL info. */ +#define EMU_SITE L"@CMAKE_PROJECT_HOMEPAGE_URL@" +#define EMU_ROMS_URL L"https://github.com/86Box/roms/releases/latest" +#define EMU_DOCS_URL L"https://86box.readthedocs.io" diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b7c356942..c619d994a 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -205,6 +205,8 @@ extern const device_t ati18800_device; /* ATi 28800 */ extern const device_t ati28800_device; extern const device_t ati28800k_device; +extern const device_t ati28800k_spc4620p_device; +extern const device_t ati28800k_spc6033p_device; extern const device_t compaq_ati28800_device; #if defined(DEV_BRANCH) && defined(USE_XL24) extern const device_t ati28800_wonderxl24_device; diff --git a/src/include/86box/win.h b/src/include/86box/win.h index dd83af427..e73bcfd50 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -102,7 +102,7 @@ extern HANDLE ghMutex; extern LCID lang_id; extern HICON hIcon[256]; extern RECT oldclip; -extern int sbar_height; +extern int sbar_height, user_resize; // extern int status_is_open; diff --git a/src/include/86box/version.h b/src/include_make/86box/version.h similarity index 93% rename from src/include/86box/version.h rename to src/include_make/86box/version.h index ce286e89f..b3da62c6e 100644 --- a/src/include/86box/version.h +++ b/src/include_make/86box/version.h @@ -28,4 +28,4 @@ /* Web URL info. */ #define EMU_SITE L"86box.net" #define EMU_ROMS_URL L"https://github.com/86Box/roms/releases/latest" -#define EMU_DOCS_URL L"https://86box.readthedocs.io" +#define EMU_DOCS_URL L"https://86box.readthedocs.io" \ No newline at end of file diff --git a/src/lpt.c b/src/lpt.c index bf0cc339e..6332417d3 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -108,7 +108,7 @@ lpt_write(uint16_t port, uint8_t val, void *priv) switch (port & 3) { case 0: - if (dev->dt && dev->dt->write_data) + if (dev->dt && dev->dt->write_data && dev->priv) dev->dt->write_data(val, dev->priv); dev->dat = val; break; @@ -117,7 +117,7 @@ lpt_write(uint16_t port, uint8_t val, void *priv) break; case 2: - if (dev->dt && dev->dt->write_ctrl) + if (dev->dt && dev->dt->write_ctrl && dev->priv) dev->dt->write_ctrl(val, dev->priv); dev->ctrl = val; dev->enable_irq = val & 0x10; @@ -134,21 +134,21 @@ lpt_read(uint16_t port, void *priv) switch (port & 3) { case 0: - if (dev->dt && dev->dt->read_data) + if (dev->dt && dev->dt->read_data && dev->priv) ret = dev->dt->read_data(dev->priv); else ret = dev->dat; break; case 1: - if (dev->dt && dev->dt->read_status) + if (dev->dt && dev->dt->read_status && dev->priv) ret = dev->dt->read_status(dev->priv) | 0x07; else ret = 0xdf; break; case 2: - if (dev->dt && dev->dt->read_ctrl) + if (dev->dt && dev->dt->read_ctrl && dev->priv) ret = (dev->dt->read_ctrl(dev->priv) & 0xef) | dev->enable_irq; else ret = 0xe0 | dev->ctrl | dev->enable_irq; diff --git a/src/machine/CMakeLists.txt b/src/machine/CMakeLists.txt new file mode 100644 index 000000000..18a43eb03 --- /dev/null +++ b/src/machine/CMakeLists.txt @@ -0,0 +1,63 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(mch OBJECT machine.c machine_table.c m_xt.c m_xt_compaq.c + m_xt_t1000.c m_xt_t1000_vid.c m_xt_xi8088.c m_xt_zenith.c m_pcjr.c + m_amstrad.c m_europc.c m_xt_olivetti.c m_tandy.c m_at.c m_at_commodore.c + m_at_t3100e.c m_at_t3100e_vid.c m_ps1.c m_ps1_hdc.c m_ps2_isa.c + m_ps2_mca.c m_at_compaq.c m_at_286_386sx.c m_at_386dx_486.c + m_at_socket4_5.c m_at_socket7.c m_at_sockets7.c m_at_socket8.c + m_at_slot1.c m_at_slot2.c m_at_socket370.c m_at_misc.c) + +if(HEDAKA) + target_compile_definitions(mch PRIVATE USE_HEDAKA) +endif() + +if(LASERXT) + target_sources(mch PRIVATE m_xt_laserxt.c) + target_compile_definitions(mch PRIVATE USE_LASERXT) +endif() + +if(NO_SIO) + target_compile_definitions(mch PRIVATE NO_SIO) +endif() + +if(OPEN_AT) + target_compile_definitions(mch PRIVATE USE_OPEN_AT) +endif() + +if(PS1M2133) + target_compile_definitions(mch PRIVATE USE_PS1M2133) +endif() + +if(PS2M70T4) + target_compile_definitions(mch PRIVATE USE_PS2M70T4) +endif() + +if(M1489) + target_compile_definitions(mch PRIVATE USE_M1489) +endif() + +if(M6117) + target_compile_definitions(mch PRIVATE USE_M6117) +endif() + +if(VECT486VL) + target_compile_definitions(mch PRIVATE USE_VECT486VL) +endif() + +if(DELLS4) + target_compile_definitions(mch PRIVATE USE_DELLS4) +endif() \ No newline at end of file diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index a259f1d8a..ead2154c7 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -37,6 +37,7 @@ #include <86box/fdc.h> #include <86box/hdc.h> #include <86box/sio.h> +#include <86box/serial.h> #include <86box/video.h> #include <86box/flash.h> #include <86box/machine.h> @@ -355,6 +356,34 @@ machine_at_spc4216p_init(const machine_t *model) } +const device_t * +at_spc4620p_get_device(void) +{ + return &ati28800k_spc4620p_device; +} + + +int +machine_at_spc4620p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/spc4620p/31005h.u8", + L"roms/machines/spc4620p/31005h.u10", + 0x000f0000, 131072, 0x8000); + + if (bios_only || !ret) + return ret; + + machine_at_scat_init(model, 1); + + if (gfxcard == VID_INTERNAL) + device_add(&ati28800k_spc4620p_device); + + return ret; +} + + int machine_at_kmxc02_init(const machine_t *model) { @@ -458,20 +487,13 @@ machine_at_wd76c10_init(const machine_t *model) } -const device_t * -at_commodore_sl386sx_get_device(void) -{ - return &gd5402_onboard_device; -} - - int -machine_at_commodore_sl386sx_init(const machine_t *model) +machine_at_commodore_sl386sx16_init(const machine_t *model) { int ret; - ret = bios_load_interleaved(L"roms/machines/cbm_sl386sx25/cbm-sl386sx-bios-lo-v1.04-390914-04.bin", - L"roms/machines/cbm_sl386sx25/cbm-sl386sx-bios-hi-v1.04-390915-04.bin", + ret = bios_load_interleaved(L"roms/machines/cbm_sl386sx16/cbm-sl386sx-bios-lo-v1.04-390914-04.bin", + L"roms/machines/cbm_sl386sx16/cbm-sl386sx-bios-hi-v1.04-390915-04.bin", 0x000f0000, 65536, 0); if (bios_only || !ret) @@ -481,7 +503,45 @@ machine_at_commodore_sl386sx_init(const machine_t *model) device_add(&keyboard_at_device); device_add(&fdc_at_device); + device_add(&neat_device); + /* Two serial ports - on the real hardware SL386SX-16, they are on the single UMC UM82C452. */ + device_add_inst(&ns16450_device, 1); + device_add_inst(&ns16450_device, 2); + + return ret; +} + + +static void +machine_at_scamp_common_init(const machine_t *model) +{ + machine_at_common_ide_init(model); + + device_add(&keyboard_ps2_ami_device); + device_add(&fdc_at_device); device_add(&vlsi_scamp_device); +} + + +const device_t * +at_commodore_sl386sx25_get_device(void) +{ + return &gd5402_onboard_device; +} + + +int +machine_at_commodore_sl386sx25_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/cbm_sl386sx25/f000.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_scamp_common_init(model); if (gfxcard == VID_INTERNAL) device_add(&gd5402_onboard_device); @@ -490,6 +550,33 @@ machine_at_commodore_sl386sx_init(const machine_t *model) } +const device_t * +at_spc6033p_get_device(void) +{ + return &ati28800k_spc6033p_device; +} + + +int +machine_at_spc6033p_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/spc6033p/phoenix.bin", + 0x000f0000, 65536, 0x10000); + + if (bios_only || !ret) + return ret; + + machine_at_scamp_common_init(model); + + if (gfxcard == VID_INTERNAL) + device_add(&ati28800k_spc6033p_device); + + return ret; +} + + int machine_at_awardsx_init(const machine_t *model) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index 74ca503d5..e040e3128 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -157,12 +157,34 @@ machine_at_ecs386_init(const machine_t *model) machine_at_common_init(model); device_add(&cs8230_device); - device_add(&keyboard_at_ami_device); device_add(&fdc_at_device); + device_add(&keyboard_at_ami_device); return ret; } + +int +machine_at_spc6000a_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved(L"roms/machines/spc6000a/3c80.u27", + L"roms/machines/spc6000a/9f80.u26", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 1); + device_add(&cs8230_device); + device_add(&fdc_at_device); + device_add(&keyboard_at_samsung_device); + + return ret; +} + + int machine_at_ustechnologies386_init(const machine_t *model) { @@ -183,6 +205,7 @@ machine_at_ustechnologies386_init(const machine_t *model) return ret; } + int machine_at_rycleopardlx_init(const machine_t *model) { @@ -224,6 +247,7 @@ machine_at_486vchd_init(const machine_t *model) return ret; } + int machine_at_cs4031_init(const machine_t *model) { @@ -243,6 +267,7 @@ machine_at_cs4031_init(const machine_t *model) return ret; } + int machine_at_pb410a_init(const machine_t *model) { @@ -269,6 +294,7 @@ machine_at_pb410a_init(const machine_t *model) return ret; } + #if defined(DEV_BRANCH) && defined(USE_VECT486VL) int machine_at_vect486vl_init(const machine_t *model) // has HDC problems @@ -294,6 +320,7 @@ machine_at_vect486vl_init(const machine_t *model) // has HDC problems return ret; } + const device_t * at_vect486vl_get_device(void) { @@ -301,6 +328,7 @@ at_vect486vl_get_device(void) } #endif + int machine_at_acera1g_init(const machine_t *model) { @@ -325,6 +353,7 @@ machine_at_acera1g_init(const machine_t *model) return ret; } + const device_t * at_acera1g_get_device(void) { @@ -466,6 +495,7 @@ machine_at_403tg_init(const machine_t *model) return ret; } + int machine_at_pc330_6571_init(const machine_t *model) // doesn't like every CPU other than the iDX4 and the Intel OverDrive, hangs without a PS/2 mouse { @@ -488,6 +518,27 @@ machine_at_pc330_6571_init(const machine_t *model) // doesn't like every CPU oth return ret; } +int +machine_at_mvi486_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/mvi486/MVI627.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&opti895_device); + + device_add(&keyboard_at_device); + device_add(&pc87311_ide_device); + + return ret; +} + static void machine_at_sis_85c471_common_init(const machine_t *model) { @@ -516,6 +567,7 @@ machine_at_ami471_init(const machine_t *model) return ret; } + int machine_at_vli486sv2g_init(const machine_t *model) { @@ -534,6 +586,7 @@ machine_at_vli486sv2g_init(const machine_t *model) return ret; } + int machine_at_dtk486_init(const machine_t *model) { @@ -891,6 +944,7 @@ machine_at_486vipio2_init(const machine_t *model) } #endif + #if defined(DEV_BRANCH) && defined(USE_M1489) int machine_at_abpb4_init(const machine_t *model) @@ -912,7 +966,6 @@ machine_at_abpb4_init(const machine_t *model) pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); device_add(&ali1489_device); - device_add(&ide_pci_2ch_device); device_add(&w83787f_device); device_add(&keyboard_at_device); @@ -920,6 +973,7 @@ machine_at_abpb4_init(const machine_t *model) } #endif + #if defined(DEV_BRANCH) && defined(USE_STPC) int machine_at_itoxstar_init(const machine_t *model) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index ebdc421b1..202f975ff 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -622,3 +622,33 @@ machine_at_p3v4x_init(const machine_t *model) return ret; } + +int +machine_at_vei8_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/vei8/QHW1001.BIN", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + device_add(&i440bx_device); + device_add(&piix4e_device); + device_add(&fdc37m60x_370_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&sst_flash_39sf020_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 512); + + return ret; +} diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index c2d2d6e5d..acdb2278e 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -580,6 +580,34 @@ machine_at_p55tvp4_init(const machine_t *model) return ret; } +int +machine_at_5ivg_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/5ivg/5IVG.BIN", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_pci_device); + device_add(&prime3c_device); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_i430vx_init(const machine_t *model) { @@ -1004,6 +1032,66 @@ machine_at_p5mms98_init(const machine_t *model) return ret; } +#if defined(DEV_BRANCH) && defined(USE_SIS_5571) +int +machine_at_r534f_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/r534f/r534f008.bin", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5571_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&sst_flash_29ee010_device); + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + +int +machine_at_ms5146_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear(L"roms/machines/ms5146/A546MS11.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + + device_add(&sis_5571_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83877f_device); + device_add(&intel_flash_bxt_device); + + return ret; +} +#endif int machine_at_ficva502_init(const machine_t *model) diff --git a/src/machine/m_ps1.c b/src/machine/m_ps1.c index ccad28139..350e15e70 100644 --- a/src/machine/m_ps1.c +++ b/src/machine/m_ps1.c @@ -326,25 +326,31 @@ ps1_write(uint16_t port, uint8_t val, void *priv) break; case 0x0102: - lpt1_remove(); - if (val & 0x04) - serial_setup(ps->uart, SERIAL1_ADDR, SERIAL1_IRQ); - else + if (!(ps->ps1_94 & 0x80)) { + lpt1_remove(); serial_remove(ps->uart); - if (val & 0x10) { - switch ((val >> 5) & 3) { - case 0: - lpt1_init(0x03bc); - break; - case 1: - lpt1_init(0x0378); - break; - case 2: - lpt1_init(0x0278); - break; + if (val & 0x04) { + if (val & 0x08) + serial_setup(ps->uart, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(ps->uart, SERIAL2_ADDR, SERIAL2_IRQ); } + if (val & 0x10) { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps->ps1_102 = val; } - ps->ps1_102 = val; break; case 0x0103: @@ -469,17 +475,16 @@ ps1_setup(int model) ps1_hdc_inform(priv, &ps->ps1_91); } - } - - if (model == 2121) { + + /* Enable the PS/1 VGA controller. */ + device_add(&ps1vga_device); + } else if (model == 2121) { io_sethandler(0x00e0, 2, ps1_read, NULL, NULL, ps1_write, NULL, NULL, ps); -#if 0 rom_init(&ps->high_rom, L"roms/machines/ibmps1_2121/fc0000.bin", 0xfc0000, 0x20000, 0x1ffff, 0, MEM_MAPPING_EXTERNAL); -#endif /* Initialize the video controller. */ if (gfxcard == VID_INTERNAL) @@ -491,12 +496,6 @@ ps1_setup(int model) device_add(&snd_device); } - - /* Enable the PS/1 VGA controller. */ - if (model == 2011) - device_add(&ps1vga_device); - else if (model == 2021) - device_add(&ibm_ps1_2121_device); } static void diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index 226a3eda4..604841b5a 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -84,28 +84,33 @@ static void ps2_write(uint16_t port, uint8_t val, void *p) ps2_94 = val; break; case 0x102: - lpt1_remove(); - if (val & 0x04) - serial_setup(ps2_uart, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_remove(ps2_uart); - if (val & 0x10) - { - switch ((val >> 5) & 3) - { - case 0: - lpt1_init(0x3bc); - break; - case 1: - lpt1_init(0x378); - break; - case 2: - lpt1_init(0x278); - break; - } - } - ps2_102 = val; - break; + if (!(ps2_94 & 0x80)) { + lpt1_remove(); + serial_remove(ps2_uart); + if (val & 0x04) { + if (val & 0x08) + serial_setup(ps2_uart, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(ps2_uart, SERIAL2_ADDR, SERIAL2_IRQ); + } + if (val & 0x10) { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps2_102 = val; + } + break; + case 0x103: ps2_103 = val; break; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 21e0db0f0..07e684cee 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -133,7 +133,7 @@ const machine_t machines[] = { { "[GC103] Quadtel 286 clone", "quadt286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_quadt286_init, NULL }, { "[GC103] Trigem 286M", "tg286m", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 512, 8192, 128, 127, machine_at_tg286m_init, NULL }, { "[NEAT] AMI 286 clone", "ami286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[NEAT] NCR 3302", "ncr_3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_ncr3302_init, NULL }, + { "[NEAT] NCR 3302", "ncr_3302", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_VIDEO, 512, 16384, 128, 127, machine_at_ncr3302_init, NULL }, { "[NEAT] Phoenix 286 clone", "px286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_px286_init, NULL }, { "[SCAT] Award 286 clone", "award286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_award286_init, NULL }, { "[SCAT] GW-286CT GEAR", "gw286ct", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_gw286ct_init, NULL }, @@ -141,6 +141,7 @@ const machine_t machines[] = { { "[SCAT] Hyundai Super-286TR", "super286tr", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_super286tr_init, NULL }, { "[SCAT] Samsung SPC-4200P", "spc4200p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 512, 2048, 128, 127, machine_at_spc4200p_init, NULL }, { "[SCAT] Samsung SPC-4216P", "spc4216p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2, 1024, 5120,1024, 127, machine_at_spc4216p_init, NULL }, + { "[SCAT] Samsung SPC-4620P", "spc4620p", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_VIDEO, 1024, 5120,1024, 127, machine_at_spc4620p_init, NULL }, { "[SCAT] Samsung Deskmaster 286", "deskmaster286", MACHINE_TYPE_286, CPU_PKG_286, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_deskmaster286_init, NULL }, /* 286 machines that utilize the MCA bus */ @@ -156,9 +157,11 @@ const machine_t machines[] = { { "[HT18] AMA-932J", "ama932j", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 512, 8192, 128, 127, machine_at_ama932j_init, at_ama932j_get_device }, { "[Intel 82335] ADI 386SX", "adi386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_adi386sx_init, NULL }, { "[Intel 82335] Shuttle 386SX", "shuttle386sx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_shuttle386sx_init, NULL }, + { "[NEAT] Commodore SL386SX-16", "cbm_sl386sx16", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 8192, 512, 127, machine_at_commodore_sl386sx16_init, NULL }, { "[NEAT] DTK 386SX clone", "dtk386", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_init, NULL }, { "[OPTi 291] DTK PPM-3333P", "awardsx", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_awardsx_init, NULL }, - { "[SCAMP] Commodore SL386SX", "cbm_sl386sx25", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127, machine_at_commodore_sl386sx_init, at_commodore_sl386sx_get_device }, + { "[SCAMP] Commodore SL386SX-25", "cbm_sl386sx25", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 8192, 512, 127, machine_at_commodore_sl386sx25_init, at_commodore_sl386sx25_get_device }, + { "[SCAMP] Samsung SPC-6033P", "spc6033p", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 2048, 12288, 2048, 127, machine_at_spc6033p_init, at_spc6033p_get_device }, { "[SCAT] KMX-C-02", "kmxc02", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 512, 127, machine_at_kmxc02_init, NULL }, { "[WD76C10] Amstrad MegaPC", "megapc", MACHINE_TYPE_386SX, CPU_PKG_386SX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE | MACHINE_VIDEO, 1024, 32768, 1024, 127, machine_at_wd76c10_init, NULL }, @@ -167,7 +170,8 @@ const machine_t machines[] = { /* 386DX machines */ { "[ACC 2168] AMI 386DX clone", "acc386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_acc386_init, NULL }, - { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_ecs386_init, NULL }, + { "[C&T 386] ECS 386/32", "ecs386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 1024, 16384, 1024, 127, machine_at_ecs386_init, NULL }, + { "[C&T 386] Samsung SPC-6000A", "spc6000a", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_spc6000a_init, NULL }, { "[ISA] Compaq Portable III (386)", "portableiii386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE | MACHINE_VIDEO, 1024, 14336, 1024, 127, machine_at_portableiii386_init, at_cpqiii_get_device }, { "[ISA] Micronics 386 clone", "micronics386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 8192, 128, 127, machine_at_micronics386_init, NULL }, { "[SiS 310] ASUS ISA-386C", "asus386", MACHINE_TYPE_386DX, CPU_PKG_386DX, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT, 512, 16384, 128, 127, machine_at_asus386_init, NULL }, @@ -196,6 +200,7 @@ const machine_t machines[] = { { "[OPTi 495] MR 486 clone", "mr486", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 32768, 1024, 127, machine_at_opti495_mr_init, NULL }, { "[OPTi 802G] IBM PC 330 (type 6571)", "pc330_6571", MACHINE_TYPE_486, CPU_PKG_SOCKET3_PC330, 0, 25000000, 33333333, 0, 0, 2.0, 3.0, MACHINE_VLB | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_pc330_6571_init, NULL }, { "[OPTi 895] Jetway J-403TG", "403tg", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB, 1024, 65536, 1024, 127, machine_at_403tg_init, NULL }, + { "[OPTi 895] Mylex MVI486", "mvi486", MACHINE_TYPE_486, CPU_PKG_SOCKET1, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE_DUAL, 1024, 65536, 1024, 127, machine_at_mvi486_init, NULL }, { "[SiS 401] AMI 486 Clone", "sis401", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_sis401_init, NULL }, { "[SiS 460] ABIT AV4", "av4", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_VLB | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_av4_init, NULL }, { "[SiS 461] IBM PS/ValuePoint 433DX/Si", "valuepoint433", MACHINE_TYPE_486, CPU_PKG_SOCKET3, 0, 0, 0, 0, 0, 0, 0, MACHINE_AT | MACHINE_BUS_PS2 | MACHINE_IDE, 1024, 65536, 1024, 127, machine_at_valuepoint433_init, NULL }, @@ -243,7 +248,7 @@ const machine_t machines[] = { { "[i430LX] ASUS P/I-P5MP3", "p5mp3", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2048, 196608, 2048, 127, machine_at_p5mp3_init, NULL }, { "[i430LX] Dell Dimension XPS P60", "dellxp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE, 2048, 131072, 2048, 127, machine_at_dellxp60_init, NULL }, { "[i430LX] Dell OptiPlex 560/L", "opti560l", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_opti560l_init, NULL }, - { "[i430LX] IBM Ambra DP60 PCI", "ambradp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_ambradp60_init, NULL }, + { "[i430LX] AMBRA DP60 PCI", "ambradp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_ambradp60_init, NULL }, { "[i430LX] IBM PS/ValuePoint P60", "valuepointp60", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_valuepointp60_init, NULL }, { "[i430LX] Intel Premiere/PCI", "revenge", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_batman_init, NULL }, { "[i430LX] Micro Star 586MC1", "586mc1", MACHINE_TYPE_SOCKET4, CPU_PKG_SOCKET4, 0, 60000000, 66666667, 5000, 5000, MACHINE_MULTIPLIER_FIXED, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_586mc1_init, NULL }, @@ -258,7 +263,7 @@ const machine_t machines[] = { /* Socket 5 machines */ /* 430NX */ { "[i430NX] Intel Premiere/PCI II", "plato", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_plato_init, NULL }, - { "[i430NX] IBM Ambra DP90 PCI", "ambradp90", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_ambradp90_init, NULL }, + { "[i430NX] AMBRA DP90 PCI", "ambradp90", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 3380, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_ambradp90_init, NULL }, { "[i430NX] Gigabyte GA-586IP", "430nx", MACHINE_TYPE_SOCKET5, CPU_PKG_SOCKET5_7, 0, 60000000, 66666667, 3520, 3520, 1.5, 1.5, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 2048, 131072, 2048, 127, machine_at_430nx_init, NULL }, /* 430FX */ @@ -305,6 +310,7 @@ const machine_t machines[] = { /* 430VX */ { "[i430VX] ASUS P/I-P55TVP4", "p55tvp4", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p55tvp4_init, NULL }, + { "[i430VX] Azza 5IVG", "5ivg", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_5ivg_init, NULL }, { "[i430VX] Biostar MB-8500TVX-A", "8500tvxa", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2600, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_8500tvxa_init, NULL }, { "[i430VX] Compaq Presario 4500", "presario4500", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2800, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_VIDEO, 8192, 131072, 8192, 127, machine_at_presario4500_init, NULL }, { "[i430VX] Epox P55-VA", "p55va", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 131072, 8192, 127, machine_at_p55va_init, NULL }, @@ -327,7 +333,13 @@ const machine_t machines[] = { /* Apollo VP3 */ { "[VIA VP3] FIC PA-2012", "ficpa2012", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 55000000, 75000000, 2100, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 127, machine_at_ficpa2012_init, NULL }, - + + /* SiS 5571 */ +#if defined(DEV_BRANCH) && defined(USE_SIS_5571) + { "[SiS 5571] Rise R534F", "r534f", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 127, machine_at_r534f_init, NULL }, + { "[SiS 5571] MSI MS-5146", "ms5146", MACHINE_TYPE_SOCKET7, CPU_PKG_SOCKET5_7, 0, 50000000, 66666667, 2500, 3520, 1.5, 3.0, MACHINE_PCI | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 393216, 8192, 127, machine_at_ms5146_init, NULL }, +#endif + /* Super Socket 7 machines */ /* Apollo MVP3 */ { "[VIA MVP3] AOpen AX59 Pro", "ax59pro", MACHINE_TYPE_SOCKETS7, CPU_PKG_SOCKET5_7, 0, 66666667, 124242424, 1300, 3520, 1.5, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_ax59pro_init, NULL }, @@ -363,6 +375,7 @@ const machine_t machines[] = { { "[i440BX] ABIT BF6", "bf6", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 133333333, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_bf6_init, NULL }, { "[i440BX] AOpen AX6BC", "ax6bc", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 1.5, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_ax6bc_init, NULL }, { "[i440BX] Gigabyte GA-686BX", "686bx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_686bx_init, NULL }, + { "[i440BX] HP Vectra VEi 8", "vei8", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 5.5, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_vei8_init, NULL }, { "[i440BX] Tyan Tsunami ATX", "tsunamiatx", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 112121212, 1800, 3500, 3.5, 5.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL | MACHINE_SOUND, 8192,1048576, 8192, 255, machine_at_tsunamiatx_init, at_tsunamiatx_get_device }, { "[i440BX] SuperMicro Super P6SBA", "p6sba", MACHINE_TYPE_SLOT1, CPU_PKG_SLOT1, 0, 66666667, 100000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_p6sba_init, NULL }, #if defined(DEV_BRANCH) && defined(NO_SIO) @@ -391,9 +404,9 @@ const machine_t machines[] = { { "[i440LX] SuperMicro Super 370SLM", "s370slm", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_s370slm_init, NULL }, /* 440BX */ - { "[i440BX] AEWIN AW-O671R", "awo671r", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 255, machine_at_awo671r_init, NULL }, + { "[i440BX] AEWIN AW-O671R", "awo671r", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 2.0, 8.0, /* limits assumed */ MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 524288, 8192, 255, machine_at_awo671r_init, NULL }, { "[i440BX] ASUS CUBX", "cubx", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_cubx_init, NULL }, - { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_ambx133_init, NULL }, + { "[i440BX] AmazePC AM-BX133", "ambx133", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 2.0, 8.0, /* limits assumed */ MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_ambx133_init, NULL }, { "[i440BX] Tyan Trinity 371", "trinity371", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 3.5, 7.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_trinity371_init, NULL }, /* 440ZX */ @@ -405,7 +418,7 @@ const machine_t machines[] = { /* VIA Apollo Pro */ { "[VIA Apollo Pro] PC Partner APAS3", "apas3", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 100000000, 1800, 3500, 3.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192, 786432, 8192, 255, machine_at_apas3_init, NULL }, { "[VIA Apollo Pro133] ECS P6BAP", "p6bap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_p6bap_init, NULL }, - { "[VIA Apollo Pro133A] AEWIN WCF-681", "wcf681", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 0, 0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_wcf681_init, NULL }, + { "[VIA Apollo Pro133A] AEWIN WCF-681", "wcf681", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 133333333, 1300, 3500, 2.0, 8.0, /* limits assumed */ MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_wcf681_init, NULL }, { "[VIA Apollo Pro133A] ASUS CUV4X-LS", "cuv4xls", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 2.0, 8.0, (MACHINE_AGP & ~MACHINE_AT) | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 16384,1572864, 8192, 255, machine_at_cuv4xls_init, NULL }, { "[VIA Apollo Pro133A] Acorp 6VIA90AP", "6via90ap", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, MACHINE_MULTIPLIER_FIXED, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1572864, 8192, 255, machine_at_6via90ap_init, NULL }, { "[VIA Apollo ProMedia] Jetway 603TCF", "603tcf", MACHINE_TYPE_SOCKET370, CPU_PKG_SOCKET370, 0, 66666667, 150000000, 1300, 3500, 2.0, 8.0, MACHINE_AGP | MACHINE_BUS_PS2 | MACHINE_IDE_DUAL, 8192,1048576, 8192, 255, machine_at_603tcf_init, NULL }, diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt new file mode 100644 index 000000000..6bf044762 --- /dev/null +++ b/src/mem/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(mem OBJECT catalyst_flash.c i2c_eeprom.c intel_flash.c mem.c rom.c + smram.c spd.c sst_flash.c) \ No newline at end of file diff --git a/src/mem/mem.c b/src/mem/mem.c index 4c9d6a8c2..ae716718e 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -122,6 +122,7 @@ static mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static uint8_t *_mem_exec[MEM_MAPPINGS_NO]; static uint32_t _mem_state[MEM_MAPPINGS_NO]; +static uint32_t remap_start_addr; #ifdef ENABLE_MEM_LOG @@ -1976,8 +1977,7 @@ mem_write_raml(uint32_t addr, uint32_t val, void *priv) static uint8_t mem_read_remapped(uint32_t addr, void *priv) { - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) addreadlookup(mem_logical_addr, addr); return ram[addr]; @@ -1987,8 +1987,7 @@ mem_read_remapped(uint32_t addr, void *priv) static uint16_t mem_read_remappedw(uint32_t addr, void *priv) { - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; @@ -1998,8 +1997,7 @@ mem_read_remappedw(uint32_t addr, void *priv) static uint32_t mem_read_remappedl(uint32_t addr, void *priv) { - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; @@ -2010,8 +2008,7 @@ static void mem_write_remapped(uint32_t addr, uint8_t val, void *priv) { uint32_t oldaddr = addr; - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); @@ -2024,8 +2021,7 @@ static void mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) { uint32_t oldaddr = addr; - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) { addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); @@ -2038,8 +2034,7 @@ static void mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) { uint32_t oldaddr = addr; - if ((addr >= (mem_size * 1024)) && (addr < ((mem_size + 384) * 1024))) - addr = 0xA0000 + (addr - (mem_size * 1024)); + addr = 0xA0000 + (addr - remap_start_addr); if (AT) { addwritelookup(mem_logical_addr, addr); mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); @@ -2693,14 +2688,12 @@ mem_reset(void) base_mapping = last_mapping = NULL; - memset(_mem_state, 0x00, sizeof(_mem_state)); + /* Set the entire memory space as external. */ + memset(_mem_state, 0x02, sizeof(_mem_state)); + /* Set the low RAM space as internal. */ mem_set_mem_state_both(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state_both(0x0a0000, 0x60000, - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state_both((mem_size << 10), (uint32_t) (0x100000000ULL - (mem_size << 10)), - MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, @@ -2802,6 +2795,8 @@ mem_remap_top(int kb) if (size > kb) size = kb; + remap_start_addr = start << 10; + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { offset = c - ((start * 1024) >> 12); pages[c].mem = &ram[0xA0000 + (offset << 12)]; diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt new file mode 100644 index 000000000..e8db1a01e --- /dev/null +++ b/src/network/CMakeLists.txt @@ -0,0 +1,20 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(net OBJECT network.c net_pcap.c net_slirp.c net_dp8390.c net_3c503.c + net_ne2000.c net_pcnet.c net_wd8003.c net_plip.c) + +add_subdirectory(slirp) +target_link_libraries(86Box slirp) \ No newline at end of file diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 83823cf5d..00509798a 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -81,15 +81,15 @@ struct bpf_program { typedef struct pcap_if pcap_if_t; -typedef struct timeval { +typedef struct net_timeval { long tv_sec; long tv_usec; -} timeval; +} net_timeval; #define PCAP_ERRBUF_SIZE 256 struct pcap_pkthdr { - struct timeval ts; + struct net_timeval ts; bpf_u_int32 caplen; bpf_u_int32 len; }; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 73f1c01b0..478a51282 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -2264,6 +2264,26 @@ pcnet_word_write(nic_t *dev, uint32_t addr, uint16_t val) } } +static uint8_t +pcnet_byte_read(nic_t *dev, uint32_t addr) +{ + uint8_t val = 0xff; + + if (!BCR_DWIO(dev)) { + switch (addr & 0x0f) { + case 0x04: + pcnetSoftReset(dev); + val = 0; + break; + } + } + + pcnetUpdateIrq(dev); + + pcnetlog(3, "%s: pcnet_word_read: addr = %04x, val = %04x, DWIO not set = %04x\n", dev->name, addr & 0x0f, val, !BCR_DWIO(dev)); + + return(val); +} static uint16_t pcnet_word_read(nic_t *dev, uint32_t addr) @@ -2449,7 +2469,9 @@ pcnet_read(nic_t *dev, uint32_t addr, int len) (pcnet_aprom_readb(dev, addr + 2) << 16) | (pcnet_aprom_readb(dev, addr + 3) << 24); } } else { - if (len == 2) + if (len == 1) + retval = pcnet_byte_read(dev, addr); + else if (len == 2) retval = pcnet_word_read(dev, addr); else if (len == 4) retval = pcnet_dword_read(dev, addr); diff --git a/src/network/slirp/CMakeLists.txt b/src/network/slirp/CMakeLists.txt new file mode 100644 index 000000000..83a8105ba --- /dev/null +++ b/src/network/slirp/CMakeLists.txt @@ -0,0 +1,20 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(slirp STATIC arp_table.c bootp.c cksum.c dnssearch.c if.c ip_icmp.c + ip_input.c ip_output.c mbuf.c misc.c sbuf.c slirp.c socket.c tcp_input.c + tcp_output.c tcp_subr.c tcp_timer.c udp.c util.c version.c) + +target_link_libraries(slirp wsock32 iphlpapi) \ No newline at end of file diff --git a/src/network/slirp/ip_input.c b/src/network/slirp/ip_input.c index 7f017a238..e04d1506d 100644 --- a/src/network/slirp/ip_input.c +++ b/src/network/slirp/ip_input.c @@ -38,6 +38,7 @@ #include "slirp.h" #include "ip_icmp.h" +#include static struct ip *ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp); static void ip_freef(Slirp *slirp, struct ipq *fp); diff --git a/src/network/slirp/mbuf.c b/src/network/slirp/mbuf.c index 54ec721eb..e59db76d8 100644 --- a/src/network/slirp/mbuf.c +++ b/src/network/slirp/mbuf.c @@ -14,6 +14,7 @@ */ #include "slirp.h" +#include #define MBUF_THRESH 30 diff --git a/src/network/slirp/misc.c b/src/network/slirp/misc.c index 78515cbda..371212b34 100644 --- a/src/network/slirp/misc.c +++ b/src/network/slirp/misc.c @@ -4,6 +4,7 @@ */ #include "slirp.h" +#include #ifdef G_OS_UNIX #include #endif @@ -366,7 +367,7 @@ char *slirp_connection_info(Slirp *slirp) so->so_rcv.sb_cc, so->so_snd.sb_cc); } - return g_string_free(str, FALSE); + return g_string_free(str, false); } int slirp_bind_outbound(struct socket *so, unsigned short af) diff --git a/src/pc.c b/src/pc.c index bea9d3781..ef1005091 100644 --- a/src/pc.c +++ b/src/pc.c @@ -647,26 +647,15 @@ pc_init_modules(void) } -/* Insert keystrokes into the machine's keyboard buffer. */ -static void -pc_keyboard_send(uint8_t val) -{ - if (AT) - keyboard_at_adddata_keyboard_raw(val); - else - keyboard_send(val); -} - - void -pc_send_ca(uint8_t sc) +pc_send_ca(uint16_t sc) { - pc_keyboard_send(29); /* Ctrl key pressed */ - pc_keyboard_send(56); /* Alt key pressed */ - pc_keyboard_send(sc); - pc_keyboard_send(sc | 0x80); - pc_keyboard_send(184); /* Alt key released */ - pc_keyboard_send(157); /* Ctrl key released */ + keyboard_input(1, 0x1D); /* Ctrl key pressed */ + keyboard_input(1, 0x38); /* Alt key pressed */ + keyboard_input(1, sc); + keyboard_input(0, sc); + keyboard_input(0, 0x38); /* Alt key released */ + keyboard_input(0, 0x1D); /* Ctrl key released */ } @@ -674,7 +663,7 @@ pc_send_ca(uint8_t sc) void pc_send_cad(void) { - pc_send_ca(83); + pc_send_ca(0xE053); } diff --git a/src/port_92.c b/src/port_92.c index 83efb3213..d46d2327b 100644 --- a/src/port_92.c +++ b/src/port_92.c @@ -71,7 +71,7 @@ port_92_readw(uint16_t port, void *priv) static void port_92_pulse(void *priv) { - softresetx86(); + resetx86(); cpu_set_edx(); } diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt new file mode 100644 index 000000000..ace9ac0c8 --- /dev/null +++ b/src/printer/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(print OBJECT png.c prt_cpmap.c prt_escp.c prt_text.c prt_ps.c) \ No newline at end of file diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index b30d955ef..953862c04 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1983,7 +1983,7 @@ write_ctrl(uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 500000 * TIMER_USEC); + timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); } dev->ctrl = val; diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index 4024deb64..f374e83d5 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -410,7 +410,7 @@ write_ctrl(uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 500000 * TIMER_USEC); + timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); } dev->ctrl = val; diff --git a/src/scsi/CMakeLists.txt b/src/scsi/CMakeLists.txt new file mode 100644 index 000000000..444c87b70 --- /dev/null +++ b/src/scsi/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(scsi OBJECT scsi.c scsi_device.c scsi_cdrom.c scsi_disk.c + scsi_x54x.c scsi_aha154x.c scsi_buslogic.c scsi_ncr5380.c + scsi_ncr53c8xx.c scsi_pcscsi.c scsi_spock.c) \ No newline at end of file diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index b1c823b46..4b148a08e 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2490,6 +2490,7 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) { scsi_cdrom_t *dev = (scsi_cdrom_t *) sc; uint16_t block_desc_len, pos; + uint16_t param_list_len; uint16_t i = 0; uint8_t error = 0; @@ -2498,10 +2499,15 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) switch(dev->current_cdb[0]) { case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { @@ -2519,7 +2525,7 @@ scsi_cdrom_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { scsi_cdrom_log("CD-ROM %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 763cfd05b..e411916fa 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -1077,6 +1077,7 @@ scsi_disk_phase_data_out(scsi_common_t *sc) uint32_t last_sector = hdd_image_get_last_sector(dev->id); uint32_t c, h, s, last_to_write = 0; uint16_t block_desc_len, pos; + uint16_t param_list_len; uint8_t hdr_len, val, old_val, ch, error = 0; uint8_t page, page_len; @@ -1133,10 +1134,15 @@ scsi_disk_phase_data_out(scsi_common_t *sc) break; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) + if (dev->current_cdb[0] == GPCMD_MODE_SELECT_10) { hdr_len = 8; - else + param_list_len = dev->current_cdb[7]; + param_list_len <<= 8; + param_list_len |= dev->current_cdb[8]; + } else { hdr_len = 4; + param_list_len = dev->current_cdb[4]; + } if (dev->current_cdb[0] == GPCMD_MODE_SELECT_6) { block_desc_len = dev->temp_buffer[2]; @@ -1151,7 +1157,7 @@ scsi_disk_phase_data_out(scsi_common_t *sc) pos = hdr_len + block_desc_len; while(1) { - if (pos >= dev->current_cdb[4]) { + if (pos >= param_list_len) { scsi_disk_log("SCSI HD %i: Buffer has only block descriptor\n", dev->id); break; } diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index 50dee9d40..2760d2623 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -122,7 +122,7 @@ typedef struct { int8_t irq; int8_t type; int8_t bios_ver; - uint8_t block_count; + uint8_t block_count, block_count_num; uint8_t status_ctrl; uint8_t pad[2]; @@ -181,9 +181,26 @@ ncr_log(const char *fmt, ...) #define SET_BUS_STATE(ncr, state) ncr->cur_bus = (ncr->cur_bus & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN)) +static void +ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr); + +static void +ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr); + static void ncr_callback(void *priv); +static void +ncr_irq(ncr5380_t *ncr_dev, ncr_t *ncr, int set_irq) +{ + if (set_irq) { + ncr->isr |= STATUS_INT; + picint(1 << ncr_dev->irq); + } else { + ncr->isr &= ~STATUS_INT; + picintc(1 << ncr_dev->irq); + } +} static int get_dev_id(uint8_t data) @@ -211,58 +228,35 @@ getmsglen(uint8_t *msgp, int len) } static void -ncr_reset(ncr_t *ncr) +ncr_reset(ncr5380_t *ncr_dev, ncr_t *ncr) { memset(ncr, 0x00, sizeof(ncr_t)); ncr_log("NCR reset\n"); + + timer_stop(&ncr_dev->timer); + + for (int i = 0; i < 8; i++) + scsi_device_reset(&scsi_devices[i]); + + ncr_irq(ncr_dev, ncr, 0); } - static void -dma_timer_on(ncr5380_t *ncr_dev) +ncr_timer_on(ncr5380_t *ncr_dev, ncr_t *ncr, int callback) { - ncr_t *ncr = &ncr_dev->ncr; - double period = ncr_dev->period; - - /* DMA Timer on: 1 wait period + 64 byte periods + 64 byte periods if first time. */ - if (ncr->data_wait & 2) { + double p = ncr_dev->period; + + if (ncr->data_wait & 2) ncr->data_wait &= ~2; - period *= 128.0; - } else - period *= 64.0; - /* This is the 1 us wait period. */ - period += 1.0; + if (callback) { + p *= 128.0; + } + + p += 1.0; - timer_on_auto(&ncr_dev->timer, period); -} - - -static void -wait_timer_on(ncr5380_t *ncr_dev) -{ - /* PIO Wait Timer On: 1 period. */ - timer_on_auto(&ncr_dev->timer, ncr_dev->period); -} - - -static void -set_dma_enable(ncr5380_t *dev, int enable) -{ - if (enable) { - if (!timer_is_enabled(&dev->timer)) - dma_timer_on(dev); - } else - timer_stop(&dev->timer); -} - - -static void -dma_changed(ncr5380_t *dev, int mode, int enable) -{ - dev->dma_enabled = (mode && enable); - - set_dma_enable(dev, dev->dma_enabled && dev->block_count_loaded); + ncr_log("P = %lf\n", p); + timer_on_auto(&ncr_dev->timer, p); } @@ -376,6 +370,8 @@ ncr_bus_update(void *priv, int bus) if (bus & BUS_ARB) ncr->state = STATE_IDLE; + ncr_log("State = %i\n", ncr->state); + switch (ncr->state) { case STATE_IDLE: ncr->clear_req = ncr->wait_data = ncr->wait_complete = 0; @@ -407,7 +403,6 @@ ncr_bus_update(void *priv, int bus) ncr_log("CurBus BSY|REQ=%02x\n", ncr->cur_bus); ncr->command_pos = 0; SET_BUS_STATE(ncr, SCSI_PHASE_COMMAND); - picint(1 << ncr_dev->irq); } else { ncr->state = STATE_IDLE; ncr->cur_bus = 0; @@ -448,7 +443,7 @@ ncr_bus_update(void *priv, int bus) scsi_device_command_phase0(dev, ncr->command); ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase); - ncr_dev->period = 1.0; /* 1 us default */ + ncr_dev->period = 1.0; ncr->wait_data = 4; ncr->data_wait = 0; @@ -456,14 +451,14 @@ ncr_bus_update(void *priv, int bus) /*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/ if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) { p = scsi_device_get_callback(dev); - if (p <= 0.0) - ncr_dev->period = 0.2/* * ((double) dev->buffer_length) */; - else + if (p <= 0.0) { + ncr_dev->period = 0.2; + } else ncr_dev->period = p / ((double) dev->buffer_length); ncr->data_wait |= 2; + ncr_log("SCSI ID %i: command 0x%02x for p = %lf, update = %lf, len = %i\n", ncr->target_id, ncr->command[0], p, ncr_dev->period, dev->buffer_length); } } - ncr->new_phase = dev->phase; } } @@ -482,9 +477,10 @@ ncr_bus_update(void *priv, int bus) ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ; if (ncr->data_wait & 2) ncr->data_wait &= ~2; - if (ncr->dma_mode == DMA_IDLE) { + if (ncr->dma_mode == DMA_IDLE) { /*If a data in command that is not read 6/10 has been issued*/ ncr->data_wait |= 1; - wait_timer_on(ncr_dev); + ncr_log("DMA mode idle in\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period); } else ncr->clear_req = 3; ncr->cur_bus &= ~BUS_REQ; @@ -494,7 +490,6 @@ ncr_bus_update(void *priv, int bus) break; case STATE_DATAOUT: dev = &scsi_devices[ncr->target_id]; - if ((bus & BUS_ACK) && !(ncr->bus_in & BUS_ACK)) { dev->sc->temp_buffer[ncr->data_pos++] = BUS_GETDATA(bus); @@ -506,11 +501,13 @@ ncr_bus_update(void *priv, int bus) ncr->wait_complete = 8; } else { /*More data is to be transferred, place a request*/ - if (ncr->dma_mode == DMA_IDLE) { + if (ncr->dma_mode == DMA_IDLE) { /*If a data out command that is not write 6/10 has been issued*/ ncr->data_wait |= 1; - wait_timer_on(ncr_dev); - } else + ncr_log("DMA mode idle out\n"); + timer_on_auto(&ncr_dev->timer, ncr_dev->period); + } else { ncr->clear_req = 3; + } ncr->cur_bus &= ~BUS_REQ; ncr_log("CurBus ~REQ_DataOut=%02x\n", ncr->cur_bus); } @@ -580,7 +577,7 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr_log("Write: Initiator command register\n"); if ((val & 0x80) && !(ncr->icr & 0x80)) { ncr_log("Resetting the 5380\n"); - ncr_reset(&ncr_dev->ncr); + ncr_reset(ncr_dev, &ncr_dev->ncr); } ncr->icr = val; break; @@ -595,9 +592,11 @@ ncr_write(uint16_t port, uint8_t val, void *priv) ncr->mode = val; /*Don't stop the timer until it finishes the transfer*/ - if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA)) - dma_changed(ncr_dev, ncr->dma_mode, ncr->mode & MODE_DMA); - + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + ncr_log("Continuing DMA mode\n"); + ncr_timer_on(ncr_dev, ncr, 0); + } + /*When a pseudo-DMA transfer has completed (Send or Initiator Receive), mark it as complete and idle the status*/ if (!ncr_dev->block_count_loaded && !(ncr->mode & MODE_DMA)) { ncr_log("No DMA mode\n"); @@ -618,18 +617,20 @@ ncr_write(uint16_t port, uint8_t val, void *priv) case 5: /* start DMA Send */ ncr_log("Write: start DMA send register\n"); - ncr_log("Write 6 or 10, block count loaded=%d\n", ncr_dev->block_count_loaded); /*a Write 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_SEND; - dma_changed(ncr_dev, ncr->dma_mode, ncr->mode & MODE_DMA); + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + ncr_timer_on(ncr_dev, ncr, 0); + } break; case 7: /* start DMA Initiator Receive */ - ncr_log("Write: start DMA initiator receive register\n"); - ncr_log("Read 6 or 10, block count loaded=%d\n", ncr_dev->block_count_loaded); + ncr_log("Write: start DMA initiator receive register, dma? = %02x\n", ncr->mode & MODE_DMA); /*a Read 6/10 has occurred, start the timer when the block count is loaded*/ ncr->dma_mode = DMA_INITIATOR_RECEIVE; - dma_changed(ncr_dev, ncr->dma_mode, ncr->mode & MODE_DMA); + if (ncr_dev->block_count_loaded && (ncr->mode & MODE_DMA) && !timer_is_enabled(&ncr_dev->timer)) { + ncr_timer_on(ncr_dev, ncr, 0); + } break; default: @@ -637,8 +638,10 @@ ncr_write(uint16_t port, uint8_t val, void *priv) break; } - bus_host = get_bus_host(ncr); - ncr_bus_update(priv, bus_host); + if (ncr->dma_mode == DMA_IDLE || ncr_dev->type == 0) { + bus_host = get_bus_host(ncr); + ncr_bus_update(priv, bus_host); + } } @@ -667,7 +670,6 @@ ncr_read(uint16_t port, void *priv) case 1: /* Initiator Command Register */ ncr_log("Read: Initiator Command register, NCR ICR Read=%02x\n", ncr->icr); - ret = ncr->icr; break; @@ -691,7 +693,7 @@ ncr_read(uint16_t port, void *priv) case 5: /* Bus and Status register */ ncr_log("Read: Bus and Status register\n"); - ret = 0; + ret = 0; bus = get_bus_host(ncr); ncr_log("Get host from Interrupt\n"); @@ -700,14 +702,15 @@ ncr_read(uint16_t port, void *priv) if ((bus & SCSI_PHASE_MESSAGE_IN) == (ncr->cur_bus & SCSI_PHASE_MESSAGE_IN)) { ncr_log("Phase match\n"); ret |= STATUS_PHASE_MATCH; - } else - picint(1 << ncr_dev->irq); + } ncr_bus_read(ncr_dev); bus = ncr->cur_bus; if (bus & BUS_ACK) ret |= STATUS_ACK; + if (bus & BUS_ATN) + ret |= 0x02; if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) { ncr_log("Entering DMA mode\n"); @@ -721,8 +724,10 @@ ncr_read(uint16_t port, void *priv) bus_state |= TCR_CD; if (bus & BUS_MSG) bus_state |= TCR_MSG; - if ((ncr->tcr & 7) != bus_state) - ncr->isr |= STATUS_INT; + if ((ncr->tcr & 7) != bus_state) { + ncr_irq(ncr_dev, ncr, 1); + ncr_log("IRQ issued\n"); + } } if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { ncr_log("Busy error\n"); @@ -731,10 +736,14 @@ ncr_read(uint16_t port, void *priv) ret |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); break; + case 6: + ret = ncr->tx_data; + break; + case 7: /* reset Parity/Interrupt */ - ncr->isr &= ~STATUS_INT; - picintc(1 << ncr_dev->irq); - ncr_log("Reset IRQ\n"); + ncr->isr &= ~(STATUS_BUSY_ERROR | 0x20); + ncr_irq(ncr_dev, ncr, 0); + ncr_log("Reset Interrupt\n"); break; default: @@ -779,10 +788,11 @@ memio_read(uint32_t addr, void *priv) break; case 0x3900: - if (ncr_dev->buffer_host_pos >= 128 || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) + if (ncr_dev->buffer_host_pos >= 128 || !(ncr_dev->status_ctrl & CTRL_DATA_DIR)) { ret = 0xff; - else { + } else { ret = ncr_dev->buffer[ncr_dev->buffer_host_pos++]; + ncr_log("Read Host pos = %i\n", ncr_dev->buffer_host_pos); if (ncr_dev->buffer_host_pos == 128) { ncr_log("Not ready\n"); @@ -829,6 +839,7 @@ static void memio_write(uint32_t addr, uint8_t val, void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *)priv; + ncr_t *ncr = &ncr_dev->ncr; addr &= 0x3fff; @@ -849,6 +860,8 @@ memio_write(uint32_t addr, uint8_t val, void *priv) if (!(ncr_dev->status_ctrl & CTRL_DATA_DIR) && ncr_dev->buffer_host_pos < 128) { ncr_dev->buffer[ncr_dev->buffer_host_pos++] = val; + ncr_log("Write host pos = %i\n", ncr_dev->buffer_host_pos); + if (ncr_dev->buffer_host_pos == 128) { ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; ncr_dev->ncr_busy = 1; @@ -871,11 +884,15 @@ memio_write(uint32_t addr, uint8_t val, void *priv) break; case 0x3981: /* block counter register */ - ncr_log("Write block counter register: val=%d\n", val); + ncr_log("Write block counter register: val=%d, dma mode = %i, period = %lf\n", val, ncr->dma_mode, ncr_dev->period); ncr_dev->block_count = val; ncr_dev->block_count_loaded = 1; - set_dma_enable(ncr_dev, ncr_dev->dma_enabled && ncr_dev->block_count_loaded); + if (ncr->mode & MODE_DMA) { + ncr_log("Start timer, buffer not ready = %02x\n", !(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)); + ncr_timer_on(ncr_dev, ncr, 0); + } + if (ncr_dev->status_ctrl & CTRL_DATA_DIR) { ncr_dev->buffer_host_pos = 128; ncr_dev->status_ctrl |= STATUS_BUFFER_NOT_READY; @@ -970,27 +987,131 @@ t130b_out(uint16_t port, uint8_t val, void *priv) } } +static void +ncr_dma_send(ncr5380_t *ncr_dev, ncr_t *ncr) +{ + scsi_device_t *dev = &scsi_devices[ncr->target_id]; + + int bus, c = 0; + uint8_t data; + + if (scsi_device_get_callback(dev) > 0.0) + ncr_timer_on(ncr_dev, ncr, 1); + + for (c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + if (c == 10) + return; + + /* Data ready. */ + data = ncr_dev->buffer[ncr_dev->buffer_pos]; + bus = get_bus_host(ncr) & ~BUS_DATAMASK; + bus |= BUS_SETDATA(data); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->buffer_pos++; + ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); + + if (ncr_dev->buffer_pos == 128) { + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->ncr_busy = 0; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of write transfer\n"); + ncr->tcr |= TCR_LAST_BYTE_SENT; + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR write irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + return; + } + ncr_dma_send(ncr_dev, ncr); +} + +static void +ncr_dma_initiator_receive(ncr5380_t *ncr_dev, ncr_t *ncr) +{ + scsi_device_t *dev = &scsi_devices[ncr->target_id]; + + int bus, c = 0; + uint8_t temp; + + if (scsi_device_get_callback(dev) > 0.0) + ncr_timer_on(ncr_dev, ncr, 1); + + for (c = 0; c < 10; c++) { + ncr_bus_read(ncr_dev); + if (ncr->cur_bus & BUS_REQ) + break; + } + + if (c == 10) + return; + + /* Data ready. */ + ncr_bus_read(ncr_dev); + temp = BUS_GETDATA(ncr->cur_bus); + + bus = get_bus_host(ncr); + + ncr_bus_update(ncr_dev, bus | BUS_ACK); + ncr_bus_update(ncr_dev, bus & ~BUS_ACK); + + ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; + ncr_log("Buffer pos for reading = %d\n", ncr_dev->buffer_pos); + + if (ncr_dev->buffer_pos == 128) { + ncr_dev->buffer_pos = 0; + ncr_dev->buffer_host_pos = 0; + ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; + ncr_dev->block_count = (ncr_dev->block_count - 1) & 0xff; + ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); + if (!ncr_dev->block_count) { + ncr_dev->block_count_loaded = 0; + ncr_log("IO End of read transfer\n"); + ncr->isr |= STATUS_END_OF_DMA; + timer_stop(&ncr_dev->timer); + if (ncr->mode & MODE_ENA_EOP_INT) { + ncr_log("NCR read irq\n"); + ncr_irq(ncr_dev, ncr, 1); + } + } + return; + } + ncr_dma_initiator_receive(ncr_dev, ncr); +} static void ncr_callback(void *priv) { ncr5380_t *ncr_dev = (ncr5380_t *)priv; ncr_t *ncr = &ncr_dev->ncr; - int bus, bt = 0, c = 0; - uint8_t temp, data; + scsi_device_t *dev = &scsi_devices[ncr->target_id]; - ncr_log("DMA mode=%d\n", ncr->dma_mode); + ncr_log("DMA mode=%d, status ctrl = %02x\n", ncr->dma_mode, ncr_dev->status_ctrl); - if (ncr->data_wait & 1) - ncr->clear_req = 3; - - if (ncr->dma_mode != DMA_IDLE) - dma_timer_on(ncr_dev); + if (ncr->dma_mode != DMA_IDLE && (ncr->mode & MODE_DMA) && ncr_dev->block_count_loaded && scsi_device_get_callback(dev) <= 0.0) + timer_on_auto(&ncr_dev->timer, 10.0); if (ncr->data_wait & 1) { + ncr->clear_req = 3; ncr->data_wait &= ~1; - if (ncr->dma_mode == DMA_IDLE) + if (ncr->dma_mode == DMA_IDLE) { return; + } } switch(ncr->dma_mode) { @@ -999,62 +1120,16 @@ ncr_callback(void *priv) ncr_log("DMA_SEND with DMA direction set wrong\n"); break; } - - ncr_log("Status for writing=%02x\n", ncr_dev->status_ctrl); - + if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { - ncr_log("Buffer ready\n"); + ncr_log("Write buffer status ready\n"); break; } if (!ncr_dev->block_count_loaded) break; - while (bt < 64) { - for (c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - if (c == 10) - break; - - /* Data ready. */ - data = ncr_dev->buffer[ncr_dev->buffer_pos]; - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(data); - - ncr_bus_update(priv, bus | BUS_ACK); - ncr_bus_update(priv, bus & ~BUS_ACK); - - bt++; - ncr_dev->buffer_pos++; - ncr_log("Buffer pos for writing = %d\n", ncr_dev->buffer_pos); - - if (ncr_dev->buffer_pos == 128) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->ncr_busy = 0; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 255; - ncr_log("Remaining blocks to be written=%d\n", ncr_dev->block_count); - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - set_dma_enable(ncr_dev, 0); - ncr_log("IO End of write transfer\n"); - - ncr->tcr |= TCR_LAST_BYTE_SENT; - ncr->isr |= STATUS_END_OF_DMA; - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR write irq\n"); - ncr->isr |= STATUS_INT; - picint(1 << ncr_dev->irq); - } - } - break; - } - } + ncr_dma_send(ncr_dev, ncr); break; case DMA_INITIATOR_RECEIVE: @@ -1063,59 +1138,15 @@ ncr_callback(void *priv) break; } - ncr_log("Status for reading=%02x\n", ncr_dev->status_ctrl); - - if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) + if (!(ncr_dev->status_ctrl & STATUS_BUFFER_NOT_READY)) { + ncr_log("Read buffer status ready\n"); break; + } if (!ncr_dev->block_count_loaded) break; - while (bt < 64) { - for (c = 0; c < 10; c++) { - ncr_bus_read(ncr_dev); - if (ncr->cur_bus & BUS_REQ) - break; - } - - if (c == 10) - break; - - /* Data ready. */ - ncr_bus_read(ncr_dev); - temp = BUS_GETDATA(ncr->cur_bus); - - bus = get_bus_host(ncr); - - ncr_bus_update(priv, bus | BUS_ACK); - ncr_bus_update(priv, bus & ~BUS_ACK); - - ncr_dev->buffer[ncr_dev->buffer_pos++] = temp; - bt++; - - if (ncr_dev->buffer_pos == 128) { - ncr_dev->buffer_pos = 0; - ncr_dev->buffer_host_pos = 0; - ncr_dev->status_ctrl &= ~STATUS_BUFFER_NOT_READY; - ncr_dev->block_count = (ncr_dev->block_count - 1) & 255; - - ncr_log("Remaining blocks to be read=%d\n", ncr_dev->block_count); - - if (!ncr_dev->block_count) { - ncr_dev->block_count_loaded = 0; - set_dma_enable(ncr_dev, 0); - ncr_log("IO End of read transfer\n"); - - ncr->isr |= STATUS_END_OF_DMA; - if (ncr->mode & MODE_ENA_EOP_INT) { - ncr_log("NCR read irq\n"); - ncr->isr |= STATUS_INT; - picint(1 << ncr_dev->irq); - } - } - break; - } - } + ncr_dma_initiator_receive(ncr_dev, ncr); break; } @@ -1125,7 +1156,7 @@ ncr_callback(void *priv) ncr_log("Updating DMA\n"); ncr->mode &= ~MODE_DMA; ncr->dma_mode = DMA_IDLE; - dma_changed(ncr_dev, ncr->dma_mode, ncr->mode & MODE_DMA); + timer_on_auto(&ncr_dev->timer, 10.0); } } @@ -1201,7 +1232,7 @@ ncr_init(const device_t *info) sprintf(&temp[strlen(temp)], " IRQ=%d", ncr_dev->irq); ncr_log("%s\n", temp); - ncr_reset(&ncr_dev->ncr); + ncr_reset(ncr_dev, &ncr_dev->ncr); ncr_dev->status_ctrl = STATUS_BUFFER_NOT_READY; ncr_dev->buffer_host_pos = 128; @@ -1277,6 +1308,9 @@ static const device_config_t ncr5380_mmio_config[] = { { "IRQ 5", 5 }, + { + "IRQ 7", 7 + }, { "" } @@ -1318,6 +1352,9 @@ static const device_config_t rancho_config[] = { { "IRQ 5", 5 }, + { + "IRQ 7", 7 + }, { "" } diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index e898e7d76..2ec5932c2 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -10,9 +10,6 @@ * Adapters made by NCR and later Symbios and LSI. These * controllers were designed for the PCI bus. * - * To do: Identify the type of serial EEPROM used and its - * interface. - * * * * Authors: Paul Brook (QEMU) @@ -48,7 +45,17 @@ #include <86box/scsi_device.h> #include <86box/scsi_ncr53c8xx.h> -#define NCR53C8XX_ROM L"roms/scsi/ncr53c8xx/NCR307.BIN" + +#define NCR53C810_SDMS3_ROM L"roms/scsi/ncr53c8xx/810/NCR307.BIN" +#define SYM53C810_SDMS4_ROM L"roms/scsi/ncr53c8xx/810/8XX_64.ROM" +#define NCR53C815_SDMS3_ROM L"roms/scsi/ncr53c8xx/815/NCR307.BIN" +#define SYM53C815_SDMS4_ROM L"roms/scsi/ncr53c8xx/815/8XX_64.ROM" +#define NCR53C825A_SDMS3_ROM L"roms/scsi/ncr53c8xx/825A/NCR307.BIN" +#define SYM53C825A_SDMS4_ROM L"roms/scsi/ncr53c8xx/825A/8XX_64.ROM" +#define NCR53C860_SDMS3_ROM L"roms/scsi/ncr53c8xx/860/NCR307.BIN" +#define SYM53C860_SDMS4_ROM L"roms/scsi/ncr53c8xx/860/8XX_64.ROM" +#define NCR53C875_SDMS3_ROM L"roms/scsi/ncr53c8xx/875/NCR307.BIN" +#define SYM53C875_SDMS4_ROM L"roms/scsi/ncr53c8xx/875/8XX_64.ROM" #define HA_ID 7 @@ -2231,13 +2238,11 @@ ncr53c8xx_ram_set_addr(ncr53c8xx_t *dev, uint32_t base) } -#ifdef USE_BIOS_BAR static void ncr53c8xx_bios_set_addr(ncr53c8xx_t *dev, uint32_t base) { mem_mapping_set_addr(&dev->bios.mapping, base, 0x10000); } -#endif static void @@ -2254,13 +2259,11 @@ ncr53c8xx_ram_disable(ncr53c8xx_t *dev) } -#ifdef USE_BIOS_BAR static void ncr53c8xx_bios_disable(ncr53c8xx_t *dev) { mem_mapping_disable(&dev->bios.mapping); } -#endif uint8_t ncr53c8xx_pci_regs[256]; @@ -2324,47 +2327,37 @@ ncr53c8xx_pci_read(int func, int addr, void *p) case 0x18: return 0; /*Memory space*/ case 0x19: - if (dev->chip < CHIP_825) + if (dev->chip == CHIP_815 || dev->chip < CHIP_825) return 0; return ncr53c8xx_pci_bar[2].addr_regs[1]; case 0x1A: - if (dev->chip < CHIP_825) + if (dev->chip == CHIP_815 || dev->chip < CHIP_825) return 0; return ncr53c8xx_pci_bar[2].addr_regs[2]; case 0x1B: - if (dev->chip < CHIP_825) + if (dev->chip == CHIP_815 || dev->chip < CHIP_825) return 0; return ncr53c8xx_pci_bar[2].addr_regs[3]; case 0x2C: return 0x00; case 0x2D: - if (dev->chip >= CHIP_825) + if (dev->chip >= CHIP_825 || dev->chip != CHIP_815) return 0; return 0x10; case 0x2E: - if (dev->chip >= CHIP_825) + if (dev->chip >= CHIP_825 || dev->chip != CHIP_815) return 0; return 0x01; case 0x2F: return 0x00; -#ifdef USE_BIOS_BAR case 0x30: - if ((dev->chip < CHIP_825) || !dev->has_bios) - return 0; - return ncr53c8xx_pci_bar[3].addr_regs[0]; + return ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01; case 0x31: - if ((dev->chip < CHIP_825) || !dev->has_bios) - return 0; return ncr53c8xx_pci_bar[3].addr_regs[1]; case 0x32: - if ((dev->chip < CHIP_825) || !dev->has_bios) - return 0; return ncr53c8xx_pci_bar[3].addr_regs[2]; case 0x33: - if ((dev->chip < CHIP_825) || !dev->has_bios) - return 0; return ncr53c8xx_pci_bar[3].addr_regs[3]; -#endif case 0x3C: return dev->irq; case 0x3D: @@ -2405,7 +2398,7 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) ncr53c8xx_mem_disable(dev); if ((dev->MMIOBase != 0) && (val & PCI_COMMAND_MEM)) ncr53c8xx_mem_set_addr(dev, dev->MMIOBase); - if (dev->chip >= CHIP_825) { + if (dev->chip != CHIP_815 || dev->chip >= CHIP_825) { ncr53c8xx_ram_disable(dev); if ((dev->RAMBase != 0) && (val & PCI_COMMAND_MEM)) ncr53c8xx_ram_set_addr(dev, dev->RAMBase); @@ -2449,8 +2442,8 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) /* Then let's set the PCI regs. */ ncr53c8xx_pci_bar[1].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[1].addr &= 0xffffc000; - dev->MMIOBase = ncr53c8xx_pci_bar[1].addr & 0xffffc000; + ncr53c8xx_pci_bar[1].addr &= 0xfffcf000; + dev->MMIOBase = ncr53c8xx_pci_bar[1].addr & 0xfffcf000; /* Log the new base. */ ncr53c8xx_log("NCR53c8xx: New MMIO base is %08X\n" , dev->MMIOBase); /* We're done, so get out of the here. */ @@ -2461,7 +2454,7 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) return; case 0x19: case 0x1A: case 0x1B: - if (dev->chip < CHIP_825) + if (dev->chip == CHIP_815 || dev->chip < CHIP_825) return; /* RAM Base set. */ /* First, remove the old I/O. */ @@ -2469,8 +2462,8 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) /* Then let's set the PCI regs. */ ncr53c8xx_pci_bar[2].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[2].addr &= 0xffffc000; - dev->RAMBase = ncr53c8xx_pci_bar[2].addr & 0xffffc000; + ncr53c8xx_pci_bar[2].addr &= 0xfffcf000; + dev->RAMBase = ncr53c8xx_pci_bar[2].addr & 0xfffcf000; /* Log the new base. */ ncr53c8xx_log("NCR53c8xx: New RAM base is %08X\n" , dev->RAMBase); /* We're done, so get out of the here. */ @@ -2480,10 +2473,8 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) } return; -#ifdef USE_BIOS_BAR case 0x30: case 0x31: case 0x32: case 0x33: - return; - if ((dev->chip < CHIP_825) || !dev->has_bios) + if (dev->has_bios == 0) return; /* BIOS Base set. */ /* First, remove the old I/O. */ @@ -2491,15 +2482,15 @@ ncr53c8xx_pci_write(int func, int addr, uint8_t val, void *p) /* Then let's set the PCI regs. */ ncr53c8xx_pci_bar[3].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - ncr53c8xx_pci_bar[3].addr &= 0xffff0001; - dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & 0xffff0000; + ncr53c8xx_pci_bar[3].addr &= 0xfffcf001; + dev->BIOSBase = ncr53c8xx_pci_bar[3].addr & 0xfffcf000; /* Log the new base. */ ncr53c8xx_log("NCR53c8xx: New BIOS base is %08X\n" , dev->BIOSBase); /* We're done, so get out of the here. */ - if (ncr53c8xx_pci_bar[3].addr & 0x00000001) + if (ncr53c8xx_pci_bar[3].addr_regs[0] & 0x01) { ncr53c8xx_bios_set_addr(dev, dev->BIOSBase); - return; -#endif + } + return; case 0x3C: ncr53c8xx_pci_regs[addr] = val; @@ -2518,52 +2509,74 @@ ncr53c8xx_init(const device_t *info) memset(dev, 0x00, sizeof(ncr53c8xx_t)); dev->chip_rev = 0; - // dev->pci_slot = pci_add_card(PCI_ADD_SCSI, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); dev->pci_slot = pci_add_card(PCI_ADD_NORMAL, ncr53c8xx_pci_read, ncr53c8xx_pci_write, dev); - ncr53c8xx_pci_bar[0].addr_regs[0] = 1; - ncr53c8xx_pci_bar[1].addr_regs[0] = 0; dev->chip = info->local & 0xff; - ncr53c8xx_pci_regs[0x04] = 3; - - ncr53c8xx_mem_init(dev, 0x0fffff00); - ncr53c8xx_mem_disable(dev); - if (info->local & 0x8000) dev->has_bios = 0; else dev->has_bios = device_get_config_int("bios"); - if (dev->has_bios) - rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (dev->chip >= CHIP_825) { - if (dev->chip == CHIP_875) { - dev->chip_rev = 0x04; - dev->nvr_path = L"ncr53c875.nvr"; - } else if (dev->chip == CHIP_860) { - dev->chip_rev = 0x04; - dev->nvr_path = L"ncr53c860.nvr"; - } else { - dev->chip_rev = 0x26; - dev->nvr_path = L"ncr53c825a.nvr"; - } - ncr53c8xx_pci_bar[2].addr_regs[0] = 0; - ncr53c8xx_pci_bar[3].addr = 0xffff0000; + if (dev->chip == CHIP_875) { + if (dev->has_bios == 2) + rom_init(&dev->bios, SYM53C875_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else if (dev->has_bios == 1) + rom_init(&dev->bios, NCR53C875_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + dev->chip_rev = 0x04; + dev->nvr_path = L"ncr53c875.nvr"; + } else if (dev->chip == CHIP_860) { + if (dev->has_bios == 2) + rom_init(&dev->bios, SYM53C860_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else if (dev->has_bios == 1) + rom_init(&dev->bios, NCR53C860_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + dev->chip_rev = 0x04; + dev->nvr_path = L"ncr53c860.nvr"; + } else if (dev->chip == CHIP_825) { + if (dev->has_bios == 2) + rom_init(&dev->bios, SYM53C825A_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else if (dev->has_bios == 1) + rom_init(&dev->bios, NCR53C825A_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + dev->chip_rev = 0x26; + dev->nvr_path = L"ncr53c825a.nvr"; + } else if (dev->chip == CHIP_810) { + if (dev->has_bios == 2) + rom_init(&dev->bios, SYM53C810_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else if (dev->has_bios == 1) + rom_init(&dev->bios, NCR53C810_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + dev->nvr_path = L"ncr53c810.nvr"; + } else if (dev->chip == CHIP_815) { + if (dev->has_bios == 2) + rom_init(&dev->bios, SYM53C815_SDMS4_ROM, 0xc8000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else if (dev->has_bios == 1) + rom_init(&dev->bios, NCR53C815_SDMS3_ROM, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + dev->chip_rev = 0x04; + dev->nvr_path = L"ncr53c815.nvr"; + } + + ncr53c8xx_pci_bar[0].addr_regs[0] = 1; + ncr53c8xx_pci_bar[1].addr_regs[0] = 0; + ncr53c8xx_pci_regs[0x04] = 3; + + if (dev->has_bios) { + ncr53c8xx_pci_bar[3].addr = 0xffffc000; + } else { + ncr53c8xx_pci_bar[3].addr = 0; + } + + ncr53c8xx_mem_init(dev, 0x0fffff00); + ncr53c8xx_mem_disable(dev); + + ncr53c8xx_pci_bar[2].addr_regs[0] = 0; + + if (dev->chip >= CHIP_825 || (dev->chip != CHIP_815)) { /* Need to make it align on a 16k boundary as that's this emulator's memory mapping granularity. */ ncr53c8xx_ram_init(dev, 0x0fffc000); ncr53c8xx_ram_disable(dev); - -#ifdef USE_BIOS_BAR - if (dev->has_bios) - ncr53c8xx_bios_disable(dev); -#endif - } else { - /* if (dev->has_bios) - rom_init(&dev->bios, NCR53C8XX_ROM, 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); */ - - dev->nvr_path = L"ncr53c810.nvr"; } + + if (dev->has_bios) + ncr53c8xx_bios_disable(dev); dev->i2c = i2c_gpio_init("nvr_ncr53c8xx"); dev->eeprom = i2c_eeprom_init(i2c_gpio_get_bus(dev->i2c), 0x50, dev->nvram, sizeof(dev->nvram), 1); @@ -2599,11 +2612,24 @@ ncr53c8xx_close(void *priv) } } - static const device_config_t ncr53c8xx_pci_config[] = { - { - "bios", "Enable BIOS", CONFIG_BINARY, "", 0 - }, + { + "bios", "BIOS", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { + "SDMS 4.x BIOS", 2 + }, + { + "SDMS 3.x BIOS", 1 + }, + { + "Disable BIOS", 0 + }, + { + "" + } + }, + }, { "", "", -1 } @@ -2612,9 +2638,9 @@ static const device_config_t ncr53c8xx_pci_config[] = { const device_t ncr53c810_pci_device = { - "NCR 53C810", + "NCR 53c810", DEVICE_PCI, - 0x01, + CHIP_810, ncr53c8xx_init, ncr53c8xx_close, NULL, { NULL }, NULL, NULL, ncr53c8xx_pci_config @@ -2622,7 +2648,7 @@ const device_t ncr53c810_pci_device = const device_t ncr53c810_onboard_pci_device = { - "NCR 53C810 On-Board", + "NCR 53c810 On-Board", DEVICE_PCI, 0x8001, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2630,9 +2656,19 @@ const device_t ncr53c810_onboard_pci_device = NULL }; +const device_t ncr53c815_pci_device = +{ + "NCR 53c815", + DEVICE_PCI, + CHIP_815, + ncr53c8xx_init, ncr53c8xx_close, NULL, + { NULL }, NULL, NULL, + ncr53c8xx_pci_config +}; + const device_t ncr53c825a_pci_device = { - "NCR 53C825A", + "NCR 53c825A", DEVICE_PCI, CHIP_825, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2642,7 +2678,7 @@ const device_t ncr53c825a_pci_device = const device_t ncr53c860_pci_device = { - "NCR 53C860", + "NCR 53c860", DEVICE_PCI, CHIP_860, ncr53c8xx_init, ncr53c8xx_close, NULL, @@ -2652,7 +2688,7 @@ const device_t ncr53c860_pci_device = const device_t ncr53c875_pci_device = { - "NCR 53C875", + "NCR 53c875", DEVICE_PCI, CHIP_875, ncr53c8xx_init, ncr53c8xx_close, NULL, diff --git a/src/sio/CMakeLists.txt b/src/sio/CMakeLists.txt new file mode 100644 index 000000000..8dcb8416e --- /dev/null +++ b/src/sio/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(sio OBJECT sio_acc3221.c sio_f82c710.c sio_82091aa.c sio_fdc37c661.c + sio_fdc37c66x.c sio_fdc37c669.c sio_fdc37c93x.c sio_fdc37m60x.c + sio_pc87306.c sio_pc87307.c sio_pc87309.c sio_pc87311.c sio_pc87332.c + sio_prime3c.c sio_w83787f.c sio_w83877f.c sio_w83977f.c sio_um8669f.c + sio_vt82c686.c) + +if(SIO_DETECT) + target_sources(sio PRIVATE sio_detect.c) +endif() \ No newline at end of file diff --git a/src/sio/sio_fdc37c66x.c b/src/sio/sio_fdc37c66x.c index 970925e14..6f8797f13 100644 --- a/src/sio/sio_fdc37c66x.c +++ b/src/sio/sio_fdc37c66x.c @@ -282,8 +282,6 @@ fdc37c66x_init(const device_t *info) dev->chip_id = info->local & 0xff; dev->has_ide = !!(info->local & 0x100); - if (dev->has_ide) - io_sethandler(0x03f0, 0x0002, fdc37c66x_read, NULL, NULL, fdc37c66x_write, NULL, NULL, dev); diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c new file mode 100644 index 000000000..ca0111405 --- /dev/null +++ b/src/sio/sio_fdc37m60x.c @@ -0,0 +1,321 @@ +/* + * 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 SMSC FDC37M60x Super I/O + * + * Authors: Tiseno100 + * Copyright 2020 Tiseno100 + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/keyboard.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + +#define SIO_INDEX_PORT dev->sio_index_port +#define INDEX dev->index + +/* Current Logical Device Number */ +#define CURRENT_LOGICAL_DEVICE dev->regs[0x07] + +/* Global Device Configuration */ +#define ENABLED dev->device_regs[CURRENT_LOGICAL_DEVICE][0x30] +#define BASE_ADDRESS ((dev->device_regs[CURRENT_LOGICAL_DEVICE][0x60] << 8) | (dev->device_regs[CURRENT_LOGICAL_DEVICE][0x61])) +#define IRQ dev->device_regs[CURRENT_LOGICAL_DEVICE][0x70] +#define DMA dev->device_regs[CURRENT_LOGICAL_DEVICE][0x74] + +/* Miscellaneous Chip Functionality */ +#define SOFT_RESET (val & 0x01) +#define POWER_CONTROL dev->regs[0x22] + +#ifdef ENABLE_FDC37M60X_LOG +int fdc37m60x_do_log = ENABLE_FDC37M60X_LOG; +static void +fdc37m60x_log(const char *fmt, ...) +{ + va_list ap; + + if (fdc37m60x_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define fdc37m60x_log(fmt, ...) +#endif + +typedef struct +{ + uint8_t index, regs[256], device_regs[10][256], cfg_lock, ide_function; + uint16_t sio_index_port; + + fdc_t *fdc_controller; + serial_t *uart[2]; + +} fdc37m60x_t; + +void fdc37m60x_fdc_handler(fdc37m60x_t *dev); +void fdc37m60x_uart_handler(uint8_t num, fdc37m60x_t *dev); +void fdc37m60x_lpt_handler(fdc37m60x_t *dev); +void fdc37m60x_logical_device_handler(fdc37m60x_t *dev); +static void fdc37m60x_reset(void *priv); + +static void +fdc37m60x_write(uint16_t addr, uint8_t val, void *priv) +{ + fdc37m60x_t *dev = (fdc37m60x_t *)priv; + + switch (addr) + { + case 0x3f0: + case 0x370: + INDEX = val; + + /* Enter/Escape Configuration Mode */ + if (val == 0x55) + dev->cfg_lock = 0; + else if (val == 0xaa) + dev->cfg_lock = 1; + break; + + case 0x3f1: + case 0x371: + if (!dev->cfg_lock) + { + switch (INDEX) + { + /* Global Configuration */ + case 0x02: + dev->regs[INDEX] = val; + if (SOFT_RESET) + fdc37m60x_reset(dev); + break; + + case 0x07: + CURRENT_LOGICAL_DEVICE = (val & 0x0f); + break; + + case 0x22: + POWER_CONTROL = val & 0x3f; + break; + + case 0x23: + dev->regs[INDEX] = val & 0x3f; + break; + + case 0x24: + dev->regs[INDEX] = val & 0xce; + break; + + /* Device Configuration */ + case 0x30: + case 0x60: + case 0x61: + case 0x70: + case 0x74: + if(CURRENT_LOGICAL_DEVICE <= 0x81) /* Avoid Overflow */ + dev->device_regs[CURRENT_LOGICAL_DEVICE][INDEX] = (INDEX == 0x30) ? (val & 1) : val; + fdc37m60x_logical_device_handler(dev); + break; + } + } + break; + } +} + +static uint8_t +fdc37m60x_read(uint16_t addr, void *priv) +{ + fdc37m60x_t *dev = (fdc37m60x_t *)priv; + + return (INDEX >= 0x30) ? dev->device_regs[CURRENT_LOGICAL_DEVICE][INDEX] : dev->regs[INDEX]; +} + +void fdc37m60x_fdc_handler(fdc37m60x_t *dev) +{ + fdc_remove(dev->fdc_controller); + if(ENABLED || (POWER_CONTROL & 0x01)) + { + fdc_set_base(dev->fdc_controller, BASE_ADDRESS); + fdc_set_irq(dev->fdc_controller, IRQ & 0xf); + fdc_set_dma_ch(dev->fdc_controller, DMA & 0x07); + fdc37m60x_log("SMC60x-FDC: BASE %04x IRQ %d DMA %d\n", BASE_ADDRESS, IRQ & 0xf, DMA & 0x07); + } +} + +void fdc37m60x_uart_handler(uint8_t num, fdc37m60x_t *dev) +{ + serial_remove(dev->uart[num & 1]); + if(!(num & 1) ? (ENABLED || (POWER_CONTROL & 0x10)) : (ENABLED || (POWER_CONTROL & 0x20))) + { + serial_setup(dev->uart[num & 1], BASE_ADDRESS, IRQ & 0xf); + fdc37m60x_log("SMC60x-UART%d: BASE %04x IRQ %d\n", num & 1, BASE_ADDRESS, IRQ & 0xf); + } +} + +void fdc37m60x_lpt_handler(fdc37m60x_t *dev) +{ + lpt1_remove(); + if(ENABLED || (POWER_CONTROL & 0x80)) + { + lpt1_init(BASE_ADDRESS); + lpt1_irq(IRQ & 0xf); + fdc37m60x_log("SMC60x-LPT: BASE %04x IRQ %d\n", BASE_ADDRESS, IRQ & 0xf); + } +} + +void fdc37m60x_logical_device_handler(fdc37m60x_t *dev) +{ +/* +Register 07h: +Device 0: FDC +Device 3: LPT +Device 4: UART1 +Device 5: UART2 +*/ + switch (CURRENT_LOGICAL_DEVICE) + { + case 0x00: + fdc37m60x_fdc_handler(dev); + break; + + case 0x03: + fdc37m60x_lpt_handler(dev); + break; + + case 0x04: + fdc37m60x_uart_handler(0, dev); + break; + + case 0x05: + fdc37m60x_uart_handler(1, dev); + break; + } +} + +static void +fdc37m60x_reset(void *priv) +{ + fdc37m60x_t *dev = (fdc37m60x_t *)priv; + + CURRENT_LOGICAL_DEVICE = 0x00; + dev->regs[0x22] = 0x00; + dev->regs[0x26] = SIO_INDEX_PORT & 0xf; + dev->regs[0x27] = (SIO_INDEX_PORT >> 4) & 0xf; + + /* FDC Registers */ + dev->device_regs[0][0x30] = 0x00; + dev->device_regs[0][0x60] = 0x03; /* Base Address */ + dev->device_regs[0][0x61] = 0xf0; + + dev->device_regs[0][0x70] = 0x06; + dev->device_regs[0][0x74] = 0x02; + + /* LPT Port */ + dev->device_regs[3][0x30] = 0x00; + dev->device_regs[3][0x60] = 0x00; /* Base Address */ + dev->device_regs[3][0x61] = 0x00; + + dev->device_regs[3][0x64] = 0x04; + + /* UART1 */ + dev->device_regs[4][0x30] = 0x00; + dev->device_regs[4][0x60] = 0x00; /* Base Address */ + dev->device_regs[4][0x61] = 0x00; + + dev->device_regs[4][0x70] = 0x00; + + /* UART2 */ + dev->device_regs[5][0x30] = 0x00; + dev->device_regs[5][0x60] = 0x00; /* Base Address */ + dev->device_regs[5][0x61] = 0x00; + + dev->device_regs[5][0x70] = 0x00; + + /* AUX */ + dev->device_regs[8][0x30] = 0x00; + + fdc37m60x_fdc_handler(dev); + fdc37m60x_uart_handler(0, dev); + fdc37m60x_uart_handler(1, dev); + fdc37m60x_lpt_handler(dev); +} + +static void +fdc37m60x_close(void *priv) +{ + fdc37m60x_t *dev = (fdc37m60x_t *)priv; + + free(dev); +} + +static void * +fdc37m60x_init(const device_t *info) +{ + fdc37m60x_t *dev = (fdc37m60x_t *)malloc(sizeof(fdc37m60x_t)); + memset(dev, 0, sizeof(fdc37m60x_t)); + SIO_INDEX_PORT = info->local; + + dev->regs[0x20] = 0x47; + dev->regs[0x24] = 0x04; + dev->device_regs[0][0xf0] = 0x0e; + dev->device_regs[0][0xf2] = 0xff; + dev->device_regs[3][0xf0] = 0x3c; + dev->device_regs[4][0xf1] = 0x02; + dev->device_regs[4][0xf2] = 0x03; + dev->device_regs[8][0xc0] = 0x06; + dev->device_regs[8][0xc1] = 0x03; + + dev->fdc_controller = device_add(&fdc_at_smc_device); + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + io_sethandler(SIO_INDEX_PORT, 0x0002, fdc37m60x_read, NULL, NULL, fdc37m60x_write, NULL, NULL, dev); + + return dev; +} + +const device_t fdc37m60x_device = { + "SMSC FDC37M60X", + 0, + 0x03f0, + fdc37m60x_init, + fdc37m60x_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; + +const device_t fdc37m60x_370_device = { + "SMSC FDC37M60X with 10K Pull Up Resistor", + 0, + 0x0370, + fdc37m60x_init, + fdc37m60x_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/sio/sio_pc87311.c b/src/sio/sio_pc87311.c new file mode 100644 index 000000000..2fff65d6c --- /dev/null +++ b/src/sio/sio_pc87311.c @@ -0,0 +1,297 @@ +/* + * 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 National Semiconductor PC87311 Super I/O + * + * Authors: Tiseno100 + * Copyright 2020 Tiseno100 + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + +#define HAS_IDE_FUNCTIONALITY dev->ide_function + +/* Basic Functionalities */ +#define FUNCTION_ENABLE dev->regs[0x00] +#define FUNCTION_ADDRESS dev->regs[0x01] +#define POWER_TEST dev->regs[0x02] + +/* Base Addresses */ +#define LPT_BA (FUNCTION_ADDRESS & 0x03) +#define UART1_BA ((FUNCTION_ADDRESS >> 2) & 0x03) +#define UART2_BA ((FUNCTION_ADDRESS >> 4) & 0x03) +#define COM_BA ((FUNCTION_ADDRESS >> 6) & 0x03) + +#ifdef ENABLE_PC87311_LOG +int pc87311_do_log = ENABLE_PC87311_LOG; +static void +pc87311_log(const char *fmt, ...) +{ + va_list ap; + + if (pc87311_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define pc87311_log(fmt, ...) +#endif + +typedef struct +{ + uint8_t index, regs[256], cfg_lock, ide_function; + uint16_t base, irq; + fdc_t *fdc_controller; + serial_t *uart[2]; + +} pc87311_t; + +void pc87311_fdc_handler(pc87311_t *dev); +void pc87311_uart_handler(uint8_t num, pc87311_t *dev); +void pc87311_lpt_handler(pc87311_t *dev); +void pc87311_ide_handler(pc87311_t *dev); +void pc87311_enable(pc87311_t *dev); + +static void +pc87311_write(uint16_t addr, uint8_t val, void *priv) +{ + pc87311_t *dev = (pc87311_t *)priv; + + switch (addr) + { + case 0x398: + case 0x26e: + dev->index = val; + break; + + case 0x399: + case 0x26f: + switch (dev->index) + { + case 0x00: + FUNCTION_ENABLE = val; + break; + case 0x01: + FUNCTION_ADDRESS = val; + break; + case 0x02: + POWER_TEST = val; + break; + } + break; + } + + pc87311_enable(dev); +} + +static uint8_t +pc87311_read(uint16_t addr, void *priv) +{ + pc87311_t *dev = (pc87311_t *)priv; + + return dev->regs[dev->index]; +} + +void pc87311_fdc_handler(pc87311_t *dev) +{ + fdc_remove(dev->fdc_controller); + fdc_set_base(dev->fdc_controller, (FUNCTION_ENABLE & 0x20) ? 0x0370 : 0x03f0); + pc87311_log("PC87311-FDC: BASE %04x\n", (FUNCTION_ENABLE & 0x20) ? 0x0370 : 0x03f0); +} + +uint16_t com3(pc87311_t *dev) +{ + switch (COM_BA) + { + case 0: + return 0x03e8; + case 1: + return 0x0338; + case 2: + return 0x02e8; + case 3: + return 0x0220; + default: + return 0x03e8; + } +} + +uint16_t com4(pc87311_t *dev) +{ + switch (COM_BA) + { + case 0: + return 0x02e8; + case 1: + return 0x0238; + case 2: + return 0x02e0; + case 3: + return 0x0228; + default: + return 0x02e8; + } +} + +void pc87311_uart_handler(uint8_t num, pc87311_t *dev) +{ + serial_remove(dev->uart[num & 1]); + + switch ((!num & 1) ? UART1_BA : UART2_BA) + { + case 0: + dev->base = 0x03f8; + dev->irq = 4; + break; + case 1: + dev->base = 0x02f8; + dev->irq = 3; + break; + case 2: + dev->base = com3(dev); + dev->irq = 4; + break; + case 3: + dev->base = com4(dev); + dev->irq = 3; + break; + } + serial_setup(dev->uart[num & 1], dev->base, dev->irq); + pc87311_log("PC87311-UART%01x: BASE %04x IRQ %01x\n", num & 1, dev->base, dev->irq); +} + +void pc87311_lpt_handler(pc87311_t *dev) +{ + lpt1_remove(); + switch (LPT_BA) + { + case 0: + dev->base = 0x0378; + dev->irq = (POWER_TEST & 0x08) ? 7 : 5; + break; + case 1: + dev->base = 0x03bc; + dev->irq = 7; + break; + case 2: + dev->base = 0x0278; + dev->irq = 5; + break; + } + lpt1_init(dev->base); + lpt1_irq(dev->irq); + pc87311_log("PC87311-LPT: BASE %04x IRQ %01x\n", dev->base, dev->irq); +} + +void pc87311_ide_handler(pc87311_t *dev) +{ + ide_pri_disable(); + ide_sec_disable(); + + ide_set_base(0, 0x1f0); + ide_set_side(0, 0x3f6); + ide_pri_enable(); + + if (FUNCTION_ENABLE & 0x80) + { + ide_set_base(1, 0x170); + ide_set_side(1, 0x376); + ide_sec_enable(); + } + pc87311_log("PC87311-IDE: PRI %01x SEC %01x\n", (FUNCTION_ENABLE >> 6) & 1, (FUNCTION_ENABLE >> 7) & 1); +} + +void pc87311_enable(pc87311_t *dev) +{ + (FUNCTION_ENABLE & 0x01) ? pc87311_lpt_handler(dev) : lpt1_remove(); + (FUNCTION_ENABLE & 0x02) ? pc87311_uart_handler(0, dev) : serial_remove(dev->uart[0]); + (FUNCTION_ENABLE & 0x04) ? pc87311_uart_handler(1, dev) : serial_remove(dev->uart[1]); + (FUNCTION_ENABLE & 0x08) ? pc87311_fdc_handler(dev) : fdc_remove(dev->fdc_controller); + if (FUNCTION_ENABLE & 0x20) + pc87311_fdc_handler(dev); + if (HAS_IDE_FUNCTIONALITY) + { + (FUNCTION_ENABLE & 0x40) ? pc87311_ide_handler(dev) : ide_pri_disable(); + (FUNCTION_ADDRESS & 0x80) ? pc87311_ide_handler(dev) : ide_sec_disable(); + } +} + +static void +pc87311_close(void *priv) +{ + pc87311_t *dev = (pc87311_t *)priv; + + free(dev); +} + +static void * +pc87311_init(const device_t *info) +{ + pc87311_t *dev = (pc87311_t *)malloc(sizeof(pc87311_t)); + memset(dev, 0, sizeof(pc87311_t)); + + /* Avoid conflicting with machines that make no use of the PC87311 Internal IDE */ + HAS_IDE_FUNCTIONALITY = info->local; + + dev->fdc_controller = device_add(&fdc_at_nsc_device); + dev->uart[0] = device_add_inst(&ns16450_device, 1); + dev->uart[1] = device_add_inst(&ns16450_device, 2); + + if (HAS_IDE_FUNCTIONALITY) + device_add(&ide_isa_2ch_device); + + io_sethandler(0x0398, 0x0002, pc87311_read, NULL, NULL, pc87311_write, NULL, NULL, dev); + io_sethandler(0x026e, 0x0002, pc87311_read, NULL, NULL, pc87311_write, NULL, NULL, dev); + + pc87311_enable(dev); + + return dev; +} + +const device_t pc87311_device = { + "National Semiconductor PC87311", + 0, + 0, + pc87311_init, + pc87311_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; + +const device_t pc87311_ide_device = { + "National Semiconductor PC87311 with IDE functionality", + 0, + 1, + pc87311_init, + pc87311_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/sio/sio_prime3c.c b/src/sio/sio_prime3c.c new file mode 100644 index 000000000..b18e274fa --- /dev/null +++ b/src/sio/sio_prime3c.c @@ -0,0 +1,341 @@ +/* + * 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 LG Prime3C Super I/O + * + * Authors: Tiseno100 + * Copyright 2020 Tiseno100 + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/serial.h> +#include <86box/hdc.h> +#include <86box/hdc_ide.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/sio.h> + +#ifdef ENABLE_PRIME3C_LOG +int prime3c_do_log = ENABLE_PRIME3C_LOG; +static void +prime3c_log(const char *fmt, ...) +{ + va_list ap; + + if (prime3c_do_log) + { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +#define prime3c_log(fmt, ...) +#endif + +/* Function Select(Note on prime3c_enable) */ +#define FUNCTION_SELECT dev->regs[0xc2] + +/* Base Address Registers */ +#define FDC_BASE_ADDRESS dev->regs[0xc3] +#define IDE_BASE_ADDRESS dev->regs[0xc4] +#define IDE_SIDE_ADDRESS dev->regs[0xc5] +#define LPT_BASE_ADDRESS dev->regs[0xc6] +#define UART1_BASE_ADDRESS dev->regs[0xc7] +#define UART2_BASE_ADDRESS dev->regs[0xc8] + +/* FDC/LPT Configuration */ +#define FDC_LPT_DMA dev->regs[0xc9] +#define FDC_LPT_IRQ dev->regs[0xca] + +/* UART 1/2 Configuration */ +#define UART_IRQ dev->regs[0xcb] + +/* Miscellaneous Configuration*/ +#define FDC_SWAP (dev->regs[0xd6] & 0x01) + +/* IDE functionality(Note on Init) */ +#define HAS_IDE_FUNCTIONALITY dev->ide_function + +typedef struct +{ + uint8_t index, regs[256], cfg_lock, ide_function; + + fdc_t *fdc_controller; + serial_t *uart[2]; + +} prime3c_t; + +void prime3c_fdc_handler(prime3c_t *dev); +void prime3c_uart_handler(uint8_t num, prime3c_t *dev); +void prime3c_lpt_handler(prime3c_t *dev); +void prime3c_ide_handler(prime3c_t *dev); +void prime3c_enable(prime3c_t *dev); + +static void +prime3c_write(uint16_t addr, uint8_t val, void *priv) +{ + prime3c_t *dev = (prime3c_t *)priv; + + switch (addr) + { + case 0x398: + dev->index = val; + + /* Enter/Escape Configuration Mode */ + if (val == 0x33) + dev->cfg_lock = 0; + else if (val == 0x55) + dev->cfg_lock = 1; + break; + + case 0x399: + if (!dev->cfg_lock) + { + switch (dev->index) + { + case 0xc2: + FUNCTION_SELECT = val & 0xbf; + prime3c_enable(dev); + break; + + case 0xc3: + FDC_BASE_ADDRESS = val & 0xfc; + prime3c_fdc_handler(dev); + break; + + case 0xc4: + IDE_BASE_ADDRESS = val & 0xfc; + if (HAS_IDE_FUNCTIONALITY) + prime3c_ide_handler(dev); + break; + + case 0xc5: + IDE_SIDE_ADDRESS = (val & 0xfc) | 0x02; + prime3c_ide_handler(dev); + break; + + case 0xc6: + LPT_BASE_ADDRESS = val; + break; + + case 0xc7: + UART1_BASE_ADDRESS = val & 0xfe; + prime3c_uart_handler(0, dev); + break; + + case 0xc8: + UART2_BASE_ADDRESS = val & 0xfe; + prime3c_uart_handler(1, dev); + break; + + case 0xc9: + FDC_LPT_DMA = val; + prime3c_fdc_handler(dev); + break; + + case 0xca: + FDC_LPT_IRQ = val; + prime3c_fdc_handler(dev); + prime3c_lpt_handler(dev); + break; + + case 0xcb: + UART_IRQ = val; + prime3c_uart_handler(0, dev); + prime3c_uart_handler(1, dev); + break; + + case 0xcd: + case 0xce: + dev->regs[dev->index] = val; + break; + + case 0xcf: + dev->regs[dev->index] = val & 0x3f; + break; + + case 0xd0: + dev->regs[dev->index] = val & 0xfc; + break; + + case 0xd1: + dev->regs[dev->index] = val & 0x3f; + break; + + case 0xd3: + dev->regs[dev->index] = val & 0x7c; + break; + + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + dev->regs[dev->index] = val; + break; + } + } + break; + } +} + +static uint8_t +prime3c_read(uint16_t addr, void *priv) +{ + prime3c_t *dev = (prime3c_t *)priv; + + return dev->regs[dev->index]; +} + +void prime3c_fdc_handler(prime3c_t *dev) +{ + fdc_remove(dev->fdc_controller); + if (FUNCTION_SELECT & 0x10) + { + fdc_set_base(dev->fdc_controller, FDC_BASE_ADDRESS << 2); + fdc_set_irq(dev->fdc_controller, (FDC_LPT_IRQ >> 4) & 0xf); + fdc_set_dma_ch(dev->fdc_controller, (FDC_LPT_DMA >> 4) & 0xf); + fdc_set_swap(dev->fdc_controller, FDC_SWAP); + prime3c_log("Prime3C-FDC: BASE %04x IRQ %01x DMA %01x\n", FDC_BASE_ADDRESS << 2, (FDC_LPT_IRQ >> 4) & 0xf, (FDC_LPT_DMA >> 4) & 0xf); + } +} + +void prime3c_uart_handler(uint8_t num, prime3c_t *dev) +{ + serial_remove(dev->uart[num & 1]); + if (FUNCTION_SELECT & (!(num & 1) ? 0x04 : 0x08)) + { + serial_setup(dev->uart[num & 1], (!(num & 1) ? UART1_BASE_ADDRESS : UART2_BASE_ADDRESS) << 2, (UART_IRQ >> (!(num & 1) ? 4 : 0)) & 0xf); + prime3c_log("Prime3C-UART%01x: BASE %04x IRQ %01x\n", num & 1, (!(num & 1) ? UART1_BASE_ADDRESS : UART2_BASE_ADDRESS) << 2, (UART_IRQ >> (!(num & 1) ? 4 : 0)) & 0xf); + } +} + +void prime3c_lpt_handler(prime3c_t *dev) +{ + lpt1_remove(); + if (!(FUNCTION_SELECT & 0x03)) + { + + lpt1_init(LPT_BASE_ADDRESS << 2); + lpt1_irq(FDC_LPT_IRQ & 0xf); + prime3c_log("Prime3C-LPT: BASE %04x IRQ %02x\n", LPT_BASE_ADDRESS << 2, FDC_LPT_IRQ & 0xf); + } +} + +void prime3c_ide_handler(prime3c_t *dev) +{ + ide_pri_disable(); + if (FUNCTION_SELECT & 0x20) + { + ide_set_base(0, IDE_BASE_ADDRESS << 2); + ide_set_side(0, IDE_SIDE_ADDRESS << 2); + ide_pri_enable(); + prime3c_log("Prime3C-IDE: BASE %04x SIDE %04x\n", IDE_BASE_ADDRESS << 2, IDE_SIDE_ADDRESS << 2); + } +} + +void prime3c_enable(prime3c_t *dev) +{ +/* +Simulate a device enable/disable scenario + +Register C2: Function Select +Bit 7: Gameport +Bit 6: Reserved +Bit 5: IDE +Bit 4: FDC +Bit 3: UART 2 +Bit 2: UART 1 +Bit 1/0: PIO (0/0 Unidirectional , 0/1 ECP, 1/0 EPP, 1/1 Disabled) + +Note: 86Box LPT is simplistic and can't do ECP or EPP. +*/ + +!(FUNCTION_SELECT & 0x03) ? prime3c_lpt_handler(dev) : lpt1_remove(); +(FUNCTION_SELECT & 0x04) ? prime3c_uart_handler(0, dev) : serial_remove(dev->uart[0]); +(FUNCTION_SELECT & 0x08) ? prime3c_uart_handler(1, dev) : serial_remove(dev->uart[1]); +(FUNCTION_SELECT & 0x10) ? prime3c_fdc_handler(dev) : fdc_remove(dev->fdc_controller); +if (HAS_IDE_FUNCTIONALITY) + (FUNCTION_SELECT & 0x20) ? prime3c_ide_handler(dev) : ide_pri_disable(); +} + +static void +prime3c_close(void *priv) +{ + prime3c_t *dev = (prime3c_t *)priv; + + free(dev); +} + +static void * +prime3c_init(const device_t *info) +{ + prime3c_t *dev = (prime3c_t *)malloc(sizeof(prime3c_t)); + memset(dev, 0, sizeof(prime3c_t)); + + /* Avoid conflicting with machines that make no use of the Prime3C Internal IDE */ + HAS_IDE_FUNCTIONALITY = info->local; + + dev->regs[0xc0] = 0x3c; + dev->regs[0xc2] = 0x03; + dev->regs[0xc3] = 0x3c; + dev->regs[0xc4] = 0x3c; + dev->regs[0xc5] = 0x3d; + dev->regs[0xd5] = 0x3c; + + dev->fdc_controller = device_add(&fdc_at_device); + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + if (HAS_IDE_FUNCTIONALITY) + device_add(&ide_isa_device); + + prime3c_fdc_handler(dev); + prime3c_uart_handler(0, dev); + prime3c_uart_handler(1, dev); + prime3c_lpt_handler(dev); + if (HAS_IDE_FUNCTIONALITY) + prime3c_ide_handler(dev); + + io_sethandler(0x0398, 0x0002, prime3c_read, NULL, NULL, prime3c_write, NULL, NULL, dev); + + return dev; +} + +const device_t prime3c_device = { + "Goldstar Prime3C", + 0, + 0, + prime3c_init, + prime3c_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; + +const device_t prime3c_ide_device = { + "Goldstar Prime3C with IDE functionality", + 0, + 1, + prime3c_init, + prime3c_close, + NULL, + {NULL}, + NULL, + NULL, + NULL}; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt new file mode 100644 index 000000000..32d72a34f --- /dev/null +++ b/src/sound/CMakeLists.txt @@ -0,0 +1,45 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(snd OBJECT sound.c openal.c snd_opl.c snd_opl_nuked.c snd_resid.cc + midi.c midi_system.c snd_speaker.c snd_pssj.c snd_lpt_dac.c + snd_lpt_dss.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c + snd_azt2316a.c snd_cms.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_emu8k.c + snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) + +if(FLUIDSYNTH) + target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) + target_sources(snd PRIVATE midi_fluidsynth.c) +endif() + +if(MUNT) + target_compile_definitions(snd PRIVATE USE_MUNT) + target_sources(snd PRIVATE midi_mt32.c) + + add_subdirectory(munt) + target_link_libraries(86Box mt32emu) +endif() + +if(PAS16) + target_compile_definitions(snd PRIVATE USE_PAS16) + target_sources(snd PRIVATE snd_pas16.c) +endif() + +if(GUSMAX) + target_compile_definitions(snd PRIVATE USE_GUSMAX) +endif() + +add_subdirectory(resid-fp) +target_link_libraries(86Box resid-fp) \ No newline at end of file diff --git a/src/sound/munt/CMakeLists.txt b/src/sound/munt/CMakeLists.txt new file mode 100644 index 000000000..e694bc7ae --- /dev/null +++ b/src/sound/munt/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(mt32emu STATIC Analog.cpp BReverbModel.cpp File.cpp FileStream.cpp + LA32Ramp.cpp LA32FloatWaveGenerator.cpp LA32WaveGenerator.cpp + MidiStreamParser.cpp Part.cpp Partial.cpp PartialManager.cpp + Poly.cpp ROMInfo.cpp SampleRateConverter.cpp + srchelper/srctools/src/FIRResampler.cpp + srchelper/srctools/src/IIR2xResampler.cpp + srchelper/srctools/src/LinearResampler.cpp + srchelper/srctools/src/ResamplerModel.cpp + srchelper/srctools/src/SincResampler.cpp + srchelper/InternalResampler.cpp Synth.cpp Tables.cpp TVA.cpp TVF.cpp + TVP.cpp sha1/sha1.cpp c_interface/c_interface.cpp) \ No newline at end of file diff --git a/src/sound/resid-fp/CMakeLists.txt b/src/sound/resid-fp/CMakeLists.txt new file mode 100644 index 000000000..8b5a16f40 --- /dev/null +++ b/src/sound/resid-fp/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(resid-fp STATIC convolve-sse.cc convolve.cc envelope.cc extfilt.cc + filter.cc pot.cc sid.cc voice.cc wave.cc wave6581_PST.cc + wave6581_PS_.cc wave6581_P_T.cc wave6581__ST.cc wave8580_PST.cc + wave8580_PS_.cc wave8580_P_T.cc wave8580__ST.cc) \ No newline at end of file diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 303c69ba1..e1cc18f7e 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1172,7 +1172,8 @@ sb_2_init(const device_t *info) sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); - sb_ct1335_mixer_reset(sb); + if (mixer_addr > 0x000) + sb_ct1335_mixer_reset(sb); /* CMS I/O handler is activated on the dedicated sound_cms module DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { @@ -1186,7 +1187,7 @@ sb_2_init(const device_t *info) opl2_write, NULL, NULL, &sb->opl); } - if (mixer_addr > 0x0000) { + if (mixer_addr > 0x000) { sb->mixer_enabled = 1; io_sethandler(addr + 4, 0x0002, sb_ct1335_mixer_read, NULL, NULL, sb_ct1335_mixer_write, NULL, NULL, sb); @@ -1558,6 +1559,91 @@ static const device_config_t sb_config[] = } }; + +static const device_config_t sb2_config[] = +{ + { + "base", "Address", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { + "0x220", 0x220 + }, + { + "0x240", 0x240 + }, + { + "0x260", 0x260 + }, + { + "" + } + } + }, + { + "mixaddr", "Mixer", CONFIG_HEX16, "", 0x220, "", { 0 }, + { + { + "Disabled", 0 + }, + { + "0x220", 0x220 + }, + { + "0x240", 0x240 + }, + { + "0x260", 0x260 + }, + { + "" + } + } + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 7, "", { 0 }, + { + { + "IRQ 2", 2 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "" + } + } + }, + { + "dma", "DMA", CONFIG_SELECTION, "", 1, "", { 0 }, + { + { + "DMA 1", 1 + }, + { + "DMA 3", 3 + }, + { + "" + } + } + }, + { + "opl", "Enable OPL", CONFIG_BINARY, "", 1 + }, + { + "receive_input", "Receive input (SB MIDI)", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 + } +}; + static const device_config_t sb_mcv_config[] = { { @@ -1961,7 +2047,7 @@ const device_t sb_2_device = sb_2_init, sb_close, NULL, { NULL }, sb_speed_changed, NULL, - sb_config + sb2_config }; const device_t sb_pro_v1_device = diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt new file mode 100644 index 000000000..9419e3e4a --- /dev/null +++ b/src/video/CMakeLists.txt @@ -0,0 +1,55 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +add_library(vid OBJECT video.c vid_table.c vid_cga.c vid_cga_comp.c + vid_compaq_cga.c vid_mda.c vid_hercules.c vid_herculesplus.c + vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c + vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c + vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c + vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c + vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c + vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c + vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c + vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c + vid_sdac_ramdac.c vid_voodoo.c vid_voodoo_banshee.c + vid_voodoo_banshee_blitter.c vid_voodoo_blitter.c vid_voodoo_display.c + vid_voodoo_fb.c vid_voodoo_fifo.c vid_voodoo_reg.c vid_voodoo_render.c + vid_voodoo_setup.c vid_voodoo_texture.c vid_ogc.c vid_nga.c) + +if(NOT MSVC) + target_compile_options(vid PRIVATE "-msse2") +endif() + +if(CL5422) + target_compile_definitions(vid PRIVATE USE_CL5422) +endif() + +if(MGA) + target_compile_definitions(vid PRIVATE USE_MGA) + target_sources(vid PRIVATE vid_mga.c) +endif() + +if(S3TRIO3D2X) + target_compile_definitions(vid PRIVATE USE_S3TRIO3D2X) +endif() + +if(VGAWONDER) + target_compile_definitions(vid PRIVATE USE_VGAWONDER) +endif() + +if(XL24) + target_compile_definitions(vid PRIVATE USE_XL24) +endif() \ No newline at end of file diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 5dcca426a..da7fc4fcc 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -43,7 +43,12 @@ #endif #define BIOS_ATIKOR_PATH L"roms/video/ati28800/atikorvga.bin" +#define BIOS_ATIKOR_4620P_PATH_L L"roms/machines/spc4620p/31005h.u8" +#define BIOS_ATIKOR_4620P_PATH_H L"roms/machines/spc4620p/31005h.u10" +#define BIOS_ATIKOR_6033P_PATH L"roms/machines/spc6033p/phoenix.bin" #define FONT_ATIKOR_PATH L"roms/video/ati28800/ati_ksc5601.rom" +#define FONT_ATIKOR_4620P_PATH L"roms/machines/spc4620p/svb6120a_font.rom" +#define FONT_ATIKOR_6033P_PATH L"roms/machines/spc6033p/svb6120a_font.rom" #define BIOS_VGAXL_EVEN_PATH L"roms/video/ati28800/xleven.bin" #define BIOS_VGAXL_ODD_PATH L"roms/video/ati28800/xlodd.bin" @@ -80,7 +85,8 @@ typedef struct ati28800_t } ati28800_t; -static video_timings_t timing_ati28800 = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; +static video_timings_t timing_ati28800 = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; +static video_timings_t timing_ati28800_spc = {VIDEO_ISA, 2, 2, 4, 4, 4, 8}; #ifdef ENABLE_ATI28800_LOG @@ -459,9 +465,13 @@ ati28800k_init(const device_t *info) ati28800_t *ati28800 = (ati28800_t *) malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); - - ati28800->memory = device_get_config_int("memory"); + if (info->local == 0) { + ati28800->memory = device_get_config_int("memory"); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); + } else { + ati28800->memory = 512; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800_spc); + } ati28800->port_03dd_val = 0; ati28800->get_korean_font_base = 0; @@ -471,8 +481,22 @@ ati28800k_init(const device_t *info) ati28800->in_get_korean_font_kind_set = 0; ati28800->ksc5601_mode_enabled = 0; - rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_PATH, 6); + switch(info->local) { + case 0: + default: + rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_PATH, 6); + break; + case 1: + rom_init_interleaved(&ati28800->bios_rom, BIOS_ATIKOR_4620P_PATH_L, BIOS_ATIKOR_4620P_PATH_H, 0xc0000, + 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_4620P_PATH, 6); + break; + case 2: + rom_init(&ati28800->bios_rom, BIOS_ATIKOR_6033P_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_6033P_PATH, 6); + break; + } svga_init(info, &ati28800->svga, ati28800, ati28800->memory << 10, /*Memory size, default 512KB*/ ati28800k_recalctimings, @@ -709,6 +733,28 @@ const device_t ati28800k_device = ati28800_config }; +const device_t ati28800k_spc4620p_device = +{ + "ATI Korean VGA On-Board SPC-4620P", + DEVICE_ISA, + 1, + ati28800k_init, ati28800_close, NULL, + { NULL }, + ati28800_speed_changed, + ati28800_force_redraw +}; + +const device_t ati28800k_spc6033p_device = +{ + "ATI Korean VGA On-Board SPC-6033P", + DEVICE_ISA, + 2, + ati28800k_init, ati28800_close, NULL, + { NULL }, + ati28800_speed_changed, + ati28800_force_redraw +}; + const device_t compaq_ati28800_device = { "Compaq ATI-28800", diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 96a4e13a1..d08863952 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -42,7 +42,7 @@ #define BIOS_GD5401_PATH L"roms/video/cirruslogic/avga1.rom" #define BIOS_GD5402_PATH L"roms/video/cirruslogic/avga2.rom" -#define BIOS_GD5402_ONBOARD_PATH L"roms/machines/cbm_sl386sx25/Commodore386SX-25_AVGA2.bin" +#define BIOS_GD5402_ONBOARD_PATH L"roms/machines/cbm_sl386sx25/c000.rom" #define BIOS_GD5420_PATH L"roms/video/cirruslogic/5420.vbi" #define BIOS_GD5422_PATH L"roms/video/cirruslogic/cl5422.bin" #define BIOS_GD5426_PATH L"roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 95adeb81c..0a82bdee1 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -324,10 +324,10 @@ compaq_cga_poll(void *p) ys_temp = (self->cga.lastline - self->cga.firstline); if ((xs_temp > 0) && (ys_temp > 0)) { - if (xsize < 64) xs_temp = 656; - if (ysize < 32) ys_temp = 400; + if (xs_temp < 64) xs_temp = 656; + if (ys_temp < 32) ys_temp = 400; if (!enable_overscan) - xsize -= 16; + xs_temp -= 16; if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { xsize = xs_temp; @@ -340,14 +340,14 @@ compaq_cga_poll(void *p) if (enable_overscan) { if (self->cga.composite) - video_blit_memtoscreen(0, self->cga.firstline - 8, 0, ysize + 16, xsize + 16, ysize + 16); + video_blit_memtoscreen(0, self->cga.firstline - 8, 0, (self->cga.lastline - self->cga.firstline) + 16, xsize, (self->cga.lastline - self->cga.firstline) + 16); else - video_blit_memtoscreen_8(0, self->cga.firstline - 8, 0, ysize + 16, xsize + 16, ysize + 16); + video_blit_memtoscreen_8(0, self->cga.firstline - 8, 0, (self->cga.lastline - self->cga.firstline) + 16, xsize, (self->cga.lastline - self->cga.firstline) + 16); } else { if (self->cga.composite) - video_blit_memtoscreen(8, self->cga.firstline, 0, ysize, xsize, ysize); + video_blit_memtoscreen(8, self->cga.firstline, 0, self->cga.lastline - self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); else - video_blit_memtoscreen_8(8, self->cga.firstline, 0, ysize, xsize, ysize); + video_blit_memtoscreen_8(8, self->cga.firstline, 0, self->cga.lastline - self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); } } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 96f587ba4..b9c1eba0b 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -4195,7 +4195,7 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) s3->videoengine.sx_scale = (double)(s3->videoengine.k1 - 2); s3->videoengine.sx_scale_dec = (s3->videoengine.sx_scale / (double)(s3->videoengine.len - s3->videoengine.start - 2)); - if (s3->videoengine.sx_scale_dec >= 0.5d) { + if (s3->videoengine.sx_scale_dec >= 0.5) { s3->videoengine.sx_scale++; } } @@ -4211,8 +4211,8 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; } s3->videoengine.input = 2; - s3->videoengine.cx = 0.0d; - s3->videoengine.dx = 0.0d; + s3->videoengine.cx = 0.0; + s3->videoengine.dx = 0.0; } while (count) { @@ -4255,8 +4255,8 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) s3->videoengine.sx_scale_inc = (double)((s3->videoengine.sx_backup >> 1)); s3->videoengine.sx_scale_inc = s3->videoengine.sx_scale_inc / (double)((s3->videoengine.sx >> 1)); - s3->videoengine.cx = 0.0d; - s3->videoengine.dx = 0.0d; + s3->videoengine.cx = 0.0; + s3->videoengine.dx = 0.0; if (s3->bpp == 0) { s3->videoengine.dest = s3->videoengine.dest_base + s3->width; @@ -4299,12 +4299,12 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) s3->videoengine.sx_scale = (double)(s3->videoengine.k1 - 2); s3->videoengine.sx_scale_dec = (s3->videoengine.sx_scale / (double)(s3->videoengine.len - s3->videoengine.start - 2)); - if (s3->videoengine.sx_scale_dec >= 0.5d) { + if (s3->videoengine.sx_scale_dec >= 0.5) { s3->videoengine.sx_scale++; } - s3->videoengine.cx = 0.0d; - s3->videoengine.dx = 0.0d; + s3->videoengine.cx = 0.0; + s3->videoengine.dx = 0.0; if (s3->bpp == 0) { s3->videoengine.dest = s3->videoengine.dest_base + s3->width; diff --git a/src/win/86Box.rc b/src/win/86Box.rc index a7891b81d..8dfa152db 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -696,68 +696,76 @@ BEGIN END +#ifndef NO_INCLUDE_MANIFEST ///////////////////////////////////////////////////////////////////////////// // // 24 // 1 24 MOVEABLE PURE "86Box.manifest" +#endif ///////////////////////////////////////////////////////////////////////////// // // Icon // +#ifdef CMAKE +#define ICON_PATH +#else +#define ICON_PATH "win/" +#endif + // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. #ifdef RELEASE_BUILD /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ - 10 ICON DISCARDABLE "win/icons/86Box-RB.ico" + 10 ICON DISCARDABLE ICON_PATH "icons/86Box-RB.ico" #else /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ - 10 ICON DISCARDABLE "win/icons/86Box.ico" + 10 ICON DISCARDABLE ICON_PATH "icons/86Box.ico" #endif - 16 ICON DISCARDABLE "win/icons/floppy_525.ico" - 17 ICON DISCARDABLE "win/icons/floppy_525_active.ico" - 24 ICON DISCARDABLE "win/icons/floppy_35.ico" - 25 ICON DISCARDABLE "win/icons/floppy_35_active.ico" - 32 ICON DISCARDABLE "win/icons/cdrom.ico" - 33 ICON DISCARDABLE "win/icons/cdrom_active.ico" - 48 ICON DISCARDABLE "win/icons/zip.ico" - 49 ICON DISCARDABLE "win/icons/zip_active.ico" - 56 ICON DISCARDABLE "win/icons/mo.ico" - 57 ICON DISCARDABLE "win/icons/mo_active.ico" - 64 ICON DISCARDABLE "win/icons/cassette.ico" - 65 ICON DISCARDABLE "win/icons/cassette_active.ico" - 80 ICON DISCARDABLE "win/icons/hard_disk.ico" - 81 ICON DISCARDABLE "win/icons/hard_disk_active.ico" - 96 ICON DISCARDABLE "win/icons/network.ico" - 97 ICON DISCARDABLE "win/icons/network_active.ico" -144 ICON DISCARDABLE "win/icons/floppy_525_empty.ico" -145 ICON DISCARDABLE "win/icons/floppy_525_empty_active.ico" -152 ICON DISCARDABLE "win/icons/floppy_35_empty.ico" -153 ICON DISCARDABLE "win/icons/floppy_35_empty_active.ico" -160 ICON DISCARDABLE "win/icons/cdrom_empty.ico" -161 ICON DISCARDABLE "win/icons/cdrom_empty_active.ico" -176 ICON DISCARDABLE "win/icons/zip_empty.ico" -177 ICON DISCARDABLE "win/icons/zip_empty_active.ico" -184 ICON DISCARDABLE "win/icons/mo_empty.ico" -185 ICON DISCARDABLE "win/icons/mo_empty_active.ico" -192 ICON DISCARDABLE "win/icons/cassette_empty.ico" -193 ICON DISCARDABLE "win/icons/cassette_empty_active.ico" -240 ICON DISCARDABLE "win/icons/machine.ico" -241 ICON DISCARDABLE "win/icons/display.ico" -242 ICON DISCARDABLE "win/icons/input_devices.ico" -243 ICON DISCARDABLE "win/icons/sound.ico" -244 ICON DISCARDABLE "win/icons/ports.ico" -245 ICON DISCARDABLE "win/icons/other_peripherals.ico" -246 ICON DISCARDABLE "win/icons/floppy_and_cdrom_drives.ico" -247 ICON DISCARDABLE "win/icons/other_removable_devices.ico" -248 ICON DISCARDABLE "win/icons/floppy_disabled.ico" -249 ICON DISCARDABLE "win/icons/cdrom_disabled.ico" -250 ICON DISCARDABLE "win/icons/zip_disabled.ico" -251 ICON DISCARDABLE "win/icons/mo_disabled.ico" -252 ICON DISCARDABLE "win/icons/storage_controllers.ico" + 16 ICON DISCARDABLE ICON_PATH "icons/floppy_525.ico" + 17 ICON DISCARDABLE ICON_PATH "icons/floppy_525_active.ico" + 24 ICON DISCARDABLE ICON_PATH "icons/floppy_35.ico" + 25 ICON DISCARDABLE ICON_PATH "icons/floppy_35_active.ico" + 32 ICON DISCARDABLE ICON_PATH "icons/cdrom.ico" + 33 ICON DISCARDABLE ICON_PATH "icons/cdrom_active.ico" + 48 ICON DISCARDABLE ICON_PATH "icons/zip.ico" + 49 ICON DISCARDABLE ICON_PATH "icons/zip_active.ico" + 56 ICON DISCARDABLE ICON_PATH "icons/mo.ico" + 57 ICON DISCARDABLE ICON_PATH "icons/mo_active.ico" + 64 ICON DISCARDABLE ICON_PATH "icons/cassette.ico" + 65 ICON DISCARDABLE ICON_PATH "icons/cassette_active.ico" + 80 ICON DISCARDABLE ICON_PATH "icons/hard_disk.ico" + 81 ICON DISCARDABLE ICON_PATH "icons/hard_disk_active.ico" + 96 ICON DISCARDABLE ICON_PATH "icons/network.ico" + 97 ICON DISCARDABLE ICON_PATH "icons/network_active.ico" +144 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty.ico" +145 ICON DISCARDABLE ICON_PATH "icons/floppy_525_empty_active.ico" +152 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty.ico" +153 ICON DISCARDABLE ICON_PATH "icons/floppy_35_empty_active.ico" +160 ICON DISCARDABLE ICON_PATH "icons/cdrom_empty.ico" +161 ICON DISCARDABLE ICON_PATH "icons/cdrom_empty_active.ico" +176 ICON DISCARDABLE ICON_PATH "icons/zip_empty.ico" +177 ICON DISCARDABLE ICON_PATH "icons/zip_empty_active.ico" +184 ICON DISCARDABLE ICON_PATH "icons/mo_empty.ico" +185 ICON DISCARDABLE ICON_PATH "icons/mo_empty_active.ico" +192 ICON DISCARDABLE ICON_PATH "icons/cassette_empty.ico" +193 ICON DISCARDABLE ICON_PATH "icons/cassette_empty_active.ico" +240 ICON DISCARDABLE ICON_PATH "icons/machine.ico" +241 ICON DISCARDABLE ICON_PATH "icons/display.ico" +242 ICON DISCARDABLE ICON_PATH "icons/input_devices.ico" +243 ICON DISCARDABLE ICON_PATH "icons/sound.ico" +244 ICON DISCARDABLE ICON_PATH "icons/ports.ico" +245 ICON DISCARDABLE ICON_PATH "icons/other_peripherals.ico" +246 ICON DISCARDABLE ICON_PATH "icons/floppy_and_cdrom_drives.ico" +247 ICON DISCARDABLE ICON_PATH "icons/other_removable_devices.ico" +248 ICON DISCARDABLE ICON_PATH "icons/floppy_disabled.ico" +249 ICON DISCARDABLE ICON_PATH "icons/cdrom_disabled.ico" +250 ICON DISCARDABLE ICON_PATH "icons/zip_disabled.ico" +251 ICON DISCARDABLE ICON_PATH "icons/mo_disabled.ico" +252 ICON DISCARDABLE ICON_PATH "icons/storage_controllers.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -931,7 +939,7 @@ BEGIN IDS_2060 "On" IDS_2061 "Off" IDS_2062 "All images (*.86F;*.DSK;*.FLP;*.IM?;*.*FD?)\0*.86F;*.DSK;*.FLP;*.IM?;*.*FD?\0Basic sector images (*.DSK;*.FLP;*.IM?;*.*FD?)\0*.DSK;*.FLP;*.IM?;*.IMG;*.*FD?\0Surface images (*.86F)\0*.86F\0" - IDS_2063 "Machine ""%S"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." + IDS_2063 "Machine ""%s"" is not available due to missing ROMs in the roms/machines directory. Switching to an available machine." END STRINGTABLE DISCARDABLE diff --git a/src/win/CMakeLists.txt b/src/win/CMakeLists.txt new file mode 100644 index 000000000..f8c248ae3 --- /dev/null +++ b/src/win/CMakeLists.txt @@ -0,0 +1,48 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020,2021 David Hrdlička. +# + +enable_language(RC) + +add_library(plat OBJECT win.c win_dynld.c win_thread.c win_cdrom.c + win_keyboard.c win_crashdump.c win_midi.c win_mouse.c) + +add_library(ui OBJECT win_ui.c win_stbar.c win_sdl.c win_dialog.c win_about.c + win_settings.c win_devconf.c win_snd_gain.c win_new_floppy.c + win_jsconf.c win_media_menu.c 86Box.rc) + +if(MSVC) + # MSVC complains when we include the manifest from 86Box.rc... + # On the bright side, CMake supports passing the manifest as a source + # file when using MSVC, so we might just as well do that! + target_compile_definitions(ui PRIVATE NO_INCLUDE_MANIFEST) + target_sources(86Box PRIVATE 86Box.manifest) +endif() + +if(DINPUT) + target_sources(plat PRIVATE win_joystick.cpp) + target_link_libraries(86Box dinput8) +else() + target_sources(plat PRIVATE win_joystick_rawinput.c) +endif() + +if(DISCORD) + # PUBLIC due to config.c and pc.c + target_compile_definitions(ui PUBLIC USE_DISCORD) + + target_sources(ui PRIVATE win_discord.c) +endif() + +target_link_libraries(86Box advapi32 comctl32 comdlg32 gdi32 shell32 iphlpapi + dxguid imm32 hid setupapi uxtheme version winmm psapi) \ No newline at end of file diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 0cdbc1621..5d71b35e3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -84,6 +84,9 @@ ifeq ($(DEV_BUILD), y) ifndef M6117 M6117 := y endif + ifndef SIS_5571 + SIS_5571 := y + endif ifndef VGAWONDER VGAWONDER := y endif @@ -154,6 +157,9 @@ else ifndef M6117 M6117 := n endif + ifndef SIS_5571 + SIS_5571 := n + endif ifndef VGAWONDER VGAWONDER := n endif @@ -312,7 +318,7 @@ DEPFILE := win/.depends # Set up the correct toolchain flags. OPTS := $(EXTRAS) $(STUFF) -OPTS += -Iinclude \ +OPTS += -Iinclude -Iinclude_make \ -iquote $(CODEGEN) -iquote cpu ifdef EXFLAGS OPTS += $(EXFLAGS) @@ -363,7 +369,7 @@ ifeq ($(ARM64), y) AOPTIM := AFLAGS := -mfloat-abi=hard endif -RFLAGS := --input-format=rc -O coff -Iinclude +RFLAGS := --input-format=rc -O coff -Iinclude -Iinclude_make ifeq ($(RELEASE), y) OPTS += -DRELEASE_BUILD RFLAGS += -DRELEASE_BUILD @@ -552,6 +558,11 @@ OPTS += -DUSE_M6117 DEVBROBJ += ali6117.o endif +ifeq ($(SIS_5571), y) +OPTS += -DUSE_SIS_5571 +DEVBROBJ += sis_5571.o +endif + ifeq ($(VGAWONDER), y) OPTS += -DUSE_VGAWONDER endif @@ -628,8 +639,9 @@ DEVOBJ := bugger.o hwm.o hwm_lm75.o hwm_lm78.o hwm_gl518sm.o hwm_vt82c686.o ibm SIOOBJ := sio_acc3221.o \ sio_f82c710.o sio_82091aa.o \ - sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o \ - sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87332.o \ + sio_fdc37c661.o sio_fdc37c66x.o sio_fdc37c669.o sio_fdc37c93x.o sio_fdc37m60x.o \ + sio_pc87306.o sio_pc87307.o sio_pc87309.o sio_pc87311.o sio_pc87332.o \ + sio_prime3c.o \ sio_w83787f.o \ sio_w83877f.o sio_w83977f.o \ sio_um8669f.o \ diff --git a/src/win/win.c b/src/win/win.c index 74f8d16a4..3e29062eb 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -810,15 +810,24 @@ plat_setfullscreen(int on) plat_resize(scrnsz_x, scrnsz_y); if (vid_resize) { /* scale the screen base on DPI */ - if (dpi_scale) { - temp_x = MulDiv(unscaled_size_x, dpi, 96); - temp_y = MulDiv(unscaled_size_y, dpi, 96); + if (window_remember) { + MoveWindow(hwndMain, window_x, window_y, window_w, window_h, TRUE); + GetClientRect(hwndMain, &rect); + + temp_x = rect.right - rect.left + 1; + temp_y = rect.bottom - rect.top + 1 - sbar_height; } else { - temp_x = unscaled_size_x; - temp_y = unscaled_size_y; + if (dpi_scale) { + temp_x = MulDiv(unscaled_size_x, dpi, 96); + temp_y = MulDiv(unscaled_size_y, dpi, 96); + } else { + temp_x = unscaled_size_x; + temp_y = unscaled_size_y; + } + + /* Main Window. */ + ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); } - /* Main Window. */ - ResizeWindowByClientArea(hwndMain, temp_x, temp_y + sbar_height); /* Render window. */ MoveWindow(hwndRender, 0, 0, temp_x, temp_y, TRUE); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 862927f59..1d9912316 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -234,7 +234,7 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h) SDL_Rect r_src; int ret; - if (!sdl_enabled || (y1 == y2) || (h <= 0) || (render_buffer == NULL)) { + if (!sdl_enabled || (y1 == y2) || (h <= 0) || (render_buffer == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { video_blit_complete(); return; } diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 2b8623ce2..e72307d9b 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -662,6 +662,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) reset_screen_size(); device_force_redraw(); video_force_resize_set(1); + doresize = 1; config_save(); break; diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 000000000..e57a7db16 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,13 @@ +{ + "name": "86box", + "version-string": "3.0", + "homepage": "https://86box.net/", + "documentation": "http://86box.readthedocs.io/", + "license": "GPL-2.0-or-later", + "dependencies": [ + "freetype", + "libpng", + "openal-soft", + "sdl2" + ] +} \ No newline at end of file