Merge branch 'master' into master

This commit is contained in:
Jose Phillips
2024-12-01 18:31:58 -05:00
committed by GitHub
490 changed files with 70062 additions and 34561 deletions

View File

@@ -59,6 +59,7 @@ AppDir:
- libqt5widgets5 # if QT:BOOL=ON
- libsixel1 # if CLI:BOOL=ON
- libslirp0
- libsndfile1
- libsndio7.0 # if OPENAL:BOOL=ON
- libvdeplug-dev # -dev also pulls in libvdeplug2. -dev is required to get the proper .so symlink to the library
- libx11-6 # if QT:BOOL=ON

7
.ci/Jenkinsfile vendored
View File

@@ -20,11 +20,12 @@ def repository = ['https://github.com/86Box/86Box.git', scm.userRemoteConfigs[0]
def commitBrowser = ['https://github.com/86Box/86Box/commit/%s', null]
def branch = ['master', scm.branches[0].name]
def buildType = ['beta', 'alpha']
def tarballFlags = ['', '-s']
def buildBranch = env.JOB_BASE_NAME.contains('-') ? 1 : 0
def osArchs = [
'Windows': ['32', '64'],
'Linux': ['x86', 'x86_64', 'arm32', 'arm64'],
'Windows': ['64'],
'Linux': ['x86_64', 'arm64'],
'macOS': ['x86_64+x86_64h+arm64']
]
@@ -238,7 +239,7 @@ pipeline {
dir("${env.WORKSPACE_TMP}/output") {
/* Run source tarball creation process. */
def packageName = "${env.JOB_BASE_NAME}-Source$buildSuffix"
if (runBuild("-s \"$packageName\"") == 0) {
if (runBuild("-s \"$packageName\" ${tarballFlags[buildBranch]}") == 0) {
/* Archive resulting artifacts. */
archiveArtifacts artifacts: "$packageName*"
} else {

View File

@@ -208,7 +208,7 @@ cmake_flags_extra=
if [ -z "$package_name" -a -z "$tarball_name" ] || [ -n "$package_name" -a -z "$arch" ]
then
echo '[!] Usage: build.sh -b {package_name} {architecture} [-t] [cmake_flags...]'
echo ' build.sh -s {source_tarball_name}'
echo ' build.sh -s {source_tarball_name} [-t]'
echo 'Dep. tree: build.sh -p [archive_tmp/path/to/binary]'
exit 100
fi
@@ -228,7 +228,10 @@ then
[ ! -d "$cwd" ] && mkdir -p "$cwd"
# Save current HEAD commit to VERSION.
git log --stat -1 > VERSION || rm -f VERSION
if [ $strip -eq 0 ]
then
git log --stat -1 > VERSION || rm -f VERSION
fi
# Archive source.
make_tar "$cwd/$tarball_name.tar"
@@ -535,6 +538,20 @@ then
sudo sed -i -e 's/-no-feature-vulkan/-feature-vulkan/g' "$qt5_portfile"
sudo sed -i -e 's/configure.env-append MAKE=/configure.env-append VULKAN_SDK=${prefix} MAKE=/g' "$qt5_portfile"
fi
# Patch openal-soft to use 1.23.1 on all targets instead of 1.24.0 on >=11.0 only,
# to prevent a symlink mismatch from having different versions on x86_64 and arm64.
# See: https://github.com/macports/macports-ports/commit/9b4903fc9c76769d476079e404c9a3b8a225f8aa
openal_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/audio/openal-soft/Portfile"
sudo sed -i -e 's/if {${os.platform} ne "darwin" || ${os.major} >= 21}/if {0}/g' "$openal_portfile"
# Patch wget to remove libproxy support, as it depends on shared-mime-info which
# fails to build for a 10.13 target, which we have to do despite wget only being
# a host dependency. MacPorts issue 69406 strongly implies this will not be fixed.
wget_portfile="$macports/var/macports/sources/rsync.macports.org/macports/release/tarballs/ports/net/wget/Portfile"
sudo sed -i -e 's/--enable-libproxy/--disable-libproxy/g' "$wget_portfile"
sudo sed -i -e 's/port:libproxy//g' "$wget_portfile"
while :
do
# Attempt to install dependencies.
@@ -582,7 +599,7 @@ else
grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version
# Establish general dependencies.
pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream"
pkgs="cmake ninja-build pkg-config git wget p7zip-full extra-cmake-modules wayland-protocols tar gzip file appstream qttranslations5-l10n"
if [ "$(dpkg --print-architecture)" = "$arch_deb" ]
then
pkgs="$pkgs build-essential"
@@ -605,7 +622,7 @@ else
# ...and the ones we do want listed. Non-dev packages fill missing spots on the list.
libpkgs=""
longest_libpkg=0
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev
for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev
do
libpkgs="$libpkgs $pkg:$arch_deb"
length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c)

View File

@@ -15,3 +15,4 @@ fluidsynth
ghostscript
libslirp
vde2
libsndfile

View File

@@ -13,3 +13,4 @@ fluidsynth
qt5-static
qt5-translations
vulkan-headers
libsndfile

View File

@@ -40,10 +40,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
preset: dev_debug
slug: -Debug
- name: Dev
preset: experimental
preset: development
slug: -Dev
dynarec:
- name: ODR
@@ -63,6 +63,7 @@ jobs:
qtbase5-dev
qtbase5-private-dev
qttools5-dev
qttranslations5-l10n
libevdev-dev
libxkbcommon-x11-dev
@@ -80,6 +81,7 @@ jobs:
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvdeplug-dev
${{ matrix.ui.packages }}
- name: Checkout repository

View File

@@ -25,10 +25,10 @@ on:
jobs:
macos12:
macos13-x86_64:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
runs-on: macos-12
runs-on: macos-13
env:
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
@@ -40,10 +40,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
preset: dev_debug
slug: -Debug
- name: Dev
preset: experimental
preset: development
slug: -Dev
dynarec:
- name: ODR
@@ -80,6 +80,8 @@ jobs:
rtmidi
openal-soft
fluidsynth
libslirp
vde
${{ matrix.ui.packages }}
- name: Checkout repository
@@ -138,10 +140,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
preset: dev_debug
slug: -Debug
- name: Dev
preset: experimental
preset: development
slug: -Dev
dynarec:
# - name: ODR

View File

@@ -44,10 +44,10 @@ jobs:
# - name: Regular
# preset: regular
- name: Debug
preset: debug
preset: dev_debug
slug: -Debug
- name: Dev
preset: experimental
preset: development
slug: -Dev
dynarec:
- name: ODR
@@ -67,15 +67,9 @@ jobs:
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: MINGW32
# prefix: mingw-w64-i686
# toolchain: ./cmake/flags-gcc-i686.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG32
# prefix: mingw-w64-clang-i686
# toolchain: ./cmake/llvm-win32-i686.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake

View File

@@ -47,7 +47,7 @@ jobs:
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
preset: dev_debug
slug: -Dev
dynarec:
- name: ODR
@@ -66,6 +66,7 @@ jobs:
qtbase5-dev
qtbase5-private-dev
qttools5-dev
qttranslations5-l10n
libevdev-dev
libxkbcommon-x11-dev
@@ -83,6 +84,7 @@ jobs:
libopenal-dev
libslirp-dev
libfluidsynth-dev
libvdeplug-dev
${{ matrix.ui.packages }}
- name: Checkout repository

View File

@@ -25,11 +25,11 @@ on:
jobs:
analyze-macos12:
analyze-macos13-x86_64:
name: "${{ matrix.ui.name }}, ${{ matrix.build.name }}, ${{ matrix.dynarec.name }}, x86_64"
runs-on: macos-12
runs-on: macos-13
permissions:
actions: read
@@ -47,7 +47,7 @@ jobs:
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
preset: dev_debug
slug: -Dev
dynarec:
- name: ODR
@@ -74,6 +74,8 @@ jobs:
rtmidi
openal-soft
fluidsynth
libslirp
vde
${{ matrix.ui.packages }}
- name: Checkout repository

View File

@@ -51,7 +51,7 @@ jobs:
# preset: debug
# slug: -Debug
- name: Dev
preset: experimental
preset: dev_debug
slug: -Dev
dynarec:
- name: ODR
@@ -72,15 +72,9 @@ jobs:
environment:
# - msystem: MSYS
# toolchain: ./cmake/flags-gcc-x86_64.cmake
- msystem: MINGW32
prefix: mingw-w64-i686
toolchain: ./cmake/flags-gcc-i686.cmake
- msystem: MINGW64
prefix: mingw-w64-x86_64
toolchain: ./cmake/flags-gcc-x86_64.cmake
# - msystem: CLANG32
# prefix: mingw-w64-clang-i686
# toolchain: ./cmake/llvm-win32-i686.cmake
# - msystem: CLANG64
# prefix: mingw-w64-clang-x86_64
# toolchain: ./cmake/llvm-win32-x86_64.cmake

3
.gitignore vendored
View File

@@ -62,3 +62,6 @@ CMakeLists.txt.user
# clangd
.cache
# Jetbrains CLion
.idea

View File

@@ -1,16 +1,17 @@
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box distribution.
# This file is part of the 86Box distribution.
#
# CMake build script.
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2020-2021 David Hrdlička.
# Copyright 2021-2024 Jasmine Iwanek.
#
cmake_minimum_required(VERSION 3.16)
@@ -35,7 +36,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
VERSION 4.2
VERSION 4.3
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)
@@ -122,46 +123,55 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# Optional features
#
# Option Description Def.
# ------ ----------- ----
option(RELEASE "Release build" OFF)
option(DYNAREC "Dynamic recompiler" ON)
option(OPENAL "OpenAL" ON)
option(RTMIDI "RtMidi" ON)
option(FLUIDSYNTH "FluidSynth" ON)
option(MUNT "MUNT" ON)
option(VNC "VNC renderer" OFF)
option(CPPTHREADS "C++11 threads" ON)
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
option(DEV_BRANCH "Development branch" OFF)
option(DISCORD "Discord Rich Presence support" ON)
option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
# Option Description Def.
# ------ ----------- ----
option(RELEASE "Release build" OFF)
option(DYNAREC "Dynamic recompiler" ON)
option(OPENAL "OpenAL" ON)
option(RTMIDI "RtMidi" ON)
option(FLUIDSYNTH "FluidSynth" ON)
option(MUNT "MUNT" ON)
option(VNC "VNC renderer" OFF)
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
option(MINITRACE "Enable Chrome tracing using the modified minitrace library" OFF)
option(GDBSTUB "Enable GDB stub server for debugging" OFF)
option(DEV_BRANCH "Development branch" OFF)
option(DISCORD "Discord Rich Presence support" ON)
option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF)
if(WIN32)
set(QT ON)
option(CPPTHREADS "C++11 threads" OFF)
else()
option(QT "Qt GUI" ON)
option(CPPTHREADS "C++11 threads" ON)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,wxneeded")
endif()
# Development branch features
#
# Option Description Def. Condition Otherwise
# ------ ----------- ---- --------- ---------
cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
cmake_dependent_option(AN430TX "Intel AN430TX" 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(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
# Option Description Def. Condition Otherwise
# ------ ----------- ---- ------------ ---------
cmake_dependent_option(AMD_K5 "AMD K5" ON "DEV_BRANCH" OFF)
cmake_dependent_option(AN430TX "Intel AN430TX" ON "DEV_BRANCH" OFF)
cmake_dependent_option(CDROM_MITSUMI "Mitsumi CDROM" ON "DEV_BRANCH" OFF)
cmake_dependent_option(CYRIX_6X86 "Cyrix 6x86" ON "DEV_BRANCH" OFF)
cmake_dependent_option(G100 "Matrox Productiva G100" ON "DEV_BRANCH" OFF)
cmake_dependent_option(GUSMAX "Gravis UltraSound MAX" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF)
cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF)
cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF)
cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF)
cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF)
cmake_dependent_option(WACOM "Wacom Input Devices" ON "DEV_BRANCH" OFF)
cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF)
# Ditto but for Qt
if(QT)

View File

@@ -43,17 +43,15 @@
"name": "development",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"DEV_BRANCH": "ON",
"NEW_DYNAREC": "OFF"
"DEV_BRANCH": "ON"
},
"inherits": "base"
},
{
"name": "experimental",
"name": "dev_debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"DEV_BRANCH": "ON",
"NEW_DYNAREC": "ON"
"DEV_BRANCH": "ON"
},
"inherits": "base"
},

View File

@@ -53,10 +53,14 @@ We operate an IRC channel and a Discord server for discussing 86Box, its develop
[![Visit our Discord server](https://discordapp.com/api/guilds/262614059009048590/embed.png)](https://discord.gg/QXK9XTv)
Contributions
---------
-------------
We welcome all contributions to the project, as long as the [contribution guidelines](CONTRIBUTING.md) are followed.
Building
---------
For instructions on how to build 86Box from source, see the [build guide](https://86box.readthedocs.io/en/latest/dev/buildguide.html).
Licensing
---------

4
debian/changelog vendored
View File

@@ -1,5 +1,5 @@
86box (4.2) UNRELEASED; urgency=medium
86box (4.3) UNRELEASED; urgency=medium
* Bump release.
-- Jasmine Iwanek <jriwanek@gmail.com> Sat, 23 Mar 2024 17:19:08 +0100
-- Jasmine Iwanek <jriwanek@gmail.com> Wed, 13 Nov 2024 06:31:46 +0100

3
debian/control vendored
View File

@@ -13,6 +13,7 @@ Build-Depends: cmake (>= 3.21),
libsdl2-dev,
libslirp-dev,
libxkbcommon-x11-dev,
libsndfile-dev,
ninja-build,
qttools5-dev,
qtbase5-private-dev
@@ -31,4 +32,4 @@ Recommends: libpcap0.8-dev
Description: An emulator for classic IBM PC clones
86Box is a low level x86 emulator that runs older operating systems and software
designed for IBM PC systems and compatibles from 1981 through
fairly recent system designs based on the PCI bus.
fairly recent system designs based on the PCI bus.

View File

@@ -171,15 +171,15 @@ int video_filter_method = 1; /* (C) video *
int video_vsync = 0; /* (C) video */
int video_framerate = -1; /* (C) video */
char video_shader[512] = { '\0' }; /* (C) video */
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0 }; /* (C) activation and kind of
pass-through for serial ports */
bool serial_passthrough_enabled[SERIAL_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; /* (C) activation and kind of
pass-through for serial ports */
int bugger_enabled = 0; /* (C) enable ISAbugger */
int novell_keycard_enabled = 0; /* (C) enable Novell NetWare 2.x key card emulation. */
int postcard_enabled = 0; /* (C) enable POST card */
int unittester_enabled = 0; /* (C) enable unit tester device */
int isamem_type[ISAMEM_MAX] = { 0, 0, 0, 0 }; /* (C) enable ISA mem cards */
int isartc_type = 0; /* (C) enable ISA RTC card */
int gfxcard[2] = { 0, 0 }; /* (C) graphics/video card */
int gfxcard[GFXCARD_MAX] = { 0, 0 }; /* (C) graphics/video card */
int show_second_monitors = 1; /* (C) show non-primary monitors */
int sound_is_float = 1; /* (C) sound uses FP values */
int voodoo_enabled = 0; /* (C) video option */
@@ -354,12 +354,14 @@ fatal(const char *fmt, ...)
if ((sp = strchr(temp, '\n')) != NULL)
*sp = '\0';
do_pause(2);
ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
/* Cleanly terminate all of the emulator's components so as
to avoid things like threads getting stuck. */
do_stop();
ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
fflush(stdlog);
exit(-1);
@@ -396,12 +398,14 @@ fatal_ex(const char *fmt, va_list ap)
if ((sp = strchr(temp, '\n')) != NULL)
*sp = '\0';
do_pause(2);
ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
/* Cleanly terminate all of the emulator's components so as
to avoid things like threads getting stuck. */
do_stop();
ui_msgbox(MBX_ERROR | MBX_FATAL | MBX_ANSI, temp);
fflush(stdlog);
}
@@ -1000,12 +1004,15 @@ pc_init_modules(void)
}
}
if (!video_card_available(gfxcard[1])) {
char tempc[512] = { 0 };
device_get_name(video_card_getdevice(gfxcard[1]), 0, tempc);
swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc);
ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
gfxcard[1] = 0;
// TODO
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
if (!video_card_available(gfxcard[i])) {
char tempc[512] = { 0 };
device_get_name(video_card_getdevice(gfxcard[i]), 0, tempc);
swprintf(temp, sizeof_w(temp), plat_get_string(STRING_HW_NOT_AVAILABLE_VIDEO2), tempc);
ui_msgbox_header(MBX_INFO, plat_get_string(STRING_HW_NOT_AVAILABLE_TITLE), temp);
gfxcard[i] = 0;
}
}
atfullspeed = 0;

View File

@@ -12,16 +12,45 @@
# dob205
#
# Copyright 2020-2022 David Hrdlička.
# Copyright 2021 dob205.
# Copyright 2021 dob205.
# Copyright 2024 Jasmine Iwanek.
#
if(APPLE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()
add_executable(86Box 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
dma.c ddma.c nmi.c pic.c pit.c pit_fast.c port_6x.c port_92.c ppi.c pci.c
mca.c usb.c fifo.c fifo8.c device.c nvr.c nvr_at.c nvr_ps2.c
machine_status.c ini.c cJSON.c)
add_executable(86Box
86box.c
config.c
log.c
random.c
timer.c
io.c
acpi.c
apm.c
dma.c
ddma.c
nmi.c
pic.c
pit.c
pit_fast.c
port_6x.c
port_92.c
ppi.c
pci.c
mca.c
usb.c
fifo.c
fifo8.c
device.c
nvr.c
nvr_at.c
nvr_ps2.c
machine_status.c
ini.c
cJSON.c
)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_compile_definitions(_FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE=1 _LARGEFILE64_SOURCE=1)
@@ -48,10 +77,6 @@ if(DYNAREC)
add_compile_definitions(USE_DYNAREC)
endif()
if(DEV_BRANCH)
add_compile_definitions(DEV_BRANCH)
endif()
if(DISCORD)
add_compile_definitions(DISCORD)
target_sources(86Box PRIVATE discord.c)
@@ -65,7 +90,10 @@ if(VNC)
find_package(LibVNCServer)
if(LibVNCServer_FOUND)
add_compile_definitions(USE_VNC)
add_library(vnc OBJECT vnc.c vnc_keymap.c)
add_library(vnc OBJECT
vnc.c
vnc_keymap.c
)
target_link_libraries(86Box vnc LibVNCServer::vncserver)
if(WIN32)
target_link_libraries(86Box ws2_32)
@@ -143,8 +171,10 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)
include_directories(include)
if(NEW_DYNAREC)
include_directories(cpu codegen_new)
else()
elseif(DYNAREC)
include_directories(cpu codegen)
else()
include_directories(cpu)
endif()
add_subdirectory(cdrom)
@@ -153,7 +183,7 @@ add_subdirectory(chipset)
add_subdirectory(cpu)
if(NEW_DYNAREC)
add_subdirectory(codegen_new)
else()
elseif(DYNAREC)
add_subdirectory(codegen)
endif()

View File

@@ -9,8 +9,31 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2024 Jasmine Iwanek.
#
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_ioctl.c cdrom_mitsumi.c)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SNDFILE REQUIRED IMPORTED_TARGET sndfile)
add_library(cdrom OBJECT
cdrom.c
cdrom_image_backend.c
cdrom_image_viso.c
cdrom_image.c
cdrom_ioctl.c
)
target_link_libraries(86Box PkgConfig::SNDFILE)
if(CDROM_MITSUMI)
target_compile_definitions(cdrom PRIVATE USE_CDROM_MITSUMI)
target_sources(cdrom PRIVATE cdrom_mitsumi.c)
endif()
if (WIN32)
# MSYS2
target_link_libraries(86Box -static ${SNDFILE_STATIC_LIBRARIES})
endif()

View File

@@ -1167,33 +1167,108 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf)
static int
read_toc_raw(cdrom_t *dev, unsigned char *b)
{
track_info_t ti;
int len = 4;
int first_track;
int last_track;
cdrom_log("read_toc_raw(%08X, %08X)\n", dev, b);
dev->ops->get_tracks(dev, &first_track, &last_track);
track_info_t ti;
raw_track_info_t rti[256] = { 0 };
int num = 0;
int len = 4;
int first_track;
int last_track;
/* Bytes 2 and 3 = Number of first and last sessions */
b[2] = b[3] = 1;
for (int i = 0; i <= last_track; i++) {
dev->ops->get_track_info(dev, i + 1, 0, &ti);
if (dev->ops->get_raw_track_info != NULL) {
cdrom_log("read_toc_raw(%08X, %08X): Raw tracks\n", dev, b);
pclog("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR "): Raw tracks\n",
(uintptr_t) dev, (uintptr_t) b);
dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti);
if (num != 0) for (int i = 0; i < num; i++) {
b[len++] = rti[i].session;
b[len++] = rti[i].adr_ctl;
b[len++] = rti[i].tno;
b[len++] = rti[i].point;
b[len++] = rti[i].m;
b[len++] = rti[i].s;
b[len++] = rti[i].f;
b[len++] = rti[i].zero;
b[len++] = rti[i].pm;
b[len++] = rti[i].ps;
b[len++] = rti[i].pf;
}
} else {
cdrom_log("read_toc_raw(%08X, %08X): Cooked tracks\n", dev, b);
pclog("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR "): Cooked tracks\n",
(uintptr_t) dev, (uintptr_t) b);
dev->ops->get_tracks(dev, &first_track, &last_track);
dev->ops->get_track_info(dev, 1, 0, &ti);
b[len++] = 1; /* Session number */
b[len++] = ti.attr; /* Track ADR and Control */
b[len++] = 0; /* TNO (always 0) */
b[len++] = 0xA0; /* Point (for track points - track number) */
/* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = ti.number; /* First track number */
b[len++] = 0;
b[len++] = 0;
dev->ops->get_track_info(dev, last_track, 0, &ti);
b[len++] = 1; /* Session number */
b[len++] = ti.attr; /* Track ADR and Control */
b[len++] = 0; /* TNO (always 0) */
b[len++] = 0xA1; /* Point (for track points - track number) */
/* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = ti.number; /* First track number */
b[len++] = 0;
b[len++] = 0;
dev->ops->get_track_info(dev, last_track + 1, 0, &ti);
cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f);
b[len++] = 1; /* Session number */
b[len++] = ti.attr; /* Track ADR and Control */
b[len++] = 0; /* TNO (always 0) */
b[len++] = ti.number; /* Point (for track points - track number) */
b[len++] = ti.m; /* M */
b[len++] = ti.s; /* S */
b[len++] = ti.f; /* F */
b[len++] = 0xA2; /* Point (for track points - track number) */
/* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = ti.m; /* PM */
b[len++] = ti.s; /* PS */
b[len++] = ti.f; /* PF */
for (int i = 0; i < last_track; i++) {
dev->ops->get_track_info(dev, i + 1, 0, &ti);
cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f);
b[len++] = 1; /* Session number */
b[len++] = ti.attr; /* Track ADR and Control */
b[len++] = 0; /* TNO (always 0) */
b[len++] = ti.number; /* Point (for track points - track number) */
/* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = 0;
b[len++] = ti.m; /* PM */
b[len++] = ti.s; /* PS */
b[len++] = ti.f; /* PF */
}
}
return len;
@@ -1520,13 +1595,13 @@ track_type_is_valid(UNUSED(uint8_t id), int type, int flags, int audio, int mode
return 1;
}
static void
static int
read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len)
{
uint8_t *bb = rbuf;
const int offset = (!!(mode2 & 0x03)) ? 24 : 16;
dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
int ret = dev->ops->read_sector(dev, CD_READ_DATA, rbuf + offset, lba);
/* Sync bytes */
bb[0] = 0;
@@ -1546,25 +1621,30 @@ read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, i
memset(bb, 0, 280);
else if (!mode2)
memset(bb, 0, 288);
return ret;
}
static void
static int
read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b)
{
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
int ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
memcpy(b, raw_buffer, 2352);
cdrom_sector_size = 2352;
return ret;
}
static void
static int
read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
{
int ret;
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048))
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
else
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
cdrom_sector_size = 0;
@@ -1610,15 +1690,18 @@ read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int
cdrom_sector_size += 288;
b += 288;
}
return ret;
}
static void
static int
read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
{
int ret;
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2336))
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336);
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336);
else
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
cdrom_sector_size = 0;
@@ -1654,15 +1737,18 @@ read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t m
cdrom_sector_size += 2336;
b += 2336;
}
return ret;
}
static void
static int
read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
{
int ret;
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2048))
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048);
else
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
cdrom_sector_size = 0;
@@ -1705,15 +1791,18 @@ read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
cdrom_sector_size += 280;
b += 280;
}
return ret;
}
static void
static int
read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b)
{
int ret;
if ((dev->cd_status == CD_STATUS_DATA_ONLY) || (dev->ops->sector_size(dev, lba) == 2324))
read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324);
ret = read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324);
else
dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
ret = dev->ops->read_sector(dev, CD_READ_RAW, raw_buffer, lba);
cdrom_sector_size = 0;
@@ -1748,6 +1837,8 @@ read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t
cdrom_sector_size += 2328;
b += 2328;
}
return ret;
}
int
@@ -1763,6 +1854,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
int m;
int s;
int f;
int ret = 0;
if (dev->cd_status == CD_STATUS_EMPTY)
return 0;
@@ -1827,21 +1919,21 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
return 0;
}
read_audio(dev, lba, temp_b);
ret = read_audio(dev, lba, temp_b);
} else if (cdrom_sector_type == 2) {
if (audio || mode2) {
cdrom_log("CD-ROM %i: [Mode 1] Attempting to read a sector of another type\n", dev->id);
return 0;
}
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
} else if (cdrom_sector_type == 3) {
if (audio || !mode2 || (mode2 & 0x03)) {
cdrom_log("CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type\n", dev->id);
return 0;
}
read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
} else if (cdrom_sector_type == 4) {
if (audio || !mode2 || ((mode2 & 0x03) != 1)) {
cdrom_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type\n", dev->id);
@@ -1855,7 +1947,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
return 0;
}
read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
} else if (cdrom_sector_type == 8) {
if (audio) {
cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", dev->id);
@@ -1863,9 +1955,9 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
}
if (mode2 && ((mode2 & 0x03) == 1))
read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
else if (!mode2)
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
else {
cdrom_log("CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes\n", dev->id);
return 0;
@@ -1873,16 +1965,16 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
} else {
if (mode2) {
if ((mode2 & 0x03) == 0x01)
read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode2_xa_form1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
else if ((mode2 & 0x03) == 0x02)
read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode2_xa_form2(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
else
read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode2_non_xa(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
} else {
if (audio)
read_audio(dev, lba, temp_b);
ret = read_audio(dev, lba, temp_b);
else
read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
ret = read_mode1(dev, cdrom_sector_flags, lba, msf, mode2, temp_b);
}
}
@@ -1914,7 +2006,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int c
*len = cdrom_sector_size;
return 1;
return ret;
}
/* Peform a master init on the entire module. */
@@ -1935,6 +2027,22 @@ cdrom_drive_reset(cdrom_t *dev)
dev->get_channel = NULL;
}
/* Will be removed later. */
#ifdef ENABLE_CDROM_LOG
static void
cdrom_toc_dump(cdrom_t *dev)
{
uint8_t b[65536] = { 0 };
int len = cdrom_read_toc(dev, b, CD_TOC_RAW, 0, 0, 65536);
const char *fn2 = "d:\\86boxnew\\toc_cue.dmp";
FILE * f = fopen(fn2, "wb");
fwrite(b, 1, len, f);
fflush(f);
fclose(f);
pclog("Written TOC of %i bytes to %s\n", len, fn2);
}
#endif
void
cdrom_hard_reset(void)
{
@@ -1975,6 +2083,10 @@ cdrom_hard_reset(void)
cdrom_ioctl_open(dev, dev->image_path);
else
cdrom_image_open(dev, dev->image_path);
#ifdef ENABLE_CDROM_LOG
cdrom_toc_dump(dev);
#endif
}
}
}
@@ -2016,6 +2128,25 @@ cdrom_insert(uint8_t id)
dev->insert(dev->priv);
}
void
cdrom_exit(uint8_t id)
{
cdrom_t *dev = &cdrom[id];
strcpy(dev->prev_image_path, dev->image_path);
if (dev->ops) {
if (dev->ops->exit)
dev->ops->exit(dev);
dev->ops = NULL;
}
memset(dev->image_path, 0, sizeof(dev->image_path));
cdrom_insert(id);
}
/* The mechanics of ejecting a CD-ROM from a drive. */
void
cdrom_eject(uint8_t id)
@@ -2028,13 +2159,7 @@ cdrom_eject(uint8_t id)
return;
}
strcpy(dev->prev_image_path, dev->image_path);
dev->ops->exit(dev);
dev->ops = NULL;
memset(dev->image_path, 0, sizeof(dev->image_path));
cdrom_insert(id);
cdrom_exit(id);
plat_cdrom_ui_update(id, 0);
@@ -2063,15 +2188,13 @@ cdrom_reload(uint8_t id)
strcpy(dev->image_path, dev->prev_image_path);
#ifdef _WIN32
if (strlen(dev->prev_image_path) > 0) {
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/'))
dev->image_path[strlen(dev->image_path) - 1] = '\\';
}
if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) &&
(dev->image_path[strlen(dev->image_path) - 1] == '/'))
dev->image_path[strlen(dev->image_path) - 1] = '\\';
#else
if (strlen(dev->prev_image_path) > 0) {
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\'))
dev->image_path[strlen(dev->image_path) - 1] = '/';
}
if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) &&
(dev->image_path[strlen(dev->image_path) - 1] == '\\'))
dev->image_path[strlen(dev->image_path) - 1] = '/';
#endif
if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path))
@@ -2079,6 +2202,10 @@ cdrom_reload(uint8_t id)
else
cdrom_image_open(dev, dev->image_path);
#ifdef ENABLE_CDROM_LOG
cdrom_toc_dump(dev);
#endif
cdrom_insert(id);
}

View File

@@ -61,7 +61,7 @@ cdrom_image_log(const char *fmt, ...)
static void
image_get_tracks(cdrom_t *dev, int *first, int *last)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
TMSF tmsf;
cdi_get_audio_tracks(img, first, last, &tmsf);
@@ -70,7 +70,7 @@ image_get_tracks(cdrom_t *dev, int *first, int *last)
static void
image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
TMSF tmsf;
cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr);
@@ -83,7 +83,7 @@ image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
static void
image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
TMSF rel_pos;
TMSF abs_pos;
@@ -105,7 +105,7 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
static int
image_get_capacity(cdrom_t *dev)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
int first_track;
int last_track;
int number;
@@ -130,7 +130,7 @@ image_get_capacity(cdrom_t *dev)
static int
image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
uint8_t attr;
TMSF tmsf;
int m;
@@ -162,7 +162,7 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
static int
image_is_track_pre(cdrom_t *dev, uint32_t lba)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
int track;
/* GetTrack requires LBA. */
@@ -177,7 +177,7 @@ image_is_track_pre(cdrom_t *dev, uint32_t lba)
static int
image_sector_size(struct cdrom *dev, uint32_t lba)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
return cdi_get_sector_size(img, lba);
}
@@ -185,7 +185,7 @@ image_sector_size(struct cdrom *dev, uint32_t lba)
static int
image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
switch (type) {
case CD_READ_DATA:
@@ -206,7 +206,7 @@ image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba)
static int
image_track_type(cdrom_t *dev, uint32_t lba)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
if (img) {
if (image_is_track_audio(dev, lba, 0))
@@ -229,14 +229,14 @@ image_ext_medium_changed(cdrom_t *dev)
static void
image_exit(cdrom_t *dev)
{
cd_img_t *img = (cd_img_t *) dev->image;
cd_img_t *img = (cd_img_t *) dev->local;
cdrom_image_log("CDROM: image_exit(%s)\n", dev->image_path);
dev->cd_status = CD_STATUS_EMPTY;
if (img) {
cdi_close(img);
dev->image = NULL;
dev->local = NULL;
}
dev->ops = NULL;
@@ -245,6 +245,7 @@ image_exit(cdrom_t *dev)
static const cdrom_ops_t cdrom_image_ops = {
image_get_tracks,
image_get_track_info,
NULL,
image_get_subchannel,
image_is_track_pre,
image_sector_size,
@@ -282,7 +283,7 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
return image_open_abort(dev);
memset(img, 0, sizeof(cd_img_t));
dev->image = img;
dev->local = img;
/* Open the image. */
int i = cdi_set_device(img, fn);
@@ -294,11 +295,16 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
dev->cd_status = CD_STATUS_DATA_ONLY;
else
dev->cd_status = CD_STATUS_STOPPED;
dev->is_dir = (i == 3);
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cdrom_capacity = image_get_capacity(dev);
cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL);
int cm, cs, cf;
cf = dev->cdrom_capacity % 75;
cs = (dev->cdrom_capacity / 75) % 60;
cm = (dev->cdrom_capacity / 75) / 60;
pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n",
dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf);
/* Attach this handler to the drive. */
dev->ops = &cdrom_image_ops;

View File

@@ -14,10 +14,12 @@
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* The DOSBox Team, <unknown>
* Cacodemon345
*
* Copyright 2016-2020 Miran Grca.
* Copyright 2017-2020 Fred N. van Kempen.
* Copyright 2002-2020 The DOSBox Team.
* Copyright 2024 Cacodemon345.
*/
#define __STDC_FORMAT_MACROS
#include <ctype.h>
@@ -40,6 +42,8 @@
#include <86box/plat.h>
#include <86box/cdrom_image_backend.h>
#include <sndfile.h>
#define CDROM_BCD(x) (((x) % 10) | (((x) / 10) << 4))
#define MAX_LINE_LENGTH 512
@@ -66,30 +70,133 @@ cdrom_image_backend_log(const char *fmt, ...)
# define cdrom_image_backend_log(fmt, ...)
#endif
typedef struct audio_file_t {
SNDFILE *file;
SF_INFO info;
} audio_file_t;
/* Audio file functions */
static int
audio_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
{
track_file_t *tf = (track_file_t *) priv;
audio_file_t *audio = (audio_file_t *) tf->priv;
uint64_t samples_seek = seek / 4;
uint64_t samples_count = count / 4;
if ((seek & 3) || (count & 3)) {
cdrom_image_backend_log("CD Audio file: Reading on non-4-aligned boundaries.\n");
}
sf_count_t res = sf_seek(audio->file, samples_seek, SEEK_SET);
if (res == -1)
return 0;
return !!sf_readf_short(audio->file, (short *) buffer, samples_count);
}
static uint64_t
audio_get_length(void *priv)
{
track_file_t *tf = (track_file_t *) priv;
audio_file_t *audio = (audio_file_t *) tf->priv;
/* Assume 16-bit audio, 2 channel. */
return audio->info.frames * 4ull;
}
static void
audio_close(void *priv)
{
track_file_t *tf = (track_file_t *) priv;
audio_file_t *audio = (audio_file_t *) tf->priv;
memset(tf->fn, 0x00, sizeof(tf->fn));
if (audio && audio->file)
sf_close(audio->file);
free(audio);
free(tf);
}
static track_file_t *
audio_init(const char *filename, int *error)
{
track_file_t *tf = (track_file_t *) calloc(sizeof(track_file_t), 1);
audio_file_t *audio = (audio_file_t *) calloc(sizeof(audio_file_t), 1);
#ifdef _WIN32
wchar_t filename_w[4096];
#endif
if (tf == NULL || audio == NULL) {
goto cleanup_error;
}
memset(tf->fn, 0x00, sizeof(tf->fn));
strncpy(tf->fn, filename, sizeof(tf->fn) - 1);
#ifdef _WIN32
mbstowcs(filename_w, filename, 4096);
audio->file = sf_wchar_open(filename_w, SFM_READ, &audio->info);
#else
audio->file = sf_open(filename, SFM_READ, &audio->info);
#endif
if (!audio->file) {
cdrom_image_backend_log("Audio file open error!");
goto cleanup_error;
}
if (audio->info.channels != 2 || audio->info.samplerate != 44100 || !audio->info.seekable) {
cdrom_image_backend_log("Audio file not seekable or in non-CD format!");
sf_close(audio->file);
goto cleanup_error;
}
*error = 0;
tf->priv = audio;
tf->fp = NULL;
tf->close = audio_close;
tf->get_length = audio_get_length;
tf->read = audio_read;
return tf;
cleanup_error:
free(tf);
free(audio);
*error = 1;
return NULL;
}
/* Binary file functions. */
static int
bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
{
track_file_t *tf;
cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu\n",
tf->fp, seek, count);
track_file_t *tf = NULL;
if ((tf = (track_file_t *) priv)->fp == NULL)
return 0;
cdrom_image_backend_log("CDROM: binary_read(%08lx, pos=%" PRIu64 " count=%lu)\n",
tf->fp, seek, count);
if (fseeko64(tf->fp, seek, SEEK_SET) == -1) {
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during seek!\n");
#endif
return 0;
return -1;
}
if (fread(buffer, count, 1, tf->fp) != 1) {
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CDROM: binary_read failed during read!\n");
#endif
return 0;
return -1;
}
if (UNLIKELY(tf->motorola)) {
for (uint64_t i = 0; i < count; i += 2) {
uint8_t buffer0 = buffer[i];
uint8_t buffer1 = buffer[i + 1];
buffer[i] = buffer1;
buffer[i + 1] = buffer0;
}
}
return 1;
@@ -98,9 +205,7 @@ bin_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
static uint64_t
bin_get_length(void *priv)
{
track_file_t *tf;
cdrom_image_backend_log("CDROM: binary_length(%08lx)\n", tf->fp);
track_file_t *tf = NULL;
if ((tf = (track_file_t *) priv)->fp == NULL)
return 0;
@@ -133,7 +238,7 @@ bin_close(void *priv)
static track_file_t *
bin_init(const char *filename, int *error)
{
track_file_t *tf = (track_file_t *) malloc(sizeof(track_file_t));
track_file_t *tf = (track_file_t *) calloc(1, sizeof(track_file_t));
struct stat stats;
if (tf == NULL) {
@@ -279,12 +384,11 @@ int
cdi_get_audio_track_info(cd_img_t *cdi, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
{
const track_t *trk = &cdi->tracks[track - 1];
const int pos = trk->start + 150;
if ((track < 1) || (track > cdi->tracks_num))
return 0;
const int pos = trk->start + 150;
FRAMES_TO_MSF(pos, &start->min, &start->sec, &start->fr);
*track_num = trk->track_number;
@@ -360,20 +464,20 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
{
const int track = cdi_get_track(cdi, sector) - 1;
const uint64_t sect = (uint64_t) sector;
int raw_size;
int cooked_size;
uint64_t offset;
int m = 0;
int s = 0;
int f = 0;
int raw_size;
int cooked_size;
uint64_t offset;
int m = 0;
int s = 0;
int f = 0;
if (track < 0)
return 0;
const track_t *trk = &cdi->tracks[track];
const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
const track_t *trk = &cdi->tracks[track];
const int track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size);
const uint64_t seek = trk->skip + ((sect - trk->start) * trk->sector_size);
if (track_is_raw)
raw_size = trk->sector_size;
@@ -398,8 +502,8 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
if (raw && !track_is_raw) {
memset(buffer, 0x00, 2448);
const int ret = trk->file->read(trk->file, buffer + offset, seek, length);
if (!ret)
return 0;
if (ret <= 0)
return ret;
/* Construct the rest of the raw sector. */
memset(buffer + 1, 0xff, 10);
buffer += 12;
@@ -420,23 +524,21 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
int
cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num)
{
int success = 1;
int success = 1;
/* TODO: This fails to account for Mode 2. Shouldn't we have a function
to get sector size? */
const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
const uint32_t buf_len = num * sector_size;
uint8_t *buf = (uint8_t *) malloc(buf_len * sizeof(uint8_t));
const int sector_size = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
const uint32_t buf_len = num * sector_size;
uint8_t *buf = (uint8_t *) calloc(1, buf_len * sizeof(uint8_t));
for (uint32_t i = 0; i < num; i++) {
success = cdi_read_sector(cdi, &buf[i * sector_size], raw, sector + i);
if (!success)
if (success <= 0)
break;
/* Based on the DOSBox patch, but check all 8 bytes and makes sure it's not an
audio track. */
if (raw && (sector < cdi->tracks[0].length) &&
!cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) &&
*(uint64_t *) &(buf[(i * sector_size) + 2068]))
if (raw && (sector < cdi->tracks[0].length) && !cdi->tracks[0].mode2 && (cdi->tracks[0].attr != AUDIO_TRACK) && *(uint64_t *) &(buf[(i * sector_size) + 2068]))
return 0;
}
@@ -509,11 +611,12 @@ cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form)
uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */
if (sector_size == RAW_SECTOR_SIZE) {
if (!mode2 || (form == 0))
seek += 16;
else
if (mode2 && (form > 0))
seek += 24;
}
else
seek += 16;
} else if (form > 0)
seek += 8;
file->read(file, pvd, seek, COOKED_SECTOR_SIZE);
@@ -536,76 +639,94 @@ cdi_track_push_back(cd_img_t *cdi, track_t *trk)
cdi->tracks_num++;
}
int
cdi_get_iso_track(cd_img_t *cdi, track_t *trk, const char *filename)
{
int error = 0;
int ret = 2;
memset(trk, 0, sizeof(track_t));
/* Data track (shouldn't there be a lead in track?). */
trk->file = bin_init(filename, &error);
if (error) {
if ((trk->file != NULL) && (trk->file->close != NULL))
trk->file->close(trk->file);
ret = 3;
trk->file = viso_init(filename, &error);
if (error) {
if ((trk->file != NULL) && (trk->file->close != NULL))
trk->file->close(trk->file);
return 0;
}
}
trk->number = 1;
trk->track_number = 1;
trk->attr = DATA_TRACK;
/* Try to detect ISO type. */
trk->form = 0;
trk->mode2 = 0;
if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 0, 0))
trk->sector_size = RAW_SECTOR_SIZE;
else if (cdi_can_read_pvd(trk->file, 2336, 1, 0)) {
trk->sector_size = 2336;
trk->mode2 = 1;
} else if (cdi_can_read_pvd(trk->file, 2324, 1, 2)) {
trk->sector_size = 2324;
trk->mode2 = 1;
trk->form = 2;
trk->noskip = 1;
} else if (cdi_can_read_pvd(trk->file, 2328, 1, 2)) {
trk->sector_size = 2328;
trk->mode2 = 1;
trk->form = 2;
trk->noskip = 1;
} else if (cdi_can_read_pvd(trk->file, 2336, 1, 1)) {
trk->sector_size = 2336;
trk->mode2 = 1;
trk->form = 1;
trk->skip = 8;
} else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 0)) {
trk->sector_size = RAW_SECTOR_SIZE;
trk->mode2 = 1;
} else if (cdi_can_read_pvd(trk->file, RAW_SECTOR_SIZE, 1, 1)) {
trk->sector_size = RAW_SECTOR_SIZE;
trk->mode2 = 1;
trk->form = 1;
} else {
/* We use 2048 mode 1 as the default. */
trk->sector_size = COOKED_SECTOR_SIZE;
}
trk->length = trk->file->get_length(trk->file) / trk->sector_size;
cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk->length, trk->sector_size);
return ret;
}
int
cdi_load_iso(cd_img_t *cdi, const char *filename)
{
int error;
int ret = 2;
track_t trk;
track_t trk = { 0 };
cdi->tracks = NULL;
cdi->tracks_num = 0;
memset(&trk, 0, sizeof(track_t));
ret = cdi_get_iso_track(cdi, &trk, filename);
/* Data track (shouldn't there be a lead in track?). */
trk.file = bin_init(filename, &error);
if (error) {
if ((trk.file != NULL) && (trk.file->close != NULL))
trk.file->close(trk.file);
ret = 3;
trk.file = viso_init(filename, &error);
if (error) {
if ((trk.file != NULL) && (trk.file->close != NULL))
trk.file->close(trk.file);
return 0;
}
if (ret >= 1) {
cdi_track_push_back(cdi, &trk);
/* Lead out track. */
trk.number = 2;
trk.track_number = 0xAA;
trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */
trk.start = trk.length;
trk.length = 0;
trk.file = NULL;
cdi_track_push_back(cdi, &trk);
}
trk.number = 1;
trk.track_number = 1;
trk.attr = DATA_TRACK;
/* Try to detect ISO type. */
trk.form = 0;
trk.mode2 = 0;
if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0, 0))
trk.sector_size = RAW_SECTOR_SIZE;
else if (cdi_can_read_pvd(trk.file, 2336, 1, 0)) {
trk.sector_size = 2336;
trk.mode2 = 1;
} else if (cdi_can_read_pvd(trk.file, 2324, 1, 2)) {
trk.sector_size = 2324;
trk.mode2 = 1;
trk.form = 2;
} else if (cdi_can_read_pvd(trk.file, 2328, 1, 2)) {
trk.sector_size = 2328;
trk.mode2 = 1;
trk.form = 2;
} else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.mode2 = 1;
} else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 1)) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.mode2 = 1;
trk.form = 1;
} else {
/* We use 2048 mode 1 as the default. */
trk.sector_size = COOKED_SECTOR_SIZE;
}
trk.length = trk.file->get_length(trk.file) / trk.sector_size;
cdrom_image_backend_log("ISO: Data track: length = %" PRIu64 ", sector_size = %i\n", trk.length, trk.sector_size);
cdi_track_push_back(cdi, &trk);
/* Lead out track. */
trk.number = 2;
trk.track_number = 0xAA;
trk.attr = 0x16; /* Was originally 0x00, but I believe 0x16 is appropriate. */
trk.start = trk.length;
trk.length = 0;
trk.file = NULL;
cdi_track_push_back(cdi, &trk);
return ret;
}
@@ -698,7 +819,7 @@ cdi_cue_get_frame(uint64_t *frames, char **line)
char temp[128];
int min = 0;
int sec = 0;
int fr = 0;
int fr = 0;
int success;
success = cdi_cue_get_buffer(temp, line, 0);
@@ -736,7 +857,7 @@ cdi_cue_get_flags(track_t *cur, char **line)
}
static int
cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t *total_pregap, uint64_t cur_pregap)
cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, uint64_t cur_pregap)
{
/* Frames between index 0 (prestart) and 1 (current track start) must be skipped. */
track_t *prev = NULL;
@@ -744,7 +865,8 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
/* Skip *MUST* be calculated even if prestart is 0. */
if (prestart > cur->start)
return 0;
const uint64_t skip = cur->start - prestart;
/* If prestart is 0, there is no skip. */
uint64_t skip = (prestart == 0) ? 0 : (cur->start - prestart);
if ((cdi->tracks != NULL) && (cdi->tracks_num != 0))
prev = &cdi->tracks[cdi->tracks_num - 1];
@@ -759,8 +881,9 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
if (cur->number != 1)
return 0;
cur->skip = skip * cur->sector_size;
if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip)
cur->skip += 8;
cur->start += cur_pregap;
*total_pregap = cur_pregap;
cdi_track_push_back(cdi, cur);
return 1;
}
@@ -768,21 +891,21 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
/* Current track consumes data from the same file as the previous. */
if (prev->file == cur->file) {
cur->start += *shift;
prev->length = cur->start + *total_pregap - prev->start - skip;
prev->length = cur->start - prev->start - skip;
cur->skip += prev->skip + (prev->length * prev->sector_size) + (skip * cur->sector_size);
*total_pregap += cur_pregap;
cur->start += *total_pregap;
cur->start += cur_pregap;
} else {
const uint64_t temp = prev->file->get_length(prev->file) - (prev->skip);
prev->length = temp / ((uint64_t) prev->sector_size);
prev->length = temp / ((uint64_t) prev->sector_size);
if ((temp % prev->sector_size) != 0)
/* Padding. */
prev->length++;
/* Padding. */
cur->start += prev->start + prev->length + cur_pregap;
cur->skip = skip * cur->sector_size;
if ((cur->sector_size != RAW_SECTOR_SIZE) && (cur->form > 0) && !cur->noskip)
cur->skip += 8;
*shift += prev->start + prev->length;
*total_pregap = cur_pregap;
}
/* Error checks. */
@@ -803,12 +926,12 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
{
track_t trk;
char pathname[MAX_FILENAME_LENGTH];
uint64_t shift = 0ULL;
uint64_t prestart = 0ULL;
uint64_t cur_pregap = 0ULL;
uint64_t total_pregap = 0ULL;
uint64_t frame = 0ULL;
uint64_t shift = 0ULL;
uint64_t prestart = 0ULL;
uint64_t cur_pregap = 0ULL;
uint64_t frame = 0ULL;
uint64_t index;
int iso_file_used = 0;
int success;
int error;
int can_add_track = 0;
@@ -858,87 +981,103 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
if (!strcmp(command, "TRACK")) {
if (can_add_track)
success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap);
success = cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap);
else
success = 1;
if (!success)
break;
trk.start = 0;
trk.skip = 0;
cur_pregap = 0;
prestart = 0;
if (iso_file_used) {
/* We don't alter anything of the detected track type with the one specified in the CUE file, except its numbers. */
cur_pregap = 0;
prestart = 0;
trk.number = cdi_cue_get_number(&line);
trk.track_number = trk.number;
success = cdi_cue_get_keyword(&type, &line);
if (!success)
break;
trk.number = cdi_cue_get_number(&line);
trk.track_number = trk.number;
success = cdi_cue_get_keyword(&type, &line);
if (!success)
break;
can_add_track = 1;
trk.form = 0;
trk.mode2 = 0;
iso_file_used = 0;
} else {
trk.start = 0;
trk.skip = 0;
cur_pregap = 0;
prestart = 0;
trk.pre = 0;
trk.number = cdi_cue_get_number(&line);
trk.track_number = trk.number;
success = cdi_cue_get_keyword(&type, &line);
if (!success)
break;
if (!strcmp(type, "AUDIO")) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = AUDIO_TRACK;
} else if (!strcmp(type, "MODE1/2048")) {
trk.sector_size = COOKED_SECTOR_SIZE;
trk.attr = DATA_TRACK;
} else if (!strcmp(type, "MODE1/2352")) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = DATA_TRACK;
} else if (!strcmp(type, "MODE1/2448")) {
trk.sector_size = 2448;
trk.attr = DATA_TRACK;
} else if (!strcmp(type, "MODE2/2048")) {
trk.form = 1;
trk.sector_size = COOKED_SECTOR_SIZE;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2324")) {
trk.form = 2;
trk.sector_size = 2324;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2328")) {
trk.form = 2;
trk.sector_size = 2328;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2336")) {
trk.sector_size = 2336;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2352")) {
/* Assume this is XA Mode 2 Form 1. */
trk.form = 1;
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2448")) {
/* Assume this is XA Mode 2 Form 1. */
trk.form = 1;
trk.sector_size = 2448;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "CDG/2448")) {
trk.sector_size = 2448;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "CDI/2336")) {
trk.sector_size = 2336;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "CDI/2352")) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else
success = 0;
trk.form = 0;
trk.mode2 = 0;
can_add_track = 1;
trk.pre = 0;
if (!strcmp(type, "AUDIO")) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = AUDIO_TRACK;
} else if (!strcmp(type, "MODE1/2048")) {
trk.sector_size = COOKED_SECTOR_SIZE;
trk.attr = DATA_TRACK;
} else if (!strcmp(type, "MODE1/2352")) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = DATA_TRACK;
} else if (!strcmp(type, "MODE1/2448")) {
trk.sector_size = 2448;
trk.attr = DATA_TRACK;
} else if (!strcmp(type, "MODE2/2048")) {
trk.form = 1;
trk.sector_size = COOKED_SECTOR_SIZE;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2324")) {
trk.form = 2;
trk.sector_size = 2324;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2328")) {
trk.form = 2;
trk.sector_size = 2328;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2336")) {
trk.form = 1;
trk.sector_size = 2336;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2352")) {
/* Assume this is XA Mode 2 Form 1. */
trk.form = 1;
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "MODE2/2448")) {
/* Assume this is XA Mode 2 Form 1. */
trk.form = 1;
trk.sector_size = 2448;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "CDG/2448")) {
trk.sector_size = 2448;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "CDI/2336")) {
trk.sector_size = 2336;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else if (!strcmp(type, "CDI/2352")) {
trk.sector_size = RAW_SECTOR_SIZE;
trk.attr = DATA_TRACK;
trk.mode2 = 1;
} else
success = 0;
can_add_track = 1;
}
} else if (!strcmp(command, "INDEX")) {
index = cdi_cue_get_number(&line);
success = cdi_cue_get_frame(&frame, &line);
@@ -957,11 +1096,11 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
break;
}
} else if (!strcmp(command, "FILE")) {
char filename[MAX_FILENAME_LENGTH];
char ansi[MAX_FILENAME_LENGTH];
char filename[MAX_FILENAME_LENGTH];
char ansi[MAX_FILENAME_LENGTH];
if (can_add_track)
success = cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap);
success = cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap);
else
success = 1;
if (!success)
@@ -981,15 +1120,41 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
trk.file = NULL;
error = 1;
if (!strcmp(type, "BINARY")) {
path_append_filename(filename, pathname, ansi);
trk.file = track_file_init(filename, &error);
if (!strcmp(type, "BINARY") || !strcmp(type, "MOTOROLA")) {
int fn_len = 0;
if (!path_abs(ansi)) {
path_append_filename(filename, pathname, ansi);
} else {
strcpy(filename, ansi);
}
fn_len = strlen(filename);
if ((tolower((int) filename[fn_len - 1]) == 'o'
&& tolower((int) filename[fn_len - 2]) == 's'
&& tolower((int) filename[fn_len - 3]) == 'i'
&& filename[fn_len - 4] == '.')
|| plat_dir_check(filename)) {
error = !cdi_get_iso_track(cdi, &trk, filename);
if (!error) {
iso_file_used = 1;
}
} else
trk.file = track_file_init(filename, &error);
if (trk.file) {
trk.file->motorola = !strcmp(type, "MOTOROLA");
}
} else if (!strcmp(type, "WAVE") || !strcmp(type, "AIFF") || !strcmp(type, "MP3")) {
if (!path_abs(ansi)) {
path_append_filename(filename, pathname, ansi);
} else {
strcpy(filename, ansi);
}
trk.file = audio_init(filename, &error);
}
if (error) {
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CUE: cannot open fille '%s' in cue sheet!\n",
cdrom_image_backend_log("CUE: cannot open file '%s' in cue sheet!\n",
filename);
#endif
if (trk.file != NULL) {
trk.file->close(trk.file);
trk.file = NULL;
@@ -1004,9 +1169,8 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
/* Ignored commands. */
success = 1;
} else {
#ifdef ENABLE_CDROM_IMAGE_BACKEND_LOG
cdrom_image_backend_log("CUE: unsupported command '%s' in cue sheet!\n", command);
#endif
success = 0;
}
@@ -1019,17 +1183,16 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
return 0;
/* Add last track. */
if (!cdi_add_track(cdi, &trk, &shift, prestart, &total_pregap, cur_pregap))
if (!cdi_add_track(cdi, &trk, &shift, prestart, cur_pregap))
return 0;
/* Add lead out track. */
trk.number++;
trk.track_number = 0xAA;
trk.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */
trk.start = 0;
trk.length = 0;
trk.file = NULL;
if (!cdi_add_track(cdi, &trk, &shift, 0, &total_pregap, 0))
if (!cdi_add_track(cdi, &trk, &shift, 0, 0))
return 0;
return 1;
@@ -1056,7 +1219,7 @@ cdi_has_audio_track(cd_img_t *cdi)
if ((cdi == NULL) || (cdi->tracks == NULL))
return 0;
/* Audio track has attribute 0x14. */
/* Audio track has attribute 0x10. */
for (int i = 0; i < cdi->tracks_num; i++) {
if (cdi->tracks[i].attr == AUDIO_TRACK)
return 1;

View File

@@ -46,28 +46,35 @@
# define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
#endif
#define VISO_SKIP(p, n) \
{ \
memset(p, 0x00, n); \
p += n; \
#ifdef _WIN32
# define stat _stat64
typedef struct __stat64 stat_t;
#else
typedef struct stat stat_t;
#endif
#define VISO_SKIP(p, n) \
{ \
memset((p), 0x00, (n)); \
(p) += (n); \
}
#define VISO_TIME_VALID(t) ((t) > 0)
/* ISO 9660 defines "both endian" data formats, which
are stored as little endian followed by big endian. */
#define VISO_LBE_16(p, x) \
{ \
*((uint16_t *) p) = cpu_to_le16(x); \
p += 2; \
*((uint16_t *) p) = cpu_to_be16(x); \
p += 2; \
#define VISO_LBE_16(p, x) \
{ \
*((uint16_t *) (p)) = cpu_to_le16((x)); \
(p) += 2; \
*((uint16_t *) (p)) = cpu_to_be16((x)); \
(p) += 2; \
}
#define VISO_LBE_32(p, x) \
{ \
*((uint32_t *) p) = cpu_to_le32(x); \
p += 4; \
*((uint32_t *) p) = cpu_to_be32(x); \
p += 4; \
#define VISO_LBE_32(p, x) \
{ \
*((uint32_t *) (p)) = cpu_to_le32((x)); \
(p) += 4; \
*((uint32_t *) (p)) = cpu_to_be32((x)); \
(p) += 4; \
}
#define VISO_SECTOR_SIZE COOKED_SECTOR_SIZE
@@ -106,7 +113,7 @@ typedef struct _viso_entry_ {
};
uint16_t pt_idx;
struct stat stats;
stat_t stats;
struct _viso_entry_ *parent, *next, *next_dir, *first_child;
@@ -496,10 +503,6 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type)
*p++ = 0; /* extended attribute length */
VISO_SKIP(p, 8); /* sector offset */
VISO_LBE_32(p, entry->stats.st_size); /* size (filled in later if this is a directory) */
#ifdef _WIN32
if (entry->stats.st_mtime < 0)
pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path);
#endif
p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* time */
*p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */
@@ -671,9 +674,9 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
/* Handle reads in a sector by sector basis. */
while (count > 0) {
/* Determine the current sector, offset and remainder. */
uint32_t sector = seek / viso->sector_size;
uint32_t sector_offset = seek % viso->sector_size;
uint32_t sector_remain = MIN(count, viso->sector_size - sector_offset);
size_t sector = seek / viso->sector_size;
size_t sector_offset = seek % viso->sector_size;
size_t sector_remain = MIN(count, viso->sector_size - sector_offset);
/* Handle sector. */
if (sector < viso->metadata_sectors) {
@@ -713,8 +716,11 @@ viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count)
}
/* Read data. */
if (entry->file && (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) != -1))
read = fread(buffer, 1, sector_remain, entry->file);
if (!entry->file || (fseeko64(entry->file, seek - entry->data_offset, SEEK_SET) == -1))
return -1;
read = fread(buffer, 1, sector_remain, entry->file);
if (sector_remain && !read)
return -1;
}
/* Fill remainder with 00 bytes if needed. */
@@ -830,7 +836,7 @@ viso_init(const char *dirname, int *error)
strcpy(dir->path, dirname);
if (stat(dirname, &dir->stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&dir->stats, 0x00, sizeof(struct stat));
memset(&dir->stats, 0x00, sizeof(stat_t));
}
if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */
goto end;
@@ -879,7 +885,7 @@ viso_init(const char *dirname, int *error)
/* Stat the current directory or parent directory. */
if (stat(children_count ? dir->parent->path : dir->path, &entry->stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&entry->stats, 0x00, sizeof(struct stat));
memset(&entry->stats, 0x00, sizeof(stat_t));
}
/* Set basename. */
@@ -909,7 +915,7 @@ viso_init(const char *dirname, int *error)
/* Stat this child. */
if (stat(entry->path, &entry->stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&entry->stats, 0x00, sizeof(struct stat));
memset(&entry->stats, 0x00, sizeof(stat_t));
}
/* Handle file size and El Torito boot code. */
@@ -1432,7 +1438,7 @@ next_entry:
/* Allocate entry map for sector->file lookups. */
size_t orig_sector_size = viso->sector_size;
while (1) {
cdrom_image_viso_log("VISO: Allocating entry map for %d %d-byte sectors\n", viso->entry_map_size, viso->sector_size);
cdrom_image_viso_log("VISO: Allocating entry map for %zu %zu-byte sectors\n", viso->entry_map_size, viso->sector_size);
viso->entry_map = (viso_entry_t **) calloc(viso->entry_map_size, sizeof(viso_entry_t *));
if (viso->entry_map) {
/* Successfully allocated. */
@@ -1444,7 +1450,7 @@ next_entry:
/* If we don't have enough memory, double the sector size. */
viso->sector_size *= 2;
if (viso->sector_size == 0) /* give up if sectors become too large */
if ((viso->sector_size < VISO_SECTOR_SIZE) || (viso->sector_size > (1 << 30))) /* give up if sectors become too large */
goto end;
/* Go through files, recalculating the entry map size. */
@@ -1515,10 +1521,10 @@ next_entry:
entry->data_offset = ((uint64_t) viso->all_sectors) * viso->sector_size;
/* Determine how many sectors this file will take. */
uint32_t size = entry->stats.st_size / viso->sector_size;
size_t size = entry->stats.st_size / viso->sector_size;
if (entry->stats.st_size % viso->sector_size)
size++; /* round up to the next sector */
cdrom_image_viso_log("[%08X] %s => %" PRIu32 " + %" PRIu32 " sectors\n", entry, entry->path, viso->all_sectors, size);
cdrom_image_viso_log("[%08X] %s => %zu + %zu sectors\n", entry, entry->path, viso->all_sectors, size);
/* Allocate sectors to this file. */
viso->all_sectors += size;
@@ -1537,13 +1543,13 @@ next_entry:
viso_pwrite(data, viso->vol_size_offsets[i], 8, 1, viso->tf.fp);
/* Metadata processing is finished, read it back to memory. */
cdrom_image_viso_log("VISO: Reading back %d %d-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
cdrom_image_viso_log("VISO: Reading back %zu %zu-byte sectors of metadata\n", viso->metadata_sectors, viso->sector_size);
viso->metadata = (uint8_t *) calloc(viso->metadata_sectors, viso->sector_size);
if (!viso->metadata)
goto end;
fseeko64(viso->tf.fp, 0, SEEK_SET);
uint64_t metadata_size = viso->metadata_sectors * viso->sector_size;
uint64_t metadata_remain = metadata_size;
size_t metadata_size = viso->metadata_sectors * viso->sector_size;
size_t metadata_remain = metadata_size;
while (metadata_remain > 0)
metadata_remain -= fread(viso->metadata + (metadata_size - metadata_remain), 1, MIN(metadata_remain, viso->sector_size), viso->tf.fp);

View File

@@ -28,9 +28,9 @@
#include <86box/config.h>
#include <86box/path.h>
#include <86box/plat.h>
#include <86box/plat_cdrom.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/plat_cdrom.h>
#ifdef ENABLE_CDROM_IOCTL_LOG
int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG;
@@ -56,19 +56,19 @@ cdrom_ioctl_log(const char *fmt, ...)
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static void
ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last)
ioctl_get_tracks(cdrom_t *dev, int *first, int *last)
{
TMSF tmsf;
plat_cdrom_get_audio_tracks(first, last, &tmsf);
plat_cdrom_get_audio_tracks(dev->local, first, last, &tmsf);
}
static void
ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t *ti)
ioctl_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
{
TMSF tmsf;
plat_cdrom_get_audio_track_info(end, track, &ti->number, &tmsf, &ti->attr);
plat_cdrom_get_audio_track_info(dev->local, end, track, &ti->number, &tmsf, &ti->attr);
ti->m = tmsf.min;
ti->s = tmsf.sec;
@@ -76,13 +76,19 @@ ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t
}
static void
ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc)
ioctl_get_raw_track_info(cdrom_t *dev, int *num, raw_track_info_t *rti)
{
plat_cdrom_get_raw_track_info(dev->local, num, rti);
}
static void
ioctl_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
{
TMSF rel_pos;
TMSF abs_pos;
if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) {
const uint32_t trk = plat_cdrom_get_track_start(lba, &subc->attr, &subc->track);
const uint32_t trk = plat_cdrom_get_track_start(dev->local, lba, &subc->attr, &subc->track);
FRAMES_TO_MSF(lba + 150, &abs_pos.min, &abs_pos.sec, &abs_pos.fr);
@@ -91,7 +97,7 @@ ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc)
subc->index = 1;
} else
plat_cdrom_get_audio_sub(lba, &subc->attr, &subc->track, &subc->index,
plat_cdrom_get_audio_sub(dev->local, lba, &subc->attr, &subc->track, &subc->index,
&rel_pos, &abs_pos);
subc->abs_m = abs_pos.min;
@@ -107,11 +113,11 @@ ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc)
}
static int
ioctl_get_capacity(UNUSED(cdrom_t *dev))
ioctl_get_capacity(cdrom_t *dev)
{
int ret;
ret = plat_cdrom_get_last_block();
ret = plat_cdrom_get_last_block(dev->local);
cdrom_ioctl_log("GetCapacity=%x.\n", ret);
return ret;
}
@@ -134,35 +140,35 @@ ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
}
/* GetTrack requires LBA. */
return plat_cdrom_is_track_audio(pos);
return plat_cdrom_is_track_audio(dev->local, pos);
}
static int
ioctl_is_track_pre(UNUSED(cdrom_t *dev), uint32_t lba)
ioctl_is_track_pre(cdrom_t *dev, uint32_t lba)
{
return plat_cdrom_is_track_pre(lba);
return plat_cdrom_is_track_pre(dev->local, lba);
}
static int
ioctl_sector_size(UNUSED(cdrom_t *dev), uint32_t lba)
ioctl_sector_size(cdrom_t *dev, uint32_t lba)
{
cdrom_ioctl_log("LBA=%x.\n", lba);
return plat_cdrom_get_sector_size(lba);
return plat_cdrom_get_sector_size(dev->local, lba);
}
static int
ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba)
ioctl_read_sector(cdrom_t *dev, int type, uint8_t *b, uint32_t lba)
{
switch (type) {
case CD_READ_DATA:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n");
return plat_cdrom_read_sector(b, 0, lba);
return plat_cdrom_read_sector(dev->local, b, 0, lba);
case CD_READ_AUDIO:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n");
return plat_cdrom_read_sector(b, 1, lba);
return plat_cdrom_read_sector(dev->local, b, 1, lba);
case CD_READ_RAW:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n");
return plat_cdrom_read_sector(b, 1, lba);
return plat_cdrom_read_sector(dev->local, b, 1, lba);
default:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n");
break;
@@ -191,7 +197,7 @@ ioctl_ext_medium_changed(cdrom_t *dev)
if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED))
ret = 0;
else
ret = plat_cdrom_ext_medium_changed();
ret = plat_cdrom_ext_medium_changed(dev->local);
if (ret == 1) {
dev->cd_status = CD_STATUS_STOPPED;
@@ -208,7 +214,8 @@ ioctl_exit(cdrom_t *dev)
cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path);
dev->cd_status = CD_STATUS_EMPTY;
plat_cdrom_close();
plat_cdrom_close(dev->local);
dev->local = NULL;
dev->ops = NULL;
}
@@ -216,6 +223,7 @@ ioctl_exit(cdrom_t *dev)
static const cdrom_ops_t cdrom_ioctl_ops = {
ioctl_get_tracks,
ioctl_get_track_info,
ioctl_get_raw_track_info,
ioctl_get_subchannel,
ioctl_is_track_pre,
ioctl_sector_size,
@@ -238,9 +246,10 @@ int
cdrom_ioctl_open(cdrom_t *dev, const char *drv)
{
const char *actual_drv = &(drv[8]);
int local_size = plat_cdrom_get_local_size();
/* Make sure to not STRCPY if the two are pointing
at the same place. */
at the same place. */
if (drv != dev->image_path)
strcpy(dev->image_path, drv);
@@ -248,13 +257,14 @@ cdrom_ioctl_open(cdrom_t *dev, const char *drv)
if (strstr(drv, "ioctl://") != drv)
return cdrom_ioctl_open_abort(dev);
cdrom_ioctl_log("actual_drv = %s\n", actual_drv);
int i = plat_cdrom_set_drive(actual_drv);
if (dev->local == NULL)
dev->local = calloc(1, local_size);
int i = plat_cdrom_set_drive(dev->local, actual_drv);
if (!i)
return cdrom_ioctl_open_abort(dev);
/* All good, reset state. */
dev->cd_status = CD_STATUS_STOPPED;
dev->is_dir = 0;
dev->seek_pos = 0;
dev->cd_buflen = 0;
dev->cdrom_capacity = ioctl_get_capacity(dev);

View File

@@ -197,7 +197,7 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first)
}
cdrom_stop(&cdrom);
ret = cdrom_readsector_raw(&cdrom, dev->buf, cdrom.seek_pos, 0, 2, 0x10, (int *) &dev->readcount, 0);
if (!ret)
if (ret <= 0)
return 0;
if (dev->mode & 0x40) {
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);

View File

@@ -9,20 +9,80 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2024 Jasmine Iwanek.
#
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1435.c ali1489.c
ali1531.c ali1541.c ali1543.c ali1621.c ali6117.c ali1409.c headland.c ims8848.c intel_82335.c
compaq_386.c contaq_82c59x.c cs4031.c intel_420ex.c intel_4x0.c intel_i450kx.c
intel_sio.c intel_piix.c ../ioapic.c neat.c opti283.c opti291.c opti391.c opti495.c
opti602.c opti822.c opti895.c opti5x7.c scamp.c scat.c sis_85c310.c sis_85c4xx.c
sis_85c496.c sis_85c50x.c sis_5511.c sis_5571.c sis_5581.c sis_5591.c sis_5600.c
sis_5511_h2p.c sis_5571_h2p.c sis_5581_h2p.c sis_5591_h2p.c sis_5600_h2p.c
sis_5513_p2i.c sis_5513_ide.c sis_5572_usb.c sis_5595_pmu.c sis_55xx.c via_vt82c49x.c
via_vt82c505.c sis_85c310.c sis_85c4xx.c sis_85c496.c sis_85c50x.c gc100.c stpc.c
umc_8886.c umc_hb4.c umc_8890.c via_apollo.c via_pipc.c vl82c480.c wd76c10.c)
add_library(chipset OBJECT
82c100.c
acc2168.c
cs8230.c
ali1429.c
ali1435.c
ali1489.c
ali1531.c
ali1541.c
ali1543.c
ali1621.c
ali6117.c
ali1409.c
headland.c
ims8848.c
intel_82335.c
compaq_386.c
contaq_82c59x.c
cs4031.c
intel_420ex.c
intel_4x0.c
intel_i450kx.c
intel_sio.c
intel_piix.c
../ioapic.c
neat.c
opti283.c
opti291.c
opti391.c
opti495.c
opti499.c
opti602.c
opti822.c
opti895.c
opti5x7.c
scamp.c
scat.c
sis_85c310.c
sis_85c4xx.c
sis_85c496.c
sis_85c50x.c
sis_5511.c
sis_5571.c
sis_5581.c
sis_5591.c
sis_5600.c
sis_5511_h2p.c
sis_5571_h2p.c
sis_5581_h2p.c
sis_5591_h2p.c
sis_5600_h2p.c
sis_5513_p2i.c
sis_5513_ide.c
sis_5572_usb.c
sis_5595_pmu.c
sis_55xx.c
via_vt82c49x.c
via_vt82c505.c
gc100.c
stpc.c
umc_8886.c
umc_hb4.c
umc_8890.c
via_apollo.c
via_pipc.c
vl82c480.c
wd76c10.c
)
if(OLIVETTI)
target_sources(chipset PRIVATE olivetti_eva.c)

View File

@@ -37,6 +37,7 @@
#include <86box/vid_cga.h>
#include <86box/vid_cga_comp.h>
#include <86box/plat_unused.h>
#include <86box/chipset.h>
#define RAM_DIAG_L_BASE_MEM_640KB 0x00
#define RAM_DIAG_L_BASE_MEM_INV 0x10
@@ -746,6 +747,23 @@ compaq_386_init(UNUSED(const device_t *info))
return dev;
}
static void
compaq_genoa_outw(uint16_t port, uint16_t val, void *priv)
{
if (port == 0x0c02)
cpq_write_regs(0x80c00000, val, priv);
}
static void *
compaq_genoa_init(UNUSED(const device_t *info))
{
void *cpq = device_add(&compaq_386_device);
io_sethandler(0x0c02, 2, NULL, NULL, NULL, NULL, compaq_genoa_outw, NULL, cpq);
return ram;
}
const device_t compaq_386_device = {
.name = "Compaq 386 Memory Control",
.internal_name = "compaq_386",
@@ -759,3 +777,17 @@ const device_t compaq_386_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t compaq_genoa_device = {
.name = "Compaq Genoa Memory Control",
.internal_name = "compaq_genoa",
.flags = 0,
.local = 0,
.init = compaq_genoa_init,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -599,9 +599,9 @@ piix_write(int func, int addr, uint8_t val, void *priv)
pci_set_mirq_routing(PCI_MIRQ0 + (addr & 0x01), val & 0xf);
if (dev->type == 3) {
if (val & 0x20)
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
else
sff_set_irq_mode(dev->bm[1], IRQ_MODE_LEGACY);
else
sff_set_irq_mode(dev->bm[1], IRQ_MODE_MIRQ_0);
}
piix_log("MIRQ%i is %s\n", addr & 0x01, (val & 0x20) ? "disabled" : "enabled");
}

View File

@@ -31,6 +31,7 @@
#include <86box/mem.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#include <86box/port_92.h>
#include <86box/chipset.h>
#ifdef ENABLE_OPTI283_LOG
@@ -215,16 +216,27 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
opti283_t *dev = (opti283_t *) priv;
switch (addr) {
default:
break;
case 0x22:
dev->index = val;
break;
case 0x23:
if (dev->index == 0x01)
dev->regs[dev->index] = val;
break;
case 0x24:
opti283_log("OPTi 283: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
default:
break;
case 0x10:
dev->regs[dev->index] = val;
dev->regs[dev->index] = (dev->regs[dev->index] & 0x80) | (val & 0x7f);
break;
case 0x14:
@@ -236,13 +248,9 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
dev->regs[dev->index] = val;
opti283_shadow_recalc(dev);
break;
default:
break;
}
break;
default:
dev->index = 0xff;
break;
}
}
@@ -250,11 +258,17 @@ opti283_write(uint16_t addr, uint8_t val, void *priv)
static uint8_t
opti283_read(uint16_t addr, void *priv)
{
const opti283_t *dev = (opti283_t *) priv;
uint8_t ret = 0xff;
opti283_t *dev = (opti283_t *) priv;
uint8_t ret = 0xff;
if (addr == 0x24)
if ((addr == 0x23) && (dev->index == 0x01))
ret = dev->regs[dev->index];
else if (addr == 0x24) {
if ((dev->index >= 0x10) && (dev->index <= 0x14))
ret = dev->regs[dev->index];
dev->index = 0xff;
}
return ret;
}
@@ -274,6 +288,7 @@ opti283_init(UNUSED(const device_t *info))
memset(dev, 0x00, sizeof(opti283_t));
io_sethandler(0x0022, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x0023, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti283_read, NULL, NULL, opti283_write, NULL, NULL, dev);
dev->regs[0x10] = 0x3f;
@@ -296,6 +311,8 @@ opti283_init(UNUSED(const device_t *info))
opti283_shadow_recalc(dev);
device_add(&port_92_device);
return dev;
}

View File

@@ -54,10 +54,34 @@ typedef struct mem_remapping_t {
} mem_remapping_t;
typedef struct opti391_t {
uint8_t type;
uint8_t reg_base;
uint8_t min_reg;
uint8_t max_reg;
uint16_t shadowed;
uint16_t old_start;
uint8_t index;
uint8_t regs[256];
} opti391_t;
static void
opti391_recalcremap(opti391_t *dev)
{
if (dev->type < 2) {
if ((mem_size > 8192) || (dev->shadowed & 0x0ff0) ||
!(dev->regs[0x01] & 0x0f) || !(dev->regs[0x01] & 0x10)) {
mem_remap_top_ex(0, dev->old_start);
dev->old_start = 1024;
} else {
mem_remap_top_ex(0, dev->old_start);
dev->old_start = (dev->regs[0x01] & 0x0f) * 1024;
mem_remap_top_ex(-256, dev->old_start);
}
}
}
static void
opti391_shadow_recalc(opti391_t *dev)
{
@@ -70,24 +94,25 @@ opti391_shadow_recalc(opti391_t *dev)
shadowbios = shadowbios_write = 0;
/* F0000-FFFFF */
sh_enable = !(dev->regs[0x22] & 0x80);
sh_enable = (dev->regs[0x02] & 0x80);
if (sh_enable)
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
else
mem_set_mem_state_both(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
dev->shadowed |= 0xf000;
sh_write_internal = (dev->regs[0x26] & 0x40);
sh_write_internal = (dev->regs[0x06] & 0x40);
/* D0000-EFFFF */
for (uint8_t i = 0; i < 8; i++) {
base = 0xd0000 + (i << 14);
if (base >= 0xe0000) {
sh_master = (dev->regs[0x22] & 0x40);
sh_wp = (dev->regs[0x22] & 0x10);
sh_master = (dev->regs[0x02] & 0x20);
sh_wp = (dev->regs[0x02] & 0x08);
} else {
sh_master = (dev->regs[0x22] & 0x20);
sh_wp = (dev->regs[0x22] & 0x08);
sh_master = (dev->regs[0x02] & 0x40);
sh_wp = (dev->regs[0x02] & 0x10);
}
sh_enable = dev->regs[0x23] & (1 << i);
sh_enable = dev->regs[0x03] & (1 << i);
if (sh_master) {
if (sh_enable) {
@@ -95,22 +120,29 @@ opti391_shadow_recalc(opti391_t *dev)
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
else
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
} else if (sh_write_internal)
dev->shadowed |= (1 << (i + 4));
} else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
else
dev->shadowed |= (1 << (i + 4));
} else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
} else if (sh_write_internal)
dev->shadowed &= ~(1 << (i + 4));
}
} else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
else
dev->shadowed |= (1 << (i + 4));
} else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
dev->shadowed &= ~(1 << (i + 4));
}
}
/* C0000-CFFFF */
sh_master = !(dev->regs[0x26] & 0x10);
sh_wp = (dev->regs[0x26] & 0x20);
sh_master = (dev->regs[0x06] & 0x10); /* OPTi 391 datasheet erratum! */
sh_wp = (dev->regs[0x06] & 0x20);
for (uint8_t i = 0; i < 4; i++) {
base = 0xc0000 + (i << 14);
sh_enable = dev->regs[0x26] & (1 << i);
sh_enable = dev->regs[0x06] & (1 << i);
if (sh_master) {
if (sh_enable) {
@@ -118,15 +150,24 @@ opti391_shadow_recalc(opti391_t *dev)
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
else
mem_set_mem_state_both(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
} else if (sh_write_internal)
dev->shadowed |= (1 << i);
} else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
else
dev->shadowed |= (1 << i);
} else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
} else if (sh_write_internal)
dev->shadowed &= ~(1 << i);
}
} else if (sh_write_internal) {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_INTERNAL);
else
dev->shadowed |= (1 << i);
} else {
mem_set_mem_state_both(base, 0x4000, MEM_READ_EXTANY | MEM_WRITE_EXTANY);
dev->shadowed &= ~(1 << i);
}
}
opti391_recalcremap(dev);
}
static void
@@ -134,7 +175,12 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
{
opti391_t *dev = (opti391_t *) priv;
opti391_log("[W] %04X = %02X\n", addr, val);
switch (addr) {
default:
break;
case 0x22:
dev->index = val;
break;
@@ -142,35 +188,92 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
case 0x24:
opti391_log("OPTi 391: dev->regs[%02x] = %02x\n", dev->index, val);
switch (dev->index) {
case 0x20:
dev->regs[dev->index] = (dev->regs[dev->index] & 0xc0) | (val & 0x3f);
if ((dev->index <= 0x01) && (dev->type < 2)) switch (dev->index) {
case 0x00:
if (!(dev->regs[0x10] & 0x20) && (val & 0x20)) {
softresetx86(); /* Pulse reset! */
cpu_set_edx();
flushmmucache();
}
dev->regs[dev->index + 0x10] = val;
break;
case 0x21:
case 0x24:
case 0x25:
case 0x27:
case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
dev->regs[dev->index] = val;
case 0x01:
dev->regs[dev->index + 0x10] = val;
reset_on_hlt = !!(val & 0x02);
break;
case 0x22:
case 0x23:
case 0x26:
dev->regs[dev->index] = val;
opti391_shadow_recalc(dev);
break;
} else switch (dev->index - dev->reg_base) {
default:
break;
}
break;
default:
case 0x00:
if (dev->type == 2) {
reset_on_hlt = !!(val & 0x02);
if (!(dev->regs[dev->index - dev->reg_base] & 0x01) && (val & 0x01)) {
softresetx86(); /* Pulse reset! */
cpu_set_edx();
flushmmucache();
}
dev->regs[dev->index - dev->reg_base] =
(dev->regs[dev->index - dev->reg_base] & 0xc0) | (val & 0x3f);
}
break;
case 0x01:
dev->regs[dev->index - dev->reg_base] = val;
if (dev->type == 2) {
cpu_cache_ext_enabled = !!(dev->regs[0x01] & 0x10);
cpu_update_waitstates();
} else
opti391_recalcremap(dev);
break;
case 0x05:
if (dev->type == 2)
dev->regs[dev->index - dev->reg_base] = val & 0xf8;
else
dev->regs[dev->index - dev->reg_base] = val;
break;
case 0x04:
case 0x09:
case 0x0a:
case 0x0b:
dev->regs[dev->index - dev->reg_base] = val;
break;
case 0x07:
dev->regs[dev->index - dev->reg_base] = val;
if (dev->type < 2) {
mem_a20_alt = val & 0x08;
mem_a20_recalc();
}
break;
case 0x08:
if (dev->type == 2)
dev->regs[dev->index - dev->reg_base] = val & 0xe3;
else {
dev->regs[dev->index - dev->reg_base] = val;
cpu_cache_ext_enabled = !!(dev->regs[0x02] & 0x40);
cpu_update_waitstates();
}
break;
case 0x0c:
case 0x0d:
if (dev->type < 2)
dev->regs[dev->index - dev->reg_base] = val;
break;
case 0x02:
case 0x03:
case 0x06:
opti391_log("Write %02X: %02X\n", dev->index - dev->reg_base, val);
dev->regs[dev->index - dev->reg_base] = val;
opti391_shadow_recalc(dev);
break;
}
dev->index = 0xff;
break;
}
}
@@ -178,11 +281,19 @@ opti391_write(uint16_t addr, uint8_t val, void *priv)
static uint8_t
opti391_read(uint16_t addr, void *priv)
{
const opti391_t *dev = (opti391_t *) priv;
uint8_t ret = 0xff;
opti391_t *dev = (opti391_t *) priv;
uint8_t ret = 0xff;
if (addr == 0x24)
ret = dev->regs[dev->index];
if (addr == 0x24) {
if ((dev->index <= 0x01) && (dev->type < 2))
ret = dev->regs[dev->index + 0x10];
else if ((dev->index >= dev->min_reg) && (dev->index <= dev->max_reg))
ret = dev->regs[dev->index - dev->reg_base];
dev->index = 0xff;
}
opti391_log("[R] %04X = %02X\n", addr, ret);
return ret;
}
@@ -196,32 +307,68 @@ opti391_close(void *priv)
}
static void *
opti391_init(UNUSED(const device_t *info))
opti391_init(const device_t *info)
{
opti391_t *dev = (opti391_t *) malloc(sizeof(opti391_t));
memset(dev, 0x00, sizeof(opti391_t));
opti391_t *dev = (opti391_t *) calloc(1, sizeof(opti391_t));
io_sethandler(0x0022, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
io_sethandler(0x0024, 0x0001, opti391_read, NULL, NULL, opti391_write, NULL, NULL, dev);
dev->regs[0x21] = 0x84;
dev->regs[0x24] = 0x07;
dev->regs[0x25] = 0xf0;
dev->regs[0x26] = 0x30;
dev->regs[0x27] = 0x91;
dev->regs[0x28] = 0x80;
dev->regs[0x29] = 0x10;
dev->regs[0x2a] = 0x80;
dev->regs[0x2b] = 0x10;
dev->type = info->local;
if (info->local == 2) {
dev->reg_base = 0x20;
dev->min_reg = 0x20;
dev->max_reg = 0x2b;
dev->regs[0x02] = 0x84;
dev->regs[0x04] = 0x07;
dev->regs[0x05] = 0xf0;
dev->regs[0x06] = 0x30;
dev->regs[0x07] = 0x91;
dev->regs[0x08] = 0x80;
dev->regs[0x09] = 0x10;
dev->regs[0x0a] = 0x80;
dev->regs[0x0b] = 0x10;
} else {
dev->reg_base = 0x0f;
dev->min_reg = 0x10;
dev->max_reg = 0x1c;
dev->regs[0x01] = 0x01;
dev->regs[0x02] = 0xe0;
if (info->local == 1)
/* Guess due to no OPTi 48x datasheet. */
dev->regs[0x04] = 0x07;
else
dev->regs[0x04] = 0x77;
dev->regs[0x05] = 0x60;
dev->regs[0x06] = 0x10;
dev->regs[0x07] = 0x50;
if (info->local == 1) {
/* Guess due to no OPTi 48x datasheet. */
dev->regs[0x09] = 0x80; /* Non-Cacheable Block 1 */
dev->regs[0x0b] = 0x80; /* Non-Cacheable Block 2 */
dev->regs[0x0d] = 0x91; /* Cacheable Area */
} else {
dev->regs[0x09] = 0xe0; /* Non-Cacheable Block 1 */
dev->regs[0x0b] = 0x10; /* Non-Cacheable Block 2 */
dev->regs[0x0d] = 0x80; /* Cacheable Area */
}
dev->regs[0x0a] = 0x10;
dev->regs[0x0c] = 0x10;
}
dev->old_start = 1024;
opti391_shadow_recalc(dev);
return dev;
}
const device_t opti391_device = {
.name = "OPTi 82C391",
.internal_name = "opti391",
const device_t opti381_device = {
.name = "OPTi 82C381",
.internal_name = "opti381",
.flags = 0,
.local = 0,
.init = opti391_init,
@@ -232,3 +379,31 @@ const device_t opti391_device = {
.force_redraw = NULL,
.config = NULL
};
const device_t opti481_device = {
.name = "OPTi 82C481",
.internal_name = "opti481",
.flags = 0,
.local = 1,
.init = opti391_init,
.close = opti391_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t opti391_device = {
.name = "OPTi 82C391",
.internal_name = "opti391",
.flags = 0,
.local = 2,
.init = opti391_init,
.close = opti391_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -32,6 +32,8 @@
#include <86box/chipset.h>
typedef struct opti495_t {
uint8_t type;
uint8_t max;
uint8_t idx;
uint8_t regs[256];
uint8_t scratch[2];
@@ -55,6 +57,22 @@ opti495_log(const char *fmt, ...)
# define opti495_log(fmt, ...)
#endif
enum {
OPTI493 = 0,
OPTI495,
OPTI495SLC,
OPTI495SX,
OPTI495XLC,
TMAX
};
/* OPTi 82C493: According to The Last Byte, bit 1 of register 22h, while unused, must still be writable. */
static uint8_t masks[TMAX][0x1c] = { { 0x3f, 0xff, 0xff, 0xff, 0xf7, 0xfb, 0x7f, 0x9f, 0xe3, 0xff, 0xe3, 0xff },
{ 0x3a, 0x7f, 0xff, 0xff, 0xf0, 0xfb, 0x7f, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
{ 0x3a, 0x7f, 0xfc, 0xff, 0xf0, 0xfb, 0xff, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
{ 0x3a, 0xff, 0xfd, 0xff, 0xf0, 0xfb, 0x7f, 0xbf, 0xe3, 0xff, 0x00, 0x00 },
{ 0x3a, 0xff, 0xfc, 0xff, 0xf0, 0xfb, 0xff, 0xbf, 0xe3, 0xff, 0x00, 0x00 } };
static void
opti495_recalc(opti495_t *dev)
{
@@ -119,16 +137,25 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
opti495_t *dev = (opti495_t *) priv;
switch (addr) {
default:
break;
case 0x22:
opti495_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
dev->idx = val;
break;
case 0x24:
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
dev->regs[dev->idx] = val;
if ((dev->idx >= 0x20) && (dev->idx <= dev->max)) {
opti495_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
dev->regs[dev->idx] = val & masks[dev->type][dev->idx - 0x20];
if ((dev->type == OPTI493) && (dev->idx == 0x20))
val |= 0x40;
switch (dev->idx) {
default:
break;
case 0x21:
cpu_cache_ext_enabled = !!(dev->regs[0x21] & 0x10);
cpu_update_waitstates();
@@ -139,36 +166,36 @@ opti495_write(uint16_t addr, uint8_t val, void *priv)
case 0x26:
opti495_recalc(dev);
break;
default:
break;
}
}
dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
dev->scratch[~addr & 0x01] = val;
break;
default:
break;
}
}
static uint8_t
opti495_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
const opti495_t *dev = (opti495_t *) priv;
uint8_t ret = 0xff;
opti495_t *dev = (opti495_t *) priv;
switch (addr) {
case 0x22:
opti495_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
break;
case 0x24:
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
if ((dev->idx >= 0x20) && (dev->idx <= dev->max)) {
ret = dev->regs[dev->idx];
opti495_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
}
dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
@@ -202,8 +229,11 @@ opti495_init(const device_t *info)
dev->scratch[0] = dev->scratch[1] = 0xff;
if (info->local == 1) {
dev->type = info->local;
if (info->local >= OPTI495) {
/* 85C495 */
dev->max = 0x29;
dev->regs[0x20] = 0x02;
dev->regs[0x21] = 0x20;
dev->regs[0x22] = 0xe4;
@@ -214,6 +244,7 @@ opti495_init(const device_t *info)
dev->regs[0x29] = 0x10;
} else {
/* 85C493 */
dev->max = 0x2b;
dev->regs[0x20] = 0x40;
dev->regs[0x22] = 0x84;
dev->regs[0x24] = 0x87;
@@ -236,7 +267,7 @@ const device_t opti493_device = {
.name = "OPTi 82C493",
.internal_name = "opti493",
.flags = 0,
.local = 0,
.local = OPTI493,
.init = opti495_init,
.close = opti495_close,
.reset = NULL,
@@ -250,7 +281,7 @@ const device_t opti495_device = {
.name = "OPTi 82C495",
.internal_name = "opti495",
.flags = 0,
.local = 1,
.local = OPTI495XLC,
.init = opti495_init,
.close = opti495_close,
.reset = NULL,

View File

@@ -38,6 +38,9 @@ typedef struct opti499_t {
uint8_t scratch[2];
} opti499_t;
/* According to The Last Byte, register 2Dh bit 7 must still be writable, even if it is unused. */
static uint8_t masks[0x0e] = { 0x3f, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfb, 0xff, 0x00, 0xff };
#ifdef ENABLE_OPTI499_LOG
int opti499_do_log = ENABLE_OPTI499_LOG;
@@ -84,7 +87,7 @@ opti499_recalc(opti499_t *dev)
shflags = MEM_READ_INTERNAL;
shflags |= (dev->regs[0x22] & ((base >= 0xe0000) ? 0x08 : 0x10)) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x2d] && (1 << ((i >> 1) + 2)))
if (dev->regs[0x2d] & (1 << ((i >> 1) + 2)))
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
else
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
@@ -101,13 +104,13 @@ opti499_recalc(opti499_t *dev)
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x26] & 0x40) {
if (dev->regs[0x2d] && (1 << (i >> 1)))
if (dev->regs[0x2d] & (1 << (i >> 1)))
shflags = MEM_READ_EXTANY;
else
shflags = MEM_READ_EXTERNAL;
shflags |= (dev->regs[0x26] & 0x20) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL;
} else {
if (dev->regs[0x2d] && (1 << (i >> 1)))
if (dev->regs[0x2d] & (1 << (i >> 1)))
shflags = MEM_READ_EXTANY | MEM_WRITE_EXTANY;
else
shflags = MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL;
@@ -126,19 +129,25 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
opti499_t *dev = (opti499_t *) priv;
switch (addr) {
default:
break;
case 0x22:
opti499_log("[%04X:%08X] [W] dev->idx = %02X\n", CS, cpu_state.pc, val);
dev->idx = val;
break;
case 0x24:
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
if (dev->idx == 0x20)
dev->regs[dev->idx] = (dev->regs[dev->idx] & 0xc0) | (val & 0x3f);
else
dev->regs[dev->idx] = val;
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d) && (dev->idx != 0x2c)) {
opti499_log("[%04X:%08X] [W] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, val);
dev->regs[dev->idx] = val & masks[dev->idx - 0x20];
if (dev->idx == 0x2a)
dev->regs[dev->idx] |= 0x04;
switch (dev->idx) {
default:
break;
case 0x20:
reset_on_hlt = !(val & 0x02);
break;
@@ -154,20 +163,16 @@ opti499_write(uint16_t addr, uint8_t val, void *priv)
case 0x2d:
opti499_recalc(dev);
break;
default:
break;
}
}
dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
dev->scratch[~addr & 0x01] = val;
break;
default:
break;
}
}
@@ -178,25 +183,23 @@ opti499_read(uint16_t addr, void *priv)
opti499_t *dev = (opti499_t *) priv;
switch (addr) {
default:
break;
case 0x22:
opti499_log("[%04X:%08X] [R] dev->idx = %02X\n", CS, cpu_state.pc, ret);
break;
case 0x24:
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d)) {
if (dev->idx == 0x2d)
ret = dev->regs[dev->idx] & 0xbf;
else
ret = dev->regs[dev->idx];
if ((dev->idx >= 0x20) && (dev->idx <= 0x2d) && (dev->idx != 0x2c)) {
ret = dev->regs[dev->idx];
opti499_log("[%04X:%08X] [R] dev->regs[%04X] = %02X\n", CS, cpu_state.pc, dev->idx, ret);
}
dev->idx = 0xff;
break;
case 0xe1:
case 0xe2:
ret = dev->scratch[~addr & 0x01];
break;
default:
break;
}
return ret;
@@ -226,8 +229,6 @@ opti499_reset(void *priv)
cpu_update_waitstates();
opti499_recalc(dev);
free(dev);
}
static void

View File

@@ -35,7 +35,7 @@
typedef struct opti5x7_t {
uint8_t idx;
uint8_t is_pci;
uint8_t regs[16];
uint8_t regs[18];
} opti5x7_t;
#ifdef ENABLE_OPTI5X7_LOG
@@ -158,7 +158,7 @@ opti5x7_read(uint16_t addr, void *priv)
{
const opti5x7_t *dev = (opti5x7_t *) priv;
return (addr == 0x24) ? dev->regs[dev->idx] : 0xff;
return ((addr == 0x24) && (dev->idx < sizeof(dev->regs))) ? dev->regs[dev->idx] : 0xff;
}
static void

View File

@@ -42,6 +42,9 @@ typedef struct opti895_t {
smram_t *smram;
} opti895_t;
static uint8_t masks[0x10] = { 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0xe3, 0xff, 0xe3, 0xff, 0x00, 0xff, 0xff, 0xff };
#ifdef ENABLE_OPTI895_LOG
int opti895_do_log = ENABLE_OPTI895_LOG;
@@ -153,8 +156,12 @@ opti895_write(uint16_t addr, uint8_t val, void *priv)
}
break;
case 0x24:
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
dev->regs[dev->idx] = val;
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f) && (dev->idx != 0x2c)) ||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
if (dev->idx > 0x2f)
dev->regs[dev->idx] = val;
else
dev->regs[dev->idx] = val & masks[dev->idx - 0x20];
opti895_log("dev->regs[%04x] = %08x\n", dev->idx, val);
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
@@ -217,7 +224,8 @@ opti895_read(uint16_t addr, void *priv)
break;
case 0x24:
/* TODO: Registers 0x30-0x3F for OPTi 802GP and 898. */
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f)) || ((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
if (((dev->idx >= 0x20) && (dev->idx <= 0x2f) && (dev->idx != 0x2c)) ||
((dev->idx >= 0xe0) && (dev->idx <= 0xef))) {
ret = dev->regs[dev->idx];
if (dev->idx == 0xe0)
ret = (ret & 0xf6) | (in_smm ? 0x00 : 0x08) | !!dev->forced_green;

View File

@@ -107,8 +107,8 @@ sis_85c50x_shadow_recalc(sis_85c50x_t *dev)
if (dev->states[8 + i] != state) {
mem_set_mem_state_both(base, 0x00004000, state);
sis_85c50x_log("%05X-%05X: R%c, W%c\n", base, base + 0x3fff,
(dev->pci_conf[0x543 & (0x80 >> i)) ?
((dev->pci_conf[0x54] & 0x40) ? 'I' : 'D') : 'E',
(dev->pci_conf[0x54] & (0x80 >> i)) ?
((dev->pci_conf[0x53] & 0x40) ? 'I' : 'D') : 'E',
(dev->pci_conf[0x54] & (0x80 >> i)) ?
((dev->pci_conf[0x53] & 0x20) ? 'P' : 'I') : 'E');
dev->states[8 + i] = state;

View File

@@ -126,19 +126,70 @@ umc_8886_ide_handler(umc_8886_t *dev)
ide_sec_disable();
if (dev->pci_conf_sb[1][0x04] & 0x01) {
if (dev->pci_conf_sb[1][0x40] & 0x80)
if (dev->pci_conf_sb[1][0x41] & 0x80)
ide_pri_enable();
if (dev->pci_conf_sb[1][0x40] & 0x40)
if (dev->pci_conf_sb[1][0x41] & 0x40)
ide_sec_enable();
}
}
static void
umc_8886_bus_recalc(umc_8886_t *dev)
{
switch (dev->pci_conf_sb[0x00][0xa4] & 0x03) {
case 0x00:
cpu_set_pci_speed(cpu_busspeed / 2);
break;
case 0x01:
cpu_set_pci_speed(cpu_busspeed);
break;
case 0x02:
cpu_set_pci_speed((cpu_busspeed * 2) / 3);
break;
}
switch (dev->pci_conf_sb[0x00][0x56] & 0x03) {
default:
break;
case 0x00:
cpu_set_isa_pci_div(3);
break;
case 0x01:
cpu_set_isa_pci_div(4);
break;
case 0x02:
cpu_set_isa_pci_div(2);
break;
}
}
static void
umc_8886_irq_recalc(umc_8886_t *dev)
{
int irq_routing;
uint8_t *conf = dev->pci_conf_sb[0];
irq_routing = (conf[0x46] & 0x01) ? (conf[0x43] >> 4) : PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTA, irq_routing);
irq_routing = (conf[0x46] & 0x02) ? (conf[0x43] & 0x0f) : PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTB, irq_routing);
irq_routing = (conf[0x46] & 0x04) ? (conf[0x44] >> 4) : PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTC, irq_routing);
irq_routing = (conf[0x46] & 0x08) ? (conf[0x44] & 0x0f) : PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTD, irq_routing);
pci_set_irq_level(PCI_INTA, (conf[0x47] & 0x01));
pci_set_irq_level(PCI_INTB, (conf[0x47] & 0x02));
pci_set_irq_level(PCI_INTC, (conf[0x47] & 0x04));
pci_set_irq_level(PCI_INTD, (conf[0x47] & 0x08));
}
static void
umc_8886_write(int func, int addr, uint8_t val, void *priv)
{
umc_8886_t *dev = (umc_8886_t *) priv;
int irq_routing;
if (func <= dev->max_func)
switch (func) {
@@ -153,7 +204,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 0x50 ... 0x55:
case 0x57:
case 0x70 ... 0x76:
case 0x80 ... 0x82:
case 0x80 ... 0x83:
case 0x90 ... 0x92:
case 0xa0 ... 0xa1:
case 0xa5 ... 0xa8:
@@ -165,46 +216,17 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x43:
dev->pci_conf_sb[func][addr] = val;
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x01) ? (val >> 8) :
PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTA, irq_routing);
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x02) ? (val & 0x0f) :
PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTB, irq_routing);
break;
case 0x44:
dev->pci_conf_sb[func][addr] = val;
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x04) ? (val >> 8) :
PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTC, irq_routing);
irq_routing = (dev->pci_conf_sb[func][0x46] & 0x08) ? (val & 0x0f) :
PCI_IRQ_DISABLED;
pci_set_irq_routing(PCI_INTD, irq_routing);
break;
case 0x46: /* Bits 3-0 = 0 = IRQ disabled, 1 = IRQ enabled. */
case 0x47: /* Bits 3-0 = 0 = IRQ edge-triggered, 1 = IRQ level-triggered. */
/* Bit 6 seems to be the IRQ/SMI# toggle, 1 = IRQ, 0 = SMI#. */
dev->pci_conf_sb[func][addr] = val;
umc_8886_irq_recalc(dev);
break;
case 0x56:
dev->pci_conf_sb[func][addr] = val;
switch (val & 3) {
case 0:
cpu_set_isa_pci_div(3);
break;
case 1:
cpu_set_isa_pci_div(4);
break;
case 2:
cpu_set_isa_pci_div(2);
break;
default:
break;
}
umc_8886_bus_recalc(dev);
break;
case 0xa2:
@@ -225,7 +247,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
case 0xa4:
dev->pci_conf_sb[func][addr] = val;
cpu_set_pci_speed(cpu_busspeed / ((val & 1) ? 1 : 2));
umc_8886_bus_recalc(dev);
break;
default:
@@ -248,13 +270,13 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv)
break;
case 0x3c:
case 0x41 ... 0x4b:
case 0x54 ... 0x59:
case 0x40:
case 0x42 ... 0x59:
if (dev->ide_id == 0x673a)
dev->pci_conf_sb[func][addr] = val;
break;
case 0x40:
case 0x41:
if (dev->ide_id == 0x673a) {
dev->pci_conf_sb[func][addr] = val;
umc_8886_ide_handler(dev);
@@ -300,25 +322,17 @@ umc_8886_reset(void *priv)
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][0x40] = 0x01;
dev->pci_conf_sb[0][0x41] = 0x06;
dev->pci_conf_sb[0][0x41] = 0x04;
dev->pci_conf_sb[0][0x42] = 0x08;
dev->pci_conf_sb[0][0x43] = 0x00;
dev->pci_conf_sb[0][0x44] = 0x00;
dev->pci_conf_sb[0][0x45] = 0x04;
dev->pci_conf_sb[0][0x46] = 0x00;
dev->pci_conf_sb[0][0x47] = 0x40;
dev->pci_conf_sb[0][0x50] = 0x01;
dev->pci_conf_sb[0][0x51] = 0x03;
dev->pci_conf_sb[0][0x56] = dev->pci_conf_sb[0][0x57] = 0x00;
dev->pci_conf_sb[0][0x70] = dev->pci_conf_sb[0][0x71] = 0x00;
dev->pci_conf_sb[0][0x72] = dev->pci_conf_sb[0][0x73] = 0x00;
dev->pci_conf_sb[0][0x74] = dev->pci_conf_sb[0][0x76] = 0x00;
dev->pci_conf_sb[0][0x82] = 0x00;
dev->pci_conf_sb[0][0x90] = dev->pci_conf_sb[0][0x91] = 0x00;
dev->pci_conf_sb[0][0xa0] = dev->pci_conf_sb[0][0xa2] = 0x00;
dev->pci_conf_sb[0][0xa4] = 0x00;
dev->pci_conf_sb[0][0xa8] = 0x20;
dev->pci_conf_sb[0][0x43] = 0x9a;
dev->pci_conf_sb[0][0x44] = 0xbc;
dev->pci_conf_sb[0][0x45] = 0x00;
dev->pci_conf_sb[0][0x46] = 0x10;
dev->pci_conf_sb[0][0x47] = 0x30;
dev->pci_conf_sb[0][0x51] = 0x02;
if (dev->has_ide) {
dev->pci_conf_sb[1][0x00] = 0x60; /* UMC */
@@ -341,13 +355,15 @@ umc_8886_reset(void *priv)
dev->pci_conf_sb[1][0x21] = 0x10;
if (dev->ide_id == 0x673a) {
dev->pci_conf_sb[1][0x40] = 0xc0;
dev->pci_conf_sb[1][0x41] = 0x00;
dev->pci_conf_sb[1][0x40] = 0x00;
dev->pci_conf_sb[1][0x41] = 0xc0;
dev->pci_conf_sb[1][0x42] = dev->pci_conf_sb[1][0x43] = 0x00;
dev->pci_conf_sb[1][0x44] = dev->pci_conf_sb[1][0x45] = 0x00;
dev->pci_conf_sb[1][0x46] = dev->pci_conf_sb[1][0x47] = 0x00;
dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x00;
dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x00;
dev->pci_conf_sb[1][0x48] = dev->pci_conf_sb[1][0x49] = 0x55;
dev->pci_conf_sb[1][0x4a] = dev->pci_conf_sb[1][0x4b] = 0x55;
dev->pci_conf_sb[1][0x4c] = dev->pci_conf_sb[1][0x4d] = 0x88;
dev->pci_conf_sb[1][0x4e] = dev->pci_conf_sb[1][0x4f] = 0xaa;
dev->pci_conf_sb[1][0x54] = dev->pci_conf_sb[1][0x55] = 0x00;
dev->pci_conf_sb[1][0x56] = dev->pci_conf_sb[1][0x57] = 0x00;
dev->pci_conf_sb[1][0x58] = dev->pci_conf_sb[1][0x59] = 0x00;
@@ -362,8 +378,7 @@ umc_8886_reset(void *priv)
for (uint8_t i = 1; i < 5; i++) /* Disable all IRQ interrupts */
pci_set_irq_routing(i, PCI_IRQ_DISABLED);
cpu_set_isa_pci_div(3);
cpu_set_pci_speed(cpu_busspeed / 2);
umc_8886_bus_recalc(dev);
}
static void

View File

@@ -136,6 +136,9 @@ hb4_log(const char *fmt, ...)
#endif
typedef struct hb4_t {
uint8_t idx;
uint8_t access_data;
uint8_t pci_slot;
uint8_t pci_conf[256]; /* PCI Registers */
@@ -176,7 +179,9 @@ hb4_shadow_bios_low(hb4_t *dev)
int state;
/* Erratum in Vogons' datasheet: Register 55h bit 7 in fact controls E0000-FFFFF. */
state = shadow_bios[dev->pci_conf[0x55] >> 6];
state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[dev->pci_conf[0x54] & 0x01] :
MEM_READ_EXTANY;
state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[7]) {
mem_set_mem_state_both(0xe0000, 0x10000, state);
@@ -194,8 +199,9 @@ hb4_shadow_main(hb4_t *dev)
int n = 0;
for (uint8_t i = 0; i < 6; i++) {
state = shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] |
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[(dev->pci_conf[0x54] >> (i + 2)) & 0x01] :
MEM_READ_EXTANY;
state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[i + 1]) {
n++;
@@ -212,8 +218,9 @@ hb4_shadow_video(hb4_t *dev)
{
int state;
state = shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] |
shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
state = (dev->pci_conf[0x55] & 0x80) ? shadow_read[(dev->pci_conf[0x54] >> 1) & 0x01] :
MEM_READ_EXTANY;
state |= shadow_write[(dev->pci_conf[0x55] >> 6) & 0x01];
if (state != dev->mem_state[0]) {
mem_set_mem_state_both(0xc0000, 0x8000, state);
@@ -302,7 +309,7 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv)
hb4_shadow(dev);
break;
case 0x56 ... 0x5b:
case 0x56 ... 0x5a:
case 0x5e ... 0x5f:
dev->pci_conf[addr] = val;
break;
@@ -313,10 +320,14 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv)
hb4_smram(dev);
break;
case 0x61 ... 0x62:
case 0x61:
dev->pci_conf[addr] = val;
break;
case 0x62:
dev->pci_conf[addr] = val & 0x03;
break;
default:
break;
}
@@ -354,14 +365,16 @@ hb4_reset(void *priv)
dev->pci_conf[0x52] = 0x01;
dev->pci_conf[0x53] = 0x00;
dev->pci_conf[0x54] = 0x00;
dev->pci_conf[0x55] = 0x00;
dev->pci_conf[0x56] = 0x00;
dev->pci_conf[0x57] = 0x00;
dev->pci_conf[0x58] = 0x00;
dev->pci_conf[0x59] = 0x00;
dev->pci_conf[0x5a] = 0x04;
dev->pci_conf[0x55] = 0x40;
dev->pci_conf[0x56] = 0xff;
dev->pci_conf[0x57] = 0x0f;
dev->pci_conf[0x58] = 0xff;
dev->pci_conf[0x59] = 0x0f;
dev->pci_conf[0x5a] = 0x00;
dev->pci_conf[0x5b] = 0x2c;
dev->pci_conf[0x5c] = 0x00;
dev->pci_conf[0x5d] = 0x20;
dev->pci_conf[0x5d] = 0x0f;
dev->pci_conf[0x5e] = 0x00;
dev->pci_conf[0x5f] = 0xff;
dev->pci_conf[0x60] = 0x00;
dev->pci_conf[0x61] = 0x00;
@@ -385,6 +398,55 @@ hb4_close(void *priv)
free(dev);
}
static void
ims8848_write(uint16_t addr, uint8_t val, void *priv)
{
hb4_t *dev = (hb4_t *) priv;
switch (addr) {
case 0x22:
dev->idx = val;
break;
case 0x23:
if (((val & 0x0f) == ((dev->idx >> 4) & 0x0f)) && ((val & 0xf0) == ((dev->idx << 4) & 0xf0)))
dev->access_data = 1;
break;
case 0x24:
if (dev->access_data)
dev->access_data = 0;
break;
default:
break;
}
}
static uint8_t
ims8848_read(uint16_t addr, void *priv)
{
uint8_t ret = 0xff;
hb4_t *dev = (hb4_t *) priv;
switch (addr) {
case 0x22:
ret = dev->idx;
break;
case 0x23:
ret = (dev->idx >> 4) | (dev->idx << 4);
break;
case 0x24:
if (dev->access_data) {
ret = dev->pci_conf[dev->idx];
dev->access_data = 0;
}
break;
default:
break;
}
return ret;
}
static void *
hb4_init(UNUSED(const device_t *info))
{
@@ -402,6 +464,8 @@ hb4_init(UNUSED(const device_t *info))
dev->smram_base = 0x000a0000;
hb4_reset(dev);
io_sethandler(0x0022, 0x0003, ims8848_read, NULL, NULL, ims8848_write, NULL, NULL, dev);
return dev;
}

View File

@@ -9,19 +9,28 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2024 Jasmine Iwanek.
#
if(DYNAREC)
add_library(dynarec OBJECT codegen.c codegen_ops.c)
add_library(dynarec OBJECT
codegen.c
codegen_ops.c
)
if(ARCH STREQUAL "i386")
target_sources(dynarec PRIVATE codegen_x86.c
codegen_accumulate_x86.c)
target_sources(dynarec PRIVATE
codegen_x86.c
codegen_accumulate_x86.c
)
elseif(ARCH STREQUAL "x86_64")
target_sources(dynarec PRIVATE codegen_x86-64.c
codegen_accumulate_x86-64.c)
target_sources(dynarec PRIVATE
codegen_x86-64.c
codegen_accumulate_x86-64.c
)
else()
message(SEND_ERROR
"Dynarec is incompatible with target platform ${ARCH}")

View File

@@ -311,6 +311,7 @@ extern codegen_timing_t codegen_timing_686;
extern codegen_timing_t codegen_timing_486;
extern codegen_timing_t codegen_timing_winchip;
extern codegen_timing_t codegen_timing_winchip2;
extern codegen_timing_t codegen_timing_k5;
extern codegen_timing_t codegen_timing_k6;
extern codegen_timing_t codegen_timing_p6;

View File

@@ -7,6 +7,7 @@
# include <stdlib.h>
# define HAVE_STDARG_H
# include <86box/86box.h>
# include <86box/plat.h>
# include "cpu.h"
# include "x86.h"
# include "x86_flags.h"
@@ -25,14 +26,6 @@
# include "codegen_ops.h"
# include "codegen_ops_x86-64.h"
# if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
# include <sys/mman.h>
# include <unistd.h>
# endif
# if _WIN64
# include <windows.h>
# endif
int codegen_flat_ds;
int codegen_flat_ss;
int codegen_flags_changed = 0;
@@ -68,13 +61,7 @@ static int last_ssegs;
void
codegen_init(void)
{
# if _WIN64
codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
# elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
# else
codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t));
# endif
codeblock = plat_mmap(BLOCK_SIZE * sizeof(codeblock_t), 1);
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t));

View File

@@ -44,6 +44,7 @@
# include <stdlib.h>
# include <wchar.h>
# include <86box/86box.h>
# include <86box/plat.h>
# include "cpu.h"
# include <86box/mem.h>
# include "x86.h"
@@ -64,14 +65,6 @@
# include "codegen_ops.h"
# include "codegen_ops_x86.h"
# ifdef __unix__
# include <sys/mman.h>
# include <unistd.h>
# endif
# if defined _WIN32
# include <windows.h>
# endif
int codegen_flat_ds;
int codegen_flat_ss;
int mmx_ebx_ecx_loaded;
@@ -1194,13 +1187,7 @@ gen_MEM_CHECK_WRITE_L(void)
void
codegen_init(void)
{
# ifdef _WIN32
codeblock = VirtualAlloc(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
# elif defined __unix__
codeblock = mmap(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0);
# else
codeblock = malloc((BLOCK_SIZE + 1) * sizeof(codeblock_t));
# endif
codeblock = plat_mmap((BLOCK_SIZE + 1) * sizeof(codeblock_t), 1);
codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *));
memset(codeblock, 0, (BLOCK_SIZE + 1) * sizeof(codeblock_t));

View File

@@ -9,39 +9,71 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2024 Jasmine Iwanek.
#
if(DYNAREC)
add_library(dynarec OBJECT codegen.c codegen_accumulate.c
codegen_allocator.c codegen_block.c codegen_ir.c codegen_ops.c
codegen_ops_3dnow.c codegen_ops_branch.c codegen_ops_arith.c
codegen_ops_fpu_arith.c codegen_ops_fpu_constant.c
codegen_ops_fpu_loadstore.c codegen_ops_fpu_misc.c
codegen_ops_helpers.c codegen_ops_jump.c codegen_ops_logic.c
codegen_ops_misc.c codegen_ops_mmx_arith.c codegen_ops_mmx_cmp.c
codegen_ops_mmx_loadstore.c codegen_ops_mmx_logic.c
codegen_ops_mmx_pack.c codegen_ops_mmx_shift.c codegen_ops_mov.c
codegen_ops_shift.c codegen_ops_stack.c codegen_reg.c)
add_library(dynarec OBJECT
codegen.c
codegen_accumulate.c
codegen_allocator.c
codegen_block.c
codegen_ir.c
codegen_ops.c
codegen_ops_3dnow.c
codegen_ops_branch.c
codegen_ops_arith.c
codegen_ops_fpu_arith.c
codegen_ops_fpu_constant.c
codegen_ops_fpu_loadstore.c
codegen_ops_fpu_misc.c
codegen_ops_helpers.c
codegen_ops_jump.c
codegen_ops_logic.c
codegen_ops_misc.c
codegen_ops_mmx_arith.c
codegen_ops_mmx_cmp.c
codegen_ops_mmx_loadstore.c
codegen_ops_mmx_logic.c
codegen_ops_mmx_pack.c
codegen_ops_mmx_shift.c
codegen_ops_mov.c
codegen_ops_shift.c
codegen_ops_stack.c
codegen_reg.c
)
if(ARCH STREQUAL "i386")
target_sources(dynarec PRIVATE codegen_backend_x86.c
codegen_backend_x86_ops.c codegen_backend_x86_ops_fpu.c
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)
codegen_backend_x86_uops.c
)
elseif(ARCH STREQUAL "x86_64")
target_sources(dynarec PRIVATE codegen_backend_x86-64.c
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)
codegen_backend_x86-64_uops.c
)
elseif(ARCH STREQUAL "arm64")
target_sources(dynarec PRIVATE codegen_backend_arm64.c
codegen_backend_arm64_ops.c codegen_backend_arm64_uops.c
codegen_backend_arm64_imm.c)
target_sources(dynarec PRIVATE
codegen_backend_arm64.c
codegen_backend_arm64_ops.c
codegen_backend_arm64_uops.c
codegen_backend_arm64_imm.c
)
elseif(ARCH STREQUAL "arm")
target_sources(dynarec PRIVATE codegen_backend_arm.c
codegen_backend_arm_ops.c codegen_backend_arm_uops.c)
target_sources(dynarec PRIVATE
codegen_backend_arm.c
codegen_backend_arm_ops.c
codegen_backend_arm_uops.c
)
else()
message(SEND_ERROR
"Dynarec is incompatible with target platform ${ARCH}")

View File

@@ -341,6 +341,7 @@ extern codegen_timing_t codegen_timing_686;
extern codegen_timing_t codegen_timing_486;
extern codegen_timing_t codegen_timing_winchip;
extern codegen_timing_t codegen_timing_winchip2;
extern codegen_timing_t codegen_timing_k5;
extern codegen_timing_t codegen_timing_k6;
extern codegen_timing_t codegen_timing_p6;

View File

@@ -13,6 +13,7 @@
#include <86box/86box.h>
#include "cpu.h"
#include <86box/mem.h>
#include <86box/plat.h>
#include <86box/plat_unused.h>
#include "codegen.h"
@@ -33,15 +34,7 @@ int codegen_allocator_usage = 0;
void
codegen_allocator_init(void)
{
#if defined WIN32 || defined _WIN32 || defined _WIN32
mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
/* TODO: check deployment target: older Intel-based versions of macOS don't play
nice with MAP_JIT. */
#elif defined(__APPLE__) && defined(MAP_JIT)
mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0);
#else
mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
#endif
mem_block_alloc = plat_mmap(MEM_BLOCK_NR * MEM_BLOCK_SIZE, 1);
for (uint32_t c = 0; c < MEM_BLOCK_NR; c++) {
mem_blocks[c].offset = c * MEM_BLOCK_SIZE;

View File

@@ -118,7 +118,8 @@ load_general(void)
memset(temp, '\0', sizeof(temp));
p = ini_section_get_string(cat, "vid_renderer", "default");
vid_api = plat_vidapi(p);
ini_section_delete_var(cat, "vid_api");
if (!strcmp(p, "default"))
ini_section_delete_var(cat, "vid_api");
video_fullscreen_scale = ini_section_get_int(cat, "video_fullscreen_scale", 1);
@@ -202,12 +203,12 @@ load_general(void)
if (window_remember) {
p = ini_section_get_string(cat, "window_coordinates", NULL);
if (p == NULL)
p = "0, 0, 0, 0";
p = "640, 480, 0, 0";
sscanf(p, "%i, %i, %i, %i", &cw, &ch, &cx, &cy);
} else
} else {
cw = ch = cx = cy = 0;
ini_section_delete_var(cat, "window_coordinates");
ini_section_delete_var(cat, "window_coordinates");
}
do_auto_pause = ini_section_get_int(cat, "do_auto_pause", 0);
@@ -404,7 +405,7 @@ load_machine(void)
else
time_sync = TIME_SYNC_ENABLED;
} else
time_sync = !!ini_section_get_int(cat, "enable_sync", 1);
time_sync = TIME_SYNC_ENABLED;
pit_mode = ini_section_get_int(cat, "pit_mode", -1);
}
@@ -431,10 +432,17 @@ load_video(void)
strcpy(p, "none");
}
free_p = 1;
} else if (!strcmp(p, "c&t_69000")) {
p = (char *) malloc((strlen("chips_69000") + 1) * sizeof(char));
strcpy(p, "chips_69000");
free_p = 1;
}
gfxcard[0] = video_get_video_from_internal_name(p);
if (free_p)
if (free_p) {
free(p);
p = NULL;
free_p = 0;
}
}
if (((gfxcard[0] == VID_INTERNAL) && machine_has_flags(machine, MACHINE_VIDEO_8514A)) ||
@@ -452,10 +460,13 @@ load_video(void)
show_second_monitors = !!ini_section_get_int(cat, "show_second_monitors", 1);
video_fullscreen_scale_maximized = !!ini_section_get_int(cat, "video_fullscreen_scale_maximized", 0);
p = ini_section_get_string(cat, "gfxcard_2", NULL);
if (!p)
p = "none";
gfxcard[1] = video_get_video_from_internal_name(p);
// TODO
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
p = ini_section_get_string(cat, "gfxcard_2", NULL);
if (!p)
p = "none";
gfxcard[i] = video_get_video_from_internal_name(p);
}
}
/* Load "Input Devices" section. */
@@ -551,36 +562,24 @@ load_sound(void)
char *p;
p = ini_section_get_string(cat, "sndcard", NULL);
/* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
p = "es1371";
if (p != NULL)
sound_card_current[0] = sound_card_get_from_internal_name(p);
else
sound_card_current[0] = 0;
p = ini_section_get_string(cat, "sndcard2", NULL);
/* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
p = "es1371";
if (p != NULL)
sound_card_current[1] = sound_card_get_from_internal_name(p);
else
sound_card_current[1] = 0;
p = ini_section_get_string(cat, "sndcard3", NULL);
/* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
p = "es1371";
if (p != NULL)
sound_card_current[2] = sound_card_get_from_internal_name(p);
else
sound_card_current[2] = 0;
p = ini_section_get_string(cat, "sndcard4", NULL);
/* FIXME: Hack to not break configs with the Sound Blaster 128 PCI set. */
if ((p != NULL) && (!strcmp(p, "sbpci128") || !strcmp(p, "sb128pci")))
p = "es1371";
if (p != NULL)
sound_card_current[3] = sound_card_get_from_internal_name(p);
else
@@ -792,10 +791,31 @@ load_storage_controllers(void)
}
p = ini_section_get_string(cat, "fdc", NULL);
#if 1
if (p != NULL)
fdc_type = fdc_card_get_from_internal_name(p);
fdc_current[0] = fdc_card_get_from_internal_name(p);
else
fdc_type = FDC_INTERNAL;
fdc_current[0] = FDC_INTERNAL;
#else
if (p == NULL) {
if (machine_has_flags(machine, MACHINE_FDC)) {
p = (char *) malloc((strlen("internal") + 1) * sizeof(char));
strcpy(p, "internal");
} else {
p = (char *) malloc((strlen("none") + 1) * sizeof(char));
strcpy(p, "none");
}
free_p = 1;
}
fdc_current[0] = fdc_card_get_from_internal_name(p);
if (free_p) {
free(p);
p = NULL;
free_p = 0;
}
#endif
p = ini_section_get_string(cat, "hdc", NULL);
if (p == NULL) {
@@ -810,15 +830,15 @@ load_storage_controllers(void)
}
/* Migrate renamed and merged cards. */
if (!strcmp(p, "xtide_plus")) {
hdc_current = hdc_get_from_internal_name("xtide");
hdc_current[0] = hdc_get_from_internal_name("xtide");
migration_cat = ini_find_or_create_section(config, "PC/XT XTIDE");
ini_section_set_string(migration_cat, "bios", "xt_plus");
} else if (!strcmp(p, "xtide_at_386")) {
hdc_current = hdc_get_from_internal_name("xtide_at");
hdc_current[0] = hdc_get_from_internal_name("xtide_at");
migration_cat = ini_find_or_create_section(config, "PC/AT XTIDE");
ini_section_set_string(migration_cat, "bios", "at_386");
} else
hdc_current = hdc_get_from_internal_name(p);
hdc_current[0] = hdc_get_from_internal_name(p);
if (free_p) {
free(p);
@@ -832,6 +852,7 @@ load_storage_controllers(void)
if (free_p) {
free(p);
p = NULL;
free_p = 0;
}
ide_ter_enabled = !!ini_section_get_int(cat, "ide_ter", 0);
@@ -841,21 +862,75 @@ load_storage_controllers(void)
cassette_enable = !!ini_section_get_int(cat, "cassette_enabled", 0);
else
cassette_enable = 0;
p = ini_section_get_string(cat, "cassette_file", "");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_fname, p, 511);
p = ini_section_get_string(cat, "cassette_mode", "");
if (!strcmp(p, usr_path))
p[0] = 0x00;
if (p[0] != 0x00) {
if (path_abs(p)) {
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511 (cassette_fname)\n");
else
strncpy(cassette_fname, p, 511);
} else
path_append_filename(cassette_fname, usr_path, p);
path_normalize(cassette_fname);
}
p = ini_section_get_string(cat, "cassette_mode", "load");
if (strlen(p) > 511)
fatal("load_storage_controllers(): strlen(p) > 511\n");
else
strncpy(cassette_mode, p, 511);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cassette_image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "cassette_image_history_%02i", i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_storage_controllers(): strlen(p) > 2047 "
"(cassette_image_history[%i])\n", i);
else
snprintf(cassette_image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
} else
snprintf(cassette_image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(cassette_image_history[i]);
}
}
cassette_pos = ini_section_get_int(cat, "cassette_position", 0);
if (!cassette_pos)
ini_section_delete_var(cat, "cassette_position");
cassette_srate = ini_section_get_int(cat, "cassette_srate", 44100);
if (cassette_srate == 44100)
ini_section_delete_var(cat, "cassette_srate");
cassette_append = !!ini_section_get_int(cat, "cassette_append", 0);
if (!cassette_append)
ini_section_delete_var(cat, "cassette_append");
cassette_pcm = ini_section_get_int(cat, "cassette_pcm", 0);
if (!cassette_pcm)
ini_section_delete_var(cat, "cassette_pcm");
cassette_ui_writeprot = !!ini_section_get_int(cat, "cassette_writeprot", 0);
if (!cassette_ui_writeprot)
ini_section_delete_var(cat, "cassette_writeprot");
if (!cassette_enable) {
ini_section_delete_var(cat, "cassette_file");
ini_section_delete_var(cat, "cassette_mode");
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cassette_image_history_%02i", i + 1);
ini_section_delete_var(cat, temp);
}
ini_section_delete_var(cat, "cassette_position");
ini_section_delete_var(cat, "cassette_srate");
ini_section_delete_var(cat, "cassette_append");
ini_section_delete_var(cat, "cassette_pcm");
ini_section_delete_var(cat, "cassette_ui_writeprot");
}
for (c = 0; c < 2; c++) {
sprintf(temp, "cartridge_%02i_fn", c + 1);
@@ -874,9 +949,30 @@ load_storage_controllers(void)
path_append_filename(cart_fns[c], usr_path, p);
path_normalize(cart_fns[c]);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
cart_image_history[c][i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char));
sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
p = ini_section_get_string(cat, temp, NULL);
if (p) {
if (path_abs(p)) {
if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1))
fatal("load_storage_controllers(): strlen(p) > 2047 "
"(cart_image_history[%i][%i])\n", c, i);
else
snprintf(cart_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p);
} else
snprintf(cart_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path,
path_get_slash(usr_path), p);
path_normalize(cart_image_history[c][i]);
}
}
}
lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0);
if (!lba_enhancer_enabled)
ini_section_delete_var(cat, "lba_enhancer_enabled");
}
/* Load "Hard Disks" section. */
@@ -995,9 +1091,8 @@ load_hard_disks(void)
if (hdd[c].ide_channel > 7)
hdd[c].ide_channel = 7;
} else {
} else
ini_section_delete_var(cat, temp);
}
/* SCSI */
if (hdd[c].bus == HDD_BUS_SCSI) {
@@ -1060,24 +1155,24 @@ load_hard_disks(void)
sprintf(temp, "hdd_%02i_parameters", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_preide_channels", c + 1);
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channels", c + 1);
sprintf(temp, "hdd_%02i_xta_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_scsi_id", c + 1);
sprintf(temp, "hdd_%02i_esdi_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_fn", c + 1);
ini_section_delete_var(cat, temp);
}
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "hdd_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
}
}
@@ -1089,6 +1184,7 @@ load_floppy_and_cdrom_drives(void)
char temp[512];
char tmp2[512];
char *p;
char *def_type;
char s[512];
unsigned int board = 0;
unsigned int dev = 0;
@@ -1193,11 +1289,13 @@ load_floppy_and_cdrom_drives(void)
cdrom[c].speed = ini_section_get_int(cat, temp, 8);
sprintf(temp, "cdrom_%02i_type", c + 1);
p = ini_section_get_string(cat, temp, (c == 1) ? "86BOX_CD-ROM_1.00" : "none");
def_type = (c == 1) ? "86BOX_CD-ROM_1.00" : "none";
p = ini_section_get_string(cat, temp, def_type);
cdrom_set_type(c, cdrom_get_from_internal_name(p));
if (cdrom_get_type(c) > KNOWN_CDROM_DRIVE_TYPES)
cdrom_set_type(c, KNOWN_CDROM_DRIVE_TYPES);
ini_section_delete_var(cat, temp);
if (!strcmp(p, def_type))
ini_section_delete_var(cat, temp);
/* Default values, needed for proper operation of the Settings dialog. */
cdrom[c].ide_channel = cdrom[c].scsi_device_id = c + 2;
@@ -1288,7 +1386,7 @@ load_floppy_and_cdrom_drives(void)
sprintf(temp, "cdrom_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
sprintf(temp, "cdrom_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "cdrom_%02i_image_path", c + 1);
@@ -1418,7 +1516,7 @@ load_other_removable_devices(void)
sprintf(temp, "zip_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "zip_%02i_scsi_id", c + 1);
sprintf(temp, "zip_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "zip_%02i_image_path", c + 1);
@@ -1531,7 +1629,7 @@ load_other_removable_devices(void)
sprintf(temp, "mo_%02i_ide_channel", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "mo_%02i_scsi_id", c + 1);
sprintf(temp, "mo_%02i_scsi_location", c + 1);
ini_section_delete_var(cat, temp);
sprintf(temp, "mo_%02i_image_path", c + 1);
@@ -1558,15 +1656,33 @@ load_other_peripherals(void)
unittester_enabled = !!ini_section_get_int(cat, "unittester_enabled", 0);
novell_keycard_enabled = !!ini_section_get_int(cat, "novell_keycard_enabled", 0);
if (!bugger_enabled)
ini_section_delete_var(cat, "bugger_enabled");
if (!postcard_enabled)
ini_section_delete_var(cat, "postcard_enabled");
if (!unittester_enabled)
ini_section_delete_var(cat, "unittester_enabled");
if (!novell_keycard_enabled)
ini_section_delete_var(cat, "novell_keycard_enabled");
for (uint8_t c = 0; c < ISAMEM_MAX; c++) {
sprintf(temp, "isamem%d_type", c);
p = ini_section_get_string(cat, temp, "none");
isamem_type[c] = isamem_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
p = ini_section_get_string(cat, "isartc_type", "none");
isartc_type = isartc_get_from_internal_name(p);
if (!strcmp(p, "none"))
ini_section_delete_var(cat, temp);
}
/* Load the specified or a default configuration file. */
@@ -1611,7 +1727,7 @@ config_load(void)
video_fullscreen_first = 1;
video_fullscreen_scale = 1;
time_sync = TIME_SYNC_ENABLED;
hdc_current = hdc_get_from_internal_name("none");
hdc_current[0] = hdc_get_from_internal_name("none");
com_ports[0].enabled = 1;
com_ports[1].enabled = 1;
@@ -1700,7 +1816,7 @@ save_general(void)
char temp[512];
char buffer[512] = { 0 };
const char *va_name = NULL;
const char *va_name;
ini_section_set_int(cat, "vid_resize", vid_resize);
if (vid_resize == 0)
@@ -1947,17 +2063,20 @@ save_machine(void)
/* Write the mem_size explicitly to the setttings in order to help managers
to display it without having the actual machine table. */
ini_section_delete_var(cat, "mem_size");
ini_section_set_int(cat, "mem_size", mem_size);
ini_section_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec);
ini_section_set_int(cat, "fpu_softfloat", fpu_softfloat);
if (fpu_softfloat == 0)
ini_section_delete_var(cat, "fpu_softfloat");
else
ini_section_set_int(cat, "fpu_softfloat", fpu_softfloat);
if (time_sync & TIME_SYNC_ENABLED)
if (time_sync & TIME_SYNC_UTC)
ini_section_set_string(cat, "time_sync", "utc");
else
ini_section_set_string(cat, "time_sync", "local");
ini_section_delete_var(cat, "time_sync");
else
ini_section_set_string(cat, "time_sync", "disabled");
@@ -1993,10 +2112,13 @@ save_video(void)
else
ini_section_set_int(cat, "xga", xga_standalone_enabled);
if (gfxcard[1] == 0)
ini_section_delete_var(cat, "gfxcard_2");
else
ini_section_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard[1]));
// TODO
for (uint8_t i = 1; i < GFXCARD_MAX; i ++) {
if (gfxcard[i] == 0)
ini_section_delete_var(cat, "gfxcard_2");
else
ini_section_set_string(cat, "gfxcard_2", video_get_internal_name(gfxcard[i]));
}
if (show_second_monitors == 1)
ini_section_delete_var(cat, "show_second_monitors");
@@ -2144,7 +2266,10 @@ save_sound(void)
else
ini_section_set_string(cat, "sound_type", (sound_is_float == 1) ? "float" : "int16");
ini_section_set_string(cat, "fm_driver", (fm_driver == FM_DRV_NUKED) ? "nuked" : "ymfm");
if (fm_driver == FM_DRV_NUKED)
ini_section_delete_var(cat, "fm_driver");
else
ini_section_set_string(cat, "fm_driver", "ymfm");
ini_delete_section_if_empty(config, cat);
}
@@ -2227,11 +2352,10 @@ save_ports(void)
ini_section_set_int(cat, temp, com_ports[c].enabled);
sprintf(temp, "serial%d_passthrough_enabled", c + 1);
if (serial_passthrough_enabled[c]) {
if (serial_passthrough_enabled[c])
ini_section_set_int(cat, temp, 1);
} else {
else
ini_section_delete_var(cat, temp);
}
}
for (c = 0; c < PARALLEL_MAX; c++) {
@@ -2260,6 +2384,7 @@ save_storage_controllers(void)
ini_section_t cat = ini_find_or_create_section(config, "Storage controllers");
char temp[512];
int c;
char *def_hdc;
ini_section_delete_var(cat, "scsicard");
@@ -2273,14 +2398,22 @@ save_storage_controllers(void)
scsi_card_get_internal_name(scsi_card_current[c]));
}
if (fdc_type == FDC_INTERNAL)
if (fdc_current[0] == FDC_INTERNAL)
ini_section_delete_var(cat, "fdc");
else
ini_section_set_string(cat, "fdc",
fdc_card_get_internal_name(fdc_type));
fdc_card_get_internal_name(fdc_current[0]));
ini_section_set_string(cat, "hdc",
hdc_get_internal_name(hdc_current));
if (machine_has_flags(machine, MACHINE_HDC))
def_hdc = "internal";
else
def_hdc = "none";
if (!strcmp(hdc_get_internal_name(hdc_current[0]), def_hdc))
ini_section_delete_var(cat, "hdc");
else
ini_section_set_string(cat, "hdc",
hdc_get_internal_name(hdc_current[0]));
if (cdrom_interface_current == 0)
ini_section_delete_var(cat, "cdrom_interface");
@@ -2298,8 +2431,6 @@ save_storage_controllers(void)
else
ini_section_set_int(cat, "ide_qua", ide_qua_enabled);
ini_delete_section_if_empty(config, cat);
if (cassette_enable == 0)
ini_section_delete_var(cat, "cassette_enabled");
else
@@ -2307,14 +2438,32 @@ save_storage_controllers(void)
if (strlen(cassette_fname) == 0)
ini_section_delete_var(cat, "cassette_file");
else
ini_section_set_string(cat, "cassette_file", cassette_fname);
else {
path_normalize(cassette_fname);
if (!strnicmp(cassette_fname, usr_path, strlen(usr_path)))
ini_section_set_string(cat, "cassette_file", &cassette_fname[strlen(usr_path)]);
else
ini_section_set_string(cat, "cassette_file", cassette_fname);
}
if (strlen(cassette_mode) == 0)
if (!strcmp(cassette_mode, "load"))
ini_section_delete_var(cat, "cassette_mode");
else
ini_section_set_string(cat, "cassette_mode", cassette_mode);
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cassette_image_history_%02i", i + 1);
if ((cassette_image_history[i] == 0) || strlen(cassette_image_history[i]) == 0)
ini_section_delete_var(cat, temp);
else {
path_normalize(cassette_image_history[i]);
if (!strnicmp(cassette_image_history[i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cassette_image_history[i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cassette_image_history[i]);
}
}
if (cassette_pos == 0)
ini_section_delete_var(cat, "cassette_position");
else
@@ -2342,16 +2491,37 @@ save_storage_controllers(void)
for (c = 0; c < 2; c++) {
sprintf(temp, "cartridge_%02i_fn", c + 1);
if (strlen(cart_fns[c]) == 0)
ini_section_delete_var(cat, temp);
else
ini_section_set_string(cat, temp, cart_fns[c]);
else {
path_normalize(cart_fns[c]);
if (!strnicmp(cart_fns[c], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cart_fns[c][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cart_fns[c]);
}
for (int i = 0; i < MAX_PREV_IMAGES; i++) {
sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1);
if ((cart_image_history[c][i] == 0) || strlen(cart_image_history[c][i]) == 0)
ini_section_delete_var(cat, temp);
else {
path_normalize(cart_image_history[c][i]);
if (!strnicmp(cart_image_history[c][i], usr_path, strlen(usr_path)))
ini_section_set_string(cat, temp, &cart_image_history[c][i][strlen(usr_path)]);
else
ini_section_set_string(cat, temp, cart_image_history[c][i]);
}
}
}
if (lba_enhancer_enabled == 0)
ini_section_delete_var(cat, "lba_enhancer_enabled");
else
ini_section_set_int(cat, "lba_enhancer_enabled", 1);
ini_delete_section_if_empty(config, cat);
}
/* Save "Other Peripherals" section. */
@@ -2416,9 +2586,8 @@ save_hard_disks(void)
sprintf(tmp2, "%u, %u, %u, %i, %s",
hdd[c].spt, hdd[c].hpc, hdd[c].tracks, hdd[c].wp, p);
ini_section_set_string(cat, temp, tmp2);
} else {
} else
ini_section_delete_var(cat, temp);
}
sprintf(temp, "hdd_%02i_mfm_channel", c + 1);
if (hdd_is_valid(c) && (hdd[c].bus == HDD_BUS_MFM))

View File

@@ -212,11 +212,11 @@ fetch_ea_16_long(uint32_t rmdat)
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
#define CHECK_READ_CS(size) \
if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \
((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \
x86gpf("Limit check (READ)", 0); \
if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !(cpu_state.seg_cs.access & 0x80)) \
x86np("Read from seg not present", cpu_state.seg_cs.seg & 0xfffc); \
else if ((cpu_state.pc < cpu_state.seg_cs.limit_low) || \
((cpu_state.pc + size - 1) > cpu_state.seg_cs.limit_high)) \
x86gpf("Limit check (READ CS)", 0);
#include "386_ops.h"
@@ -261,7 +261,13 @@ exec386_2386(int32_t cycs)
fetchdat = fastreadl_fetch(cs + cpu_state.pc);
ol = opcode_length[fetchdat & 0xff];
CHECK_READ_CS(MIN(ol, 4));
if ((ol == 3) && opcode_has_modrm[fetchdat & 0xff] && (((fetchdat >> 14) & 0x03) == 0x03))
ol = 2;
if (cpu_16bitbus) {
CHECK_READ_CS(MIN(ol, 2));
} else {
CHECK_READ_CS(MIN(ol, 4));
}
ins_fetch_fault = cpu_386_check_instruction_fault();
/* Breakpoint fault has priority over other faults. */
@@ -273,7 +279,7 @@ exec386_2386(int32_t cycs)
if (!cpu_state.abrt) {
#ifdef ENABLE_386_LOG
if (in_smm)
x386_2386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
x386_log("[%04X:%08X] %08X\n", CS, cpu_state.pc, fetchdat);
#endif
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
@@ -298,6 +304,13 @@ exec386_2386(int32_t cycs)
cpu_state.pc &= 0xffff;
#endif
if (cpu_flush_pending == 1)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
flushmmucache_pc();
}
if (cpu_end_block_after_ins)
cpu_end_block_after_ins--;

View File

@@ -106,6 +106,28 @@ uint32_t backupregs[16];
x86seg _oldds;
int opcode_has_modrm[256] = {
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/
0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/
1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/
};
int opcode_length[256] = { 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 3, /* 0x0x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x1x */
3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, /* 0x2x */
@@ -994,9 +1016,14 @@ smram_restore_state_p6(uint32_t *saved_state)
cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff;
smm_seg_load(&cpu_state.seg_gs);
mem_a20_alt = 0x00;
mem_a20_key = saved_state[SMRAM_FIELD_P6_A20M] ? 0x00 : 0x02;
mem_a20_recalc();
rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF;
if (is6117)
rammask |= 0x3000000;
if (saved_state[SMRAM_FIELD_P6_A20M] & 0x01)
rammask &= 0xffefffff;
flushmmucache();
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET];

View File

@@ -449,6 +449,7 @@ get_ram_ptr(uint32_t a)
}
}
extern int opcode_has_modrm[256];
extern int opcode_length[256];
#ifdef OPS_286_386
@@ -457,6 +458,7 @@ fastreadw_fetch(uint32_t a)
{
uint16_t ret;
cpu_old_paging = (cpu_flush_pending == 2);
if ((a & 0xFFF) > 0xFFE) {
ret = fastreadb(a);
if (!cpu_state.abrt && (opcode_length[ret & 0xff] > 1))
@@ -468,6 +470,7 @@ fastreadw_fetch(uint32_t a)
ret = readmemwl_2386(a);
read_type = 4;
}
cpu_old_paging = 0;
return ret;
}
@@ -485,7 +488,9 @@ fastreadl_fetch(uint32_t a)
ret = 0;
else {
read_type = 1;
cpu_old_paging = (cpu_flush_pending == 2);
ret = readmemll_2386(a);
cpu_old_paging = 0;
read_type = 4;
}
@@ -562,35 +567,52 @@ fastreadl_fetch(uint32_t a)
}
#endif
#ifdef OPS_286_386
static __inline uint8_t
getbyte(void)
{
uint8_t ret;
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadb(cs + (cpu_state.pc - 1));
cpu_old_paging = 0;
return ret;
}
static __inline uint16_t
getword(void)
{
uint16_t ret;
cpu_state.pc += 2;
return fastreadw(cs + (cpu_state.pc - 2));
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadw(cs + (cpu_state.pc - 2));
cpu_old_paging = 0;
return ret;
}
static __inline uint32_t
getlong(void)
{
uint32_t ret;
cpu_state.pc += 4;
return fastreadl(cs + (cpu_state.pc - 4));
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadl(cs + (cpu_state.pc - 4));
cpu_old_paging = 0;
return ret;
}
static __inline uint64_t
getquad(void)
{
uint64_t ret;
cpu_state.pc += 8;
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
cpu_old_paging = (cpu_flush_pending == 2);
ret = fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
cpu_old_paging = 0;
return ret;
}
#ifdef OPS_286_386
static __inline uint8_t
geteab(void)
{
@@ -677,6 +699,34 @@ seteaq(uint64_t v)
# define seteaw_mem(v) writememwl_2386(easeg + cpu_state.eaaddr, v);
# define seteal_mem(v) writememll_2386(easeg + cpu_state.eaaddr, v);
#else
static __inline uint8_t
getbyte(void)
{
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
}
static __inline uint16_t
getword(void)
{
cpu_state.pc += 2;
return fastreadw(cs + (cpu_state.pc - 2));
}
static __inline uint32_t
getlong(void)
{
cpu_state.pc += 4;
return fastreadl(cs + (cpu_state.pc - 4));
}
static __inline uint64_t
getquad(void)
{
cpu_state.pc += 8;
return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32);
}
static __inline uint8_t
geteab(void)
{

View File

@@ -933,6 +933,13 @@ exec386(int32_t cycs)
x386_dynarec_log("[%04X:%08X] ABRT\n", CS, cpu_state.pc);
#endif
if (cpu_flush_pending == 1)
cpu_flush_pending++;
else if (cpu_flush_pending == 2) {
cpu_flush_pending = 0;
flushmmucache_pc();
}
#ifndef USE_NEW_DYNAREC
if (!use32)
cpu_state.pc &= 0xffff;

View File

@@ -649,7 +649,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a16, opMOV_w_r_a16, opMOV_r_b_a16, opMOV_r_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -671,7 +671,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a16, opMOV_l_r_a16, opMOV_r_b_a16, opMOV_r_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,ILLEGAL, opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -693,7 +693,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a32, opMOV_w_r_a32, opMOV_r_b_a32, opMOV_r_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -715,7 +715,7 @@ const OpFn OP_TABLE(386_0f)[1024] = {
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*10*/ opMOV_b_r_a32, opMOV_l_r_a32, opMOV_r_b_a32, opMOV_r_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,ILLEGAL, opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
@@ -1384,7 +1384,7 @@ const OpFn OP_TABLE(pentium_0f)[1024] = {
// clang-format on
};
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
# ifdef USE_CYRIX_6X86
const OpFn OP_TABLE(c6x86_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1476,7 +1476,7 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = {
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
// clang-format on
};
# endif
# endif /* USE_CYRIX_6X86 */
const OpFn OP_TABLE(pentiummmx_0f)[1024] = {
// clang-format off
@@ -1754,7 +1754,7 @@ const OpFn OP_TABLE(k62_0f)[1024] = {
// clang-format on
};
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
# ifdef USE_CYRIX_6X86
const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
// clang-format off
/*16-bit data, 16-bit addr*/
@@ -1846,7 +1846,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
// clang-format on
};
# endif
# endif /* USE_CYRIX_6X86 */
const OpFn OP_TABLE(pentiumpro_0f)[1024] = {
// clang-format off

View File

@@ -130,10 +130,10 @@ typedef int (*OpFn)(uint32_t fetchdat);
static int tempc_fpu = 0;
#ifdef ENABLE_808X_LOG
#if 0
void dumpregs(int);
#endif
int x808x_do_log = ENABLE_808X_LOG;
int indump = 0;
static void
x808x_log(const char *fmt, ...)
@@ -3154,8 +3154,10 @@ execx86(int cycs)
#else
cpu_src = pfq_fetchb();
#endif
if (x86_div(AL, 0))
set_pzs(16);
if (x86_div(AL, 0)) {
cpu_data = AL;
set_pzs(8);
}
break;
case 0xD5: /*AAD*/
wait(1, 0);
@@ -3169,6 +3171,7 @@ execx86(int cycs)
add(8);
AL = cpu_data;
AH = 0x00;
set_pzs(8);
break;
case 0xD6: /*SALC*/
wait(1, 0);

View File

@@ -9,32 +9,60 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2024 Jasmine Iwanek.
#
add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c
386_dynarec.c x86_ops_mmx.c x86seg_common.c x86seg.c x86seg_2386.c x87.c
x87_timings.c 8080.c)
add_library(cpu OBJECT
cpu.c
cpu_table.c
fpu.c x86.c
808x.c
386.c
386_common.c
386_dynarec.c
x86_ops_mmx.c
x86seg_common.c
x86seg.c
x86seg_2386.c
x87.c
x87_timings.c
8080.c
)
if(AMD_K5)
target_compile_definitions(cpu PRIVATE USE_AMD_K5)
if(DYNAREC)
add_library(ctk5 OBJECT codegen_timing_k5.c)
target_link_libraries(86Box ctk5)
endif()
endif()
if(CYRIX_6X86)
target_compile_definitions(cpu PRIVATE USE_CYRIX_6X86)
if(DYNAREC)
add_library(ct686 OBJECT codegen_timing_686.c)
target_link_libraries(86Box ct686)
endif()
endif()
if(DYNAREC)
target_sources(cpu PRIVATE 386_dynarec_ops.c)
add_library(cgt OBJECT codegen_timing_486.c
codegen_timing_common.c codegen_timing_k6.c
codegen_timing_pentium.c codegen_timing_p6.c
codegen_timing_winchip.c codegen_timing_winchip2.c)
add_library(cgt OBJECT
codegen_timing_486.c
codegen_timing_common.c
codegen_timing_k6.c
codegen_timing_pentium.c
codegen_timing_p6.c
codegen_timing_winchip.c
codegen_timing_winchip2.c
)
endif()
add_subdirectory(softfloat3e)

View File

@@ -18,7 +18,7 @@
#define CYCLES(c) (int *) c
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
static int *opcode_timings[256] = {
static int *opcode_timings_486[256] = {
// clang-format off
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -42,7 +42,7 @@ static int *opcode_timings[256] = {
// clang-format on
};
static int *opcode_timings_mod3[256] = {
static int *opcode_timings_486_mod3[256] = {
// clang-format off
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -66,7 +66,7 @@ static int *opcode_timings_mod3[256] = {
// clang-format on
};
static int *opcode_timings_0f[256] = {
static int *opcode_timings_486_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -89,7 +89,7 @@ static int *opcode_timings_0f[256] = {
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
// clang-format on
};
static int *opcode_timings_0f_mod3[256] = {
static int *opcode_timings_486_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -113,65 +113,65 @@ static int *opcode_timings_0f_mod3[256] = {
// clang-format on
};
static int *opcode_timings_shift[8] = {
static int *opcode_timings_486_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
};
static int *opcode_timings_shift_mod3[8] = {
static int *opcode_timings_486_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
static int *opcode_timings_f6[8] = {
static int *opcode_timings_486_f6[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f6_mod3[8] = {
static int *opcode_timings_486_f6_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f7[8] = {
static int *opcode_timings_486_f7[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static int *opcode_timings_f7_mod3[8] = {
static int *opcode_timings_486_f7_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
};
static int *opcode_timings_ff[8] = {
static int *opcode_timings_486_ff[8] = {
// clang-format off
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
};
static int *opcode_timings_ff_mod3[8] = {
static int *opcode_timings_486_ff_mod3[8] = {
// clang-format off
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
static int *opcode_timings_d8[8] = {
static int *opcode_timings_486_d8[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_d8_mod3[8] = {
static int *opcode_timings_486_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
CYCLES(8), CYCLES(16), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_d9[8] = {
static int *opcode_timings_486_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
CYCLES(3), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
// clang-format on
};
static int *opcode_timings_d9_mod3[64] = {
static int *opcode_timings_486_d9_mod3[64] = {
// clang-format off
/*FLD*/
CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4),
@@ -192,25 +192,25 @@ static int *opcode_timings_d9_mod3[64] = {
// clang-format on
};
static int *opcode_timings_da[8] = {
static int *opcode_timings_486_da[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_da_mod3[8] = {
static int *opcode_timings_486_da_mod3[8] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
// clang-format on
};
static int *opcode_timings_db[8] = {
static int *opcode_timings_486_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil FLDe FSTPe*/
CYCLES(9), NULL, CYCLES(28), CYCLES(28), NULL, CYCLES(5), NULL, CYCLES(6)
// clang-format on
};
static int *opcode_timings_db_mod3[64] = {
static int *opcode_timings_486_db_mod3[64] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -224,74 +224,74 @@ static int *opcode_timings_db_mod3[64] = {
// clang-format on
};
static int *opcode_timings_dc[8] = {
static int *opcode_timings_486_dc[8] = {
// clang-format off
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_dc_mod3[8] = {
static int *opcode_timings_486_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
CYCLES(8), CYCLES(16), NULL, NULL, CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_dd[8] = {
static int *opcode_timings_486_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
CYCLES(3), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(3)
// clang-format on
};
static int *opcode_timings_dd_mod3[8] = {
static int *opcode_timings_486_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
// clang-format on
};
static int *opcode_timings_de[8] = {
static int *opcode_timings_486_de[8] = {
// clang-format off
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(8), CYCLES(11), CYCLES(4), CYCLES(4), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_de_mod3[8] = {
static int *opcode_timings_486_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
CYCLES(8), CYCLES(16), NULL, CYCLES(5), CYCLES(8), CYCLES(8), CYCLES(73), CYCLES(73)
// clang-format on
};
static int *opcode_timings_df[8] = {
static int *opcode_timings_486_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
CYCLES(13), NULL, CYCLES(29), CYCLES(29), NULL, CYCLES(10), CYCLES(172), CYCLES(28)
// clang-format on
};
static int *opcode_timings_df_mod3[8] = {
static int *opcode_timings_486_df_mod3[8] = {
// clang-format off
/* FFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), NULL, NULL
// clang-format on
};
static int *opcode_timings_8x[8] = {
static int *opcode_timings_486_8x[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int *opcode_timings_8x_mod3[8] = {
static int *opcode_timings_486_8x_mod3[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int *opcode_timings_81[8] = {
static int *opcode_timings_486_81[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
};
static int *opcode_timings_81_mod3[8] = {
static int *opcode_timings_486_81_mod3[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
@@ -330,7 +330,7 @@ codegen_timing_486_start(void)
void
codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
{
timing_count += COUNT(opcode_timings[prefix], 0);
timing_count += COUNT(opcode_timings_486[prefix], 0);
last_prefix = prefix;
}
@@ -344,47 +344,47 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
timings = mod3 ? opcode_timings_486_0f_mod3 : opcode_timings_486_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
timings = mod3 ? opcode_timings_486_d8_mod3 : opcode_timings_486_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
timings = mod3 ? opcode_timings_486_d9_mod3 : opcode_timings_486_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
timings = mod3 ? opcode_timings_486_da_mod3 : opcode_timings_486_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
timings = mod3 ? opcode_timings_486_db_mod3 : opcode_timings_486_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
timings = mod3 ? opcode_timings_486_dc_mod3 : opcode_timings_486_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
timings = mod3 ? opcode_timings_486_dd_mod3 : opcode_timings_486_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
timings = mod3 ? opcode_timings_486_de_mod3 : opcode_timings_486_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
timings = mod3 ? opcode_timings_486_df_mod3 : opcode_timings_486_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -394,12 +394,12 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
timings = mod3 ? opcode_timings_486_8x_mod3 : opcode_timings_486_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
timings = mod3 ? opcode_timings_486_81_mod3 : opcode_timings_486_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -410,29 +410,29 @@ codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
case 0xd1:
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
timings = mod3 ? opcode_timings_486_shift_mod3 : opcode_timings_486_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
timings = mod3 ? opcode_timings_486_f6_mod3 : opcode_timings_486_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
timings = mod3 ? opcode_timings_486_f7_mod3 : opcode_timings_486_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
timings = mod3 ? opcode_timings_486_ff_mod3 : opcode_timings_486_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
timings = mod3 ? opcode_timings_486_mod3 : opcode_timings_486;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}

View File

@@ -65,7 +65,7 @@ static uint32_t prev_fetchdat;
static uint32_t last_regmask_modified;
static uint32_t regmask_modified;
static uint32_t opcode_timings[256] = {
static uint32_t opcode_timings_686[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
@@ -202,7 +202,7 @@ static uint32_t opcode_timings[256] = {
// clang-format on
};
static uint32_t opcode_timings_mod3[256] = {
static uint32_t opcode_timings_686_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
@@ -340,7 +340,7 @@ static uint32_t opcode_timings_mod3[256] = {
// clang-format on
};
static uint32_t opcode_timings_0f[256] = {
static uint32_t opcode_timings_686_0f[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -423,7 +423,7 @@ static uint32_t opcode_timings_0f[256] = {
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
// clang-format on
};
static uint32_t opcode_timings_0f_mod3[256] = {
static uint32_t opcode_timings_686_0f_mod3[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -506,44 +506,44 @@ static uint32_t opcode_timings_0f_mod3[256] = {
// clang-format on
};
static uint32_t opcode_timings_shift[8] = {
static uint32_t opcode_timings_686_shift[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
// clang-format on
};
static uint32_t opcode_timings_shift_mod3[8] = {
static uint32_t opcode_timings_686_shift_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
// clang-format on
};
static uint32_t opcode_timings_shift_imm[8] = {
static uint32_t opcode_timings_686_shift_imm[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
// clang-format on
};
static uint32_t opcode_timings_shift_imm_mod3[8] = {
static uint32_t opcode_timings_686_shift_imm_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
// clang-format on
};
static uint32_t opcode_timings_shift_cl[8] = {
static uint32_t opcode_timings_686_shift_cl[8] = {
// clang-format off
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
// clang-format on
};
static uint32_t opcode_timings_shift_cl_mod3[8] = {
static uint32_t opcode_timings_686_shift_cl_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
// clang-format on
};
static uint32_t opcode_timings_f6[8] = {
static uint32_t opcode_timings_686_f6[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -551,7 +551,7 @@ static uint32_t opcode_timings_f6[8] = {
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
// clang-format on
};
static uint32_t opcode_timings_f6_mod3[8] = {
static uint32_t opcode_timings_686_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -559,7 +559,7 @@ static uint32_t opcode_timings_f6_mod3[8] = {
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
// clang-format on
};
static uint32_t opcode_timings_f7[8] = {
static uint32_t opcode_timings_686_f7[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -567,7 +567,7 @@ static uint32_t opcode_timings_f7[8] = {
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
// clang-format on
};
static uint32_t opcode_timings_f7_mod3[8] = {
static uint32_t opcode_timings_686_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
@@ -575,7 +575,7 @@ static uint32_t opcode_timings_f7_mod3[8] = {
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
// clang-format on
};
static uint32_t opcode_timings_ff[8] = {
static uint32_t opcode_timings_686_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5),
@@ -583,7 +583,7 @@ static uint32_t opcode_timings_ff[8] = {
PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID
// clang-format on
};
static uint32_t opcode_timings_ff_mod3[8] = {
static uint32_t opcode_timings_686_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5),
@@ -592,7 +592,7 @@ static uint32_t opcode_timings_ff_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_d8[8] = {
static uint32_t opcode_timings_686_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -600,7 +600,7 @@ static uint32_t opcode_timings_d8[8] = {
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_d8_mod3[8] = {
static uint32_t opcode_timings_686_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(6), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -609,7 +609,7 @@ static uint32_t opcode_timings_d8_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_d9[8] = {
static uint32_t opcode_timings_686_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -617,7 +617,7 @@ static uint32_t opcode_timings_d9[8] = {
PAIR_X | CYCLES(30), PAIR_X | CYCLES(4), PAIR_X | CYCLES(24), PAIR_X | CYCLES(5)
// clang-format on
};
static uint32_t opcode_timings_d9_mod3[64] = {
static uint32_t opcode_timings_686_d9_mod3[64] = {
// clang-format off
/*FLD*/
PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -650,7 +650,7 @@ static uint32_t opcode_timings_d9_mod3[64] = {
// clang-format on
};
static uint32_t opcode_timings_da[8] = {
static uint32_t opcode_timings_686_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
@@ -658,14 +658,14 @@ static uint32_t opcode_timings_da[8] = {
PAIR_X | CYCLES(29), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(48)
// clang-format on
};
static uint32_t opcode_timings_da_mod3[8] = {
static uint32_t opcode_timings_686_da_mod3[8] = {
// clang-format off
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
INVALID, PAIR_X | CYCLES(5), INVALID, INVALID
// clang-format on
};
static uint32_t opcode_timings_db[8] = {
static uint32_t opcode_timings_686_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -673,7 +673,7 @@ static uint32_t opcode_timings_db[8] = {
INVALID, PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_db_mod3[64] = {
static uint32_t opcode_timings_686_db_mod3[64] = {
// clang-format off
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4), PAIR_X | CYCLES(4),
@@ -703,7 +703,7 @@ static uint32_t opcode_timings_db_mod3[64] = {
// clang-format on
};
static uint32_t opcode_timings_dc[8] = {
static uint32_t opcode_timings_686_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(7),
@@ -711,7 +711,7 @@ static uint32_t opcode_timings_dc[8] = {
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), PAIR_X | CYCLES(34), PAIR_X | CYCLES(34)
// clang-format on
};
static uint32_t opcode_timings_dc_mod3[8] = {
static uint32_t opcode_timings_686_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, INVALID,
@@ -720,7 +720,7 @@ static uint32_t opcode_timings_dc_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_dd[8] = {
static uint32_t opcode_timings_686_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
PAIR_X | CYCLES(2), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -728,7 +728,7 @@ static uint32_t opcode_timings_dd[8] = {
PAIR_X | CYCLES(72), INVALID, PAIR_X | CYCLES(67), PAIR_X | CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_dd_mod3[8] = {
static uint32_t opcode_timings_686_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
PAIR_X | CYCLES(3), INVALID, PAIR_X | CYCLES(2), PAIR_X | CYCLES(2),
@@ -737,14 +737,14 @@ static uint32_t opcode_timings_dd_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_de[8] = {
static uint32_t opcode_timings_686_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
PAIR_X | CYCLES(12), PAIR_X | CYCLES(11), PAIR_X | CYCLES(10), PAIR_X | CYCLES(10),
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
PAIR_X | CYCLES(27), PAIR_X | CYCLES(27), PAIR_X | CYCLES(38), PAIR_X | CYCLES(38)
};
static uint32_t opcode_timings_de_mod3[8] = {
static uint32_t opcode_timings_686_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP*/
PAIR_X | CYCLES(7), PAIR_X | CYCLES(7), INVALID, PAIR_X | CYCLES(7),
@@ -753,7 +753,7 @@ static uint32_t opcode_timings_de_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_df[8] = {
static uint32_t opcode_timings_686_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
PAIR_X | CYCLES(8), INVALID, PAIR_X | CYCLES(10), PAIR_X | CYCLES(13),
@@ -761,7 +761,7 @@ static uint32_t opcode_timings_df[8] = {
INVALID, PAIR_X | CYCLES(8), PAIR_X | CYCLES(63), PAIR_X | CYCLES(13)
// clang-format on
};
static uint32_t opcode_timings_df_mod3[8] = {
static uint32_t opcode_timings_686_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -769,25 +769,25 @@ static uint32_t opcode_timings_df_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_8x[8] = {
static uint32_t opcode_timings_686_8x[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
// clang-format on
};
static uint32_t opcode_timings_8x_mod3[8] = {
static uint32_t opcode_timings_686_8x_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
// clang-format on
};
static uint32_t opcode_timings_81[8] = {
static uint32_t opcode_timings_686_81[8] = {
// clang-format off
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
// clang-format on
};
static uint32_t opcode_timings_81_mod3[8] = {
static uint32_t opcode_timings_686_81_mod3[8] = {
// clang-format off
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
@@ -874,47 +874,47 @@ codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
timings = mod3 ? opcode_timings_686_0f_mod3 : opcode_timings_686_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
timings = mod3 ? opcode_timings_686_d8_mod3 : opcode_timings_686_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
timings = mod3 ? opcode_timings_686_d9_mod3 : opcode_timings_686_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
timings = mod3 ? opcode_timings_686_da_mod3 : opcode_timings_686_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
timings = mod3 ? opcode_timings_686_db_mod3 : opcode_timings_686_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
timings = mod3 ? opcode_timings_686_dc_mod3 : opcode_timings_686_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
timings = mod3 ? opcode_timings_686_dd_mod3 : opcode_timings_686_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
timings = mod3 ? opcode_timings_686_de_mod3 : opcode_timings_686_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
timings = mod3 ? opcode_timings_686_df_mod3 : opcode_timings_686_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -924,55 +924,55 @@ codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(u
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
timings = mod3 ? opcode_timings_686_8x_mod3 : opcode_timings_686_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
timings = mod3 ? opcode_timings_686_81_mod3 : opcode_timings_686_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
case 0xc0:
case 0xc1:
timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
timings = mod3 ? opcode_timings_686_shift_imm_mod3 : opcode_timings_686_shift_imm;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd0:
case 0xd1:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
timings = mod3 ? opcode_timings_686_shift_mod3 : opcode_timings_686_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
timings = mod3 ? opcode_timings_686_shift_cl_mod3 : opcode_timings_686_shift_cl;
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
timings = mod3 ? opcode_timings_686_f6_mod3 : opcode_timings_686_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
timings = mod3 ? opcode_timings_686_f7_mod3 : opcode_timings_686_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
timings = mod3 ? opcode_timings_686_ff_mod3 : opcode_timings_686_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
timings = mod3 ? opcode_timings_686_mod3 : opcode_timings_686;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}

2232
src/cpu/codegen_timing_k5.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*Most of the vector instructions here are a total guess.
Some of the timings are based on http://http://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/
Some of the timings are based on https://web.archive.org/web/20181122095446/http://users.atw.hu/instlatx64/AuthenticAMD0000562_K6_InstLatX86.txt*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
@@ -759,7 +759,7 @@ static const risc86_instruction_t vector_wbinvd_op = {
#define INVALID NULL
static const risc86_instruction_t *opcode_timings[256] = {
static const risc86_instruction_t *opcode_timings_k6[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op,
@@ -896,7 +896,7 @@ static const risc86_instruction_t *opcode_timings[256] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_mod3[256] = {
static const risc86_instruction_t *opcode_timings_k6_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alux_op, &alu_op, &alux_op, &alu_op,
@@ -1033,7 +1033,7 @@ static const risc86_instruction_t *opcode_timings_mod3[256] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_0f[256] = {
static const risc86_instruction_t *opcode_timings_k6_0f[256] = {
// clang-format off
/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
INVALID, &vector_alu6_op, &vector_alu6_op, INVALID,
@@ -1116,7 +1116,7 @@ static const risc86_instruction_t *opcode_timings_0f[256] = {
&load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_0f_mod3[256] = {
static const risc86_instruction_t *opcode_timings_k6_0f_mod3[256] = {
// clang-format off
/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op,
INVALID, &vector_alu6_op, &vector_alu6_op, INVALID,
@@ -1200,7 +1200,7 @@ static const risc86_instruction_t *opcode_timings_0f_mod3[256] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_0f0f[256] = {
static const risc86_instruction_t *opcode_timings_k6_0f0f[256] = {
// clang-format off
/*00*/ INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1283,7 +1283,7 @@ static const risc86_instruction_t *opcode_timings_0f0f[256] = {
INVALID, INVALID, INVALID, INVALID,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = {
static const risc86_instruction_t *opcode_timings_k6_0f0f_mod3[256] = {
// clang-format off
/*00*/ INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1367,57 +1367,57 @@ static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_shift[8] = {
static const risc86_instruction_t *opcode_timings_k6_shift[8] = {
// clang-format off
&vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op,
&vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_shift_b[8] = {
static const risc86_instruction_t *opcode_timings_k6_shift_b[8] = {
// clang-format off
&vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op,
&vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_shift_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_shift_mod3[8] = {
// clang-format off
&vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op,
&alu_op, &alu_op, &alu_op, &alu_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_shift_b_mod3[8] = {
// clang-format off
&vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op,
&alux_op, &alux_op, &alux_op, &alux_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_80[8] = {
static const risc86_instruction_t *opcode_timings_k6_80[8] = {
// clang-format off
&alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op,
&alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_80_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_80_mod3[8] = {
// clang-format off
&alux_op, &alux_op, &alux_store_op, &alux_store_op,
&alux_op, &alux_op, &alux_op, &alux_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_8x[8] = {
static const risc86_instruction_t *opcode_timings_k6_8x[8] = {
// clang-format off
&alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op,
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_8x_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_8x_mod3[8] = {
// clang-format off
&alu_op, &alu_op, &alu_store_op, &alu_store_op,
&alu_op, &alu_op, &alu_op, &alu_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_f6[8] = {
static const risc86_instruction_t *opcode_timings_k6_f6[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op,
@@ -1425,7 +1425,7 @@ static const risc86_instruction_t *opcode_timings_f6[8] = {
&vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_f6_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_b_op, INVALID, &alux_op, &alux_op,
@@ -1433,7 +1433,7 @@ static const risc86_instruction_t *opcode_timings_f6_mod3[8] = {
&vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_f7[8] = {
static const risc86_instruction_t *opcode_timings_k6_f7[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op,
@@ -1441,7 +1441,7 @@ static const risc86_instruction_t *opcode_timings_f7[8] = {
&vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_f7_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_op, INVALID, &alu_op, &alu_op,
@@ -1449,7 +1449,7 @@ static const risc86_instruction_t *opcode_timings_f7_mod3[8] = {
&vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_ff[8] = {
static const risc86_instruction_t *opcode_timings_k6_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&alu_store_op, &alu_store_op, &store_op, &vector_call_far_op,
@@ -1457,7 +1457,7 @@ static const risc86_instruction_t *opcode_timings_ff[8] = {
&branch_op, &vector_jmp_far_op, &push_mem_op, INVALID
// clang-format on
};
static const risc86_instruction_t *opcode_timings_ff_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op,
@@ -1466,7 +1466,7 @@ static const risc86_instruction_t *opcode_timings_ff_mod3[8] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_d8[8] = {
static const risc86_instruction_t *opcode_timings_k6_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1474,7 +1474,7 @@ static const risc86_instruction_t *opcode_timings_d8[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_d8_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
&float_op, &float_op, &float_op, &float_op,
@@ -1483,7 +1483,7 @@ static const risc86_instruction_t *opcode_timings_d8_mod3[8] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_d9[8] = {
static const risc86_instruction_t *opcode_timings_k6_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1491,7 +1491,7 @@ static const risc86_instruction_t *opcode_timings_d9[8] = {
&vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_d9_mod3[64] = {
static const risc86_instruction_t *opcode_timings_k6_d9_mod3[64] = {
// clang-format off
/*FLD*/
&float_op, &float_op, &float_op, &float_op,
@@ -1524,7 +1524,7 @@ static const risc86_instruction_t *opcode_timings_d9_mod3[64] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_da[8] = {
static const risc86_instruction_t *opcode_timings_k6_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1532,7 +1532,7 @@ static const risc86_instruction_t *opcode_timings_da[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_da_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -1540,7 +1540,7 @@ static const risc86_instruction_t *opcode_timings_da_mod3[8] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_db[8] = {
static const risc86_instruction_t *opcode_timings_k6_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1548,7 +1548,7 @@ static const risc86_instruction_t *opcode_timings_db[8] = {
INVALID, &vector_flde_op, INVALID, &vector_fste_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_db_mod3[64] = {
static const risc86_instruction_t *opcode_timings_k6_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1578,7 +1578,7 @@ static const risc86_instruction_t *opcode_timings_db_mod3[64] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_dc[8] = {
static const risc86_instruction_t *opcode_timings_k6_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1586,7 +1586,7 @@ static const risc86_instruction_t *opcode_timings_dc[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_dc_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
&float_op, &float_op, INVALID, INVALID,
@@ -1595,7 +1595,7 @@ static const risc86_instruction_t *opcode_timings_dc_mod3[8] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_dd[8] = {
static const risc86_instruction_t *opcode_timings_k6_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1603,7 +1603,7 @@ static const risc86_instruction_t *opcode_timings_dd[8] = {
&vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op
// clang-format on
};
static const risc86_instruction_t *opcode_timings_dd_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
&float_op, INVALID, &float_op, &float_op,
@@ -1612,7 +1612,7 @@ static const risc86_instruction_t *opcode_timings_dd_mod3[8] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_de[8] = {
static const risc86_instruction_t *opcode_timings_k6_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
&load_float_op, &load_float_op, &load_float_op, &load_float_op,
@@ -1620,7 +1620,7 @@ static const risc86_instruction_t *opcode_timings_de[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_de_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
&float_op, &float_op, INVALID, &float_op,
@@ -1629,7 +1629,7 @@ static const risc86_instruction_t *opcode_timings_de_mod3[8] = {
// clang-format on
};
static const risc86_instruction_t *opcode_timings_df[8] = {
static const risc86_instruction_t *opcode_timings_k6_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1637,7 +1637,7 @@ static const risc86_instruction_t *opcode_timings_df[8] = {
INVALID, &load_float_op, &vector_float_l_op, &fstore_op,
// clang-format on
};
static const risc86_instruction_t *opcode_timings_df_mod3[8] = {
static const risc86_instruction_t *opcode_timings_k6_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -1769,7 +1769,7 @@ static int fpu_st_timestamp[8];
static int last_uop_timestamp = 0;
void
decode_flush(void)
decode_flush_k6(void)
{
int uop_timestamp = 0;
@@ -1908,7 +1908,7 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
}
decode_buffer.nr_uops += ins->nr_uops;
decode_flush();
decode_flush_k6();
} else {
decode_buffer.nr_uops = ins->nr_uops;
decode_buffer.uops[0] = &ins->uop[0];
@@ -1922,7 +1922,7 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
case DECODE_LONG:
if (decode_buffer.nr_uops)
decode_flush();
decode_flush_k6();
decode_buffer.nr_uops = ins->nr_uops;
for (c = 0; c < ins->nr_uops; c++) {
@@ -1932,12 +1932,12 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
else
decode_buffer.earliest_start[c] = -1;
}
decode_flush();
decode_flush_k6();
break;
case DECODE_VECTOR:
if (decode_buffer.nr_uops)
decode_flush();
decode_flush_k6();
decode_timestamp++;
d = 0;
@@ -1953,12 +1953,12 @@ decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetc
if (d == 4) {
d = 0;
decode_buffer.nr_uops = 4;
decode_flush();
decode_flush_k6();
}
}
if (d) {
decode_buffer.nr_uops = d;
decode_flush();
decode_flush_k6();
}
break;
}
@@ -2094,51 +2094,51 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
opcode = fastreadb(cs + opcode_pc);
ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f;
ins_table = mod3 ? opcode_timings_k6_0f0f_mod3 : opcode_timings_k6_0f0f;
deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f;
} else {
ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
ins_table = mod3 ? opcode_timings_k6_0f_mod3 : opcode_timings_k6_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
}
break;
case 0xd8:
ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
ins_table = mod3 ? opcode_timings_k6_d8_mod3 : opcode_timings_k6_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
ins_table = mod3 ? opcode_timings_k6_d9_mod3 : opcode_timings_k6_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
ins_table = mod3 ? opcode_timings_k6_da_mod3 : opcode_timings_k6_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
ins_table = mod3 ? opcode_timings_k6_db_mod3 : opcode_timings_k6_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
ins_table = mod3 ? opcode_timings_k6_dc_mod3 : opcode_timings_k6_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
ins_table = mod3 ? opcode_timings_k6_dd_mod3 : opcode_timings_k6_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
ins_table = mod3 ? opcode_timings_k6_de_mod3 : opcode_timings_k6_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
ins_table = mod3 ? opcode_timings_k6_df_mod3 : opcode_timings_k6_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -2147,13 +2147,13 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
switch (opcode) {
case 0x80:
case 0x82:
ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80;
ins_table = mod3 ? opcode_timings_k6_80_mod3 : opcode_timings_k6_80;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
case 0x83:
ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
ins_table = mod3 ? opcode_timings_k6_8x_mod3 : opcode_timings_k6_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
@@ -2161,7 +2161,7 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
case 0xc0:
case 0xd0:
case 0xd2:
ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b;
ins_table = mod3 ? opcode_timings_k6_shift_b_mod3 : opcode_timings_k6_shift_b;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
@@ -2169,29 +2169,29 @@ codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t
case 0xc1:
case 0xd1:
case 0xd3:
ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
ins_table = mod3 ? opcode_timings_k6_shift_mod3 : opcode_timings_k6_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
ins_table = mod3 ? opcode_timings_k6_f6_mod3 : opcode_timings_k6_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
ins_table = mod3 ? opcode_timings_k6_f7_mod3 : opcode_timings_k6_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
ins_table = mod3 ? opcode_timings_k6_ff_mod3 : opcode_timings_k6_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
ins_table = mod3 ? opcode_timings_mod3 : opcode_timings;
ins_table = mod3 ? opcode_timings_k6_mod3 : opcode_timings_k6;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}
@@ -2209,7 +2209,7 @@ codegen_timing_k6_block_end(void)
{
if (decode_buffer.nr_uops) {
int old_last_complete_timestamp = last_complete_timestamp;
decode_flush();
decode_flush_k6();
codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp);
}
}

View File

@@ -787,7 +787,7 @@ static const macro_op_t wbinvd_op = {
};
#define INVALID NULL
static const macro_op_t *opcode_timings[256] = {
static const macro_op_t *opcode_timings_p6[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alup0_store_op, &alu_store_op, &load_alup0_op, &load_alu_op,
@@ -924,7 +924,7 @@ static const macro_op_t *opcode_timings[256] = {
// clang-format on
};
static const macro_op_t *opcode_timings_mod3[256] = {
static const macro_op_t *opcode_timings_p6_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ &alup0_op, &alu_op, &alup0_op, &alu_op,
@@ -1062,7 +1062,7 @@ static const macro_op_t *opcode_timings_mod3[256] = {
// clang-format on
};
static const macro_op_t *opcode_timings_0f[256] = {
static const macro_op_t *opcode_timings_p6_0f[256] = {
// clang-format off
/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op,
INVALID, &alu6_op, &alu6_op, INVALID,
@@ -1145,7 +1145,7 @@ static const macro_op_t *opcode_timings_0f[256] = {
&load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID,
// clang-format on
};
static const macro_op_t *opcode_timings_0f_mod3[256] = {
static const macro_op_t *opcode_timings_p6_0f_mod3[256] = {
// clang-format off
/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op,
INVALID, &alu6_op, &alu6_op, INVALID,
@@ -1228,58 +1228,58 @@ static const macro_op_t *opcode_timings_0f_mod3[256] = {
&mmx_op, &mmx_op, &mmx_op, INVALID,
};
static const macro_op_t *opcode_timings_shift[8] =
static const macro_op_t *opcode_timings_p6_shift[8] =
{
// clang-format off
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op
// clang-format on
};
static const macro_op_t *opcode_timings_shift_b[8] = {
static const macro_op_t *opcode_timings_p6_shift_b[8] = {
// clang-format off
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op,
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op
// clang-format on
};
static const macro_op_t *opcode_timings_shift_mod3[8] = {
static const macro_op_t *opcode_timings_p6_shift_mod3[8] = {
// clang-format off
&complex_alu1_op, &complex_alu1_op, &complex_alu1_op, &complex_alu1_op,
&alu_op, &alu_op, &alu_op, &alu_op
// clang-format on
};
static const macro_op_t *opcode_timings_shift_b_mod3[8] = {
static const macro_op_t *opcode_timings_p6_shift_b_mod3[8] = {
// clang-format off
&complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op, &complex_alup0_1_op,
&alup0_op, &alup0_op, &alup0_op, &alup0_op
// clang-format on
};
static const macro_op_t *opcode_timings_80[8] = {
static const macro_op_t *opcode_timings_p6_80[8] = {
// clang-format off
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op,
&alup0_store_op, &alup0_store_op, &alup0_store_op, &alup0_store_op,
// clang-format on
};
static const macro_op_t *opcode_timings_80_mod3[8] = {
static const macro_op_t *opcode_timings_p6_80_mod3[8] = {
// clang-format off
&alup0_op, &alup0_op, &alup0_store_op, &alup0_store_op,
&alup0_op, &alup0_op, &alup0_op, &alup0_op,
// clang-format on
};
static const macro_op_t *opcode_timings_8x[8] = {
static const macro_op_t *opcode_timings_p6_8x[8] = {
// clang-format off
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
&alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op,
// clang-format on
};
static const macro_op_t *opcode_timings_8x_mod3[8] = {
static const macro_op_t *opcode_timings_p6_8x_mod3[8] = {
// clang-format off
&alu_op, &alu_op, &alu_store_op, &alu_store_op,
&alu_op, &alu_op, &alu_op, &alu_op,
// clang-format on
};
static const macro_op_t *opcode_timings_f6[8] = {
static const macro_op_t *opcode_timings_p6_f6[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_b_op, INVALID, &alup0_store_op, &alup0_store_op,
@@ -1287,7 +1287,7 @@ static const macro_op_t *opcode_timings_f6[8] = {
&mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op,
// clang-format on
};
static const macro_op_t *opcode_timings_f6_mod3[8] = {
static const macro_op_t *opcode_timings_p6_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_b_op, INVALID, &alup0_op, &alup0_op,
@@ -1295,7 +1295,7 @@ static const macro_op_t *opcode_timings_f6_mod3[8] = {
&mul_op, &mul_op, &div16_op, &div16_op,
// clang-format on
};
static const macro_op_t *opcode_timings_f7[8] = {
static const macro_op_t *opcode_timings_p6_f7[8] = {
// clang-format off
/* TST NOT NEG*/
&test_mem_imm_op, INVALID, &alu_store_op, &alu_store_op,
@@ -1303,7 +1303,7 @@ static const macro_op_t *opcode_timings_f7[8] = {
&mul64_mem_op, &mul64_mem_op, &div32_mem_op, &div32_mem_op,
// clang-format on
};
static const macro_op_t *opcode_timings_f7_mod3[8] = {
static const macro_op_t *opcode_timings_p6_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
&test_reg_op, INVALID, &alu_op, &alu_op,
@@ -1311,7 +1311,7 @@ static const macro_op_t *opcode_timings_f7_mod3[8] = {
&mul64_op, &mul64_op, &div32_op, &div32_op,
// clang-format on
};
static const macro_op_t *opcode_timings_ff[8] = {
static const macro_op_t *opcode_timings_p6_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&alu_store_op, &alu_store_op, &store_op, &call_far_op,
@@ -1319,7 +1319,7 @@ static const macro_op_t *opcode_timings_ff[8] = {
&branch_op, &jmp_far_op, &push_mem_op, INVALID
// clang-format on
};
static const macro_op_t *opcode_timings_ff_mod3[8] = {
static const macro_op_t *opcode_timings_p6_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
&complex_alu1_op, &complex_alu1_op, &store_op, &call_far_op,
@@ -1328,7 +1328,7 @@ static const macro_op_t *opcode_timings_ff_mod3[8] = {
// clang-format on
};
static const macro_op_t *opcode_timings_d8[8] = {
static const macro_op_t *opcode_timings_p6_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
&load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op,
@@ -1336,7 +1336,7 @@ static const macro_op_t *opcode_timings_d8[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const macro_op_t *opcode_timings_d8_mod3[8] = {
static const macro_op_t *opcode_timings_p6_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
&fadd_op, &fmul_op, &float_op, &float_op,
@@ -1345,7 +1345,7 @@ static const macro_op_t *opcode_timings_d8_mod3[8] = {
// clang-format on
};
static const macro_op_t *opcode_timings_d9[8] = {
static const macro_op_t *opcode_timings_p6_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1353,7 +1353,7 @@ static const macro_op_t *opcode_timings_d9[8] = {
&complex_float_l_op, &fldcw_op, &complex_float_l_op, &complex_float_op
// clang-format on
};
static const macro_op_t *opcode_timings_d9_mod3[64] = {
static const macro_op_t *opcode_timings_p6_d9_mod3[64] = {
// clang-format off
/*FLD*/
&float_op, &float_op, &float_op, &float_op,
@@ -1386,7 +1386,7 @@ static const macro_op_t *opcode_timings_d9_mod3[64] = {
// clang-format on
};
static const macro_op_t *opcode_timings_da[8] = {
static const macro_op_t *opcode_timings_p6_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
&load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op,
@@ -1394,7 +1394,7 @@ static const macro_op_t *opcode_timings_da[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const macro_op_t *opcode_timings_da_mod3[8] = {
static const macro_op_t *opcode_timings_p6_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -1402,7 +1402,7 @@ static const macro_op_t *opcode_timings_da_mod3[8] = {
// clang-format on
};
static const macro_op_t *opcode_timings_db[8] = {
static const macro_op_t *opcode_timings_p6_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1410,7 +1410,7 @@ static const macro_op_t *opcode_timings_db[8] = {
INVALID, &flde_op, INVALID, &fste_op
// clang-format on
};
static const macro_op_t *opcode_timings_db_mod3[64] = {
static const macro_op_t *opcode_timings_p6_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -1440,7 +1440,7 @@ static const macro_op_t *opcode_timings_db_mod3[64] = {
// clang-format on
};
static const macro_op_t *opcode_timings_dc[8] = {
static const macro_op_t *opcode_timings_p6_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
&load_fadd_op, &load_fmul_op, &load_float_op, &load_float_op,
@@ -1448,7 +1448,7 @@ static const macro_op_t *opcode_timings_dc[8] = {
&load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op,
// clang-format on
};
static const macro_op_t *opcode_timings_dc_mod3[8] = {
static const macro_op_t *opcode_timings_p6_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
&fadd_op, &fmul_op, INVALID, INVALID,
@@ -1457,7 +1457,7 @@ static const macro_op_t *opcode_timings_dc_mod3[8] = {
// clang-format on
};
static const macro_op_t *opcode_timings_dd[8] = {
static const macro_op_t *opcode_timings_p6_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1465,7 +1465,7 @@ static const macro_op_t *opcode_timings_dd[8] = {
&complex_float_l_op, INVALID, &complex_float_l_op, &complex_float_l_op
// clang-format on
};
static const macro_op_t *opcode_timings_dd_mod3[8] = {
static const macro_op_t *opcode_timings_p6_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
&float_op, INVALID, &float_op, &float_op,
@@ -1474,7 +1474,7 @@ static const macro_op_t *opcode_timings_dd_mod3[8] = {
// clang-format on
};
static const macro_op_t *opcode_timings_de[8] = {
static const macro_op_t *opcode_timings_p6_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
&load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op,
@@ -1482,7 +1482,7 @@ static const macro_op_t *opcode_timings_de[8] = {
&load_fiadd_op, &load_fiadd_op, &load_fiadd_op, &load_fiadd_op,
// clang-format on
};
static const macro_op_t *opcode_timings_de_mod3[8] = {
static const macro_op_t *opcode_timings_p6_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
&fadd_op, &fmul_op, INVALID, &float_op,
@@ -1491,7 +1491,7 @@ static const macro_op_t *opcode_timings_de_mod3[8] = {
// clang-format on
};
static const macro_op_t *opcode_timings_df[8] = {
static const macro_op_t *opcode_timings_p6_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
&load_float_op, INVALID, &fstore_op, &fstore_op,
@@ -1499,7 +1499,7 @@ static const macro_op_t *opcode_timings_df[8] = {
INVALID, &load_float_op, &complex_float_l_op, &fstore_op,
// clang-format on
};
static const macro_op_t *opcode_timings_df_mod3[8] = {
static const macro_op_t *opcode_timings_p6_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -1865,47 +1865,47 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
switch (last_prefix) {
case 0x0f:
ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
ins_table = mod3 ? opcode_timings_p6_0f_mod3 : opcode_timings_p6_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
ins_table = mod3 ? opcode_timings_p6_d8_mod3 : opcode_timings_p6_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
ins_table = mod3 ? opcode_timings_p6_d9_mod3 : opcode_timings_p6_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
ins_table = mod3 ? opcode_timings_p6_da_mod3 : opcode_timings_p6_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
ins_table = mod3 ? opcode_timings_p6_db_mod3 : opcode_timings_p6_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
ins_table = mod3 ? opcode_timings_p6_dc_mod3 : opcode_timings_p6_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
ins_table = mod3 ? opcode_timings_p6_dd_mod3 : opcode_timings_p6_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
ins_table = mod3 ? opcode_timings_p6_de_mod3 : opcode_timings_p6_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
ins_table = mod3 ? opcode_timings_p6_df_mod3 : opcode_timings_p6_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -1914,13 +1914,13 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
switch (opcode) {
case 0x80:
case 0x82:
ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80;
ins_table = mod3 ? opcode_timings_p6_80_mod3 : opcode_timings_p6_80;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
case 0x83:
ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
ins_table = mod3 ? opcode_timings_p6_8x_mod3 : opcode_timings_p6_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
@@ -1928,7 +1928,7 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
case 0xc0:
case 0xd0:
case 0xd2:
ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b;
ins_table = mod3 ? opcode_timings_p6_shift_b_mod3 : opcode_timings_p6_shift_b;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
@@ -1936,29 +1936,29 @@ codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUSED(ui
case 0xc1:
case 0xd1:
case 0xd3:
ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
ins_table = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
ins_table = mod3 ? opcode_timings_p6_f6_mod3 : opcode_timings_p6_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
ins_table = mod3 ? opcode_timings_p6_f7_mod3 : opcode_timings_p6_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
ins_table = mod3 ? opcode_timings_p6_ff_mod3 : opcode_timings_p6_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
ins_table = mod3 ? opcode_timings_mod3 : opcode_timings;
ins_table = mod3 ? opcode_timings_p6_mod3 : opcode_timings_p6;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}

View File

@@ -110,7 +110,7 @@ static uint32_t addr_regmask;
static int fpu_latency;
static int fpu_st_latency[8];
static uint64_t opcode_timings[256] = {
static uint64_t opcode_timings_p6[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RM, PAIR_UV | CYCLES_RM,
@@ -247,7 +247,7 @@ static uint64_t opcode_timings[256] = {
// clang-format on
};
static uint64_t opcode_timings_mod3[256] = {
static uint64_t opcode_timings_p6_mod3[256] = {
// clang-format off
/* ADD ADD ADD ADD*/
/*00*/ PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
@@ -385,7 +385,7 @@ static uint64_t opcode_timings_mod3[256] = {
// clang-format on
};
static uint64_t opcode_timings_0f[256] = {
static uint64_t opcode_timings_p6_0f[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -468,7 +468,7 @@ static uint64_t opcode_timings_0f[256] = {
PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID,
// clang-format on
};
static uint64_t opcode_timings_0f_mod3[256] = {
static uint64_t opcode_timings_p6_0f_mod3[256] = {
// clang-format off
/*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10),
INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID,
@@ -552,20 +552,20 @@ static uint64_t opcode_timings_0f_mod3[256] = {
// clang-format on
};
static uint64_t opcode_timings_shift[8] = {
static uint64_t opcode_timings_p6_shift[8] = {
// clang-format off
PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW,
PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW,
// clang-format on
};
static uint64_t opcode_timings_shift_mod3[8] = {
static uint64_t opcode_timings_p6_shift_mod3[8] = {
// clang-format off
PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG,
PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG, PAIR_U | CYCLES_REG,
// clang-format on
};
static uint64_t opcode_timings_f6[8] = {
static uint64_t opcode_timings_p6_f6[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -573,7 +573,7 @@ static uint64_t opcode_timings_f6[8] = {
PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22)
// clang-format on
};
static uint64_t opcode_timings_f6_mod3[8] = {
static uint64_t opcode_timings_p6_f6_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -581,7 +581,7 @@ static uint64_t opcode_timings_f6_mod3[8] = {
PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22)
// clang-format on
};
static uint64_t opcode_timings_f7[8] = {
static uint64_t opcode_timings_p6_f7[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -589,7 +589,7 @@ static uint64_t opcode_timings_f7[8] = {
PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46)
// clang-format on
};
static uint64_t opcode_timings_f7_mod3[8] = {
static uint64_t opcode_timings_p6_f7_mod3[8] = {
// clang-format off
/* TST NOT NEG*/
PAIR_UV | CYCLES_REG, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3),
@@ -597,7 +597,7 @@ static uint64_t opcode_timings_f7_mod3[8] = {
PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46)
// clang-format on
};
static uint64_t opcode_timings_ff[8] = {
static uint64_t opcode_timings_p6_ff[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
@@ -605,7 +605,7 @@ static uint64_t opcode_timings_ff[8] = {
PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID
// clang-format on
};
static uint64_t opcode_timings_ff_mod3[8] = {
static uint64_t opcode_timings_p6_ff_mod3[8] = {
// clang-format off
/* INC DEC CALL CALL far*/
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0),
@@ -614,7 +614,7 @@ static uint64_t opcode_timings_ff_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_d8[8] = {
static uint64_t opcode_timings_p6_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -622,7 +622,7 @@ static uint64_t opcode_timings_d8[8] = {
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2)
// clang-format on
};
static uint64_t opcode_timings_d8_mod3[8] = {
static uint64_t opcode_timings_p6_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -631,7 +631,7 @@ static uint64_t opcode_timings_d8_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_d9[8] = {
static uint64_t opcode_timings_p6_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0),
@@ -639,7 +639,7 @@ static uint64_t opcode_timings_d9[8] = {
PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0)
// clang-format on
};
static uint64_t opcode_timings_d9_mod3[64] = {
static uint64_t opcode_timings_p6_d9_mod3[64] = {
// clang-format off
/*FLD*/
PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -672,7 +672,7 @@ static uint64_t opcode_timings_d9_mod3[64] = {
// clang-format on
};
static uint64_t opcode_timings_da[8] = {
static uint64_t opcode_timings_p6_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0),
@@ -680,7 +680,7 @@ static uint64_t opcode_timings_da[8] = {
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2)
// clang-format on
};
static uint64_t opcode_timings_da_mod3[8] = {
static uint64_t opcode_timings_p6_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -688,7 +688,7 @@ static uint64_t opcode_timings_da_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_db[8] = {
static uint64_t opcode_timings_p6_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0),
@@ -696,7 +696,7 @@ static uint64_t opcode_timings_db[8] = {
INVALID, PAIR_NP | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_CYCLES(3,0,0)
// clang-format on
};
static uint64_t opcode_timings_db_mod3[64] = {
static uint64_t opcode_timings_p6_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -726,7 +726,7 @@ static uint64_t opcode_timings_db_mod3[64] = {
// clang-format on
};
static uint64_t opcode_timings_dc[8] = {
static uint64_t opcode_timings_p6_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0),
@@ -734,7 +734,7 @@ static uint64_t opcode_timings_dc[8] = {
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(39,38,2), PAIR_FX | FPU_CYCLES(39,38,2)
// clang-format on
};
static uint64_t opcode_timings_dc_mod3[8] = {
static uint64_t opcode_timings_p6_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, INVALID,
@@ -743,7 +743,7 @@ static uint64_t opcode_timings_dc_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_dd[8] = {
static uint64_t opcode_timings_p6_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
PAIR_FX | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0),
@@ -751,7 +751,7 @@ static uint64_t opcode_timings_dd[8] = {
PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0)
// clang-format on
};
static uint64_t opcode_timings_dd_mod3[8] = {
static uint64_t opcode_timings_p6_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0),
@@ -760,7 +760,7 @@ static uint64_t opcode_timings_dd_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_de[8] = {
static uint64_t opcode_timings_p6_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(4,0,0), PAIR_NP | FPU_CYCLES(4,0,0),
@@ -768,7 +768,7 @@ static uint64_t opcode_timings_de[8] = {
PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(6,2,2), PAIR_NP | FPU_CYCLES(42,38,2), PAIR_NP | FPU_CYCLES(42,38,2)
// clang-format on
};
static uint64_t opcode_timings_de_mod3[8] = {
static uint64_t opcode_timings_p6_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
PAIR_FX | FPU_CYCLES(3,2,2), PAIR_FX | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_CYCLES(1,0,0),
@@ -777,7 +777,7 @@ static uint64_t opcode_timings_de_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_df[8] = {
static uint64_t opcode_timings_p6_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
PAIR_NP | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_CYCLES(6,0,0), PAIR_NP | FPU_CYCLES(6,0,0),
@@ -785,7 +785,7 @@ static uint64_t opcode_timings_df[8] = {
INVALID, PAIR_NP | FPU_CYCLES(3,2,2), PAIR_NP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_CYCLES(6,0,0)
// clang-format on
};
static uint64_t opcode_timings_df_mod3[8] = {
static uint64_t opcode_timings_p6_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -793,25 +793,25 @@ static uint64_t opcode_timings_df_mod3[8] = {
// clang-format on
};
static uint64_t opcode_timings_81[8] = {
static uint64_t opcode_timings_p6_81[8] = {
// clang-format off
PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632,
PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | CYCLES_IMM1632
// clang-format on
};
static uint64_t opcode_timings_81_mod3[8] = {
static uint64_t opcode_timings_p6_81_mod3[8] = {
// clang-format off
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG
// clang-format on
};
static uint64_t opcode_timings_8x[8] = {
static uint64_t opcode_timings_p6_8x[8] = {
// clang-format off
PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8,
PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | CYCLES_IMM8, PAIR_UV | CYCLES_RM | CYCLES_IMM8
// clang-format on
};
static uint64_t opcode_timings_8x_mod3[8] = {
static uint64_t opcode_timings_p6_8x_mod3[8] = {
// clang-format off
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG,
PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG
@@ -1097,47 +1097,47 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
timings = mod3 ? opcode_timings_p6_0f_mod3 : opcode_timings_p6_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
timings = mod3 ? opcode_timings_p6_d8_mod3 : opcode_timings_p6_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
timings = mod3 ? opcode_timings_p6_d9_mod3 : opcode_timings_p6_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
timings = mod3 ? opcode_timings_p6_da_mod3 : opcode_timings_p6_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
timings = mod3 ? opcode_timings_p6_db_mod3 : opcode_timings_p6_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
timings = mod3 ? opcode_timings_p6_dc_mod3 : opcode_timings_p6_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
timings = mod3 ? opcode_timings_p6_dd_mod3 : opcode_timings_p6_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
timings = mod3 ? opcode_timings_p6_de_mod3 : opcode_timings_p6_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
timings = mod3 ? opcode_timings_p6_df_mod3 : opcode_timings_p6_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -1147,12 +1147,12 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
timings = mod3 ? opcode_timings_p6_8x_mod3 : opcode_timings_p6_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
timings = mod3 ? opcode_timings_p6_81_mod3 : opcode_timings_p6_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -1161,36 +1161,36 @@ codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0xc1:
case 0xd0:
case 0xd1:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
timings = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
timings = mod3 ? opcode_timings_p6_shift_mod3 : opcode_timings_p6_shift;
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
timings = mod3 ? opcode_timings_p6_f6_mod3 : opcode_timings_p6_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
timings = mod3 ? opcode_timings_p6_f7_mod3 : opcode_timings_p6_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
timings = mod3 ? opcode_timings_p6_ff_mod3 : opcode_timings_p6_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
timings = mod3 ? opcode_timings_p6_mod3 : opcode_timings_p6;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}

View File

@@ -18,7 +18,7 @@
#define CYCLES(c) (int *) c
#define CYCLES2(c16, c32) (int *) ((-1 & ~0xffff) | c16 | (c32 << 8))
static int *opcode_timings[256] = {
static int *opcode_timings_winchip[256] = {
// clang-format off
/*00*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_mr, &timing_mr, &timing_rm, &timing_rm, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -42,7 +42,7 @@ static int *opcode_timings[256] = {
// clang-format on
};
static int *opcode_timings_mod3[256] = {
static int *opcode_timings_winchip_mod3[256] = {
// clang-format off
/*00*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), NULL,
/*10*/ &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3), &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, &timing_rr, CYCLES(2), CYCLES(3),
@@ -66,7 +66,7 @@ static int *opcode_timings_mod3[256] = {
// clang-format on
};
static int *opcode_timings_0f[256] = {
static int *opcode_timings_winchip_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -89,7 +89,7 @@ static int *opcode_timings_0f[256] = {
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
// clang-format on
};
static int *opcode_timings_0f_mod3[256] = {
static int *opcode_timings_winchip_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), NULL, CYCLES(195), CYCLES(7), NULL, CYCLES(1000), CYCLES(10000), NULL, NULL, NULL, NULL, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -113,68 +113,68 @@ static int *opcode_timings_0f_mod3[256] = {
// clang-format on
};
static int *opcode_timings_shift[8] = {
static int *opcode_timings_winchip_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
// clang-format on
};
static int *opcode_timings_shift_mod3[8] = {
static int *opcode_timings_winchip_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
static int *opcode_timings_f6[8] = {
static int *opcode_timings_winchip_f6[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f6_mod3[8] = {
static int *opcode_timings_winchip_f6_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static int *opcode_timings_f7[8] = {
static int *opcode_timings_winchip_f7[8] = {
// clang-format off
&timing_rm, NULL, &timing_mm, &timing_mm, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static int *opcode_timings_f7_mod3[8] = {
static int *opcode_timings_winchip_f7_mod3[8] = {
// clang-format off
&timing_rr, NULL, &timing_rr, &timing_rr, CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static int *opcode_timings_ff[8] = {
static int *opcode_timings_winchip_ff[8] = {
// clang-format off
&timing_mm, &timing_mm, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
static int *opcode_timings_ff_mod3[8] = {
static int *opcode_timings_winchip_ff_mod3[8] = {
// clang-format off
&timing_rr, &timing_rr, CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), NULL
// clang-format on
};
static int *opcode_timings_d8[8] = {
static int *opcode_timings_winchip_d8[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
static int *opcode_timings_d8_mod3[8] = {
static int *opcode_timings_winchip_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP FSUB FSUBR FDIV FDIVR*/
CYCLES(4), CYCLES(6), CYCLES(3), CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
static int *opcode_timings_d9[8] = {
static int *opcode_timings_winchip_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs FLDENV FLDCW FSTENV FSTCW*/
CYCLES(2), NULL, CYCLES(7), CYCLES(7), CYCLES(34), CYCLES(4), CYCLES(67), CYCLES(3)
// clang-format on
};
static int *opcode_timings_d9_mod3[64] = {
static int *opcode_timings_winchip_d9_mod3[64] = {
// clang-format off
/*FLD*/
CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
@@ -195,25 +195,25 @@ static int *opcode_timings_d9_mod3[64] = {
// clang-format on
};
static int *opcode_timings_da[8] = {
static int *opcode_timings_winchip_da[8] = {
// clang-format off
/* FADDil FMULil FCOMil FCOMPil FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
static int *opcode_timings_da_mod3[8] = {
static int *opcode_timings_winchip_da_mod3[8] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, CYCLES(5), NULL, NULL
// clang-format on
};
static int *opcode_timings_db[8] = {
static int *opcode_timings_winchip_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil FLDe FSTPe*/
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), NULL, CYCLES(8)
// clang-format on
};
static int *opcode_timings_db_mod3[64] = {
static int *opcode_timings_winchip_db_mod3[64] = {
// clang-format off
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -227,71 +227,71 @@ static int *opcode_timings_db_mod3[64] = {
// clang-format on
};
static int *opcode_timings_dc[8] = {
static int *opcode_timings_winchip_dc[8] = {
// clang-format off
/* opFADDd_a16 opFMULd_a16 opFCOMd_a16 opFCOMPd_a16 opFSUBd_a16 opFSUBRd_a16 opFDIVd_a16 opFDIVRd_a16*/
CYCLES(6), CYCLES(8), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(74), CYCLES(74)
// clang-format on
};
static int *opcode_timings_dc_mod3[8] = {
static int *opcode_timings_winchip_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr opFSUBRr opFSUBr opFDIVRr opFDIVr*/
CYCLES(4), CYCLES(6), NULL, NULL, CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
static int *opcode_timings_dd[8] = {
static int *opcode_timings_winchip_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd FRSTOR FSAVE FSTSW*/
CYCLES(2), NULL, CYCLES(8), CYCLES(8), CYCLES(131), NULL, CYCLES(154), CYCLES(5)
// clang-format on
};
static int *opcode_timings_dd_mod3[8] = {
static int *opcode_timings_winchip_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
// clang-format on
};
static int *opcode_timings_de[8] = {
static int *opcode_timings_winchip_de[8] = {
// clang-format off
/* FADDiw FMULiw FCOMiw FCOMPiw FSUBil FSUBRil FDIVil FDIVRil*/
CYCLES(10), CYCLES(12), CYCLES(9), CYCLES(9), CYCLES(10), CYCLES(10), CYCLES(78), CYCLES(78)
// clang-format on
};
static int *opcode_timings_de_mod3[8] = {
static int *opcode_timings_winchip_de_mod3[8] = {
// clang-format off
/* FADD FMUL FCOMPP FSUB FSUBR FDIV FDIVR*/
CYCLES(4), CYCLES(6), NULL, CYCLES(3), CYCLES(4), CYCLES(4), CYCLES(72), CYCLES(72)
// clang-format on
};
static int *opcode_timings_df[8] = {
static int *opcode_timings_winchip_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw FILDiq FBSTP FISTPiq*/
CYCLES(6), NULL, CYCLES(7), CYCLES(7), NULL, CYCLES(8), CYCLES(172), CYCLES(8)
// clang-format on
};
static int *opcode_timings_df_mod3[8] = {
static int *opcode_timings_winchip_df_mod3[8] = {
// clang-format off
/* FFREE FST FSTP FUCOM FUCOMP*/
CYCLES(3), NULL, CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(3), NULL, NULL
// clang-format on
};
static int *opcode_timings_8x[8] = {
static int *opcode_timings_winchip_8x[8] = {
// clang-format off
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
static int *opcode_timings_8x_mod3[8] =
static int *opcode_timings_winchip_8x_mod3[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
static int *opcode_timings_81[8] =
static int *opcode_timings_winchip_81[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
};
static int *opcode_timings_81_mod3[8] =
static int *opcode_timings_winchip_81_mod3[8] =
{
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
// clang-format on
@@ -330,7 +330,7 @@ codegen_timing_winchip_start(void)
void
codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
{
timing_count += COUNT(opcode_timings[prefix], 0);
timing_count += COUNT(opcode_timings_winchip[prefix], 0);
last_prefix = prefix;
}
@@ -344,47 +344,47 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
timings = mod3 ? opcode_timings_winchip_0f_mod3 : opcode_timings_winchip_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
timings = mod3 ? opcode_timings_winchip_d8_mod3 : opcode_timings_winchip_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
timings = mod3 ? opcode_timings_winchip_d9_mod3 : opcode_timings_winchip_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
timings = mod3 ? opcode_timings_winchip_da_mod3 : opcode_timings_winchip_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
timings = mod3 ? opcode_timings_winchip_db_mod3 : opcode_timings_winchip_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
timings = mod3 ? opcode_timings_winchip_dc_mod3 : opcode_timings_winchip_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
timings = mod3 ? opcode_timings_winchip_dd_mod3 : opcode_timings_winchip_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
timings = mod3 ? opcode_timings_winchip_de_mod3 : opcode_timings_winchip_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
timings = mod3 ? opcode_timings_winchip_df_mod3 : opcode_timings_winchip_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -394,12 +394,12 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
timings = mod3 ? opcode_timings_winchip_8x_mod3 : opcode_timings_winchip_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
timings = mod3 ? opcode_timings_winchip_81_mod3 : opcode_timings_winchip_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -410,29 +410,29 @@ codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNUS
case 0xd1:
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
timings = mod3 ? opcode_timings_winchip_shift_mod3 : opcode_timings_winchip_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
timings = mod3 ? opcode_timings_winchip_f6_mod3 : opcode_timings_winchip_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
timings = mod3 ? opcode_timings_winchip_f7_mod3 : opcode_timings_winchip_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
timings = mod3 ? opcode_timings_winchip_ff_mod3 : opcode_timings_winchip_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
timings = mod3 ? opcode_timings_winchip_mod3 : opcode_timings_winchip;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}

View File

@@ -63,7 +63,7 @@
#define INVALID 0
static uint32_t opcode_timings[256] = {
static uint32_t opcode_timings_winchip2[256] = {
// clang-format off
/*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID,
/*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3),
@@ -87,7 +87,7 @@ static uint32_t opcode_timings[256] = {
// clang-format on
};
static uint32_t opcode_timings_mod3[256] = {
static uint32_t opcode_timings_winchip2_mod3[256] = {
// clang-format off
/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID,
/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3),
@@ -111,7 +111,7 @@ static uint32_t opcode_timings_mod3[256] = {
// clang-format on
};
static uint32_t opcode_timings_0f[256] = {
static uint32_t opcode_timings_winchip2_0f[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1),
/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
@@ -134,7 +134,7 @@ static uint32_t opcode_timings_0f[256] = {
/*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID,
// clang-format on
};
static uint32_t opcode_timings_0f_mod3[256] = {
static uint32_t opcode_timings_winchip2_0f_mod3[256] = {
// clang-format off
/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1),
/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,
@@ -158,49 +158,49 @@ static uint32_t opcode_timings_0f_mod3[256] = {
// clang-format on
};
static uint32_t opcode_timings_shift[8] = {
static uint32_t opcode_timings_winchip2_shift[8] = {
// clang-format off
CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)
// clang-format on
};
static uint32_t opcode_timings_shift_mod3[8] = {
static uint32_t opcode_timings_winchip2_shift_mod3[8] = {
// clang-format off
CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)
// clang-format on
};
static uint32_t opcode_timings_f6[8] = {
static uint32_t opcode_timings_winchip2_f6[8] = {
// clang-format off
CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static uint32_t opcode_timings_f6_mod3[8] = {
static uint32_t opcode_timings_winchip2_f6_mod3[8] = {
// clang-format off
CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)
// clang-format on
};
static uint32_t opcode_timings_f7[8] = {
static uint32_t opcode_timings_winchip2_f7[8] = {
// clang-format off
CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static uint32_t opcode_timings_f7_mod3[8] = {
static uint32_t opcode_timings_winchip2_f7_mod3[8] = {
// clang-format off
CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22,38), CYCLES2(24,40), CYCLES2(27,43)
// clang-format on
};
static uint32_t opcode_timings_ff[8] = {
static uint32_t opcode_timings_winchip2_ff[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID
// clang-format on
};
static uint32_t opcode_timings_ff_mod3[8] = {
static uint32_t opcode_timings_winchip2_ff_mod3[8] = {
// clang-format off
CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID
// clang-format on
};
static uint32_t opcode_timings_d8[8] = {
static uint32_t opcode_timings_winchip2_d8[8] = {
// clang-format off
/* FADDs FMULs FCOMs FCOMPs*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -208,7 +208,7 @@ static uint32_t opcode_timings_d8[8] = {
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
// clang-format on
};
static uint32_t opcode_timings_d8_mod3[8] = {
static uint32_t opcode_timings_winchip2_d8_mod3[8] = {
// clang-format off
/* FADD FMUL FCOM FCOMP*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -217,7 +217,7 @@ static uint32_t opcode_timings_d8_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_d9[8] = {
static uint32_t opcode_timings_winchip2_d9[8] = {
// clang-format off
/* FLDs FSTs FSTPs*/
FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
@@ -225,7 +225,7 @@ static uint32_t opcode_timings_d9[8] = {
FPU_CYCLES(32,0,0), FPU_CYCLES(8,0,0), FPU_CYCLES(48,0,0), FPU_CYCLES(2,0,0)
// clang-format on
};
static uint32_t opcode_timings_d9_mod3[64] = {
static uint32_t opcode_timings_winchip2_d9_mod3[64] = {
// clang-format off
/*FLD*/
FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -258,7 +258,7 @@ static uint32_t opcode_timings_d9_mod3[64] = {
// clang-format on
};
static uint32_t opcode_timings_da[8] = {
static uint32_t opcode_timings_winchip2_da[8] = {
// clang-format off
/* FIADDl FIMULl FICOMl FICOMPl*/
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0),
@@ -266,7 +266,7 @@ static uint32_t opcode_timings_da[8] = {
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2)
// clang-format on
};
static uint32_t opcode_timings_da_mod3[8] = {
static uint32_t opcode_timings_winchip2_da_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FCOMPP*/
@@ -274,7 +274,7 @@ static uint32_t opcode_timings_da_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_db[8] = {
static uint32_t opcode_timings_winchip2_db[8] = {
// clang-format off
/* FLDil FSTil FSTPil*/
FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0),
@@ -282,7 +282,7 @@ static uint32_t opcode_timings_db[8] = {
INVALID, FPU_CYCLES(3,0,0), INVALID, FPU_CYCLES(3,0,0)
// clang-format on
};
static uint32_t opcode_timings_db_mod3[64] = {
static uint32_t opcode_timings_winchip2_db_mod3[64] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
INVALID, INVALID, INVALID, INVALID,
@@ -312,7 +312,7 @@ static uint32_t opcode_timings_db_mod3[64] = {
// clang-format on
};
static uint32_t opcode_timings_dc[8] = {
static uint32_t opcode_timings_winchip2_dc[8] = {
// clang-format off
/* FADDd FMULd FCOMd FCOMPd*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -320,7 +320,7 @@ static uint32_t opcode_timings_dc[8] = {
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), FPU_CYCLES(39,38,2), FPU_CYCLES(39,38,2)
// clang-format on
};
static uint32_t opcode_timings_dc_mod3[8] = {
static uint32_t opcode_timings_winchip2_dc_mod3[8] = {
// clang-format off
/* opFADDr opFMULr*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2),INVALID, INVALID,
@@ -329,7 +329,7 @@ static uint32_t opcode_timings_dc_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_dd[8] = {
static uint32_t opcode_timings_winchip2_dd[8] = {
// clang-format off
/* FLDd FSTd FSTPd*/
FPU_CYCLES(1,0,0), INVALID, FPU_CYCLES(2,0,0), FPU_CYCLES(2,0,0),
@@ -337,7 +337,7 @@ static uint32_t opcode_timings_dd[8] = {
FPU_CYCLES(70,0,0), INVALID, FPU_CYCLES(127,0,0), FPU_CYCLES(6,0,0)
// clang-format on
};
static uint32_t opcode_timings_dd_mod3[8] = {
static uint32_t opcode_timings_winchip2_dd_mod3[8] = {
// clang-format off
/* FFFREE FST FSTP*/
FPU_CYCLES(2,0,0), INVALID, FPU_CYCLES(1,0,0), FPU_CYCLES(1,0,0),
@@ -346,7 +346,7 @@ static uint32_t opcode_timings_dd_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_de[8] = {
static uint32_t opcode_timings_winchip2_de[8] = {
// clang-format off
/* FIADDw FIMULw FICOMw FICOMPw*/
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(4,0,0), FPU_CYCLES(4,0,0),
@@ -354,7 +354,7 @@ static uint32_t opcode_timings_de[8] = {
FPU_CYCLES(6,2,2), FPU_CYCLES(6,2,2), FPU_CYCLES(42,38,2), FPU_CYCLES(42,38,2)
// clang-format on
};
static uint32_t opcode_timings_de_mod3[8] = {
static uint32_t opcode_timings_winchip2_de_mod3[8] = {
// clang-format off
/* FADDP FMULP FCOMPP*/
FPU_CYCLES(3,2,2), FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(1,0,0),
@@ -363,7 +363,7 @@ static uint32_t opcode_timings_de_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_df[8] = {
static uint32_t opcode_timings_winchip2_df[8] = {
// clang-format off
/* FILDiw FISTiw FISTPiw*/
FPU_CYCLES(3,2,2), INVALID, FPU_CYCLES(6,0,0), FPU_CYCLES(6,0,0),
@@ -371,7 +371,7 @@ static uint32_t opcode_timings_df[8] = {
INVALID, FPU_CYCLES(3,2,2), FPU_CYCLES(148,0,0), FPU_CYCLES(6,0,0)
// clang-format on
};
static uint32_t opcode_timings_df_mod3[8] = {
static uint32_t opcode_timings_winchip2_df_mod3[8] = {
// clang-format off
INVALID, INVALID, INVALID, INVALID,
/* FSTSW AX*/
@@ -379,22 +379,22 @@ static uint32_t opcode_timings_df_mod3[8] = {
// clang-format on
};
static uint32_t opcode_timings_8x[8] = {
static uint32_t opcode_timings_winchip2_8x[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_8x_mod3[8] = {
static uint32_t opcode_timings_winchip2_8x_mod3[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_81[8] = {
static uint32_t opcode_timings_winchip2_81[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
};
static uint32_t opcode_timings_81_mod3[8] = {
static uint32_t opcode_timings_winchip2_81_mod3[8] = {
// clang-format off
CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)
// clang-format on
@@ -613,47 +613,47 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU
switch (last_prefix) {
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
timings = mod3 ? opcode_timings_winchip2_0f_mod3 : opcode_timings_winchip2_0f;
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
timings = mod3 ? opcode_timings_winchip2_d8_mod3 : opcode_timings_winchip2_d8;
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
opcode = (opcode >> 3) & 7;
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
timings = mod3 ? opcode_timings_winchip2_d9_mod3 : opcode_timings_winchip2_d9;
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
timings = mod3 ? opcode_timings_winchip2_da_mod3 : opcode_timings_winchip2_da;
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
opcode = (opcode >> 3) & 7;
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
timings = mod3 ? opcode_timings_winchip2_db_mod3 : opcode_timings_winchip2_db;
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
timings = mod3 ? opcode_timings_winchip2_dc_mod3 : opcode_timings_winchip2_dc;
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
opcode = (opcode >> 3) & 7;
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
timings = mod3 ? opcode_timings_winchip2_dd_mod3 : opcode_timings_winchip2_dd;
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
opcode = (opcode >> 3) & 7;
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
timings = mod3 ? opcode_timings_winchip2_de_mod3 : opcode_timings_winchip2_de;
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
opcode = (opcode >> 3) & 7;
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
timings = mod3 ? opcode_timings_winchip2_df_mod3 : opcode_timings_winchip2_df;
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
opcode = (opcode >> 3) & 7;
break;
@@ -663,12 +663,12 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU
case 0x80:
case 0x82:
case 0x83:
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
timings = mod3 ? opcode_timings_winchip2_8x_mod3 : opcode_timings_winchip2_8x;
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x;
opcode = (fetchdat >> 3) & 7;
break;
case 0x81:
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
timings = mod3 ? opcode_timings_winchip2_81_mod3 : opcode_timings_winchip2_81;
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
opcode = (fetchdat >> 3) & 7;
break;
@@ -679,29 +679,29 @@ codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, UNU
case 0xd1:
case 0xd2:
case 0xd3:
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
timings = mod3 ? opcode_timings_winchip2_shift_mod3 : opcode_timings_winchip2_shift;
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
timings = mod3 ? opcode_timings_winchip2_f6_mod3 : opcode_timings_winchip2_f6;
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
opcode = (fetchdat >> 3) & 7;
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
timings = mod3 ? opcode_timings_winchip2_f7_mod3 : opcode_timings_winchip2_f7;
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
opcode = (fetchdat >> 3) & 7;
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
timings = mod3 ? opcode_timings_winchip2_ff_mod3 : opcode_timings_winchip2_ff;
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
opcode = (fetchdat >> 3) & 7;
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
timings = mod3 ? opcode_timings_winchip2_mod3 : opcode_timings_winchip2;
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
break;
}

View File

@@ -40,13 +40,14 @@
#include <86box/nmi.h>
#include <86box/pic.h>
#include <86box/pci.h>
#include <86box/timer.h>
#include <86box/gdbstub.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
#ifdef USE_DYNAREC
# include "codegen.h"
#endif
#endif /* USE_DYNAREC */
#include "x87_timings.h"
#define CCR1_USE_SMI (1 << 1)
@@ -118,7 +119,7 @@ const OpFn *x86_dynarec_opcodes_df_a32;
const OpFn *x86_dynarec_opcodes_REPE;
const OpFn *x86_dynarec_opcodes_REPNE;
const OpFn *x86_dynarec_opcodes_3DNOW;
#endif
#endif /* USE_DYNAREC */
const OpFn *x86_opcodes;
const OpFn *x86_opcodes_0f;
@@ -181,6 +182,8 @@ int cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled;
int cpu_cache_ext_enabled;
int cpu_flush_pending;
int cpu_old_paging;
int cpu_isa_speed;
int cpu_pci_speed;
int cpu_isa_pci_div;
@@ -503,7 +506,7 @@ cpu_set(void)
#ifdef USE_ACYCS
acycs = 0;
#endif
#endif /* USE_ACYCS */
soft_reset_pci = 0;
cpu_init = 0;
@@ -575,7 +578,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
#else
x86_setopcodes(ops_386, ops_386_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_386_0f);
x86_opcodes_REPE = ops_REPE;
x86_opcodes_REPNE = ops_REPNE;
@@ -586,7 +589,7 @@ cpu_set(void)
x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW;
#endif
#endif /* USE_DYNAREC */
if (hasfpu) {
#ifdef USE_DYNAREC
@@ -625,7 +628,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_df_a32;
}
#endif
#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d8_a16 = ops_sf_fpu_d8_a16;
x86_opcodes_d8_a32 = ops_sf_fpu_d8_a32;
@@ -713,7 +716,7 @@ cpu_set(void)
x86_dynarec_opcodes_de_a32 = dynarec_ops_nofpu_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_nofpu_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_nofpu_a32;
#endif
#endif /* USE_DYNAREC */
x86_opcodes_d8_a16 = ops_nofpu_a16;
x86_opcodes_d8_a32 = ops_nofpu_a32;
x86_opcodes_d9_a16 = ops_nofpu_a16;
@@ -751,7 +754,7 @@ cpu_set(void)
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_486);
#endif
#endif /* USE_DYNAREC */
memset(&msr, 0, sizeof(msr));
@@ -773,7 +776,7 @@ cpu_set(void)
x86_setopcodes(ops_186, ops_186_0f, dynarec_ops_186, dynarec_ops_186_0f);
#else
x86_setopcodes(ops_186, ops_186_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_186, ops_2386_186_0f);
break;
@@ -782,7 +785,7 @@ cpu_set(void)
x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f);
#else
x86_setopcodes(ops_286, ops_286_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_286, ops_2386_286_0f);
if (fpu_type == FPU_287) {
@@ -818,7 +821,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
}
#endif
#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32;
@@ -920,7 +923,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_ibm486_0f, dynarec_ops_386, dynarec_ops_ibm486_0f);
#else
x86_setopcodes(ops_386, ops_ibm486_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_ibm486_0f);
cpu_features = CPU_FEATURE_MSR;
fallthrough;
@@ -960,7 +963,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
}
#endif
#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_287_d9_a32;
@@ -1066,7 +1069,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
#else
x86_setopcodes(ops_386, ops_486_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
@@ -1106,7 +1109,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
#else
x86_setopcodes(ops_386, ops_486_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
@@ -1159,7 +1162,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_486_0f, dynarec_ops_386, dynarec_ops_486_0f);
#else
x86_setopcodes(ops_386, ops_486_0f);
#endif
#endif /* USE_DYNAREC */
x86_setopcodes_2386(ops_2386_386, ops_2386_486_0f);
timing_rr = 1; /* register dest - register src */
@@ -1208,7 +1211,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_stpc_0f);
else
x86_setopcodes(ops_386, ops_c486_0f);
#endif
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 3; /* register dest - memory src */
@@ -1251,7 +1254,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_c486_0f, dynarec_ops_386, dynarec_ops_c486_0f);
#else
x86_setopcodes(ops_386, ops_c486_0f);
#endif
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 1; /* register dest - memory src */
@@ -1300,7 +1303,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_winchip2_0f);
else
x86_setopcodes(ops_386, ops_winchip_0f);
#endif
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
@@ -1349,7 +1352,7 @@ cpu_set(void)
codegen_timing_set(&codegen_timing_winchip2);
else
codegen_timing_set(&codegen_timing_winchip);
#endif
#endif /* USE_DYNAREC */
break;
case CPU_P24T:
@@ -1365,7 +1368,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentiummmx_0f);
else
x86_setopcodes(ops_386, ops_pentium_0f);
#endif
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
@@ -1408,10 +1411,10 @@ cpu_set(void)
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_pentium);
#endif
#endif /* USE_DYNAREC */
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -1433,7 +1436,7 @@ cpu_set(void)
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_686_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_686_df_a32;
}
# endif
# endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
@@ -1471,7 +1474,7 @@ cpu_set(void)
# if 0
x86_setopcodes(ops_386, ops_c6x86_0f);
# endif
# endif
# endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 1; /* register dest - memory src */
@@ -1523,19 +1526,65 @@ cpu_set(void)
# ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_686);
# endif
# endif /* USE_DYNAREC */
if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX))
ccr4 = 0x80;
else if (CPU_Cx6x86)
CPUID = 0; /* Disabled on powerup by default */
break;
#endif
#endif /* USE_CYRIX_6X86 */
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
#endif
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
#else
x86_setopcodes(ops_386, ops_pentiummmx_0f);
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
timing_mr = 3; /* memory dest - register src */
timing_mm = 3;
timing_rml = 2; /* register dest - memory src long */
timing_mrl = 3; /* memory dest - register src long */
timing_mml = 3;
timing_bt = 0; /* branch taken */
timing_bnt = 1; /* branch not taken */
timing_int = 6;
timing_int_rm = 11;
timing_int_v86 = 54;
timing_int_pm = 25;
timing_int_pm_outer = 42;
timing_iret_rm = 7;
timing_iret_v86 = 27; /* unknown */
timing_iret_pm = 10;
timing_iret_pm_outer = 27;
timing_call_rm = 4;
timing_call_pm = 4;
timing_call_pm_gate = 22;
timing_call_pm_gate_inner = 44;
timing_retf_rm = 4;
timing_retf_pm = 4;
timing_retf_pm_outer = 23;
timing_jmp_rm = 3;
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PGE;
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_k5);
#endif /* USE_DYNAREC */
break;
#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
case CPU_K6_2C:
@@ -1545,34 +1594,20 @@ cpu_set(void)
#ifdef USE_DYNAREC
if (cpu_s->cpu_type >= CPU_K6_2)
x86_setopcodes(ops_386, ops_k62_0f, dynarec_ops_386, dynarec_ops_k62_0f);
# if defined(DEV_BRANCH) && defined(USE_AMD_K5)
else if (cpu_s->cpu_type == CPU_K6)
x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f);
else
x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f);
# else
else
x86_setopcodes(ops_386, ops_k6_0f, dynarec_ops_386, dynarec_ops_k6_0f);
# endif
#else
if (cpu_s->cpu_type >= CPU_K6_2)
x86_setopcodes(ops_386, ops_k62_0f);
# if defined(DEV_BRANCH) && defined(USE_AMD_K5)
else if (cpu_s->cpu_type == CPU_K6)
x86_setopcodes(ops_386, ops_k6_0f);
else
x86_setopcodes(ops_386, ops_pentiummmx_0f);
# else
else
x86_setopcodes(ops_386, ops_k6_0f);
# endif
#endif
#endif /* USE_DYNAREC */
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) {
x86_opcodes_3DNOW = ops_3DNOWE;
#ifdef USE_DYNAREC
x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE;
#endif
#endif /* USE_DYNAREC */
}
timing_rr = 1; /* register dest - register src */
@@ -1612,27 +1647,15 @@ cpu_set(void)
cpu_features |= CPU_FEATURE_3DNOW;
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P))
cpu_features |= CPU_FEATURE_3DNOWE;
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE;
if (cpu_s->cpu_type >= CPU_K6) {
cpu_CR4_mask |= (CR4_VME | CR4_PVI | CR4_PSE);
if (cpu_s->cpu_type <= CPU_K6)
cpu_CR4_mask |= CR4_PCE;
else if (cpu_s->cpu_type >= CPU_K6_2C)
cpu_CR4_mask |= CR4_PGE;
} else
cpu_CR4_mask |= CR4_PGE;
#else
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE;
if (cpu_s->cpu_type == CPU_K6)
cpu_CR4_mask |= CR4_PCE;
else if (cpu_s->cpu_type >= CPU_K6_2C)
cpu_CR4_mask |= CR4_PGE;
#endif
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_k6);
#endif
#endif /* USE_DYNAREC */
break;
case CPU_PENTIUMPRO:
@@ -1667,7 +1690,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_pentium2d_0f);
else
x86_setopcodes(ops_386, ops_pentium2_0f);
#endif
#endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
@@ -1725,7 +1748,7 @@ cpu_set(void)
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_p6);
#endif
#endif /* USE_DYNAREC */
break;
case CPU_CYRIX3S:
@@ -1733,7 +1756,7 @@ cpu_set(void)
x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f);
#else
x86_setopcodes(ops_386, ops_winchip2_0f);
#endif
#endif /* USE_DYNAREC */
timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
timing_mr = 2; /* memory dest - register src */
@@ -1773,7 +1796,7 @@ cpu_set(void)
#ifdef USE_DYNAREC
codegen_timing_set(&codegen_timing_winchip);
#endif
#endif /* USE_DYNAREC */
break;
default:
@@ -1811,7 +1834,7 @@ cpu_set(void)
cpu_exec = exec386_dynarec;
cpu_use_exec = 1;
} else
#endif
#endif /* defined(USE_DYNAREC) && !defined(USE_GDBSTUB) */
/* Use exec386 for CPU_IBM486SLC because it can reach 100 MHz. */
if ((cpu_s->cpu_type == CPU_IBM486SLC) || (cpu_s->cpu_type == CPU_IBM486BL) ||
cpu_iscyrix || (cpu_s->cpu_type > CPU_486DLC) || cpu_override_interpreter) {
@@ -2064,7 +2087,7 @@ cpu_CPUID(void)
EAX = EBX = ECX = EDX = 0;
break;
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
#ifdef USE_AMD_K5
case CPU_K5:
if (!EAX) {
EAX = 0x00000001;
@@ -2122,7 +2145,7 @@ cpu_CPUID(void)
break;
}
break;
#endif
#endif /* USE_AMD_K5 */
case CPU_K6:
switch (EAX) {
@@ -2353,7 +2376,7 @@ cpu_CPUID(void)
EAX = EBX = ECX = EDX = 0;
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
if (!EAX) {
EAX = 0x00000001;
@@ -2409,7 +2432,7 @@ cpu_CPUID(void)
} else
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif /* USE_CYRIX_6X86 */
case CPU_PENTIUMPRO:
if (!EAX) {
@@ -2564,10 +2587,10 @@ cpu_ven_reset(void)
msr.amd_psor = (cpu_s->cpu_type >= CPU_K6_3) ? 0x008cULL : 0x018cULL;
fallthrough;
case CPU_K6_2:
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
#endif
#endif /* USE_AMD_K5 */
case CPU_K6:
msr.amd_efer = (cpu_s->cpu_type >= CPU_K6_2C) ? 2ULL : 0ULL;
break;
@@ -2588,7 +2611,9 @@ cpu_ven_reset(void)
void
cpu_RDMSR(void)
{
switch (cpu_s->cpu_type) {
if (CPL)
x86gpf(NULL, 0);
else switch (cpu_s->cpu_type) {
case CPU_IBM386SLC:
case CPU_IBM486SLC:
case CPU_IBM486BL:
@@ -2788,10 +2813,10 @@ cpu_RDMSR(void)
}
break;
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
#endif
#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
case CPU_K6_2C:
@@ -3074,7 +3099,7 @@ pentium_invalid_rdmsr:
cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -3114,7 +3139,7 @@ pentium_invalid_rdmsr:
}
cpu_log("RDMSR: ECX = %08X, val = %08X%08X\n", ECX, EDX, EAX);
break;
#endif
#endif /* USE_CYRIX_6X86 */
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
@@ -3277,26 +3302,17 @@ pentium_invalid_rdmsr:
break;
/* SYSENTER_CS - SYSENTER target CS */
case 0x174:
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
goto i686_invalid_rdmsr;
EAX &= 0xffff0000;
EAX |= msr.sysenter_cs;
EDX = 0x00000000;
break;
/* SYSENTER_ESP - SYSENTER target ESP */
case 0x175:
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
goto i686_invalid_rdmsr;
EAX = msr.sysenter_esp;
EDX = 0x00000000;
break;
/* SYSENTER_EIP - SYSENTER target EIP */
case 0x176:
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
goto i686_invalid_rdmsr;
EAX = msr.sysenter_eip;
EDX = 0x00000000;
break;
@@ -3452,7 +3468,9 @@ cpu_WRMSR(void)
cpu_log("WRMSR %08X %08X%08X\n", ECX, EDX, EAX);
switch (cpu_s->cpu_type) {
if (CPL)
x86gpf(NULL, 0);
else switch (cpu_s->cpu_type) {
case CPU_IBM386SLC:
case CPU_IBM486SLC:
case CPU_IBM486BL:
@@ -3492,7 +3510,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
@@ -3568,7 +3586,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* PERFCTR0 - Performance Counter Register 0 - aliased to TSC */
case 0xc1:
@@ -3637,10 +3655,10 @@ cpu_WRMSR(void)
}
break;
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
#ifdef USE_AMD_K5
case CPU_K5:
case CPU_5K86:
#endif
#endif /* USE_AMD_K5 */
case CPU_K6:
case CPU_K6_2:
case CPU_K6_2C:
@@ -3664,7 +3682,7 @@ cpu_WRMSR(void)
break;
/* Time Stamp Counter */
case 0x00000010:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Array Access Register */
case 0x00000082:
@@ -3691,7 +3709,7 @@ cpu_WRMSR(void)
/* Extended Feature Enable Register */
case 0xc0000080:
temp = EAX | ((uint64_t) EDX << 32);
if (temp & ~1ULL)
if (temp & ~0x1fULL)
x86gpf(NULL, 0);
else
msr.amd_efer = temp;
@@ -3834,7 +3852,7 @@ amd_k_invalid_wrmsr:
/* Time Stamp Counter */
case 0x00000010:
case 0x80000010:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x00000011:
@@ -3901,7 +3919,7 @@ pentium_invalid_wrmsr:
}
break;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
case CPU_Cx6x86:
case CPU_Cx6x86L:
case CPU_CxGX1:
@@ -3919,7 +3937,7 @@ pentium_invalid_wrmsr:
msr.tr5 = EAX & 0x008f0f3b;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Performance Monitor - Control and Event Select */
case 0x11:
@@ -3935,7 +3953,7 @@ pentium_invalid_wrmsr:
break;
}
break;
#endif
#endif /* USE_CYRIX_6X86 */
case CPU_PENTIUMPRO:
case CPU_PENTIUM2:
@@ -3952,7 +3970,7 @@ pentium_invalid_wrmsr:
break;
/* Time Stamp Counter */
case 0x10:
tsc = EAX | ((uint64_t) EDX << 32);
timer_set_new_tsc(EAX | ((uint64_t) EDX << 32));
break;
/* Unknown */
case 0x18:
@@ -4046,23 +4064,14 @@ pentium_invalid_wrmsr:
break;
/* SYSENTER_CS - SYSENTER target CS */
case 0x174:
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
goto i686_invalid_wrmsr;
msr.sysenter_cs = EAX & 0xFFFF;
break;
/* SYSENTER_ESP - SYSENTER target ESP */
case 0x175:
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
goto i686_invalid_wrmsr;
msr.sysenter_esp = EAX;
break;
/* SYSENTER_EIP - SYSENTER target EIP */
case 0x176:
if (cpu_s->cpu_type == CPU_PENTIUMPRO)
goto i686_invalid_wrmsr;
msr.sysenter_eip = EAX;
break;
/* MCG_CAP - Machine Check Global Capability */
@@ -4248,14 +4257,14 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
case 0xe8: /* CCR4 */
if ((ccr3 & 0xf0) == 0x10) {
ccr4 = val;
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
if (cpu_s->cpu_type >= CPU_Cx6x86) {
if (val & 0x80)
CPUID = cpu_s->cpuid_model;
else
CPUID = 0;
}
#endif
#endif /* USE_CYRIX_6X86 */
}
break;
case 0xe9: /* CCR5 */
@@ -4329,7 +4338,7 @@ x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
}
#endif
#endif /* USE_DYNAREC */
void
x86_setopcodes_2386(const OpFn *opcodes, const OpFn *opcodes_0f)

View File

@@ -616,6 +616,8 @@ extern int cpu_prefetch_width;
extern int cpu_mem_prefetch_cycles;
extern int cpu_rom_prefetch_cycles;
extern int cpu_waitstates;
extern int cpu_flush_pending;
extern int cpu_old_paging;
extern int cpu_cache_int_enabled;
extern int cpu_cache_ext_enabled;
extern int cpu_isa_speed;

File diff suppressed because it is too large Load Diff

View File

@@ -83,7 +83,9 @@ int fpu_cycles = 0;
int in_lock = 0;
#ifdef ENABLE_X86_LOG
#if 0
void dumpregs(int);
#endif
int x86_do_log = ENABLE_X86_LOG;
int indump = 0;
@@ -93,13 +95,14 @@ x86_log(const char *fmt, ...)
{
va_list ap;
if (x808x_do_log) {
if (x86_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#if 0
void
dumpregs(int force)
{
@@ -144,6 +147,7 @@ dumpregs(int force)
x87_dumpregs();
indump = 0;
}
#endif
#else
# define x86_log(fmt, ...)
#endif
@@ -240,7 +244,6 @@ reset_common(int hard)
if (!hard && reset_on_hlt) {
hlt_reset_pending++;
pclog("hlt_reset_pending = %i\n", hlt_reset_pending);
if (hlt_reset_pending == 2)
hlt_reset_pending = 0;
else
@@ -274,7 +277,7 @@ reset_common(int hard)
cr0 = 0;
if (is386 && !is486 && (fpu_type == FPU_387))
cr0 |= 0x10;
cpu_cache_int_enabled = 0;
cpu_cache_int_enabled = 0;
cpu_update_waitstates();
cr4 = 0;
cpu_state.eflags = 0;
@@ -322,6 +325,8 @@ reset_common(int hard)
if (hard)
codegen_reset();
#endif
cpu_flush_pending = 0;
cpu_old_paging = 0;
if (!hard)
flushmmucache();
x86_was_reset = 1;
@@ -352,7 +357,8 @@ reset_common(int hard)
/* If we have an AT or PS/2 keyboard controller, make sure the A20 state
is correct. */
device_reset_all(DEVICE_KBC);
}
} else
device_reset_all(DEVICE_SOFTRESET);
if (!is286)
reset_808x(hard);
@@ -378,9 +384,6 @@ softresetx86(void)
if (soft_reset_mask)
return;
if (ibm8514_active || xga_active)
vga_on = 1;
reset_common(0);
}

View File

@@ -90,10 +90,10 @@ extern const OpFn dynarec_ops_winchip2_0f[1024];
extern const OpFn dynarec_ops_pentium_0f[1024];
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
# ifdef USE_CYRIX_6X86
extern const OpFn dynarec_ops_c6x86_0f[1024];
extern const OpFn dynarec_ops_c6x86mx_0f[1024];
# endif
# endif /* USE_CYRIX_6X86 */
extern const OpFn dynarec_ops_k6_0f[1024];
extern const OpFn dynarec_ops_k62_0f[1024];
@@ -232,10 +232,10 @@ extern const OpFn ops_winchip2_0f[1024];
extern const OpFn ops_pentium_0f[1024];
extern const OpFn ops_pentiummmx_0f[1024];
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
extern const OpFn ops_c6x86_0f[1024];
extern const OpFn ops_c6x86mx_0f[1024];
#endif
#endif /* USE_CYRIX_6X86 */
extern const OpFn ops_k6_0f[1024];
extern const OpFn ops_k62_0f[1024];

View File

@@ -24,7 +24,7 @@ opAAD(uint32_t fetchdat)
base = 10;
AL = (AH * base) + AL;
AH = 0;
setznp16(AX);
setznp8(AL);
CLOCK_CYCLES((is486) ? 14 : 19);
PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0);
return 0;
@@ -39,7 +39,7 @@ opAAM(uint32_t fetchdat)
base = 10;
AH = AL / base;
AL %= base;
setznp16(AX);
setznp8(AL);
CLOCK_CYCLES((is486) ? 15 : 17);
PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0);
return 0;

View File

@@ -878,6 +878,10 @@ opINVD(uint32_t fetchdat)
static int
opWBINVD(uint32_t fetchdat)
{
if (CPL) {
x86gpf(NULL, 0);
return 1;
}
CLOCK_CYCLES(10000);
CPU_BLOCK_END();
return 0;

View File

@@ -110,7 +110,7 @@ opMOVD_mm_l_a32(uint32_t fetchdat)
return 0;
}
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
#ifdef USE_CYRIX_6X86
/*Cyrix maps both MOVD and SMINT to the same opcode*/
static int
opMOVD_mm_l_a16_cx(uint32_t fetchdat)
@@ -170,7 +170,7 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat)
return 0;
}
#endif
#endif /* USE_CYRIX_6X86 */
static int
opMOVQ_q_mm_a16(uint32_t fetchdat)

View File

@@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -180,8 +184,16 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG))
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 || cpu_use_dynarec)
flushmmucache();
else {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
@@ -210,7 +222,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE))
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE))
flushmmucache();
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
@@ -237,8 +249,16 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG))
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
if (is_p6 || cpu_use_dynarec)
flushmmucache();
else {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
@@ -267,7 +287,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE))
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE))
flushmmucache();
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;

View File

@@ -9,6 +9,8 @@ opMOV_r_CRx_a16(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -49,6 +51,8 @@ opMOV_r_CRx_a32(uint32_t fetchdat)
switch (cpu_reg) {
case 0:
cpu_state.regs[cpu_rm].l = cr0;
if (cpu_flush_pending)
cpu_state.regs[cpu_rm].l ^= 0x80000000;
if (is486 || isibm486)
cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/
else {
@@ -176,8 +180,12 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
fetch_ea_16(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG))
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
@@ -206,7 +214,7 @@ opMOV_CRx_r_a16(uint32_t fetchdat)
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE))
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE))
flushmmucache();
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;
@@ -233,8 +241,12 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
fetch_ea_32(fetchdat);
switch (cpu_reg) {
case 0:
if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001)
if ((cpu_state.regs[cpu_rm].l ^ cr0) & (0x00000001 | WP_FLAG))
flushmmucache();
else if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000000) {
flushmmucache_nopc();
cpu_flush_pending = 1;
}
/* Make sure CPL = 0 when switching from real mode to protected mode. */
if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01))
cpu_state.seg_cs.access &= 0x9f;
@@ -263,7 +275,7 @@ opMOV_CRx_r_a32(uint32_t fetchdat)
break;
case 4:
if (cpu_has_feature(CPU_FEATURE_CR4)) {
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PAE | CR4_PGE))
if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & (CR4_PSE | CR4_PAE | CR4_PGE))
flushmmucache();
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
break;

View File

@@ -430,12 +430,21 @@ op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
case 0x20: /*SMSW*/
if (cpu_mod != 3)
SEG_CHECK_WRITE(cpu_state.ea_seg);
if (is486 || isibm486)
seteaw(msw);
else if (is386)
seteaw(msw | /* 0xFF00 */ 0xFFE0);
else
seteaw(msw | 0xFFF0);
if (is386 && is32 && (cpu_mod == 3)) {
if (is486 || isibm486)
seteaw(cr0);
else if (is386 && !cpu_16bitbus)
seteaw(cr0 | /* 0x7FFFFF00 */ 0x7FFFFFE0);
else
seteaw(cr0 | 0x7FFFFFF0);
} else {
if (is486 || isibm486)
seteaw(msw);
else if (is386 && !cpu_16bitbus)
seteaw(msw | /* 0xFF00 */ 0xFFE0);
else
seteaw(msw | 0xFFF0);
}
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32);
break;

View File

@@ -48,12 +48,12 @@
#define seg_writememwl writememwl_2386
#define seg_writememll writememll_2386
#else
#define seg_readmembl readmembl_2386
#define seg_readmemwl readmemwl_2386
#define seg_readmemll readmemll_2386
#define seg_writemembl writemembl_2386
#define seg_writememwl writememwl_2386
#define seg_writememll writememll_2386
#define seg_readmembl readmembl
#define seg_readmemwl readmemwl
#define seg_readmemll readmemll
#define seg_writemembl writemembl
#define seg_writememwl writememwl
#define seg_writememll writememll
#endif
#define DPL ((segdat[2] >> 13) & 3)
@@ -798,6 +798,27 @@ PUSHL(uint32_t v)
}
}
static void
PUSHL_SEL(uint32_t v)
{
if (cpu_16bitbus) {
PUSHW(v >> 16);
PUSHW(v & 0xffff);
} else {
if (stack32) {
writememw(ss, ESP - 4, v);
if (cpu_state.abrt)
return;
ESP -= 4;
} else {
writememw(ss, ((SP - 4) & 0xffff), v);
if (cpu_state.abrt)
return;
SP -= 4;
}
}
}
static uint16_t
POPW(void)
{
@@ -875,7 +896,7 @@ loadcscall(uint16_t seg)
uint32_t oldsp;
uint32_t newsp;
uint32_t oldsp2;
uint16_t tempw;
uint32_t oldss_limit_high = cpu_state.seg_ss.limit_high;
const x86seg *dt;
if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) {
@@ -1092,7 +1113,7 @@ loadcscall(uint16_t seg)
x86seg_log("Type %04X\n", type);
if (type == 0x0c00) {
PUSHL(oldss);
PUSHL_SEL(oldss);
PUSHL(oldsp2);
if (cpu_state.abrt) {
SS = oldss;
@@ -1104,7 +1125,31 @@ loadcscall(uint16_t seg)
}
if (count) {
while (count--) {
PUSHL(readmeml(oldssbase, oldsp + (count << 2)));
uint32_t temp_val;
switch (oldss_limit_high - oldsp - (count << 2)) {
default:
case 3:
/* We are at least an entire DWORD away from the limit,
read long. */
PUSHL(readmeml(oldssbase, oldsp + (count << 2)));
break;
case 2:
/* We are 3 bytes away from the limit,
read word + byte. */
temp_val = readmemw(oldssbase, oldsp + (count << 2));
temp_val |= (readmemb(oldssbase, oldsp +
(count << 2) + 2) << 16);
PUSHL(temp_val);
break;
case 1:
/* We are a WORD away from the limit, read word. */
PUSHL(readmemw(oldssbase, oldsp + (count << 2)));
break;
case 0:
/* We are a BYTE away from the limit, read byte. */
PUSHL(readmemb(oldssbase, oldsp + (count << 2)));
break;
}
if (cpu_state.abrt) {
SS = oldss;
ESP = oldsp2;
@@ -1131,9 +1176,20 @@ loadcscall(uint16_t seg)
x86seg_log("Write SP to %04X:%04X\n", SS, SP);
if (count) {
while (count--) {
tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1));
x86seg_log("PUSH %04X\n", tempw);
PUSHW(tempw);
switch (oldss_limit_high - (oldsp & 0xffff) - (count << 1)) {
default:
case 1:
/* We are at least an entire WORD away from the limit,
read word. */
PUSHW(readmemw(oldssbase, (oldsp & 0xffff) +
(count << 1)));
break;
case 0:
/* We are a BYTE away from the limit, read byte. */
PUSHW(readmemb(oldssbase, (oldsp & 0xffff) +
(count << 1)));
break;
}
if (cpu_state.abrt) {
SS = oldss;
ESP = oldsp2;
@@ -1622,10 +1678,10 @@ pmodeint(int num, int soft)
cpl_override = 1;
if (type >= 0x0800) {
if (cpu_state.eflags & VM_FLAG) {
PUSHL(GS);
PUSHL(FS);
PUSHL(DS);
PUSHL(ES);
PUSHL_SEL(GS);
PUSHL_SEL(FS);
PUSHL_SEL(DS);
PUSHL_SEL(ES);
if (cpu_state.abrt)
return;
op_loadseg(0, &cpu_state.seg_ds);
@@ -1633,10 +1689,10 @@ pmodeint(int num, int soft)
op_loadseg(0, &cpu_state.seg_fs);
op_loadseg(0, &cpu_state.seg_gs);
}
PUSHL(oldss);
PUSHL_SEL(oldss);
PUSHL(oldsp);
PUSHL(cpu_state.flags | (cpu_state.eflags << 16));
PUSHL(CS);
PUSHL_SEL(CS);
PUSHL(cpu_state.pc);
if (cpu_state.abrt)
return;
@@ -1672,7 +1728,7 @@ pmodeint(int num, int soft)
}
if (type > 0x0800) {
PUSHL(cpu_state.flags | (cpu_state.eflags << 16));
PUSHL(CS);
PUSHL_SEL(CS);
PUSHL(cpu_state.pc);
if (cpu_state.abrt)
return;

View File

@@ -26,22 +26,22 @@ uint32_t x87_op_off;
uint16_t x87_pc_seg;
uint16_t x87_op_seg;
#ifdef ENABLE_FPU_LOG
int fpu_do_log = ENABLE_FPU_LOG;
#ifdef ENABLE_FPU_X87_LOG
int fpu_x87_do_log = ENABLE_FPU_X87_LOG;
void
fpu_log(const char *fmt, ...)
fpu_x87_log(const char *fmt, ...)
{
va_list ap;
if (fpu_do_log) {
if (fpu_x87_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define fpu_log(fmt, ...)
# define fpu_x87_log(fmt, ...)
#endif
#ifdef USE_NEW_DYNAREC
@@ -546,17 +546,17 @@ unpack_FPU_TW(uint16_t tag_byte)
return (twd >> 2);
}
#ifdef ENABLE_808X_LOG
#ifdef ENABLE_FPU_X87_LOG
void
x87_dumpregs(void)
{
if (cpu_state.ismmx) {
fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q);
fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q);
fpu_x87_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q);
fpu_x87_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q);
} else {
fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n", cpu_state.ST[cpu_state.TOP], cpu_state.ST[(cpu_state.TOP + 1) & 7], cpu_state.ST[(cpu_state.TOP + 2) & 7], cpu_state.ST[(cpu_state.TOP + 3) & 7]);
fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n", cpu_state.ST[(cpu_state.TOP + 4) & 7], cpu_state.ST[(cpu_state.TOP + 5) & 7], cpu_state.ST[(cpu_state.TOP + 6) & 7], cpu_state.ST[(cpu_state.TOP + 7) & 7]);
fpu_x87_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n", cpu_state.ST[cpu_state.TOP], cpu_state.ST[(cpu_state.TOP + 1) & 7], cpu_state.ST[(cpu_state.TOP + 2) & 7], cpu_state.ST[(cpu_state.TOP + 3) & 7]);
fpu_x87_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n", cpu_state.ST[(cpu_state.TOP + 4) & 7], cpu_state.ST[(cpu_state.TOP + 5) & 7], cpu_state.ST[(cpu_state.TOP + 6) & 7], cpu_state.ST[(cpu_state.TOP + 7) & 7]);
}
fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag());
fpu_x87_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag());
}
#endif

View File

@@ -228,7 +228,6 @@ FPU_save_regi_tag(extFloat80_t reg, int tag, int stnr)
#define FPU_check_pending_exceptions() \
do { \
if (fpu_state.swd & FPU_SW_Summary) { \
pclog("SW Summary.\n"); \
if (cr0 & 0x20) { \
x86_int(16); \
return 1; \

View File

@@ -78,7 +78,11 @@ opFINIT(uint32_t fetchdat)
cpu_state.npxc = 0x37F;
#endif
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
#ifdef FPU_8087
cpu_state.npxs &= 0x4700;
#else
cpu_state.npxs = 0;
#endif
p = (uint64_t *) cpu_state.tag;
#ifdef USE_NEW_DYNAREC
*p = 0;
@@ -406,7 +410,11 @@ FSAVE(void)
cpu_state.npxc = 0x37F;
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
#ifdef FPU_8087
cpu_state.npxs &= 0x4700;
#else
cpu_state.npxs = 0;
#endif
p = (uint64_t *) cpu_state.tag;
#ifdef USE_NEW_DYNAREC
*p = 0;

View File

@@ -431,11 +431,12 @@ sf_FNSAVE_a16(uint32_t fetchdat)
}
#ifdef FPU_8087
fpu_state.swd = 0x3FF;
fpu_state.cwd = 0x3FF;
fpu_state.swd &= 0x4700;
#else
fpu_state.cwd = 0x37F;
#endif
fpu_state.swd = 0;
#endif
fpu_state.tos = 0;
fpu_state.tag = 0xffff;
cpu_state.ismmx = 0;
@@ -467,7 +468,7 @@ sf_FNSAVE_a32(uint32_t fetchdat)
}
# ifdef FPU_8087
fpu_state.swd = 0x3FF;
fpu_state.cwd = 0x3FF;
# else
fpu_state.cwd = 0x37F;
# endif
@@ -504,10 +505,11 @@ sf_FNINIT(uint32_t fetchdat)
cpu_state.pc++;
#ifdef FPU_8087
fpu_state.cwd = 0x3FF;
fpu_state.swd &= 0x4700;
#else
fpu_state.cwd = 0x37F;
#endif
fpu_state.swd = 0;
#endif
fpu_state.tos = 0;
fpu_state.tag = 0xffff;
fpu_state.foo = 0;
@@ -606,7 +608,6 @@ static int
sf_FNOP(uint32_t fetchdat)
{
FP_ENTER();
pclog("FNOP.\n");
FPU_check_pending_exceptions();
cpu_state.pc++;
CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi));

View File

@@ -97,14 +97,28 @@ device_set_context(device_context_t *c, const device_t *dev, int inst)
if (inst) {
sprintf(c->name, "%s #%i", dev->name, inst);
/* If this is the first instance and a numbered section is not present, but a non-numbered
section of the same name is, rename the non-numbered section to numbered. */
if (inst == 1) {
const void *sec = config_find_section(c->name);
void * single_sec = config_find_section((char *) dev->name);
if ((sec == NULL) && (single_sec != NULL))
config_rename_section(single_sec, c->name);
}
/* If a numbered section is not present, but a non-numbered of the same name
is, rename the non-numbered section to numbered. */
const void *sec = config_find_section(c->name);
void * single_sec = config_find_section((char *) dev->name);
if ((sec == NULL) && (single_sec != NULL))
config_rename_section(single_sec, c->name);
} else if (!strcmp(dev->name, "PS/2 Mouse")) {
sprintf(c->name, "%s", dev->name);
/* Migrate the old "Standard PS/2 Mouse" section */
const void *sec = config_find_section(c->name);
void * old_sec = config_find_section("Standard PS/2 Mouse");
if ((sec == NULL) && (old_sec != NULL))
config_rename_section(old_sec, c->name);
} else if (!strcmp(dev->name, "Microsoft RAMCard")) {
sprintf(c->name, "%s", dev->name);
/* Migrate the old "Standard PS/2 Mouse" section */
const void *sec = config_find_section(c->name);
void * old_sec = config_find_section("Microsoft RAMCard for IBM PC");
if ((sec == NULL) && (old_sec != NULL))
config_rename_section(old_sec, c->name);
} else
sprintf(c->name, "%s", dev->name);
}
@@ -186,7 +200,8 @@ device_add_common(const device_t *dev, void *p, void *params, int inst)
devices[c] = NULL;
device_priv[c] = NULL;
free(init_dev);
if ((init_dev != NULL) && (init_dev != (device_t *) dev))
free(init_dev);
return (NULL);
}
@@ -842,3 +857,31 @@ device_context_get_device(void)
{
return device_current.dev;
}
const device_t device_none = {
.name = "None",
.internal_name = "none",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t device_internal = {
.name = "Internal",
.internal_name = "internal",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -9,22 +9,53 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2021 Andreas J. Reichel.
# Copyright 2021-2022 Jasmine Iwanek.
# Copyright 2021-2024 Jasmine Iwanek.
#
add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c hwm_lm78.c hwm_gl518sm.c
hwm_vt82c686.c ibm_5161.c isamem.c isartc.c ../lpt.c pci_bridge.c
postcard.c serial.c unittester.c clock_ics9xxx.c isapnp.c i2c.c i2c_gpio.c
smbus_piix4.c smbus_ali7101.c smbus_sis5595.c keyboard.c keyboard_xt.c
kbc_at.c kbc_at_dev.c
add_library(dev OBJECT
bugger.c
cassette.c
cartridge.c
hasp.c
hwm.c
hwm_lm75.c
hwm_lm78.c
hwm_gl518sm.c
hwm_vt82c686.c
ibm_5161.c
isamem.c
isartc.c
../lpt.c
pci_bridge.c
postcard.c
serial.c
unittester.c
clock_ics9xxx.c
isapnp.c
i2c.c
i2c_gpio.c
smbus_piix4.c
smbus_ali7101.c
smbus_sis5595.c
keyboard.c
keyboard_xt.c
kbc_at.c
kbc_at_dev.c
keyboard_at.c
mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c
mouse.c
mouse_bus.c
mouse_serial.c
mouse_ps2.c
nec_mate_unk.c
phoenix_486_jumper.c
serial_passthrough.c
novell_cardkey.c
mouse_microtouch_touchscreen.c)
mouse_microtouch_touchscreen.c
)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_link_libraries(86Box atomic)
@@ -45,3 +76,12 @@ endif()
if(LASERXT)
target_compile_definitions(dev PRIVATE USE_LASERXT)
endif()
if(PCL)
target_compile_definitions(dev PRIVATE USE_PCL)
endif()
if(WACOM)
target_compile_definitions(dev PRIVATE USE_WACOM)
target_sources(dev PRIVATE mouse_wacom_tablet.c)
endif()

View File

@@ -35,6 +35,7 @@ typedef struct cart_t {
} cart_t;
char cart_fns[2][512];
char *cart_image_history[2][CART_IMAGE_HISTORY];
static cart_t carts[2];
@@ -169,6 +170,7 @@ cart_close(int drive)
cart_image_close(drive);
cart_fns[drive][0] = 0;
ui_sb_update_icon_state(SB_CARTRIDGE | drive, 1);
resetx86();
}
void

View File

@@ -45,6 +45,7 @@ pc_cassette_t *cassette;
char cassette_fname[512];
char cassette_mode[512];
char * cassette_image_history[CASSETTE_IMAGE_HISTORY];
unsigned long cassette_pos;
unsigned long cassette_srate;
int cassette_enable;

View File

@@ -857,7 +857,7 @@ static const device_config_t ibmxt_32k_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 32,
@@ -905,7 +905,7 @@ static const device_config_t ibmxt_64k_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 64,
@@ -953,7 +953,7 @@ static const device_config_t ibmxt_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 128,
@@ -1001,7 +1001,7 @@ static const device_config_t genericxt_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 16,
@@ -1049,7 +1049,7 @@ static const device_config_t msramcard_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 64,
@@ -1080,7 +1080,7 @@ static const device_config_t msramcard_config[] = {
};
static const device_t msramcard_device = {
.name = "Microsoft RAMCard for IBM PC",
.name = "Microsoft RAMCard",
.internal_name = "msramcard",
.flags = DEVICE_ISA,
.local = ISAMEM_RAMCARD_CARD,
@@ -1097,7 +1097,7 @@ static const device_config_t mssystemcard_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 64,
@@ -1159,7 +1159,7 @@ static const device_config_t ibmat_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
@@ -1176,7 +1176,7 @@ static const device_config_t ibmat_config[] = {
.description = "Start Address",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
.default_int = 1024,
.file_filter = "",
.spinner = {
.min = 0,
@@ -1207,7 +1207,7 @@ static const device_config_t genericat_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
@@ -1224,7 +1224,7 @@ static const device_config_t genericat_config[] = {
.description = "Start Address",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
.default_int = 1024,
.file_filter = "",
.spinner = {
.min = 0,
@@ -1255,7 +1255,7 @@ static const device_config_t p5pak_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 128,
@@ -1303,7 +1303,7 @@ static const device_config_t a6pak_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 64,
@@ -1351,7 +1351,7 @@ static const device_config_t ems5150_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 256,
@@ -1402,7 +1402,7 @@ static const device_config_t ev159_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
@@ -1544,7 +1544,7 @@ static const device_config_t ev165a_config[] = {
// clang-format off
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
@@ -1669,7 +1669,7 @@ static const device_config_t brxt_config[] = {
},
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
@@ -1699,7 +1699,7 @@ static const device_t brxt_device = {
.config = brxt_config
};
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT)
#ifdef USE_ISAMEM_BRAT
static const device_config_t brat_config[] = {
// clang-format off
{
@@ -1762,7 +1762,7 @@ static const device_config_t brat_config[] = {
},
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 512,
@@ -1804,7 +1804,7 @@ static const device_t brat_device = {
.force_redraw = NULL,
.config = brat_config
};
#endif
#endif /* USE_ISAMEM_BRAT */
static const device_config_t lotech_config[] = {
// clang-format off
@@ -1841,7 +1841,7 @@ static const device_config_t lotech_config[] = {
},
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 2048,
@@ -1871,7 +1871,7 @@ static const device_t lotech_device = {
.config = lotech_config
};
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE)
#ifdef USE_ISAMEM_RAMPAGE
// TODO: Dual Paging support
// TODO: Conventional memory suppport
static const device_config_t rampage_config[] = {
@@ -1897,7 +1897,7 @@ static const device_config_t rampage_config[] = {
},
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 256, /* Technically 128k, but banks 2-7 must be 256, headaches elsewise */
@@ -1939,9 +1939,9 @@ static const device_t rampage_device = {
.force_redraw = NULL,
.config = rampage_config
};
#endif
#endif /* USE_ISAMEM_RAMPAGE */
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB)
#ifdef USE_ISAMEM_IAB
static const device_config_t iab_config[] = {
// clang-format off
{
@@ -2009,7 +2009,7 @@ static const device_config_t iab_config[] = {
},
{
.name = "size",
.description = "Memory Size",
.description = "Memory size",
.type = CONFIG_SPINNER,
.default_string = "",
.default_int = 128,
@@ -2038,27 +2038,13 @@ static const device_t iab_device = {
.force_redraw = NULL,
.config = iab_config
};
#endif
static const device_t isa_none_device = {
.name = "None",
.internal_name = "none",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
#endif /* USE_ISAMEM_IAB */
static const struct {
const device_t *dev;
} boards[] = {
// clang-format off
{ &isa_none_device },
{ &device_none },
// XT Ram Expansion Cards
{ &ibmxt_32k_device },
{ &ibmxt_64k_device },
@@ -2077,15 +2063,15 @@ static const struct {
{ &ev159_device },
{ &ev165a_device },
{ &brxt_device },
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_BRAT)
#ifdef USE_ISAMEM_BRAT
{ &brat_device },
#endif
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_RAMPAGE)
#endif /* USE_ISAMEM_BRAT */
#ifdef USE_ISAMEM_RAMPAGE
{ &rampage_device },
#endif
#if defined(DEV_BRANCH) && defined(USE_ISAMEM_IAB)
#endif /* USE_ISAMEM_RAMPAGE */
#ifdef USE_ISAMEM_IAB
{ &iab_device },
#endif
#endif /* USE_ISAMEM_IAB */
{ &lotech_device },
{ NULL }
// clang-format on

View File

@@ -110,6 +110,7 @@ typedef struct _isapnp_card_ {
} isapnp_card_t;
typedef struct {
uint8_t in_isolation;
uint8_t reg;
uint8_t key_pos : 5;
uint16_t read_data_addr;
@@ -313,6 +314,8 @@ isapnp_read_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uint
case 0x05: /* Status */
ret = 0x00;
if (dev->in_isolation)
ret = 0x01;
CHECK_CURRENT_CARD();
isapnp_log("ISAPnP: Query status for CSN %02X\n", card->csn);
@@ -485,15 +488,16 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
case 0x03: /* Wake[CSN] */
isapnp_log("ISAPnP: Wake[%02X]\n", val);
card = dev->first_card;
if (val == 0)
dev->in_isolation |= 1;
while (card) {
if (card->csn == val) {
card->rom_pos = 0;
card->id_checksum = isapnp_init_key[0];
if (card->state == PNP_STATE_SLEEP)
card->state = (val == 0) ? PNP_STATE_ISOLATION : PNP_STATE_CONFIG;
} else {
} else
card->state = PNP_STATE_SLEEP;
}
card = card->next;
}
@@ -505,6 +509,7 @@ isapnp_write_common(isapnp_t *dev, isapnp_card_t *card, isapnp_device_t *ld, uin
isapnp_set_csn(dev->isolated_card, val);
dev->isolated_card->state = PNP_STATE_CONFIG;
dev->isolated_card = NULL;
dev->in_isolation = 0;
} else {
isapnp_log("ISAPnP: Set CSN %02X but no card is isolated\n", val);
}

View File

@@ -752,30 +752,16 @@ const device_t vendex_xt_rtc_onboard_device = {
.config = NULL
};
static const device_t isartc_none_device = {
.name = "None",
.internal_name = "none",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
static const struct {
const device_t *dev;
} boards[] = {
// clang-format off
{ &isartc_none_device },
{ &ev170_device },
{ &pii147_device },
{ &p5pak_device },
{ &a6pak_device },
{ NULL },
{ &device_none },
{ &ev170_device },
{ &pii147_device },
{ &p5pak_device },
{ &a6pak_device },
{ NULL },
// clang-format on
};

View File

@@ -277,9 +277,26 @@ kbc_translate(atkbc_t *dev, uint8_t val)
return ret;
}
kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off");
#ifdef ENABLE_KEYBOARD_AT_LOG
kbc_at_log("scan code: ");
if (translate) {
kbc_at_log("%02X (original: ", (nont_to_t[val] | dev->sc_or));
if (dev->sc_or == 0x80)
kbc_at_log("F0 ");
kbc_at_log("%02X)\n", val);
} else
kbc_at_log("%02X\n", val);
#endif
ret = translate ? (nont_to_t[val] | dev->sc_or) : val;
if (dev->sc_or == 0x80)
dev->sc_or = 0;
/* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */
if ((dev != NULL) && (kbc_ven == KBC_VEN_TOSHIBA) &&
(keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (val) {
(keyboard_recv(0x138) || keyboard_recv(0x11d))) switch (ret) {
case 0x4f:
t3100e_notify_set(0x01);
break; /* End */
@@ -329,23 +346,6 @@ kbc_translate(atkbc_t *dev, uint8_t val)
break;
}
kbc_at_log("ATkbc: translate is %s, ", translate ? "on" : "off");
#ifdef ENABLE_KEYBOARD_AT_LOG
kbc_at_log("scan code: ");
if (translate) {
kbc_at_log("%02X (original: ", (nont_to_t[val] | dev->sc_or));
if (dev->sc_or == 0x80)
kbc_at_log("F0 ");
kbc_at_log("%02X)\n", val);
} else
kbc_at_log("%02X\n", val);
#endif
ret = translate ? (nont_to_t[val] | dev->sc_or) : val;
if (dev->sc_or == 0x80)
dev->sc_or = 0;
return ret;
}
@@ -422,6 +422,14 @@ kbc_delay_to_ob(atkbc_t *dev, uint8_t val, uint8_t channel, uint8_t stat_hi)
dev->stat_hi = stat_hi;
dev->pending = 1;
dev->state = STATE_KBC_DELAY_OUT;
if (dev->is_asic && (channel == 0) && (dev->status & STAT_OFULL)) {
/* Expedite the sending to the output buffer to prevent the wrong
data from being accidentally read. */
kbc_send_to_ob(dev, dev->val, dev->channel, dev->stat_hi);
dev->state = STATE_MAIN_IBF;
dev->pending = 0;
}
}
static void kbc_at_process_cmd(void *priv);
@@ -813,14 +821,14 @@ write_p2(atkbc_t *dev, uint8_t val)
softresetx86(); /* Pulse reset! */
cpu_set_edx();
flushmmucache();
if (kbc_ven == KBC_VEN_ALI)
if ((kbc_ven == KBC_VEN_ALI) || !strcmp(machine_get_internal_name(), "spc7700plw"))
smbase = 0x00030000;
/* Yes, this is a hack, but until someone gets ahold of the real PCD-2L
and can find out what they actually did to make it boot from FFFFF0
correctly despite A20 being gated when the CPU is reset, this will
have to do. */
if (kbc_ven == KBC_VEN_SIEMENS)
if ((kbc_ven == KBC_VEN_SIEMENS) || !strcmp(machine_get_internal_name(), "acera1g"))
is486 ? loadcs(0xf000) : loadcs_2386(0xf000);
}
}
@@ -1181,6 +1189,23 @@ write60_ami(void *priv, uint8_t val)
return 1;
}
void
kbc_at_set_ps2(void *priv, const uint8_t ps2)
{
atkbc_t *dev = (atkbc_t *) priv;
dev->ami_flags = (dev->ami_flags & 0xfe) | (!!ps2);
dev->misc_flags &= ~FLAG_PS2;
if (ps2) {
dev->misc_flags |= FLAG_PS2;
kbc_at_do_poll = kbc_at_poll_ps2;
} else
kbc_at_do_poll = kbc_at_poll_at;
write_cmd(dev, ~dev->mem[0x20]);
write_cmd(dev, dev->mem[0x20]);
}
static uint8_t
write64_ami(void *priv, uint8_t val)
{
@@ -2208,7 +2233,11 @@ static void
kbc_at_close(void *priv)
{
atkbc_t *dev = (atkbc_t *) priv;
#ifdef OLD_CODE
int max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1;
#else
int max_ports = 2;
#endif
/* Stop timers. */
timer_disable(&dev->kbc_dev_poll_timer);
@@ -2350,7 +2379,11 @@ kbc_at_init(const device_t *info)
break;
}
#ifdef OLD_CODE
max_ports = ((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) ? 2 : 1;
#else
max_ports = 2;
#endif
for (int i = 0; i < max_ports; i++) {
kbc_at_ports[i] = (kbc_at_port_t *) malloc(sizeof(kbc_at_port_t));

View File

@@ -25,6 +25,7 @@
#include <86box/86box.h>
#include <86box/machine.h>
#include <86box/keyboard.h>
#include <86box/plat.h>
#include "cpu.h"
@@ -50,7 +51,8 @@ uint16_t key_uncapture_2 = 0x14f; /* End */
void (*keyboard_send)(uint16_t val);
static int recv_key[512]; /* keyboard input buffer */
static int recv_key[512] = { 0 }; /* keyboard input buffer */
static int recv_key_ui[512] = { 0 }; /* keyboard input buffer */
static int oldkey[512];
#if 0
static int keydelay[512];
@@ -238,16 +240,13 @@ keyboard_input(int down, uint16_t scan)
}
}
/* NOTE: Shouldn't this be some sort of bit shift? An array of 8 unsigned 64-bit integers
should be enough. */
#if 0
recv_key[scan >> 6] |= ((uint64_t) down << ((uint64_t) scan & 0x3fLL));
#endif
/* pclog("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */
recv_key[scan & 0x1ff] = down;
recv_key_ui[scan & 0x1ff] = down;
key_process(scan & 0x1ff, down);
if (mouse_capture || !kbd_req_capture || video_fullscreen) {
recv_key[scan & 0x1ff] = down;
key_process(scan & 0x1ff, down);
}
}
static uint8_t
@@ -343,30 +342,36 @@ keyboard_recv(uint16_t key)
return recv_key[key];
}
int
keyboard_recv_ui(uint16_t key)
{
return recv_key_ui[key];
}
/* Do we have Control-Alt-PgDn in the keyboard buffer? */
int
keyboard_isfsenter(void)
{
return ((recv_key[0x01d] || recv_key[0x11d]) && (recv_key[0x038] || recv_key[0x138]) && (recv_key[0x049] || recv_key[0x149]));
return ((recv_key_ui[0x01d] || recv_key_ui[0x11d]) && (recv_key_ui[0x038] || recv_key_ui[0x138]) && (recv_key_ui[0x049] || recv_key_ui[0x149]));
}
int
keyboard_isfsenter_up(void)
{
return (!recv_key[0x01d] && !recv_key[0x11d] && !recv_key[0x038] && !recv_key[0x138] && !recv_key[0x049] && !recv_key[0x149]);
return (!recv_key_ui[0x01d] && !recv_key_ui[0x11d] && !recv_key_ui[0x038] && !recv_key_ui[0x138] && !recv_key_ui[0x049] && !recv_key_ui[0x149]);
}
/* Do we have Control-Alt-PgDn in the keyboard buffer? */
int
keyboard_isfsexit(void)
{
return ((recv_key[0x01d] || recv_key[0x11d]) && (recv_key[0x038] || recv_key[0x138]) && (recv_key[0x051] || recv_key[0x151]));
return ((recv_key_ui[0x01d] || recv_key_ui[0x11d]) && (recv_key_ui[0x038] || recv_key_ui[0x138]) && (recv_key_ui[0x051] || recv_key_ui[0x151]));
}
int
keyboard_isfsexit_up(void)
{
return (!recv_key[0x01d] && !recv_key[0x11d] && !recv_key[0x038] && !recv_key[0x138] && !recv_key[0x051] && !recv_key[0x151]);
return (!recv_key_ui[0x01d] && !recv_key_ui[0x11d] && !recv_key_ui[0x038] && !recv_key_ui[0x138] && !recv_key_ui[0x051] && !recv_key_ui[0x151]);
}
/* Do we have the mouse uncapture combination in the keyboard buffer? */
@@ -374,10 +379,10 @@ int
keyboard_ismsexit(void)
{
if ((key_prefix_2_1 != 0x000) || (key_prefix_2_2 != 0x000))
return ((recv_key[key_prefix_1_1] || recv_key[key_prefix_1_2]) &&
(recv_key[key_prefix_2_1] || recv_key[key_prefix_2_2]) &&
(recv_key[key_uncapture_1] || recv_key[key_uncapture_2]));
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
(recv_key_ui[key_prefix_2_1] || recv_key_ui[key_prefix_2_2]) &&
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
else
return ((recv_key[key_prefix_1_1] || recv_key[key_prefix_1_2]) &&
(recv_key[key_uncapture_1] || recv_key[key_uncapture_2]));
return ((recv_key_ui[key_prefix_1_1] || recv_key_ui[key_prefix_1_2]) &&
(recv_key_ui[key_uncapture_1] || recv_key_ui[key_uncapture_2]));
}

File diff suppressed because it is too large Load Diff

View File

@@ -90,262 +90,518 @@ typedef struct xtkbd_t {
/*XT keyboard has no escape scancodes, and no scancodes beyond 53*/
const scancode scancode_xt[512] = {
// clang-format off
{ {0}, {0} }, { {0x01, 0}, {0x81, 0} },
{ {0x02, 0}, {0x82, 0} }, { {0x03, 0}, {0x83, 0} },
{ {0x04, 0}, {0x84, 0} }, { {0x05, 0}, {0x85, 0} },
{ {0x06, 0}, {0x86, 0} }, { {0x07, 0}, {0x87, 0} },
{ {0x08, 0}, {0x88, 0} }, { {0x09, 0}, {0x89, 0} },
{ {0x0a, 0}, {0x8a, 0} }, { {0x0b, 0}, {0x8b, 0} },
{ {0x0c, 0}, {0x8c, 0} }, { {0x0d, 0}, {0x8d, 0} },
{ {0x0e, 0}, {0x8e, 0} }, { {0x0f, 0}, {0x8f, 0} },
{ {0x10, 0}, {0x90, 0} }, { {0x11, 0}, {0x91, 0} },
{ {0x12, 0}, {0x92, 0} }, { {0x13, 0}, {0x93, 0} },
{ {0x14, 0}, {0x94, 0} }, { {0x15, 0}, {0x95, 0} },
{ {0x16, 0}, {0x96, 0} }, { {0x17, 0}, {0x97, 0} },
{ {0x18, 0}, {0x98, 0} }, { {0x19, 0}, {0x99, 0} },
{ {0x1a, 0}, {0x9a, 0} }, { {0x1b, 0}, {0x9b, 0} },
{ {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} },
{ {0x1e, 0}, {0x9e, 0} }, { {0x1f, 0}, {0x9f, 0} },
{ {0x20, 0}, {0xa0, 0} }, { {0x21, 0}, {0xa1, 0} },
{ {0x22, 0}, {0xa2, 0} }, { {0x23, 0}, {0xa3, 0} },
{ {0x24, 0}, {0xa4, 0} }, { {0x25, 0}, {0xa5, 0} },
{ {0x26, 0}, {0xa6, 0} }, { {0x27, 0}, {0xa7, 0} },
{ {0x28, 0}, {0xa8, 0} }, { {0x29, 0}, {0xa9, 0} },
{ {0x2a, 0}, {0xaa, 0} }, { {0x2b, 0}, {0xab, 0} },
{ {0x2c, 0}, {0xac, 0} }, { {0x2d, 0}, {0xad, 0} },
{ {0x2e, 0}, {0xae, 0} }, { {0x2f, 0}, {0xaf, 0} },
{ {0x30, 0}, {0xb0, 0} }, { {0x31, 0}, {0xb1, 0} },
{ {0x32, 0}, {0xb2, 0} }, { {0x33, 0}, {0xb3, 0} },
{ {0x34, 0}, {0xb4, 0} }, { {0x35, 0}, {0xb5, 0} },
{ {0x36, 0}, {0xb6, 0} }, { {0x37, 0}, {0xb7, 0} },
{ {0x38, 0}, {0xb8, 0} }, { {0x39, 0}, {0xb9, 0} },
{ {0x3a, 0}, {0xba, 0} }, { {0x3b, 0}, {0xbb, 0} },
{ {0x3c, 0}, {0xbc, 0} }, { {0x3d, 0}, {0xbd, 0} },
{ {0x3e, 0}, {0xbe, 0} }, { {0x3f, 0}, {0xbf, 0} },
{ {0x40, 0}, {0xc0, 0} }, { {0x41, 0}, {0xc1, 0} },
{ {0x42, 0}, {0xc2, 0} }, { {0x43, 0}, {0xc3, 0} },
{ {0x44, 0}, {0xc4, 0} }, { {0x45, 0}, {0xc5, 0} },
{ {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} },
{ {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} },
{ {0x4a, 0}, {0xca, 0} }, { {0x4b, 0}, {0xcb, 0} },
{ {0x4c, 0}, {0xcc, 0} }, { {0x4d, 0}, {0xcd, 0} },
{ {0x4e, 0}, {0xce, 0} }, { {0x4f, 0}, {0xcf, 0} },
{ {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} },
{ {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} },
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*054*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*058*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*05c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*060*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*064*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*068*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*06c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*070*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*074*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*078*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*07c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*080*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*084*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*088*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*08c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*090*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*094*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*098*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*09c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0a0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0a4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0a8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0ac*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0b0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0b4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0b8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0bc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0c0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0c4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0c8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0cc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0d0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0d4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0d8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0dc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0e0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0e4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0e8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0ec*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0f0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0f4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0f8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*0fc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*100*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*104*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*108*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*10c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*110*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*114*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*118*/
{ {0x1c, 0}, {0x9c, 0} }, { {0x1d, 0}, {0x9d, 0} },
{ {0}, {0} }, { {0}, {0} }, /*11c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*120*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*124*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*128*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*12c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*130*/
{ {0}, {0} }, { {0x35, 0}, {0xb5, 0} },
{ {0}, {0} }, { {0x37, 0}, {0xb7, 0} }, /*134*/
{ {0x38, 0}, {0xb8, 0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*138*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*13c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*140*/
{ {0}, {0} }, { {0}, {0} },
{ {0x46, 0}, {0xc6, 0} }, { {0x47, 0}, {0xc7, 0} }, /*144*/
{ {0x48, 0}, {0xc8, 0} }, { {0x49, 0}, {0xc9, 0} },
{ {0}, {0} }, { {0x4b, 0}, {0xcb, 0} }, /*148*/
{ {0}, {0} }, { {0x4d, 0}, {0xcd, 0} },
{ {0}, {0} }, { {0x4f, 0}, {0xcf, 0} }, /*14c*/
{ {0x50, 0}, {0xd0, 0} }, { {0x51, 0}, {0xd1, 0} },
{ {0x52, 0}, {0xd2, 0} }, { {0x53, 0}, {0xd3, 0} }, /*150*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*154*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*158*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*15c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*160*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*164*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*168*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*16c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*170*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*174*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*148*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*17c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*180*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*184*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*88*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*18c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*190*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*194*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*198*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*19c*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1a0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1a4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1a8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1ac*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1b0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1b4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1b8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1bc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1c0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1c4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1c8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1cc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1d0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1d4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1d8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1dc*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1e0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1e4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1e8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1ec*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1f0*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1f4*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} }, /*1f8*/
{ {0}, {0} }, { {0}, {0} },
{ {0}, {0} }, { {0}, {0} } /*1fc*/
{ .mk = { 0 }, .brk = { 0 } }, /* 000 */
{ .mk = { 0x01, 0 }, .brk = { 0x81, 0 } }, /* 001 */
{ .mk = { 0x02, 0 }, .brk = { 0x82, 0 } }, /* 002 */
{ .mk = { 0x03, 0 }, .brk = { 0x83, 0 } }, /* 003 */
{ .mk = { 0x04, 0 }, .brk = { 0x84, 0 } }, /* 004 */
{ .mk = { 0x05, 0 }, .brk = { 0x85, 0 } }, /* 005 */
{ .mk = { 0x06, 0 }, .brk = { 0x86, 0 } }, /* 006 */
{ .mk = { 0x07, 0 }, .brk = { 0x87, 0 } }, /* 007 */
{ .mk = { 0x08, 0 }, .brk = { 0x88, 0 } }, /* 008 */
{ .mk = { 0x09, 0 }, .brk = { 0x89, 0 } }, /* 009 */
{ .mk = { 0x0a, 0 }, .brk = { 0x8a, 0 } }, /* 00a */
{ .mk = { 0x0b, 0 }, .brk = { 0x8b, 0 } }, /* 00b */
{ .mk = { 0x0c, 0 }, .brk = { 0x8c, 0 } }, /* 00c */
{ .mk = { 0x0d, 0 }, .brk = { 0x8d, 0 } }, /* 00d */
{ .mk = { 0x0e, 0 }, .brk = { 0x8e, 0 } }, /* 00e */
{ .mk = { 0x0f, 0 }, .brk = { 0x8f, 0 } }, /* 00f */
{ .mk = { 0x10, 0 }, .brk = { 0x90, 0 } }, /* 010 */
{ .mk = { 0x11, 0 }, .brk = { 0x91, 0 } }, /* 011 */
{ .mk = { 0x12, 0 }, .brk = { 0x92, 0 } }, /* 012 */
{ .mk = { 0x13, 0 }, .brk = { 0x93, 0 } }, /* 013 */
{ .mk = { 0x14, 0 }, .brk = { 0x94, 0 } }, /* 014 */
{ .mk = { 0x15, 0 }, .brk = { 0x95, 0 } }, /* 015 */
{ .mk = { 0x16, 0 }, .brk = { 0x96, 0 } }, /* 016 */
{ .mk = { 0x17, 0 }, .brk = { 0x97, 0 } }, /* 017 */
{ .mk = { 0x18, 0 }, .brk = { 0x98, 0 } }, /* 018 */
{ .mk = { 0x19, 0 }, .brk = { 0x99, 0 } }, /* 019 */
{ .mk = { 0x1a, 0 }, .brk = { 0x9a, 0 } }, /* 01a */
{ .mk = { 0x1b, 0 }, .brk = { 0x9b, 0 } }, /* 01b */
{ .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 01c */
{ .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 01d */
{ .mk = { 0x1e, 0 }, .brk = { 0x9e, 0 } }, /* 01e */
{ .mk = { 0x1f, 0 }, .brk = { 0x9f, 0 } }, /* 01f */
{ .mk = { 0x20, 0 }, .brk = { 0xa0, 0 } }, /* 020 */
{ .mk = { 0x21, 0 }, .brk = { 0xa1, 0 } }, /* 021 */
{ .mk = { 0x22, 0 }, .brk = { 0xa2, 0 } }, /* 022 */
{ .mk = { 0x23, 0 }, .brk = { 0xa3, 0 } }, /* 023 */
{ .mk = { 0x24, 0 }, .brk = { 0xa4, 0 } }, /* 024 */
{ .mk = { 0x25, 0 }, .brk = { 0xa5, 0 } }, /* 025 */
{ .mk = { 0x26, 0 }, .brk = { 0xa6, 0 } }, /* 026 */
{ .mk = { 0x27, 0 }, .brk = { 0xa7, 0 } }, /* 027 */
{ .mk = { 0x28, 0 }, .brk = { 0xa8, 0 } }, /* 028 */
{ .mk = { 0x29, 0 }, .brk = { 0xa9, 0 } }, /* 029 */
{ .mk = { 0x2a, 0 }, .brk = { 0xaa, 0 } }, /* 02a */
{ .mk = { 0x2b, 0 }, .brk = { 0xab, 0 } }, /* 02b */
{ .mk = { 0x2c, 0 }, .brk = { 0xac, 0 } }, /* 02c */
{ .mk = { 0x2d, 0 }, .brk = { 0xad, 0 } }, /* 02d */
{ .mk = { 0x2e, 0 }, .brk = { 0xae, 0 } }, /* 02e */
{ .mk = { 0x2f, 0 }, .brk = { 0xaf, 0 } }, /* 02f */
{ .mk = { 0x30, 0 }, .brk = { 0xb0, 0 } }, /* 030 */
{ .mk = { 0x31, 0 }, .brk = { 0xb1, 0 } }, /* 031 */
{ .mk = { 0x32, 0 }, .brk = { 0xb2, 0 } }, /* 032 */
{ .mk = { 0x33, 0 }, .brk = { 0xb3, 0 } }, /* 033 */
{ .mk = { 0x34, 0 }, .brk = { 0xb4, 0 } }, /* 034 */
{ .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 035 */
{ .mk = { 0x36, 0 }, .brk = { 0xb6, 0 } }, /* 036 */
{ .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 037 */
{ .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 038 */
{ .mk = { 0x39, 0 }, .brk = { 0xb9, 0 } }, /* 039 */
{ .mk = { 0x3a, 0 }, .brk = { 0xba, 0 } }, /* 03a */
{ .mk = { 0x3b, 0 }, .brk = { 0xbb, 0 } }, /* 03b */
{ .mk = { 0x3c, 0 }, .brk = { 0xbc, 0 } }, /* 03c */
{ .mk = { 0x3d, 0 }, .brk = { 0xbd, 0 } }, /* 03d */
{ .mk = { 0x3e, 0 }, .brk = { 0xbe, 0 } }, /* 03e */
{ .mk = { 0x3f, 0 }, .brk = { 0xbf, 0 } }, /* 03f */
{ .mk = { 0x40, 0 }, .brk = { 0xc0, 0 } }, /* 040 */
{ .mk = { 0x41, 0 }, .brk = { 0xc1, 0 } }, /* 041 */
{ .mk = { 0x42, 0 }, .brk = { 0xc2, 0 } }, /* 042 */
{ .mk = { 0x43, 0 }, .brk = { 0xc3, 0 } }, /* 043 */
{ .mk = { 0x44, 0 }, .brk = { 0xc4, 0 } }, /* 044 */
{ .mk = { 0x45, 0 }, .brk = { 0xc5, 0 } }, /* 045 */
{ .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 046 */
{ .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 047 */
{ .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 048 */
{ .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 049 */
{ .mk = { 0x4a, 0 }, .brk = { 0xca, 0 } }, /* 04a */
{ .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 04b */
{ .mk = { 0x4c, 0 }, .brk = { 0xcc, 0 } }, /* 04c */
{ .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 04d */
{ .mk = { 0x4e, 0 }, .brk = { 0xce, 0 } }, /* 04e */
{ .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 04f */
{ .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 050 */
{ .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 051 */
{ .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 052 */
{ .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 053 */
{ .mk = { 0 }, .brk = { 0 } }, /* 054 */
{ .mk = { 0 }, .brk = { 0 } }, /* 055 */
{ .mk = { 0 }, .brk = { 0 } }, /* 056 */
{ .mk = { 0 }, .brk = { 0 } }, /* 057 */
{ .mk = { 0 }, .brk = { 0 } }, /* 058 */
{ .mk = { 0 }, .brk = { 0 } }, /* 059 */
{ .mk = { 0 }, .brk = { 0 } }, /* 05a */
{ .mk = { 0 }, .brk = { 0 } }, /* 05b */
{ .mk = { 0 }, .brk = { 0 } }, /* 05c */
{ .mk = { 0 }, .brk = { 0 } }, /* 05d */
{ .mk = { 0 }, .brk = { 0 } }, /* 05e */
{ .mk = { 0 }, .brk = { 0 } }, /* 05f */
{ .mk = { 0 }, .brk = { 0 } }, /* 060 */
{ .mk = { 0 }, .brk = { 0 } }, /* 061 */
{ .mk = { 0 }, .brk = { 0 } }, /* 062 */
{ .mk = { 0 }, .brk = { 0 } }, /* 063 */
{ .mk = { 0 }, .brk = { 0 } }, /* 064 */
{ .mk = { 0 }, .brk = { 0 } }, /* 065 */
{ .mk = { 0 }, .brk = { 0 } }, /* 066 */
{ .mk = { 0 }, .brk = { 0 } }, /* 067 */
{ .mk = { 0 }, .brk = { 0 } }, /* 068 */
{ .mk = { 0 }, .brk = { 0 } }, /* 069 */
{ .mk = { 0 }, .brk = { 0 } }, /* 06a */
{ .mk = { 0 }, .brk = { 0 } }, /* 06b */
{ .mk = { 0 }, .brk = { 0 } }, /* 06c */
{ .mk = { 0 }, .brk = { 0 } }, /* 06d */
{ .mk = { 0 }, .brk = { 0 } }, /* 06e */
{ .mk = { 0 }, .brk = { 0 } }, /* 06f */
{ .mk = { 0 }, .brk = { 0 } }, /* 070 */
{ .mk = { 0 }, .brk = { 0 } }, /* 071 */
{ .mk = { 0 }, .brk = { 0 } }, /* 072 */
{ .mk = { 0 }, .brk = { 0 } }, /* 073 */
{ .mk = { 0 }, .brk = { 0 } }, /* 074 */
{ .mk = { 0 }, .brk = { 0 } }, /* 075 */
{ .mk = { 0 }, .brk = { 0 } }, /* 076 */
{ .mk = { 0 }, .brk = { 0 } }, /* 077 */
{ .mk = { 0 }, .brk = { 0 } }, /* 078 */
{ .mk = { 0 }, .brk = { 0 } }, /* 079 */
{ .mk = { 0 }, .brk = { 0 } }, /* 07a */
{ .mk = { 0 }, .brk = { 0 } }, /* 07b */
{ .mk = { 0 }, .brk = { 0 } }, /* 07c */
{ .mk = { 0 }, .brk = { 0 } }, /* 07d */
{ .mk = { 0 }, .brk = { 0 } }, /* 07e */
{ .mk = { 0 }, .brk = { 0 } }, /* 07f */
{ .mk = { 0 }, .brk = { 0 } }, /* 080 */
{ .mk = { 0 }, .brk = { 0 } }, /* 081 */
{ .mk = { 0 }, .brk = { 0 } }, /* 082 */
{ .mk = { 0 }, .brk = { 0 } }, /* 083 */
{ .mk = { 0 }, .brk = { 0 } }, /* 084 */
{ .mk = { 0 }, .brk = { 0 } }, /* 085 */
{ .mk = { 0 }, .brk = { 0 } }, /* 086 */
{ .mk = { 0 }, .brk = { 0 } }, /* 087 */
{ .mk = { 0 }, .brk = { 0 } }, /* 088 */
{ .mk = { 0 }, .brk = { 0 } }, /* 089 */
{ .mk = { 0 }, .brk = { 0 } }, /* 08a */
{ .mk = { 0 }, .brk = { 0 } }, /* 08b */
{ .mk = { 0 }, .brk = { 0 } }, /* 08c */
{ .mk = { 0 }, .brk = { 0 } }, /* 08d */
{ .mk = { 0 }, .brk = { 0 } }, /* 08e */
{ .mk = { 0 }, .brk = { 0 } }, /* 08f */
{ .mk = { 0 }, .brk = { 0 } }, /* 090 */
{ .mk = { 0 }, .brk = { 0 } }, /* 091 */
{ .mk = { 0 }, .brk = { 0 } }, /* 092 */
{ .mk = { 0 }, .brk = { 0 } }, /* 093 */
{ .mk = { 0 }, .brk = { 0 } }, /* 094 */
{ .mk = { 0 }, .brk = { 0 } }, /* 095 */
{ .mk = { 0 }, .brk = { 0 } }, /* 096 */
{ .mk = { 0 }, .brk = { 0 } }, /* 097 */
{ .mk = { 0 }, .brk = { 0 } }, /* 098 */
{ .mk = { 0 }, .brk = { 0 } }, /* 099 */
{ .mk = { 0 }, .brk = { 0 } }, /* 09a */
{ .mk = { 0 }, .brk = { 0 } }, /* 09b */
{ .mk = { 0 }, .brk = { 0 } }, /* 09c */
{ .mk = { 0 }, .brk = { 0 } }, /* 09d */
{ .mk = { 0 }, .brk = { 0 } }, /* 09e */
{ .mk = { 0 }, .brk = { 0 } }, /* 09f */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0a9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0aa */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ab */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ac */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ad */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ae */
{ .mk = { 0 }, .brk = { 0 } }, /* 0af */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0b9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ba */
{ .mk = { 0 }, .brk = { 0 } }, /* 0bb */
{ .mk = { 0 }, .brk = { 0 } }, /* 0bc */
{ .mk = { 0 }, .brk = { 0 } }, /* 0bd */
{ .mk = { 0 }, .brk = { 0 } }, /* 0be */
{ .mk = { 0 }, .brk = { 0 } }, /* 0bf */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0c9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ca */
{ .mk = { 0 }, .brk = { 0 } }, /* 0cb */
{ .mk = { 0 }, .brk = { 0 } }, /* 0cc */
{ .mk = { 0 }, .brk = { 0 } }, /* 0cd */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ce */
{ .mk = { 0 }, .brk = { 0 } }, /* 0cf */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0d9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0da */
{ .mk = { 0 }, .brk = { 0 } }, /* 0db */
{ .mk = { 0 }, .brk = { 0 } }, /* 0dc */
{ .mk = { 0 }, .brk = { 0 } }, /* 0dd */
{ .mk = { 0 }, .brk = { 0 } }, /* 0de */
{ .mk = { 0 }, .brk = { 0 } }, /* 0df */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0e9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ea */
{ .mk = { 0 }, .brk = { 0 } }, /* 0eb */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ec */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ed */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ee */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ef */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0f9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 0fa */
{ .mk = { 0 }, .brk = { 0 } }, /* 0fb */
{ .mk = { 0 }, .brk = { 0 } }, /* 0fc */
{ .mk = { 0 }, .brk = { 0 } }, /* 0fd */
{ .mk = { 0 }, .brk = { 0 } }, /* 0fe */
{ .mk = { 0 }, .brk = { 0 } }, /* 0ff */
{ .mk = { 0 }, .brk = { 0 } }, /* 100 */
{ .mk = { 0 }, .brk = { 0 } }, /* 101 */
{ .mk = { 0 }, .brk = { 0 } }, /* 102 */
{ .mk = { 0 }, .brk = { 0 } }, /* 103 */
{ .mk = { 0 }, .brk = { 0 } }, /* 104 */
{ .mk = { 0 }, .brk = { 0 } }, /* 105 */
{ .mk = { 0 }, .brk = { 0 } }, /* 106 */
{ .mk = { 0 }, .brk = { 0 } }, /* 107 */
{ .mk = { 0 }, .brk = { 0 } }, /* 108 */
{ .mk = { 0 }, .brk = { 0 } }, /* 109 */
{ .mk = { 0 }, .brk = { 0 } }, /* 10a */
{ .mk = { 0 }, .brk = { 0 } }, /* 10b */
{ .mk = { 0 }, .brk = { 0 } }, /* 10c */
{ .mk = { 0 }, .brk = { 0 } }, /* 10d */
{ .mk = { 0 }, .brk = { 0 } }, /* 10e */
{ .mk = { 0 }, .brk = { 0 } }, /* 10f */
{ .mk = { 0 }, .brk = { 0 } }, /* 110 */
{ .mk = { 0 }, .brk = { 0 } }, /* 111 */
{ .mk = { 0 }, .brk = { 0 } }, /* 112 */
{ .mk = { 0 }, .brk = { 0 } }, /* 113 */
{ .mk = { 0 }, .brk = { 0 } }, /* 114 */
{ .mk = { 0 }, .brk = { 0 } }, /* 115 */
{ .mk = { 0 }, .brk = { 0 } }, /* 116 */
{ .mk = { 0 }, .brk = { 0 } }, /* 117 */
{ .mk = { 0 }, .brk = { 0 } }, /* 118 */
{ .mk = { 0 }, .brk = { 0 } }, /* 119 */
{ .mk = { 0 }, .brk = { 0 } }, /* 11a */
{ .mk = { 0 }, .brk = { 0 } }, /* 11b */
{ .mk = { 0x1c, 0 }, .brk = { 0x9c, 0 } }, /* 11c */
{ .mk = { 0x1d, 0 }, .brk = { 0x9d, 0 } }, /* 11d */
{ .mk = { 0 }, .brk = { 0 } }, /* 11e */
{ .mk = { 0 }, .brk = { 0 } }, /* 11f */
{ .mk = { 0 }, .brk = { 0 } }, /* 120 */
{ .mk = { 0 }, .brk = { 0 } }, /* 121 */
{ .mk = { 0 }, .brk = { 0 } }, /* 122 */
{ .mk = { 0 }, .brk = { 0 } }, /* 123 */
{ .mk = { 0 }, .brk = { 0 } }, /* 124 */
{ .mk = { 0 }, .brk = { 0 } }, /* 125 */
{ .mk = { 0 }, .brk = { 0 } }, /* 126 */
{ .mk = { 0 }, .brk = { 0 } }, /* 127 */
{ .mk = { 0 }, .brk = { 0 } }, /* 128 */
{ .mk = { 0 }, .brk = { 0 } }, /* 129 */
{ .mk = { 0 }, .brk = { 0 } }, /* 12a */
{ .mk = { 0 }, .brk = { 0 } }, /* 12b */
{ .mk = { 0 }, .brk = { 0 } }, /* 12c */
{ .mk = { 0 }, .brk = { 0 } }, /* 12d */
{ .mk = { 0 }, .brk = { 0 } }, /* 12e */
{ .mk = { 0 }, .brk = { 0 } }, /* 12f */
{ .mk = { 0 }, .brk = { 0 } }, /* 130 */
{ .mk = { 0 }, .brk = { 0 } }, /* 131 */
{ .mk = { 0 }, .brk = { 0 } }, /* 132 */
{ .mk = { 0 }, .brk = { 0 } }, /* 133 */
{ .mk = { 0 }, .brk = { 0 } }, /* 134 */
{ .mk = { 0x35, 0 }, .brk = { 0xb5, 0 } }, /* 135 */
{ .mk = { 0 }, .brk = { 0 } }, /* 136 */
{ .mk = { 0x37, 0 }, .brk = { 0xb7, 0 } }, /* 137 */
{ .mk = { 0x38, 0 }, .brk = { 0xb8, 0 } }, /* 138 */
{ .mk = { 0 }, .brk = { 0 } }, /* 139 */
{ .mk = { 0 }, .brk = { 0 } }, /* 13a */
{ .mk = { 0 }, .brk = { 0 } }, /* 13b */
{ .mk = { 0 }, .brk = { 0 } }, /* 13c */
{ .mk = { 0 }, .brk = { 0 } }, /* 13d */
{ .mk = { 0 }, .brk = { 0 } }, /* 13e */
{ .mk = { 0 }, .brk = { 0 } }, /* 13f */
{ .mk = { 0 }, .brk = { 0 } }, /* 140 */
{ .mk = { 0 }, .brk = { 0 } }, /* 141 */
{ .mk = { 0 }, .brk = { 0 } }, /* 142 */
{ .mk = { 0 }, .brk = { 0 } }, /* 143 */
{ .mk = { 0 }, .brk = { 0 } }, /* 144 */
{ .mk = { 0 }, .brk = { 0 } }, /* 145 */
{ .mk = { 0x46, 0 }, .brk = { 0xc6, 0 } }, /* 146 */
{ .mk = { 0x47, 0 }, .brk = { 0xc7, 0 } }, /* 147 */
{ .mk = { 0x48, 0 }, .brk = { 0xc8, 0 } }, /* 148 */
{ .mk = { 0x49, 0 }, .brk = { 0xc9, 0 } }, /* 149 */
{ .mk = { 0 }, .brk = { 0 } }, /* 14a */
{ .mk = { 0x4b, 0 }, .brk = { 0xcb, 0 } }, /* 14b */
{ .mk = { 0 }, .brk = { 0 } }, /* 14c */
{ .mk = { 0x4d, 0 }, .brk = { 0xcd, 0 } }, /* 14d */
{ .mk = { 0 }, .brk = { 0 } }, /* 14e */
{ .mk = { 0x4f, 0 }, .brk = { 0xcf, 0 } }, /* 14f */
{ .mk = { 0x50, 0 }, .brk = { 0xd0, 0 } }, /* 150 */
{ .mk = { 0x51, 0 }, .brk = { 0xd1, 0 } }, /* 151 */
{ .mk = { 0x52, 0 }, .brk = { 0xd2, 0 } }, /* 152 */
{ .mk = { 0x53, 0 }, .brk = { 0xd3, 0 } }, /* 153 */
{ .mk = { 0 }, .brk = { 0 } }, /* 154 */
{ .mk = { 0 }, .brk = { 0 } }, /* 155 */
{ .mk = { 0 }, .brk = { 0 } }, /* 156 */
{ .mk = { 0 }, .brk = { 0 } }, /* 157 */
{ .mk = { 0 }, .brk = { 0 } }, /* 158 */
{ .mk = { 0 }, .brk = { 0 } }, /* 159 */
{ .mk = { 0 }, .brk = { 0 } }, /* 15a */
{ .mk = { 0 }, .brk = { 0 } }, /* 15b */
{ .mk = { 0 }, .brk = { 0 } }, /* 15c */
{ .mk = { 0 }, .brk = { 0 } }, /* 15d */
{ .mk = { 0 }, .brk = { 0 } }, /* 15e */
{ .mk = { 0 }, .brk = { 0 } }, /* 15f */
{ .mk = { 0 }, .brk = { 0 } }, /* 160 */
{ .mk = { 0 }, .brk = { 0 } }, /* 161 */
{ .mk = { 0 }, .brk = { 0 } }, /* 162 */
{ .mk = { 0 }, .brk = { 0 } }, /* 163 */
{ .mk = { 0 }, .brk = { 0 } }, /* 164 */
{ .mk = { 0 }, .brk = { 0 } }, /* 165 */
{ .mk = { 0 }, .brk = { 0 } }, /* 166 */
{ .mk = { 0 }, .brk = { 0 } }, /* 167 */
{ .mk = { 0 }, .brk = { 0 } }, /* 168 */
{ .mk = { 0 }, .brk = { 0 } }, /* 169 */
{ .mk = { 0 }, .brk = { 0 } }, /* 16a */
{ .mk = { 0 }, .brk = { 0 } }, /* 16b */
{ .mk = { 0 }, .brk = { 0 } }, /* 16c */
{ .mk = { 0 }, .brk = { 0 } }, /* 16d */
{ .mk = { 0 }, .brk = { 0 } }, /* 16e */
{ .mk = { 0 }, .brk = { 0 } }, /* 16f */
{ .mk = { 0 }, .brk = { 0 } }, /* 170 */
{ .mk = { 0 }, .brk = { 0 } }, /* 171 */
{ .mk = { 0 }, .brk = { 0 } }, /* 172 */
{ .mk = { 0 }, .brk = { 0 } }, /* 173 */
{ .mk = { 0 }, .brk = { 0 } }, /* 174 */
{ .mk = { 0 }, .brk = { 0 } }, /* 175 */
{ .mk = { 0 }, .brk = { 0 } }, /* 176 */
{ .mk = { 0 }, .brk = { 0 } }, /* 177 */
{ .mk = { 0 }, .brk = { 0 } }, /* 178 */
{ .mk = { 0 }, .brk = { 0 } }, /* 179 */
{ .mk = { 0 }, .brk = { 0 } }, /* 17a */
{ .mk = { 0 }, .brk = { 0 } }, /* 17b */
{ .mk = { 0 }, .brk = { 0 } }, /* 17c */
{ .mk = { 0 }, .brk = { 0 } }, /* 17d */
{ .mk = { 0 }, .brk = { 0 } }, /* 17e */
{ .mk = { 0 }, .brk = { 0 } }, /* 17f */
{ .mk = { 0 }, .brk = { 0 } }, /* 180 */
{ .mk = { 0 }, .brk = { 0 } }, /* 181 */
{ .mk = { 0 }, .brk = { 0 } }, /* 182 */
{ .mk = { 0 }, .brk = { 0 } }, /* 183 */
{ .mk = { 0 }, .brk = { 0 } }, /* 184 */
{ .mk = { 0 }, .brk = { 0 } }, /* 185 */
{ .mk = { 0 }, .brk = { 0 } }, /* 186 */
{ .mk = { 0 }, .brk = { 0 } }, /* 187 */
{ .mk = { 0 }, .brk = { 0 } }, /* 188 */
{ .mk = { 0 }, .brk = { 0 } }, /* 189 */
{ .mk = { 0 }, .brk = { 0 } }, /* 18a */
{ .mk = { 0 }, .brk = { 0 } }, /* 18b */
{ .mk = { 0 }, .brk = { 0 } }, /* 18c */
{ .mk = { 0 }, .brk = { 0 } }, /* 18d */
{ .mk = { 0 }, .brk = { 0 } }, /* 18e */
{ .mk = { 0 }, .brk = { 0 } }, /* 18f */
{ .mk = { 0 }, .brk = { 0 } }, /* 190 */
{ .mk = { 0 }, .brk = { 0 } }, /* 191 */
{ .mk = { 0 }, .brk = { 0 } }, /* 192 */
{ .mk = { 0 }, .brk = { 0 } }, /* 193 */
{ .mk = { 0 }, .brk = { 0 } }, /* 194 */
{ .mk = { 0 }, .brk = { 0 } }, /* 195 */
{ .mk = { 0 }, .brk = { 0 } }, /* 196 */
{ .mk = { 0 }, .brk = { 0 } }, /* 197 */
{ .mk = { 0 }, .brk = { 0 } }, /* 198 */
{ .mk = { 0 }, .brk = { 0 } }, /* 199 */
{ .mk = { 0 }, .brk = { 0 } }, /* 19a */
{ .mk = { 0 }, .brk = { 0 } }, /* 19b */
{ .mk = { 0 }, .brk = { 0 } }, /* 19c */
{ .mk = { 0 }, .brk = { 0 } }, /* 19d */
{ .mk = { 0 }, .brk = { 0 } }, /* 19e */
{ .mk = { 0 }, .brk = { 0 } }, /* 19f */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1a9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1aa */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ab */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ac */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ad */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ae */
{ .mk = { 0 }, .brk = { 0 } }, /* 1af */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1b9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ba */
{ .mk = { 0 }, .brk = { 0 } }, /* 1bb */
{ .mk = { 0 }, .brk = { 0 } }, /* 1bc */
{ .mk = { 0 }, .brk = { 0 } }, /* 1bd */
{ .mk = { 0 }, .brk = { 0 } }, /* 1be */
{ .mk = { 0 }, .brk = { 0 } }, /* 1bf */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1c9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ca */
{ .mk = { 0 }, .brk = { 0 } }, /* 1cb */
{ .mk = { 0 }, .brk = { 0 } }, /* 1cc */
{ .mk = { 0 }, .brk = { 0 } }, /* 1cd */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ce */
{ .mk = { 0 }, .brk = { 0 } }, /* 1cf */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1d9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1da */
{ .mk = { 0 }, .brk = { 0 } }, /* 1db */
{ .mk = { 0 }, .brk = { 0 } }, /* 1dc */
{ .mk = { 0 }, .brk = { 0 } }, /* 1dd */
{ .mk = { 0 }, .brk = { 0 } }, /* 1de */
{ .mk = { 0 }, .brk = { 0 } }, /* 1df */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1e9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ea */
{ .mk = { 0 }, .brk = { 0 } }, /* 1eb */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ec */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ed */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ee */
{ .mk = { 0 }, .brk = { 0 } }, /* 1ef */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f0 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f1 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f2 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f3 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f4 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f5 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f6 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f7 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f8 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1f9 */
{ .mk = { 0 }, .brk = { 0 } }, /* 1fa */
{ .mk = { 0 }, .brk = { 0 } }, /* 1fb */
{ .mk = { 0 }, .brk = { 0 } }, /* 1fc */
{ .mk = { 0 }, .brk = { 0 } }, /* 1fd */
{ .mk = { 0 }, .brk = { 0 } }, /* 1fe */
{ .mk = { 0 }, .brk = { 0 } } /* 1ff */
// clang-format on
};
@@ -672,11 +928,11 @@ kbd_read(uint16_t port, void *priv)
else {
/* LaserXT = Always 512k RAM;
LaserXT/3 = Bit 0: set = 512k, clear = 256k. */
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
#ifdef USE_LASERXT
if (kbd->type == KBD_TYPE_VTECH)
ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00);
else
#endif
#endif /* USE_LASERXT */
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
}
}
@@ -1036,7 +1292,7 @@ const device_t keyboard_xt_t1x00_device = {
.config = NULL
};
#if defined(DEV_BRANCH) && defined(USE_LASERXT)
#ifdef USE_LASERXT
const device_t keyboard_xt_lxt3_device = {
.name = "VTech Laser XT3 Keyboard",
.internal_name = "keyboard_xt_lxt3",
@@ -1050,7 +1306,7 @@ const device_t keyboard_xt_lxt3_device = {
.force_redraw = NULL,
.config = NULL
};
#endif
#endif /* USE_LASERXT */
const device_t keyboard_xt_olivetti_device = {
.name = "Olivetti XT Keyboard",

View File

@@ -98,7 +98,7 @@ static mouse_t mouse_devices[] = {
{ &mouse_wacom_device },
{ &mouse_wacom_artpad_device },
#endif
{ &mouse_mtouch_device },
{ &mouse_mtouch_device },
{ NULL }
// clang-format on
};
@@ -482,10 +482,10 @@ mouse_subtract_z(int *delta_z, int min, int max, int invert)
int z = atomic_load(&mouse_z);
int real_z = invert ? -z : z;
if (mouse_z > max) {
if (real_z > max) {
*delta_z = max;
real_z -= max;
} else if (mouse_z < min) {
} else if (real_z < min) {
*delta_z = min;
real_z += ABS(min);
} else {

View File

@@ -730,7 +730,7 @@ static const device_config_t lt_config[] = {
{ .description = "Non-timed (original)", .value = 0 },
{ .description = "30 Hz (JMP2 = 1)", .value = 30 },
{ .description = "45 Hz (JMP2 not populated)", .value = 45 },
{ .description = "60 Hz (JMP 2 = 2)", .value = 60 },
{ .description = "60 Hz (JMP2 = 2)", .value = 60 },
{ .description = "" }
}
},

View File

@@ -6,11 +6,11 @@
*
* This file is part of the 86Box distribution.
*
* 3M MicroTouch SMT3 emulation.
* 3M MicroTouch Serial emulation.
*
*
*
* Authors: Cacodemon345
* Authors: Cacodemon345, mourix
*
* Copyright 2024 Cacodemon345
*/
@@ -18,8 +18,9 @@
/* Reference: https://www.touchwindow.com/mm5/drivers/mtsctlrm.pdf */
/* TODO:
Properly implement GP/SP commands (formats are not documented at all, like anywhere; no dumps yet).
- Dynamic baud rate selection from software following this.
- Properly implement GP/SP commands (formats are not documented at all, like anywhere; no dumps yet).
- Add additional SMT2/3 formats as we currently only support Tablet, Hex and Dec.
- Mode Polled.
*/
#include <ctype.h>
#include <stdint.h>
@@ -27,6 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/timer.h>
@@ -35,149 +37,395 @@
#include <86box/plat.h>
#include <86box/fifo8.h>
#include <86box/fifo.h>
#include <86box/video.h> /* Needed to account for overscan. */
#include <86box/video.h>
#include <86box/nvr.h>
#define NVR_SIZE 16
enum mtouch_formats {
FORMAT_DEC = 1,
FORMAT_HEX = 2,
FORMAT_RAW = 3,
FORMAT_TABLET = 4
};
enum mtouch_modes {
MODE_TABLET = 1,
MODE_RAW = 2
MODE_DOWNUP = 1,
MODE_INACTIVE = 2,
MODE_POINT = 3,
MODE_STREAM = 4,
};
const char* mtouch_identity[] = {
"A30100", /* SMT2 Serial / SMT3(R)V */
"A40100", /* SMT2 PCBus */
"P50100", /* TouchPen 4(+) */
"Q10100", /* SMT3(R) Serial */
};
typedef struct mouse_microtouch_t {
double abs_x;
double abs_y;
double baud_rate;
int b;
char cmd[512];
int cmd_pos;
int mode;
uint8_t cal_cntr, pen_mode;
bool soh;
bool in_reset;
serial_t *serial;
Fifo8 resp;
pc_timer_t host_to_serial_timer;
pc_timer_t reset_timer;
char cmd[256];
double abs_x, abs_x_old, abs_y, abs_y_old;
float scale_x, scale_y, off_x, off_y;
int but, but_old;
int baud_rate, cmd_pos;
uint8_t format, mode;
uint8_t id, cal_cntr, pen_mode;
bool mode_status, cal_ex, soh;
bool in_reset, reset;
uint8_t *nvr;
char nvr_path[64];
serial_t *serial;
Fifo8 resp;
pc_timer_t host_to_serial_timer;
pc_timer_t reset_timer;
} mouse_microtouch_t;
static mouse_microtouch_t *mtouch_inst = NULL;
void
microtouch_reset_complete(void *priv)
static void
mtouch_savenvr(void *priv)
{
mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv;
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
FILE *fp;
mtouch->in_reset = false;
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
void
microtouch_calibrate_timer(void *priv)
{
mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv;
if (!fifo8_num_used(&mtouch->resp)) {
mtouch->cal_cntr--;
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2);
fp = nvr_fopen(dev->nvr_path, "wb");
if (fp) {
fwrite(dev->nvr, 1, NVR_SIZE, fp);
fclose(fp);
fp = NULL;
}
}
void
microtouch_process_commands(mouse_microtouch_t *mtouch)
static void
mtouch_writenvr(void *priv, float scale_x, float scale_y, float off_x, float off_y)
{
int i = 0;
int fifo_used = fifo8_num_used(&mtouch->resp);
mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0';
mtouch->cmd_pos = 0;
for (i = 0; i < strlen(mtouch->cmd); i++) {
mtouch->cmd[i] = toupper(mtouch->cmd[i]);
}
if (mtouch->cmd[0] == 'Z') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') {
mtouch->pen_mode = 1;
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "TP****00\r", sizeof("TP****00\r") - 1);
}
if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "P50200\r", sizeof("P50200\r") - 1);
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') {
mtouch->mode = MODE_TABLET;
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') {
mtouch->mode = MODE_RAW;
mtouch->cal_cntr = 0;
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'R') {
mtouch->in_reset = true;
mtouch->mode = MODE_TABLET;
mtouch->cal_cntr = 0;
mtouch->pen_mode = 3;
timer_on_auto(&mtouch->reset_timer, 500. * 1000.);
}
if (mtouch->cmd[0] == 'A' && (mtouch->cmd[1] == 'D' || mtouch->cmd[1] == 'E')) {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'N' && mtouch->cmd[1] == 'M') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2);
}
if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'Q') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2);
}
if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'F') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "1\r", 2);
}
if (mtouch->cmd[0] == 'P') {
if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3;
else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2;
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
mtouch->cal_cntr = 2;
}
if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "A\r", 2);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0000000000000000000000000\r", sizeof("0000000000000000000000000\r") - 1);
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "0\r", 2);
}
if (mtouch->cmd[0] == 'S' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') {
fifo8_push(&mtouch->resp, 1);
fifo8_push_all(&mtouch->resp, (uint8_t *) "A\r", 2);
}
if (fifo8_num_used(&mtouch->resp) != fifo_used)
pclog("Command received: %s\n", mtouch->cmd);
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
memcpy(&dev->nvr[0], &scale_x, 4);
memcpy(&dev->nvr[4], &scale_y, 4);
memcpy(&dev->nvr[8], &off_x, 4);
memcpy(&dev->nvr[12], &off_y, 4);
}
void
static void
mtouch_readnvr(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
memcpy(&dev->scale_x, &dev->nvr[0], 4);
memcpy(&dev->scale_y, &dev->nvr[4], 4);
memcpy(&dev->off_x, &dev->nvr[8], 4);
memcpy(&dev->off_y, &dev->nvr[12], 4);
pclog("MT NVR CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y);
}
static void
mtouch_initnvr(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
FILE *fp;
/* Allocate and initialize the EEPROM. */
dev->nvr = (uint8_t *) malloc(NVR_SIZE);
memset(dev->nvr, 0x00, NVR_SIZE);
fp = nvr_fopen(dev->nvr_path, "rb");
if (fp) {
if (fread(dev->nvr, 1, NVR_SIZE, fp) != NVR_SIZE)
fatal("mtouch_initnvr(): Error reading data\n");
fclose(fp);
fp = NULL;
} else
mtouch_writenvr(dev, 1, 1, 0, 0);
}
static void
mtouch_reset_complete(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
dev->reset = true;
dev->in_reset = false;
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* <SOH>0<CR> */
}
static void
mtouch_calibrate_timer(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if ((dev->cal_cntr == 2 && (dev->abs_x > 0.25 || dev->abs_y < 0.75)) || \
(dev->cal_cntr == 1 && (dev->abs_x < 0.75 || dev->abs_y > 0.25))) {
return;
}
dev->cal_cntr--;
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x31\x0D", 3); /* <SOH>1<CR> */
if (dev->cal_ex) {
if (!dev->cal_cntr) {
double x1_ref = 0.125;
double y1_ref = 0.875;
double x2_ref = 0.875;
double y2_ref = 0.125;
double x1 = dev->abs_x_old;
double y1 = dev->abs_y_old;
double x2 = dev->abs_x;
double y2 = dev->abs_y;
dev->scale_x = (x2_ref - x1_ref) / (x2 - x1);
dev->off_x = x1_ref - dev->scale_x * x1;
dev->scale_y = (y2_ref - y1_ref) / (y2 - y1);
dev->off_y = y1_ref - dev->scale_y * y1;
dev->cal_ex = false;
pclog("MT NEW CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y);
mtouch_writenvr(dev, dev->scale_x, dev->scale_y, dev->off_x, dev->off_y);
mtouch_savenvr(dev);
}
dev->abs_x_old = dev->abs_x;
dev->abs_y_old = dev->abs_y;
}
}
static void
mtouch_process_commands(mouse_microtouch_t *dev)
{
dev->cmd[strcspn(dev->cmd, "\r")] = '\0';
pclog("MT Command: %s\n", dev->cmd);
if (dev->cmd[0] == 'C' && dev->cmd[1] == 'N') { /* Calibrate New */
dev->cal_cntr = 2;
}
else if (dev->cmd[0] == 'C' && dev->cmd[1] == 'X') { /* Calibrate Extended */
dev->scale_x = 1;
dev->scale_y = 1;
dev->off_x = 0;
dev->off_y = 0;
dev->cal_ex = true;
dev->cal_cntr = 2;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'D') { /* Format Decimal */
dev->format = FORMAT_DEC;
dev->mode_status = false;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'O') { /* Finger Only */
dev->pen_mode = 1;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'H') { /* Format Hexadecimal */
dev->format = FORMAT_HEX;
dev->mode_status = false;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'R') { /* Format Raw */
dev->format = FORMAT_RAW;
dev->mode = MODE_INACTIVE;
dev->cal_cntr = 0;
}
else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'T') { /* Format Tablet */
dev->format = FORMAT_TABLET;
}
else if (dev->cmd[0] == 'G' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Get Parameter Block 1 */
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* <SOH>A<CR> */
fifo8_push_all(&dev->resp, (uint8_t *) "0000000000000000000000000\r", 26);
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'D' && dev->cmd[2] == 'U') { /* Mode Down/Up */
dev->mode = MODE_DOWNUP;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'I') { /* Mode Inactive */
dev->mode = MODE_INACTIVE;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'P') { /* Mode Point */
dev->mode = MODE_POINT;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'T') { /* Mode Status */
dev->mode_status = true;
}
else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'S') { /* Mode Stream */
dev->mode = MODE_STREAM;
}
else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'I') { /* Output Identity */
fifo8_push(&dev->resp, 0x01);
fifo8_push_all(&dev->resp, (uint8_t *) mtouch_identity[dev->id], 6);
fifo8_push(&dev->resp, 0x0D);
return;
}
else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'S') { /* Output Status */
if (dev->reset) {
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x60\x0D", 4);
} else {
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x40\x0D", 4);
}
return;
}
else if (dev->cmd[0] == 'P') {
if (strlen(dev->cmd) == 2) { /* Pen */
if (dev->cmd[1] == 'F') dev->pen_mode = 3; /* Pen or Finger */
else if (dev->cmd[1] == 'O') dev->pen_mode = 2; /* Pen Only */
}
else if (strlen(dev->cmd) == 5) { /* Serial Options */
if (dev->cmd[4] == 1) dev->baud_rate = 19200;
else if (dev->cmd[4] == 2) dev->baud_rate = 9600;
else if (dev->cmd[4] == 3) dev->baud_rate = 4600;
else if (dev->cmd[4] == 4) dev->baud_rate = 2400;
else if (dev->cmd[4] == 5) dev->baud_rate = 1200;
timer_stop(&dev->host_to_serial_timer);
timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10);
}
}
else if (dev->cmd[0] == 'R') { /* Reset */
dev->in_reset = true;
dev->cal_cntr = 0;
dev->pen_mode = 3;
if (dev->cmd[0] == 'D') { /* Restore Defaults */
dev->mode = MODE_STREAM;
dev->mode_status = false;
if (dev->id < 2) {
dev->format = FORMAT_DEC;
} else {
dev->format = FORMAT_TABLET;
}
}
timer_on_auto(&dev->reset_timer, 500. * 1000.);
return;
}
else if (dev->cmd[0] == 'S' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Set Parameter Block 1 */
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* <SOH>A<CR> */
return;
}
else if (dev->cmd[0] == 'U' && dev->cmd[1] == 'T') { /* Unit Type */
fifo8_push(&dev->resp, 0x01);
if (dev->id == 2) {
fifo8_push_all(&dev->resp, (uint8_t *) "TP****00", 8);
} else {
fifo8_push_all(&dev->resp, (uint8_t *) "QM****00", 8);
}
fifo8_push(&dev->resp, 0x0D);
return;
}
fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* <SOH>0<CR> */
}
static void
mtouch_write(serial_t *serial, void *priv, uint8_t data)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (data == '\x1') {
dev->soh = 1;
}
else if (dev->soh) {
if (data != '\r') {
dev->cmd[dev->cmd_pos++] = data;
} else {
dev->soh = 0;
if (!dev->cmd_pos) {
return;
}
dev->cmd[dev->cmd_pos++] = data;
dev->cmd_pos = 0;
mtouch_process_commands(dev);
}
}
}
static int
mtouch_prepare_transmit(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
char buffer[16];
double abs_x = dev->abs_x;
double abs_y = dev->abs_y;
int but = dev->but;
if (dev->mode == MODE_INACTIVE) {
return 0;
}
if (dev->cal_cntr || (!dev->but && !dev->but_old)) { /* Calibration or no buttonpress */
if (!dev->but && dev->but_old) {
mtouch_calibrate_timer(dev);
}
dev->but_old = but; /* Save buttonpress */
return 0;
}
if (dev->format == FORMAT_TABLET) {
if (but) { /* Touchdown/Continuation */
fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((but & 3))) : 0));
fifo8_push(&dev->resp, (uint16_t)(16383 * abs_x) & 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * abs_x) >> 7) & 0b1111111);
fifo8_push(&dev->resp, (uint16_t)(16383 * (1 - abs_y)) & 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * (1 - abs_y)) >> 7) & 0b1111111);
}
else if (dev->but_old) { /* Liftoff */
fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0));
fifo8_push(&dev->resp, (uint16_t)(16383 * dev->abs_x_old) & 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * dev->abs_x_old) >> 7) & 0b1111111);
fifo8_push(&dev->resp, (uint16_t)(16383 * (1 - dev->abs_y_old))& 0b1111111);
fifo8_push(&dev->resp, ((uint16_t)(16383 * (1 - dev->abs_y_old)) >> 7) & 0b1111111);
}
}
else if (dev->format == FORMAT_DEC || dev->format == FORMAT_HEX) {
if (but) {
if (!dev->but_old) { /* Touchdown (MS, MP, MDU) */
fifo8_push(&dev->resp, (dev->mode_status) ? 0x19 : 0x01);
if (dev->format == FORMAT_DEC){
snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * abs_x), (uint16_t)(999 * (1 - abs_y)));
}
else if (dev->format == FORMAT_HEX) {
snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * abs_x), (uint16_t)(1023 * (1 - abs_y)));
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
else if (dev->mode == MODE_STREAM){ /* Touch Continuation (MS) */
fifo8_push(&dev->resp, (dev->mode_status) ? 0x1c : 0x01);
if (dev->format == FORMAT_DEC){
snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * abs_x), (uint16_t)(999 * (1 - abs_y)));
}
else if (dev->format == FORMAT_HEX) {
snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * abs_x), (uint16_t)(1023 * (1 - abs_y)));
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
}
else if (dev->but_old && dev->mode != MODE_POINT) { /* Touch Liftoff (MS, MDU) */
fifo8_push(&dev->resp, (dev->mode_status) ? 0x18 : 0x01);
if (dev->format == FORMAT_DEC) {
snprintf(buffer, sizeof(buffer), "%03d,%03d\r", (uint16_t)(999 * dev->abs_x_old), (uint16_t)(999 * (1 - dev->abs_y_old)));
}
else if (dev->format == FORMAT_HEX) {
snprintf(buffer, sizeof(buffer), "%03X,%03X\r", (uint16_t)(1023 * dev->abs_x_old), (uint16_t)(1023 * (1 - dev->abs_y_old)));
}
fifo8_push_all(&dev->resp, (uint8_t *)buffer, strlen(buffer));
}
}
/* Save old states*/
dev->abs_x_old = abs_x;
dev->abs_y_old = abs_y;
dev->but_old = but;
return 0;
}
static void
mtouch_write_to_host(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (dev->serial == NULL)
goto no_write_to_machine;
if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) {
if (fifo_get_full(dev->serial->rcvr_fifo)) {
goto no_write_to_machine;
@@ -187,116 +435,57 @@ mtouch_write_to_host(void *priv)
goto no_write_to_machine;
}
}
if (dev->in_reset)
if (dev->in_reset) {
goto no_write_to_machine;
}
if (fifo8_num_used(&dev->resp)) {
serial_write_fifo(dev->serial, fifo8_pop(&dev->resp));
}
else {
mtouch_prepare_transmit(dev);
}
no_write_to_machine:
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) 9600.0) * (double) (1 + 8 + 1));
}
void
mtouch_write(serial_t *serial, void *priv, uint8_t data)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (data == '\x1') {
dev->soh = 1;
} else if (dev->soh) {
if (data != '\r') {
dev->cmd[dev->cmd_pos++] = data;
} else {
dev->cmd[dev->cmd_pos++] = data;
microtouch_process_commands(dev);
}
}
timer_on_auto(&dev->host_to_serial_timer, (1000000.0 / (double) dev->baud_rate) * (double) (1 + 8 + 1));
}
static int
mtouch_poll(void *priv)
{
mouse_microtouch_t *dev = (mouse_microtouch_t *) priv;
if (dev->mode != MODE_RAW && fifo8_num_free(&dev->resp) >= 10) {
unsigned int abs_x_int = 0, abs_y_int = 0;
double abs_x;
double abs_y;
int b = mouse_get_buttons_ex();
mouse_get_abs_coords(&abs_x, &abs_y);
dev->b |= !!(b & 3);
dev->but = mouse_get_buttons_ex();
mouse_get_abs_coords(&dev->abs_x, &dev->abs_y);
if (enable_overscan) {
int index = mouse_tablet_in_proximity - 1;
if (mouse_tablet_in_proximity == -1) {
mouse_tablet_in_proximity = 0;
}
if (abs_x >= 1.0)
abs_x = 1.0;
if (abs_y >= 1.0)
abs_y = 1.0;
if (abs_x <= 0.0)
abs_x = 0.0;
if (abs_y <= 0.0)
abs_y = 0.0;
if (enable_overscan) {
int index = mouse_tablet_in_proximity - 1;
if (mouse_tablet_in_proximity == -1)
mouse_tablet_in_proximity = 0;
abs_x *= monitors[index].mon_unscaled_size_x - 1;
abs_y *= monitors[index].mon_efscrnsz_y - 1;
if (abs_x <= (monitors[index].mon_overscan_x / 2.)) {
abs_x = (monitors[index].mon_overscan_x / 2.);
}
if (abs_y <= (monitors[index].mon_overscan_y / 2.)) {
abs_y = (monitors[index].mon_overscan_y / 2.);
}
abs_x -= (monitors[index].mon_overscan_x / 2.);
abs_y -= (monitors[index].mon_overscan_y / 2.);
abs_x = abs_x / (double) monitors[index].mon_xsize;
abs_y = abs_y / (double) monitors[index].mon_ysize;
if (abs_x >= 1.0)
abs_x = 1.0;
if (abs_y >= 1.0)
abs_y = 1.0;
dev->abs_x *= monitors[index].mon_unscaled_size_x - 1;
dev->abs_y *= monitors[index].mon_efscrnsz_y - 1;
if (dev->abs_x <= (monitors[index].mon_overscan_x / 2.)) {
dev->abs_x = (monitors[index].mon_overscan_x / 2.);
}
if (dev->cal_cntr && (!(dev->b & 1) && !!(b & 3))) {
dev->b |= 1;
} else if (dev->cal_cntr && ((dev->b & 1) && !(b & 3))) {
dev->b &= ~1;
microtouch_calibrate_timer(dev);
}
if (dev->cal_cntr) {
return 0;
}
if (!!(b & 3)) {
dev->abs_x = abs_x;
dev->abs_y = abs_y;
dev->b |= 1;
abs_x_int = abs_x * 16383;
abs_y_int = 16383 - abs_y * 16383;
fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5) | ((b & 3))) : 0));
fifo8_push(&dev->resp, abs_x_int & 0b1111111);
fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111);
fifo8_push(&dev->resp, abs_y_int & 0b1111111);
fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111);
} else if ((dev->b & 1) && !(b & 3)) {
dev->b &= ~1;
abs_x_int = dev->abs_x * 16383;
abs_y_int = 16383 - dev->abs_y * 16383;
fifo8_push(&dev->resp, 0b11000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0));
fifo8_push(&dev->resp, abs_x_int & 0b1111111);
fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111);
fifo8_push(&dev->resp, abs_y_int & 0b1111111);
fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111);
fifo8_push(&dev->resp, 0b10000000 | ((dev->pen_mode == 2) ? ((1 << 5)) : 0));
fifo8_push(&dev->resp, abs_x_int & 0b1111111);
fifo8_push(&dev->resp, (abs_x_int >> 7) & 0b1111111);
fifo8_push(&dev->resp, abs_y_int & 0b1111111);
fifo8_push(&dev->resp, (abs_y_int >> 7) & 0b1111111);
if (dev->abs_y <= (monitors[index].mon_overscan_y / 2.)) {
dev->abs_y = (monitors[index].mon_overscan_y / 2.);
}
dev->abs_x -= (monitors[index].mon_overscan_x / 2.);
dev->abs_y -= (monitors[index].mon_overscan_y / 2.);
dev->abs_x = dev->abs_x / (double) monitors[index].mon_xsize;
dev->abs_y = dev->abs_y / (double) monitors[index].mon_ysize;
}
dev->abs_x = dev->scale_x * dev->abs_x + dev->off_x;
dev->abs_y = dev->scale_y * dev->abs_y + dev->off_y;
if (dev->abs_x >= 1.0) dev->abs_x = 1.0;
if (dev->abs_y >= 1.0) dev->abs_y = 1.0;
if (dev->abs_x <= 0.0) dev->abs_x = 0.0;
if (dev->abs_y <= 0.0) dev->abs_y = 0.0;
return 0;
}
@@ -310,21 +499,36 @@ void *
mtouch_init(const device_t *info)
{
mouse_microtouch_t *dev = calloc(1, sizeof(mouse_microtouch_t));
dev->serial = serial_attach(device_get_config_int("port"), NULL, mtouch_write, dev);
dev->baud_rate = device_get_config_int("baudrate");
fifo8_create(&dev->resp, 512);
dev->baud_rate = 9600;
serial_set_cts(dev->serial, 1);
serial_set_dsr(dev->serial, 1);
serial_set_dcd(dev->serial, 1);
fifo8_create(&dev->resp, 256);
timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0);
timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0);
timer_add(&dev->reset_timer, mtouch_reset_complete, dev, 0);
timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10);
dev->mode = MODE_TABLET;
dev->id = device_get_config_int("identity");
dev->pen_mode = 3;
mouse_input_mode = 1;
dev->mode = MODE_STREAM;
sprintf(dev->nvr_path, "mtouch_%s.nvr", mtouch_identity[dev->id]);
mtouch_initnvr(dev);
mtouch_readnvr(dev);
if (dev->id < 2) { /* legacy controllers */
dev->format = FORMAT_DEC;
} else {
dev->format = FORMAT_TABLET;
}
mouse_input_mode = device_get_config_int("crosshair") + 1;
mouse_set_buttons(2);
mouse_set_poll_ex(mtouch_poll_global);
mtouch_inst = dev;
return dev;
}
@@ -335,9 +539,10 @@ mtouch_close(void *priv)
fifo8_destroy(&dev->resp);
/* Detach serial port from the mouse. */
if (dev && dev->serial && dev->serial->sd)
if (dev && dev->serial && dev->serial->sd) {
memset(dev->serial->sd, 0, sizeof(serial_device_t));
}
free(dev);
mtouch_inst = NULL;
}
@@ -361,27 +566,33 @@ static const device_config_t mtouch_config[] = {
}
},
{
.name = "baudrate",
.description = "Baud Rate",
.name = "identity",
.description = "Controller",
.type = CONFIG_SELECTION,
.default_string = "",
.default_int = 9600,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "19200", .value = 19200 },
{ .description = "9600", .value = 9600 },
{ .description = "4800", .value = 4800 },
{ .description = "2400", .value = 2400 },
{ .description = "1200", .value = 1200 }
{ .description = "A3 - SMT2 Serial / SMT3(R)V", .value = 0 },
{ .description = "A4 - SMT2 PCBus", .value = 1 },
{ .description = "P5 - TouchPen 4(+)", .value = 2 },
{ .description = "Q1 - SMT3(R) Serial", .value = 3 }
}
},
{
.name = "crosshair",
.description = "Show Crosshair",
.type = CONFIG_BINARY,
.default_string = "",
.default_int = 1
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t mouse_mtouch_device = {
.name = "3M MicroTouch TouchPen 4",
.name = "3M MicroTouch (Serial)",
.internal_name = "microtouch_touchpen",
.flags = DEVICE_COM,
.local = 0,
@@ -392,4 +603,4 @@ const device_t mouse_mtouch_device = {
.speed_changed = NULL,
.force_redraw = NULL,
.config = mtouch_config
};
};

View File

@@ -389,7 +389,7 @@ static const device_config_t ps2_config[] = {
};
const device_t mouse_ps2_device = {
.name = "Standard PS/2 Mouse",
.name = "PS/2 Mouse",
.internal_name = "ps2",
.flags = DEVICE_PS2,
.local = MOUSE_TYPE_PS2,

View File

@@ -142,7 +142,8 @@ sermouse_transmit_byte(mouse_t *dev, int do_next)
if (dev->buf_pos == 0)
dev->acc_time = 0.0;
serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]);
if (dev->serial)
serial_write_fifo(dev->serial, dev->buf[dev->buf_pos]);
if (do_next) {
dev->buf_pos = (dev->buf_pos + 1) % dev->buf_len;
@@ -1043,7 +1044,7 @@ static const device_config_t ltsermouse_config[] = {
},
{
.name = "rts_toggle",
.description = "Microsoft-compatible RTS toggle",
.description = "RTS toggle",
.type = CONFIG_BINARY,
.default_string = "",
.default_int = 0

View File

@@ -223,7 +223,7 @@ serial_write_fifo(serial_t *dev, uint8_t dat)
((dev->type >= SERIAL_16550) && dev->fifo_enabled) ?
fifo_get_count(dev->rcvr_fifo) : 0);
if (!(dev->mctrl & 0x10))
if ((dev != NULL) && !(dev->mctrl & 0x10))
write_fifo(dev, dat);
}
@@ -597,7 +597,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv)
serial_reset_fifo(dev);
if (dev->sd && dev->sd->dtr_callback && (val ^ dev->mctrl) & 1)
dev->sd->dtr_callback(dev, val & 1, dev->sd->priv);
dev->mctrl = val;
dev->mctrl = val & 0x1f;
if (val & 0x10) {
new_msr = (val & 0x0c) << 4;
new_msr |= (val & 0x02) ? 0x10 : 0;
@@ -912,7 +912,13 @@ serial_init(const device_t *info)
memset(&(serial_devices[next_inst]), 0, sizeof(serial_device_t));
dev->sd = &(serial_devices[next_inst]);
dev->sd->serial = dev;
if (next_inst == 3)
if (next_inst == 6)
serial_setup(dev, COM7_ADDR, COM7_IRQ);
else if (next_inst == 5)
serial_setup(dev, COM6_ADDR, COM6_IRQ);
else if (next_inst == 4)
serial_setup(dev, COM5_ADDR, COM5_IRQ);
else if (next_inst == 3)
serial_setup(dev, COM4_ADDR, COM4_IRQ);
else if (next_inst == 2)
serial_setup(dev, COM3_ADDR, COM3_IRQ);

View File

@@ -148,7 +148,7 @@ smbus_sis5595_read_data(void *priv)
break;
}
smbus_sis5595_log("SMBus SIS5595: read(%02X) = %02x\n", addr, ret);
smbus_sis5595_log("SMBus SIS5595: read(%02X) = %02x\n", dev->addr, ret);
return ret;
}
@@ -171,7 +171,7 @@ smbus_sis5595_write_data(void *priv, uint8_t val)
uint16_t prev_stat;
uint16_t timer_bytes = 0;
smbus_sis5595_log("SMBus SIS5595: write(%02X, %02X)\n", addr, val);
smbus_sis5595_log("SMBus SIS5595: write(%02X, %02X)\n", dev->addr, val);
prev_stat = dev->next_stat;
dev->next_stat = 0x0000;

View File

@@ -9,14 +9,33 @@
# CMake build script.
#
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
# Jasmine Iwanek, <jriwanek@gmail.com>
#
# Copyright 2020-2021 David Hrdlička.
# Copyright 2024 Jasmine Iwanek.
#
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_ali5213.c hdc_ide_opti611.c hdc_ide_cmd640.c hdc_ide_cmd646.c
hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c lba_enhancer.c)
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_ali5213.c
hdc_ide_opti611.c
hdc_ide_cmd640.c
hdc_ide_cmd646.c
hdc_ide_sff8038i.c
hdc_ide_um8673f.c
hdc_ide_w83769f.c
lba_enhancer.c
)
add_library(zip OBJECT zip.c)

View File

@@ -30,7 +30,7 @@
#include <86box/hdc_ide.h>
#include <86box/hdd.h>
int hdc_current;
int hdc_current[HDC_MAX] = { 0, 0 };
#ifdef ENABLE_HDC_LOG
int hdc_do_log = ENABLE_HDC_LOG;
@@ -50,40 +50,12 @@ hdc_log(const char *fmt, ...)
# define hdc_log(fmt, ...)
#endif
static const device_t hdc_none_device = {
.name = "None",
.internal_name = "none",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
static const device_t hdc_internal_device = {
.name = "Internal",
.internal_name = "internal",
.flags = 0,
.local = 0,
.init = NULL,
.close = NULL,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
static const struct {
const device_t *device;
} controllers[] = {
// clang-format off
{ &hdc_none_device },
{ &hdc_internal_device },
{ &device_none },
{ &device_internal },
{ &st506_xt_xebec_device },
{ &st506_xt_wdxt_gen_device },
{ &st506_xt_dtc5150x_device },
@@ -129,11 +101,11 @@ void
hdc_reset(void)
{
hdc_log("HDC: reset(current=%d, internal=%d)\n",
hdc_current, (machines[machine].flags & MACHINE_HDC) ? 1 : 0);
hdc_current[0], (machines[machine].flags & MACHINE_HDC) ? 1 : 0);
/* If we have a valid controller, add its device. */
if (hdc_current > 1)
device_add(controllers[hdc_current].device);
if (hdc_current[0] > HDC_INTERNAL)
device_add(controllers[hdc_current[0]].device);
/* Now, add the tertiary and/or quaternary IDE controllers. */
if (ide_ter_enabled)

View File

@@ -606,12 +606,16 @@ esdi_callback(void *priv)
} else {
if (get_sector(esdi, &addr)) {
esdi->error = ERR_ID_NOT_FOUND;
read_error:
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
irq_raise(esdi);
break;
}
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) {
esdi->error = ERR_BAD_BLOCK;
goto read_error;
}
esdi->pos = 0;
esdi->status = STAT_DRQ | STAT_READY | STAT_DSC;
irq_raise(esdi);
@@ -628,13 +632,17 @@ esdi_callback(void *priv)
} else {
if (get_sector(esdi, &addr)) {
esdi->error = ERR_ID_NOT_FOUND;
write_error:
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
break;
}
hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
if (hdd_image_write(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) {
esdi->error = ERR_BAD_BLOCK;
goto write_error;
}
irq_raise(esdi);
esdi->secount = (esdi->secount - 1) & 0xff;
if (esdi->secount) {
@@ -659,13 +667,17 @@ esdi_callback(void *priv)
} else {
if (get_sector(esdi, &addr)) {
esdi->error = ERR_ID_NOT_FOUND;
verify_error:
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
irq_raise(esdi);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
break;
}
hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer);
if (hdd_image_read(drive->hdd_num, addr, 1, (uint8_t *) esdi->buffer) < 0) {
esdi->error = ERR_BAD_BLOCK;
goto verify_error;
}
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 1);
next_sector(esdi);
esdi->secount = (esdi->secount - 1) & 0xff;
@@ -692,12 +704,16 @@ esdi_callback(void *priv)
} else {
if (get_sector_format(esdi, &addr)) {
esdi->error = ERR_ID_NOT_FOUND;
format_error:
esdi->status = STAT_READY | STAT_DSC | STAT_ERR;
irq_raise(esdi);
break;
}
hdd_image_zero(drive->hdd_num, addr, esdi->secount);
if (hdd_image_zero(drive->hdd_num, addr, esdi->secount) < 0) {
esdi->error = ERR_BAD_BLOCK;
goto format_error;
}
esdi->status = STAT_READY | STAT_DSC;
irq_raise(esdi);
}

View File

@@ -188,6 +188,7 @@ typedef struct esdi_t {
#define CMD_READ_VERIFY 0x03
#define CMD_WRITE_VERIFY 0x04
#define CMD_SEEK 0x05
#define CMD_PARK_HEADS 0x06
#define CMD_GET_DEV_STATUS 0x08
#define CMD_GET_DEV_CONFIG 0x09
#define CMD_GET_POS_INFO 0x0a
@@ -326,6 +327,27 @@ rba_out_of_range(esdi_t *dev)
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
}
static void
defective_block(esdi_t *dev)
{
dev->status_len = 9;
dev->status_data[0] = dev->command | STATUS_LEN(9) | dev->cmd_dev;
dev->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/
dev->status_data[2] = 0x0009; /*Defective block*/
dev->status_data[3] = 0;
dev->status_data[4] = 0;
dev->status_data[5] = 0;
dev->status_data[6] = 0;
dev->status_data[7] = 0;
dev->status_data[8] = 0;
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_FAILURE;
dev->irq_in_progress = 1;
set_irq(dev);
ui_sb_update_icon(SB_HDD | HDD_BUS_ESDI, 0);
}
static void
complete_command_status(esdi_t *dev)
{
@@ -371,7 +393,9 @@ esdi_callback(void *priv)
if (dev->in_reset) {
esdi_mca_log("ESDI reset.\n");
dev->in_reset = 0;
dev->status = STATUS_IRQ;
dev->status = STATUS_IRQ | STATUS_TRANSFER_REQ | STATUS_STATUS_OUT_FULL;
dev->status_len = 1; /*ToDo: better implementation for Xenix?*/
dev->status_data[0] = STATUS_LEN(1) | ATTN_HOST_ADAPTER;
dev->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE;
return;
}
@@ -420,7 +444,10 @@ esdi_callback(void *priv)
if (!dev->data_pos) {
if (dev->rba >= drive->sectors)
fatal("Read past end of drive\n");
hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data);
if (hdd_image_read(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data) < 0) {
defective_block(dev);
return;
}
cmd_time += hdd_timing_read(&hdd[drive->hdd_num], dev->rba, 1);
cmd_time += esdi_mca_get_xfer_time(dev, 1);
}
@@ -509,7 +536,10 @@ esdi_callback(void *priv)
if (dev->rba >= drive->sectors)
fatal("Write past end of drive\n");
hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data);
if (hdd_image_write(drive->hdd_num, dev->rba, 1, (uint8_t *) dev->data) < 0) {
defective_block(dev);
return;
}
cmd_time += hdd_timing_write(&hdd[drive->hdd_num], dev->rba, 1);
cmd_time += esdi_mca_get_xfer_time(dev, 1);
dev->rba++;
@@ -605,6 +635,35 @@ esdi_callback(void *priv)
}
break;
case CMD_PARK_HEADS:
ESDI_DRIVE_ONLY();
if (!drive->present) {
device_not_present(dev);
return;
}
switch (dev->cmd_state) {
case 0:
dev->rba = 0x00000000;
cmd_time = hdd_seek_get_time(&hdd[drive->hdd_num], dev->rba, HDD_OP_SEEK, 0, 0.0);
esdi_mca_set_callback(dev, ESDI_TIME + cmd_time);
dev->cmd_state = 1;
break;
case 1:
complete_command_status(dev);
dev->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL;
dev->irq_status = dev->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS;
dev->irq_in_progress = 1;
set_irq(dev);
break;
default:
break;
}
break;
case CMD_GET_DEV_STATUS:
ESDI_DRIVE_ONLY();
@@ -1025,8 +1084,10 @@ esdi_readw(uint16_t port, void *priv)
switch (port & 7) {
case 0: /*Status Interface Register*/
if (dev->status_pos >= dev->status_len)
if (dev->status_pos >= dev->status_len) {
esdi_mca_log("esdi_readw port=%04x, ret=0000 (pos=%d, len=%d).\n", port, dev->status_pos, dev->status_len);
return 0;
}
ret = dev->status_data[dev->status_pos++];
if (dev->status_pos >= dev->status_len) {
dev->status &= ~STATUS_STATUS_OUT_FULL;
@@ -1038,6 +1099,7 @@ esdi_readw(uint16_t port, void *priv)
fatal("esdi_readw port=%04x\n", port);
}
esdi_mca_log("esdi_readw port=%04x, ret=%04x.\n", port, ret);
return ret;
}
@@ -1220,7 +1282,7 @@ esdi_init(UNUSED(const device_t *info))
drive->spt = hdd[i].spt;
drive->hpc = hdd[i].hpc;
drive->tracks = hdd[i].tracks;
drive->sectors = hdd_image_get_last_sector(i) + 1;
drive->sectors = hdd_image_get_last_sector(i);
drive->hdd_num = i;
/* Mark drive as present. */

View File

@@ -1252,7 +1252,10 @@ ide_write_data(ide_t *ide, const uint16_t val)
const double xfer_time = ide_get_xfer_time(ide, 512);
const double wait_time = seek_time + xfer_time;
if (ide->command == WIN_WRITE_MULTIPLE) {
if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) {
if (hdd[ide->hdd_num].speed_preset == 0) {
ide->pending_delay = 0;
ide_callback(ide);
} else if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) {
ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay);
ide->pending_delay = 0;
} else {
@@ -1607,9 +1610,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide->sc->callback = 100.0 * IDE_TIME;
ide_set_callback(ide, 100.0 * IDE_TIME);
} else {
double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ?
ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0);
ide_set_callback(ide, seek_time);
if (hdd[ide->hdd_num].speed_preset == 0)
ide_set_callback(ide, 100.0 * IDE_TIME);
else {
double seek_time = hdd_seek_get_time(&hdd[ide->hdd_num], (val & 0x60) ?
ide_get_sector(ide) : 0, HDD_OP_SEEK, 0, 0.0);
ide_set_callback(ide, seek_time);
}
}
break;
@@ -1652,6 +1659,10 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv)
ide_get_sector(ide), sec_count);
double xfer_time = ide_get_xfer_time(ide, 512 * sec_count);
wait_time = seek_time > xfer_time ? seek_time : xfer_time;
} else if ((val == WIN_READ_MULTIPLE) && (hdd[ide->hdd_num].speed_preset == 0)) {
ide_set_callback(ide, 200.0 * IDE_TIME);
ide->do_initial_read = 1;
break;
} else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) {
sec_count = ide->tf->secount ? ide->tf->secount : 256;
if (sec_count > ide->blocksize)
@@ -1848,7 +1859,9 @@ ide_read_data(ide_t *ide)
ide_next_sector(ide);
ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT;
if (ide->command == WIN_READ_MULTIPLE) {
if (!ide->blockcount) {
if (hdd[ide->hdd_num].speed_preset == 0)
ide_callback(ide);
else if (!ide->blockcount) {
uint32_t cnt = ide->tf->secount ?
ide->tf->secount : 256;
if (cnt > ide->blocksize)
@@ -1888,8 +1901,7 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch)
/* On real hardware, a slave with a present master always
returns a status of 0x00.
Confirmed by the ATA-3 and ATA-4 specifications. */
// ret = 0x00;
ret = 0x01;
ret = 0x00;
} else {
ret = ide->tf->atastat;
if (ide->type == IDE_ATAPI)
@@ -2202,8 +2214,10 @@ ide_callback(void *priv)
if (ide->do_initial_read) {
ide->do_initial_read = 0;
ide->sector_pos = 0;
hdd_image_read(ide->hdd_num, ide_get_sector(ide),
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide),
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
} else {
ret = 0;
}
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);
@@ -2212,6 +2226,10 @@ ide_callback(void *priv)
ide->tf->pos = 0;
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
if (ret < 0) {
ide_log("IDE %i: Read aborted (image read error)\n", ide->channel);
err = UNC_ERR;
}
ide_irq_raise(ide);
@@ -2233,11 +2251,13 @@ ide_callback(void *priv)
ide->sector_pos = ide->tf->secount;
else
ide->sector_pos = 256;
hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer);
ide->tf->pos = 0;
if (!ide_boards[ide->board]->force_ata3 && bm->dma) {
if (hdd_image_read(ide->hdd_num, ide_get_sector(ide), ide->sector_pos, ide->sector_buffer) < 0) {
ide_log("IDE %i: DMA read aborted (image read error)\n", ide->channel);
err = UNC_ERR;
} else if (!ide_boards[ide->board]->force_ata3 && bm->dma) {
/* We should not abort - we should simply wait for the host to start DMA. */
ret = bm->dma(ide->sector_buffer, ide->sector_pos * 512, 0, bm->priv);
if (ret == 2) {
@@ -2280,8 +2300,10 @@ ide_callback(void *priv)
if (ide->do_initial_read) {
ide->do_initial_read = 0;
ide->sector_pos = 0;
hdd_image_read(ide->hdd_num, ide_get_sector(ide),
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
ret = hdd_image_read(ide->hdd_num, ide_get_sector(ide),
ide->tf->secount ? ide->tf->secount : 256, ide->sector_buffer);
} else {
ret = 0;
}
memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512);
@@ -2290,6 +2312,10 @@ ide_callback(void *priv)
ide->tf->pos = 0;
ide->tf->atastat = DRQ_STAT | DRDY_STAT | DSC_STAT;
if (ret < 0) {
ide_log("IDE %i: Read aborted (image read error)\n", ide->channel);
err = UNC_ERR;
}
if (!ide->blockcount)
ide_irq_raise(ide);
ide->blockcount++;
@@ -2308,7 +2334,7 @@ ide_callback(void *priv)
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
ide_irq_raise(ide);
ide->tf->secount--;
if (ide->tf->secount) {
@@ -2320,6 +2346,8 @@ ide_callback(void *priv)
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
}
if (ret < 0)
err = UNC_ERR;
}
ide_log("Write: %02X, %i, %08X, %" PRIi64 "\n", err, ide->hdd_num, ide->lba_addr, sector);
break;
@@ -2348,12 +2376,14 @@ ide_callback(void *priv)
return;
} else if (ret == 1) {
/* DMA successful */
ide_log("IDE %i: DMA write successful\n", ide->channel);
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide),
ide->sector_pos, ide->sector_buffer);
hdd_image_write(ide->hdd_num, ide_get_sector(ide),
ide->sector_pos, ide->sector_buffer);
ide_log("IDE %i: DMA write %ssuccessful\n", ide->channel, (ret < 0) ? "un" : "");
ide->tf->atastat = DRDY_STAT | DSC_STAT;
if (ret < 0)
err = UNC_ERR;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
@@ -2381,7 +2411,7 @@ ide_callback(void *priv)
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
ret = hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer);
ide->blockcount++;
if (ide->blockcount >= ide->blocksize || ide->tf->secount == 1) {
ide->blockcount = 0;
@@ -2396,6 +2426,8 @@ ide_callback(void *priv)
ide->tf->atastat = DRDY_STAT | DSC_STAT;
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0);
}
if (ret < 0)
err = UNC_ERR;
}
break;
@@ -2419,9 +2451,11 @@ ide_callback(void *priv)
else if (!ide->tf->lba && (ide->cfg_spt == 0))
err = IDNF_ERR;
else {
hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount);
ret = hdd_image_zero(ide->hdd_num, ide_get_sector_format(ide), ide->tf->secount);
ide->tf->atastat = DRDY_STAT | DSC_STAT;
if (ret < 0)
err = UNC_ERR;
ide_irq_raise(ide);
ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 1);

Some files were not shown because too many files have changed in this diff Show More