mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Merge branch 'master' of ssh://github.com/86Box/86Box
This commit is contained in:
12
.ci/build.sh
12
.ci/build.sh
@@ -1158,10 +1158,14 @@ EOF
|
||||
|
||||
# Run appimage-builder in extract-and-run mode for Docker compatibility.
|
||||
# --appdir is a workaround for https://github.com/AppImageCrafters/appimage-builder/issues/270
|
||||
project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \
|
||||
arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \
|
||||
--recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)"
|
||||
status=$?
|
||||
for retry in 1 2 3 4 5
|
||||
do
|
||||
project="$project" project_id="$project_id" project_version="$project_version" project_icon="$project_icon" arch_deb="$arch_deb" \
|
||||
arch_appimage="$arch_appimage" appimage_path="$cwd/$package_name.AppImage" APPIMAGE_EXTRACT_AND_RUN=1 ./appimage-builder.AppImage \
|
||||
--recipe AppImageBuilder-generated.yml --appdir "$(grep -oP '^\s+path: \K(.+)' AppImageBuilder-generated.yml)"
|
||||
status=$?
|
||||
[ $status -eq 0 ] && break
|
||||
done
|
||||
|
||||
# Remove appimage-builder binary on failure, just in case it's corrupted.
|
||||
[ $status -ne 0 ] && rm -f "$appimage_builder_binary"
|
||||
|
||||
29
.github/workflows/c-cpp.yml
vendored
29
.github/workflows/c-cpp.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: MinGW64 Makefile
|
||||
name: MSYS2 Makefile
|
||||
|
||||
on:
|
||||
|
||||
@@ -16,7 +16,7 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.environment.msystem }} Makefile build (DEV_BUILD=${{ matrix.dev-build }}, NEW_DYNAREC=${{ matrix.new-dynarec }})
|
||||
name: MSYS2 Makefile build ${{ matrix.build.name }} ${{ matrix.dynarec.name }} build (${{ matrix.environment.msystem }})
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
@@ -27,8 +27,22 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
dev-build: ['y', 'n']
|
||||
new-dynarec: ['y', 'n']
|
||||
build:
|
||||
- name: Debug
|
||||
debug: y
|
||||
dev: n
|
||||
slug: -Debug
|
||||
- name: Dev
|
||||
debug: y
|
||||
dev: y
|
||||
slug: -Dev
|
||||
dynarec:
|
||||
- name: ODR
|
||||
new: n
|
||||
slug: -ODR
|
||||
- name: NDR
|
||||
new: y
|
||||
slug: -NDR
|
||||
environment:
|
||||
- msystem: MINGW32
|
||||
prefix: mingw-w64-i686
|
||||
@@ -46,6 +60,7 @@ jobs:
|
||||
make
|
||||
${{ matrix.environment.prefix }}-gcc
|
||||
${{ matrix.environment.prefix }}-pkg-config
|
||||
${{ matrix.environment.prefix }}-openal
|
||||
${{ matrix.environment.prefix }}-freetype
|
||||
${{ matrix.environment.prefix }}-SDL2
|
||||
${{ matrix.environment.prefix }}-zlib
|
||||
@@ -54,5 +69,9 @@ jobs:
|
||||
${{ matrix.environment.prefix }}-rtmidi
|
||||
- uses: actions/checkout@v3
|
||||
- name: make
|
||||
run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.dev-build }} NEW_DYNAREC=${{ matrix.new-dynarec }} X64=${{ matrix.environment.x64 }} VNC=n
|
||||
run: make -fwin/makefile.mingw -j DEV_BUILD=${{ matrix.build.dev }} DEBUG=${{ matrix.build.debug }} NEW_DYNAREC=${{ matrix.dynarec.new }} X64=${{ matrix.environment.x64 }} VNC=n
|
||||
working-directory: ./src
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: '86Box${{ matrix.dynarec.slug }}${{ matrix.build.slug }}-Windows-${{ matrix.environment.msystem }}-gha${{ github.run_number }}'
|
||||
path: src/86Box.exe
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -44,3 +44,12 @@ RC*
|
||||
|
||||
# Qt Creator
|
||||
CMakeLists.txt.user
|
||||
|
||||
# Debian builder
|
||||
/debian/*.log
|
||||
/debian/*.substvars
|
||||
/debian/.debhelper
|
||||
/debian/86box
|
||||
/debian/debhelper-build-stamp
|
||||
/debian/files
|
||||
/obj-*-linux-gnu
|
||||
|
||||
@@ -40,7 +40,7 @@ if(MUNT_EXTERNAL)
|
||||
endif()
|
||||
|
||||
project(86Box
|
||||
VERSION 3.8
|
||||
VERSION 3.11
|
||||
DESCRIPTION "Emulator of x86-based systems"
|
||||
HOMEPAGE_URL "https://86box.net"
|
||||
LANGUAGES C CXX)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#
|
||||
|
||||
# Define our flags
|
||||
string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing")
|
||||
string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition")
|
||||
string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing")
|
||||
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3")
|
||||
@@ -32,4 +32,4 @@ foreach(LANG C;CXX)
|
||||
set(CMAKE_${LANG}_FLAGS_${CONFIG} "${CMAKE_${LANG}_FLAGS_${CONFIG}_INIT}" CACHE STRING "Flags used by the ${LANG} compiler during ${CONFIG} builds.")
|
||||
mark_as_advanced(CMAKE_${LANG}_FLAGS_${CONFIG})
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
86box (3.11.0-1) UNRELEASED; urgency=medium
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- Jasmine Iwanek <jriwanek@gmail.com> Sun, 18 Nov 2022 23:27:00 -0500
|
||||
29
debian/control
vendored
Normal file
29
debian/control
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
Source: 86box
|
||||
Section: otherosfs
|
||||
Priority: optional
|
||||
Maintainer: Mariusz Kurek <mariuszkurek@protonmail.com>
|
||||
Build-Depends: cmake (>= 3.21),
|
||||
debhelper-compat (= 13),
|
||||
libevdev-dev,
|
||||
libfreetype-dev,
|
||||
libopenal-dev,
|
||||
libqt5opengl5-dev,
|
||||
librtmidi-dev,
|
||||
libsdl2-dev,
|
||||
libslirp-dev,
|
||||
ninja-build,
|
||||
qttools5-dev
|
||||
Standards-Version: 4.6.0
|
||||
Homepage: https://86box.net/
|
||||
#Vcs-Browser: https://salsa.debian.org/debian/86box
|
||||
#Vcs-Git: https://salsa.debian.org/debian/86box.git
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: 86box
|
||||
Architecture: amd64 armhf arm64 i386
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
sse2-support [i386]
|
||||
Recommends: libpcap0.8-dev
|
||||
Description: An emulator for classic IBM PC clones
|
||||
#TODO: insert long description, indented with spaces
|
||||
38
debian/copyright
vendored
Normal file
38
debian/copyright
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: 86box
|
||||
Source: https://86box.net/
|
||||
|
||||
Files: *
|
||||
Copyright: <years> <put author's name and email here>
|
||||
<years> <likewise for another author>
|
||||
License: GPL-2.0+
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2022 Mariusz Kurek <mariuszkurek@protonmail.com>
|
||||
License: GPL-2.0+
|
||||
|
||||
License: GPL-2.0+
|
||||
This package is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
# Please also look if there are files or directories which have a
|
||||
# different copyright/license attached and list them here.
|
||||
# Please avoid picking licenses with terms that are more restrictive than the
|
||||
# packaged work, as it may make Debian's contributions unacceptable upstream.
|
||||
#
|
||||
# If you need, there are some extra license texts available in two places:
|
||||
# /usr/share/debhelper/dh_make/licenses/
|
||||
# /usr/share/common-licenses/
|
||||
41
debian/postinst
vendored
Normal file
41
debian/postinst
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
# postinst script for 86box
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> `abort-remove'
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see https://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
echo You need ROM files in order to use 86Box. These can be obtained from https://github.com/86Box/roms
|
||||
echo You can put the roms folder in, for example, /usr/share/86Box/roms or \~/.local/share/86Box/roms
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
42
debian/rules
vendored
Executable file
42
debian/rules
vendored
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/make -f
|
||||
# See debhelper(7) (uncomment to enable)
|
||||
# output every command that modifies files on the build system.
|
||||
#export DH_VERBOSE = 1
|
||||
|
||||
ARCH=$(shell dpkg-architecture -qDEB_HOST_ARCH)
|
||||
|
||||
ifeq ($(ARCH), $(filter $(ARCH), amd64 i386))
|
||||
NDR=off
|
||||
ifeq ($(ARCH),amd64)
|
||||
TOOLCHAIN=cmake/flags-gcc-x86_64.cmake
|
||||
else
|
||||
TOOLCHAIN=cmake/flags-gcc-i686.cmake
|
||||
endif
|
||||
else
|
||||
NDR=on
|
||||
ifeq ($(ARCH),armhf)
|
||||
TOOLCHAIN=cmake/flags-gcc-armv7.cmake
|
||||
else
|
||||
TOOLCHAIN=cmake/flags-gcc-aarch64.cmake
|
||||
endif
|
||||
endif
|
||||
|
||||
%:
|
||||
dh $@ --buildsystem cmake+ninja
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -DSLIRP_EXTERNAL=on
|
||||
|
||||
override_dh_auto_test:
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install --buildsystem cmake+ninja
|
||||
for i in 48x48 64x64 72x72 96x96 128x128 192x192 256x256 512x512 ; do \
|
||||
install -Dm644 src/unix/assets/$$i/net.86box.86Box.png -t debian/86box/usr/share/icons/hicolor/$$i/apps ; \
|
||||
done
|
||||
mkdir debian/86box/usr/share/applications
|
||||
sed 's/^Exec.*/Exec=86Box -P .local\/share\/86Box/' "src/unix/assets/net.86box.86Box.desktop" > "debian/86box/usr/share/applications/net.86box.86Box.desktop"
|
||||
|
||||
override_dh_installdocs:
|
||||
|
||||
override_dh_installman:
|
||||
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
15
debian/watch
vendored
Normal file
15
debian/watch
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Example watch control file for uscan
|
||||
# Rename this file to "watch" and then you can run the "uscan" command
|
||||
# to check for upstream updates and more.
|
||||
# See uscan(1) for format
|
||||
|
||||
# Compulsory line, this is a version 4 file
|
||||
version=4
|
||||
|
||||
# PGP signature mangle, so foo.tar.gz has foo.tar.gz.sig
|
||||
#opts="pgpsigurlmangle=s%$%.sig%"
|
||||
|
||||
# GitHub hosted projects
|
||||
opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%<project>-$1.tar.gz%" \
|
||||
https://github.com/86Box/86Box/tags \
|
||||
(?:.*?/)?v?(\d[\d.]*)\.tar\.gz debian uupdate
|
||||
83
src/86box.c
83
src/86box.c
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Main emulator module where most things are controlled.
|
||||
* Main emulator module where most things are controlled.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2021 Laci bá'
|
||||
* Copyright 2021 dob205
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2021 Laci bá'
|
||||
* Copyright 2021 dob205
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
@@ -205,15 +205,15 @@ char exe_path[2048]; /* path (dir) of executable */
|
||||
char usr_path[1024]; /* path (dir) of user data */
|
||||
char cfg_path[1024]; /* full path of config file */
|
||||
FILE *stdlog = NULL; /* file to log output to */
|
||||
// int scrnsz_x = SCREEN_RES_X; /* current screen size, X */
|
||||
// int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */
|
||||
// int scrnsz_x = SCREEN_RES_X; /* current screen size, X */
|
||||
// int scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */
|
||||
int config_changed; /* config has changed */
|
||||
int title_update;
|
||||
int framecountx = 0;
|
||||
int hard_reset_pending = 0;
|
||||
|
||||
// int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */
|
||||
// int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */
|
||||
// int unscaled_size_x = SCREEN_RES_X; /* current unscaled size X */
|
||||
// int unscaled_size_y = SCREEN_RES_Y; /* current unscaled size Y */
|
||||
// int efscrnsz_y = SCREEN_RES_Y;
|
||||
|
||||
static wchar_t mouse_msg[3][200];
|
||||
@@ -473,7 +473,7 @@ usage:
|
||||
printf("-D or --debug - force debug output logging\n");
|
||||
#endif
|
||||
#if 0
|
||||
printf("-E or --nographic - forces the old behavior\n");
|
||||
printf("-E or --nographic - forces the old behavior\n");
|
||||
#endif
|
||||
printf("-F or --fullscreen - start in fullscreen mode\n");
|
||||
printf("-G or --lang langid - start with specified language (e.g. en-US, or system)\n");
|
||||
@@ -769,7 +769,7 @@ usage:
|
||||
|
||||
for (i = 0; i < FDD_NUM; i++) {
|
||||
if (fn[i] != NULL) {
|
||||
if (strlen(fn[i]) <= 511)
|
||||
if (strlen(fn[i]) <= 511)
|
||||
strncpy(floppyfns[i], fn[i], 511);
|
||||
free(fn[i]);
|
||||
fn[i] = NULL;
|
||||
@@ -854,7 +854,7 @@ pc_init_modules(void)
|
||||
machine = -1;
|
||||
while (machine_get_internal_name_ex(c) != NULL) {
|
||||
if (machine_available(c)) {
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp);
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
|
||||
machine = c;
|
||||
config_save();
|
||||
break;
|
||||
@@ -877,7 +877,7 @@ pc_init_modules(void)
|
||||
while (video_get_internal_name(c) != NULL) {
|
||||
gfxcard = -1;
|
||||
if (video_card_available(c)) {
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp);
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
|
||||
gfxcard = c;
|
||||
config_save();
|
||||
break;
|
||||
@@ -892,11 +892,10 @@ pc_init_modules(void)
|
||||
}
|
||||
|
||||
if (!video_card_available(gfxcard_2)) {
|
||||
char temp[1024] = { 0 };
|
||||
char tempc[1024] = { 0 };
|
||||
char tempc[512] = { 0 };
|
||||
device_get_name(video_card_getdevice(gfxcard_2), 0, tempc);
|
||||
snprintf(temp, sizeof(temp), "Video card #2 \"%s\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc);
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2128, temp);
|
||||
swprintf(temp, sizeof(temp), (wchar_t *) "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card.", tempc);
|
||||
ui_msgbox_header(MBX_INFO, (wchar_t *) IDS_2129, temp);
|
||||
gfxcard_2 = 0;
|
||||
}
|
||||
|
||||
@@ -1122,7 +1121,7 @@ pc_reset_hard_init(void)
|
||||
}
|
||||
|
||||
void
|
||||
update_mouse_msg()
|
||||
update_mouse_msg(void)
|
||||
{
|
||||
wchar_t wcpufamily[2048], wcpu[2048], wmachine[2048], *wcp;
|
||||
|
||||
@@ -1362,6 +1361,36 @@ set_screen_size_monitor(int x, int y, int monitor_index)
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 1);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 1);
|
||||
break;
|
||||
|
||||
case 4: /* 300% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 3);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 3);
|
||||
break;
|
||||
|
||||
case 5: /* 400% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 2);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 2);
|
||||
break;
|
||||
|
||||
case 6: /* 500% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 5);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 5);
|
||||
break;
|
||||
|
||||
case 7: /* 600% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 6);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 6);
|
||||
break;
|
||||
|
||||
case 8: /* 700% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x * 7);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y * 7);
|
||||
break;
|
||||
|
||||
case 9: /* 800% */
|
||||
monitors[monitor_index].mon_scrnsz_x = (monitors[monitor_index].mon_unscaled_size_x << 3);
|
||||
monitors[monitor_index].mon_scrnsz_y = (monitors[monitor_index].mon_unscaled_size_y << 3);
|
||||
break;
|
||||
}
|
||||
|
||||
plat_resize_request(monitors[monitor_index].mon_scrnsz_x, monitors[monitor_index].mon_scrnsz_y, monitor_index);
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# dob205
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# dob205
|
||||
#
|
||||
# Copyright 2020-2022 David Hrdlička.
|
||||
# Copyright 2021 dob205.
|
||||
# Copyright 2020-2022 David Hrdlička.
|
||||
# Copyright 2021 dob205.
|
||||
#
|
||||
if(APPLE)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
18
src/acpi.c
18
src/acpi.c
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* ACPI emulation.
|
||||
* ACPI emulation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@@ -63,7 +63,7 @@ acpi_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
static uint64_t
|
||||
acpi_clock_get()
|
||||
acpi_clock_get(void)
|
||||
{
|
||||
return tsc * cpu_to_acpi;
|
||||
}
|
||||
|
||||
16
src/apm.c
16
src/apm.c
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Advanced Power Management emulation.
|
||||
* Advanced Power Management emulation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Configure-time architecture detection for the CMake build.
|
||||
* Configure-time architecture detection for the CMake build.
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c)
|
||||
add_library(cdrom OBJECT cdrom.c cdrom_image_backend.c cdrom_image_viso.c cdrom_image.c cdrom_mitsumi.c)
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Generic CD-ROM drive core.
|
||||
* Generic CD-ROM drive core.
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2018-2021 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2018-2021 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
@@ -322,13 +324,13 @@ cdrom_audio_callback(cdrom_t *dev, int16_t *output, int len)
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bin2bcd (int x)
|
||||
bin2bcd(int x)
|
||||
{
|
||||
return (x % 10) | ((x / 10) << 4);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
bcd2bin (int x)
|
||||
bcd2bin(int x)
|
||||
{
|
||||
return (x >> 4) * 10 + (x & 0x0f);
|
||||
}
|
||||
@@ -385,9 +387,9 @@ cdrom_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf)
|
||||
} else
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
|
||||
m = (len >> 16) & 0xff;
|
||||
s = (len >> 8) & 0xff;
|
||||
f = len & 0xff;
|
||||
m = (len >> 16) & 0xff;
|
||||
s = (len >> 8) & 0xff;
|
||||
f = len & 0xff;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early)
|
||||
@@ -524,7 +526,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
b[pos++] = subc.index;
|
||||
|
||||
if (msf) {
|
||||
b[pos] = 0;
|
||||
b[pos] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
@@ -543,7 +545,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
|
||||
pos += 4;
|
||||
|
||||
b[pos] = 0;
|
||||
b[pos] = 0;
|
||||
|
||||
/* NEC CDR-260 speaks BCD. */
|
||||
if ((dev->bus_type == CDROM_BUS_ATAPI) && dev->early) {
|
||||
@@ -803,7 +805,7 @@ cdrom_read_toc(cdrom_t *dev, unsigned char *b, int type, unsigned char start_tra
|
||||
return len;
|
||||
}
|
||||
|
||||
/* A new API call for Mitsumi CD-ROM. */
|
||||
/* New API calls for Mitsumi CD-ROM. */
|
||||
void
|
||||
cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
|
||||
{
|
||||
@@ -827,6 +829,64 @@ cdrom_get_track_buffer(cdrom_t *dev, uint8_t *buf)
|
||||
memset(buf, 0x00, 9);
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_get_q(cdrom_t *dev, uint8_t *buf, int *curtoctrk, uint8_t mode)
|
||||
{
|
||||
track_info_t ti;
|
||||
int first_track, last_track;
|
||||
|
||||
if (dev != NULL) {
|
||||
dev->ops->get_tracks(dev, &first_track, &last_track);
|
||||
dev->ops->get_track_info(dev, *curtoctrk, 0, &ti);
|
||||
buf[0] = (ti.attr << 4) & 0xf0;
|
||||
buf[1] = ti.number;
|
||||
buf[2] = CD_BCD(*curtoctrk + 1);
|
||||
buf[3] = ti.m;
|
||||
buf[4] = ti.s;
|
||||
buf[5] = ti.f;
|
||||
buf[6] = 0x00;
|
||||
dev->ops->get_track_info(dev, 1, 0, &ti);
|
||||
buf[7] = ti.m;
|
||||
buf[8] = ti.s;
|
||||
buf[9] = ti.f;
|
||||
if (*curtoctrk >= (last_track + 1))
|
||||
*curtoctrk = 0;
|
||||
else if (mode)
|
||||
*curtoctrk = *curtoctrk + 1;
|
||||
} else
|
||||
memset(buf, 0x00, 10);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
cdrom_mitsumi_audio_play(cdrom_t *dev, uint32_t pos, uint32_t len)
|
||||
{
|
||||
track_info_t ti;
|
||||
|
||||
if (dev->cd_status == CD_STATUS_DATA_ONLY)
|
||||
return 0;
|
||||
|
||||
cdrom_log("CD-ROM 0: Play Mitsumi audio - %08X %08X\n", pos, len);
|
||||
dev->ops->get_track_info(dev, pos, 0, &ti);
|
||||
pos = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
dev->ops->get_track_info(dev, len, 1, &ti);
|
||||
len = MSFtoLBA(ti.m, ti.s, ti.f) - 150;
|
||||
|
||||
/* Do this at this point, since it's at this point that we know the
|
||||
actual LBA position to start playing from. */
|
||||
if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) {
|
||||
cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos);
|
||||
cdrom_stop(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev->seek_pos = pos;
|
||||
dev->cd_end = len;
|
||||
dev->cd_status = CD_STATUS_PLAYING;
|
||||
dev->cd_buflen = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
cdrom_read_disc_info_toc(cdrom_t *dev, unsigned char *b, unsigned char track, int type)
|
||||
{
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* CD-ROM image support.
|
||||
* CD-ROM image support.
|
||||
*
|
||||
* Author: RichardG867,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* bit,
|
||||
*
|
||||
* Copyright 2015-2019 Richardg867.
|
||||
* Copyright 2015-2019 Miran Grca.
|
||||
* Copyright 2017-2019 bit.
|
||||
*
|
||||
* Authors: RichardG867,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* bit,
|
||||
*
|
||||
* Copyright 2015-2019 Richardg867.
|
||||
* Copyright 2015-2019 Miran Grca.
|
||||
* Copyright 2017-2019 bit.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
* CD-ROM image file handling module, translated to C from
|
||||
* cdrom_dosbox.cpp.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* The DOSBox Team, <unknown>
|
||||
@@ -133,7 +135,7 @@ static track_file_t *
|
||||
bin_init(const char *filename, int *error)
|
||||
{
|
||||
track_file_t *tf = (track_file_t *) malloc(sizeof(track_file_t));
|
||||
struct stat stats;
|
||||
struct stat stats;
|
||||
|
||||
if (tf == NULL) {
|
||||
*error = 1;
|
||||
|
||||
@@ -8,13 +8,18 @@
|
||||
*
|
||||
* Virtual ISO CD-ROM image back-end.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2022 RichardG.
|
||||
*/
|
||||
// clang-format off
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#ifndef _LARGEFILE_SOURCE
|
||||
# define _LARGEFILE_SOURCE
|
||||
#endif
|
||||
#ifndef _LARGEFILE64_SOURCE
|
||||
# define _LARGEFILE64_SOURCE
|
||||
#endif
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
@@ -36,7 +41,6 @@
|
||||
#include <86box/version.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
// clang-format on
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(m) (((m) &S_IFMT) == S_IFDIR)
|
||||
|
||||
443
src/cdrom/cdrom_mitsumi.c
Normal file
443
src/cdrom/cdrom_mitsumi.c
Normal file
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Mitsumi CD-ROM emulation for the ISA bus.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2022 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/io.h>
|
||||
#include <86box/pic.h>
|
||||
#include <86box/dma.h>
|
||||
#include <86box/cdrom.h>
|
||||
#include <86box/cdrom_mitsumi.h>
|
||||
#include <86box/plat.h>
|
||||
#include <86box/sound.h>
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
enum {
|
||||
STAT_CMD_CHECK = 0x01,
|
||||
STAT_PLAY_CDDA = 0x02,
|
||||
STAT_ERROR = 0x04,
|
||||
STAT_DISK_CDDA = 0x08,
|
||||
STAT_SPIN = 0x10,
|
||||
STAT_CHANGE = 0x20,
|
||||
STAT_READY = 0x40,
|
||||
STAT_OPEN = 0x80
|
||||
};
|
||||
enum {
|
||||
CMD_GET_INFO = 0x10,
|
||||
CMD_GET_Q = 0x20,
|
||||
CMD_GET_STAT = 0x40,
|
||||
CMD_SET_MODE = 0x50,
|
||||
CMD_SOFT_RESET = 0x60,
|
||||
CMD_STOPCDDA = 0x70,
|
||||
CMD_CONFIG = 0x90,
|
||||
CMD_SET_VOL = 0xae,
|
||||
CMD_READ1X = 0xc0,
|
||||
CMD_READ2X = 0xc1,
|
||||
CMD_GET_VER = 0xdc,
|
||||
CMD_STOP = 0xf0,
|
||||
CMD_EJECT = 0xf6,
|
||||
CMD_LOCK = 0xfe
|
||||
};
|
||||
enum {
|
||||
MODE_MUTE = 0x01,
|
||||
MODE_GET_TOC = 0x04,
|
||||
MODE_STOP = 0x08,
|
||||
MODE_ECC = 0x20,
|
||||
MODE_DATA = 0x40
|
||||
};
|
||||
enum {
|
||||
DRV_MODE_STOP,
|
||||
DRV_MODE_READ,
|
||||
DRV_MODE_CDDA
|
||||
};
|
||||
enum {
|
||||
FLAG_NODATA = 2,
|
||||
FLAG_NOSTAT = 4,
|
||||
FLAG_UNK = 8, //??
|
||||
FLAG_OPEN = 16
|
||||
};
|
||||
enum {
|
||||
IRQ_DATAREADY = 1,
|
||||
IRQ_DATACOMP = 2,
|
||||
IRQ_ERROR = 4
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int dma, irq;
|
||||
int change;
|
||||
int data;
|
||||
uint8_t stat;
|
||||
uint8_t buf[RAW_SECTOR_SIZE];
|
||||
int buf_count;
|
||||
int buf_idx;
|
||||
uint8_t cmdbuf[16];
|
||||
int cmdbuf_count;
|
||||
int cmdrd_count;
|
||||
int cmdbuf_idx;
|
||||
uint8_t mode;
|
||||
uint8_t cmd;
|
||||
uint8_t conf;
|
||||
uint8_t enable_irq;
|
||||
uint8_t enable_dma;
|
||||
uint16_t dmalen;
|
||||
uint32_t readmsf;
|
||||
uint32_t readcount;
|
||||
int locked;
|
||||
int drvmode;
|
||||
int cur_toc_track;
|
||||
int pos;
|
||||
} mcd_t;
|
||||
|
||||
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
|
||||
there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start
|
||||
of the audio while audio still plays. With an absolute conversion, the counter is fine. */
|
||||
#undef MSFtoLBA
|
||||
#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
|
||||
|
||||
#define CD_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
||||
#define CD_DCB(x) ((((x) &0xf0) >> 4) * 10 + ((x) &0x0f))
|
||||
|
||||
#ifdef ENABLE_MITSUMI_CDROM_LOG
|
||||
int mitsumi_cdrom_do_log = ENABLE_MITSUMI_CDROM_LOG;
|
||||
|
||||
void
|
||||
mitsumi_cdrom_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (mitsumi_cdrom_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define mitsumi_cdrom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_reset(mcd_t *dev)
|
||||
{
|
||||
cdrom_t *cdrom = &cdrom[0];
|
||||
|
||||
dev->stat = cdrom->host_drive ? (STAT_READY | STAT_CHANGE) : 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 0;
|
||||
dev->buf_count = 0;
|
||||
dev->cur_toc_track = 0;
|
||||
dev->enable_dma = 0;
|
||||
dev->enable_irq = 0;
|
||||
dev->conf = 0;
|
||||
dev->dmalen = COOKED_SECTOR_SIZE;
|
||||
dev->locked = 0;
|
||||
dev->change = 1;
|
||||
dev->data = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mitsumi_cdrom_read_sector(mcd_t *dev, int first)
|
||||
{
|
||||
cdrom_t *cdrom = &cdrom[0];
|
||||
uint8_t status;
|
||||
int ret;
|
||||
|
||||
if (cdrom == NULL)
|
||||
return 0;
|
||||
|
||||
if (dev->drvmode == DRV_MODE_CDDA) {
|
||||
status = cdrom_mitsumi_audio_play(cdrom, dev->readmsf, dev->readcount);
|
||||
if (status == 1)
|
||||
return status;
|
||||
else
|
||||
dev->drvmode = DRV_MODE_READ;
|
||||
}
|
||||
|
||||
if ((dev->enable_irq & IRQ_DATACOMP) && !first) {
|
||||
picint(1 << dev->irq);
|
||||
}
|
||||
if (!dev->readcount) {
|
||||
dev->data = 0;
|
||||
return 0;
|
||||
}
|
||||
cdrom_stop(cdrom);
|
||||
ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, (int *) &dev->readcount);
|
||||
if (!ret)
|
||||
return 0;
|
||||
if (dev->mode & 0x40) {
|
||||
dev->buf[12] = CD_BCD((dev->readmsf >> 16) & 0xff);
|
||||
dev->buf[13] = CD_BCD((dev->readmsf >> 8) & 0xff);
|
||||
}
|
||||
dev->readmsf = cdrom_lba_to_msf_accurate(cdrom->seek_pos + 1);
|
||||
dev->buf_count = dev->dmalen + 1;
|
||||
dev->buf_idx = 0;
|
||||
dev->data = 1;
|
||||
if (dev->enable_dma) {
|
||||
while (dev->pos < dev->readcount) {
|
||||
dma_channel_write(dev->dma, dev->buf[dev->pos]);
|
||||
dev->pos++;
|
||||
}
|
||||
dev->pos = 0;
|
||||
}
|
||||
dev->readcount--;
|
||||
if ((dev->enable_irq & IRQ_DATAREADY) && first)
|
||||
picint(1 << dev->irq);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
mitsumi_cdrom_in(uint16_t port, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
uint8_t ret;
|
||||
|
||||
switch (port & 1) {
|
||||
case 0:
|
||||
if (dev->cmdbuf_count) {
|
||||
dev->cmdbuf_count--;
|
||||
return dev->cmdbuf[dev->cmdbuf_idx++];
|
||||
} else if (dev->buf_count) {
|
||||
ret = (dev->buf_idx < RAW_SECTOR_SIZE) ? dev->buf[dev->buf_idx] : 0;
|
||||
dev->buf_idx++;
|
||||
dev->buf_count--;
|
||||
if (!dev->buf_count)
|
||||
mitsumi_cdrom_read_sector(dev, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
return dev->stat;
|
||||
case 1:
|
||||
ret = 0;
|
||||
picintc(1 << dev->irq);
|
||||
if (!dev->buf_count || !dev->data || dev->enable_dma)
|
||||
ret |= FLAG_NODATA;
|
||||
if (!dev->cmdbuf_count)
|
||||
ret |= FLAG_NOSTAT;
|
||||
return ret | FLAG_UNK;
|
||||
}
|
||||
|
||||
return (0xff);
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
cdrom_t *cdrom = &cdrom[0];
|
||||
|
||||
switch (port & 1) {
|
||||
case 0:
|
||||
if (dev->cmdrd_count) {
|
||||
dev->cmdrd_count--;
|
||||
switch (dev->cmd) {
|
||||
case CMD_SET_MODE:
|
||||
dev->mode = val;
|
||||
dev->cmdbuf[1] = 0;
|
||||
dev->cmdbuf_count = 2;
|
||||
break;
|
||||
case CMD_LOCK:
|
||||
dev->locked = val & 1;
|
||||
dev->cmdbuf[1] = 0;
|
||||
dev->cmdbuf[2] = 0;
|
||||
dev->cmdbuf_count = 3;
|
||||
break;
|
||||
case CMD_CONFIG:
|
||||
switch (dev->cmdrd_count) {
|
||||
case 0:
|
||||
switch (dev->conf) {
|
||||
case 0x01:
|
||||
dev->dmalen |= val;
|
||||
break;
|
||||
case 0x02:
|
||||
dev->enable_dma = val;
|
||||
break;
|
||||
case 0x10:
|
||||
dev->enable_irq = val;
|
||||
break;
|
||||
}
|
||||
dev->cmdbuf[1] = 0;
|
||||
dev->cmdbuf_count = 2;
|
||||
dev->conf = 0;
|
||||
break;
|
||||
case 1:
|
||||
if (dev->conf == 1) {
|
||||
dev->dmalen = val << 8;
|
||||
break;
|
||||
}
|
||||
dev->conf = val;
|
||||
if (dev->conf == 1)
|
||||
dev->cmdrd_count++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CMD_READ1X:
|
||||
case CMD_READ2X:
|
||||
switch (dev->cmdrd_count) {
|
||||
case 0:
|
||||
dev->readcount |= val;
|
||||
mitsumi_cdrom_read_sector(dev, 1);
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_SPIN | STAT_READY;
|
||||
break;
|
||||
case 1:
|
||||
dev->readcount |= (val << 8);
|
||||
break;
|
||||
case 2:
|
||||
dev->readcount = (val << 16);
|
||||
break;
|
||||
case 5:
|
||||
dev->readmsf = 0;
|
||||
case 4:
|
||||
case 3:
|
||||
dev->readmsf |= CD_DCB(val) << ((dev->cmdrd_count - 3) << 3);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!dev->cmdrd_count)
|
||||
dev->stat = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
return;
|
||||
}
|
||||
dev->cmd = val;
|
||||
dev->cmdbuf_idx = 0;
|
||||
dev->cmdrd_count = 0;
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = cdrom->host_drive ? (STAT_READY | (dev->change ? STAT_CHANGE : 0)) : 0;
|
||||
dev->data = 0;
|
||||
switch (val) {
|
||||
case CMD_GET_INFO:
|
||||
if (cdrom->host_drive) {
|
||||
cdrom_get_track_buffer(cdrom, &(dev->cmdbuf[1]));
|
||||
dev->cmdbuf_count = 10;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_CMD_CHECK;
|
||||
}
|
||||
break;
|
||||
case CMD_GET_Q:
|
||||
if (cdrom->host_drive) {
|
||||
cdrom_get_q(cdrom, &(dev->cmdbuf[1]), &dev->cur_toc_track, dev->mode & MODE_GET_TOC);
|
||||
dev->cmdbuf_count = 11;
|
||||
dev->readcount = 0;
|
||||
} else {
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_CMD_CHECK;
|
||||
}
|
||||
break;
|
||||
case CMD_GET_STAT:
|
||||
dev->change = 0;
|
||||
break;
|
||||
case CMD_SET_MODE:
|
||||
dev->cmdrd_count = 1;
|
||||
break;
|
||||
case CMD_STOPCDDA:
|
||||
case CMD_STOP:
|
||||
cdrom_stop(cdrom);
|
||||
dev->drvmode = DRV_MODE_STOP;
|
||||
dev->cur_toc_track = 0;
|
||||
break;
|
||||
case CMD_CONFIG:
|
||||
dev->cmdrd_count = 2;
|
||||
break;
|
||||
case CMD_READ1X:
|
||||
case CMD_READ2X:
|
||||
if (cdrom->host_drive) {
|
||||
dev->readcount = 0;
|
||||
dev->drvmode = (val == CMD_READ1X) ? DRV_MODE_CDDA : DRV_MODE_READ;
|
||||
dev->cmdrd_count = 6;
|
||||
} else {
|
||||
dev->cmdbuf_count = 1;
|
||||
dev->cmdbuf[0] = STAT_CMD_CHECK;
|
||||
}
|
||||
break;
|
||||
case CMD_GET_VER:
|
||||
dev->cmdbuf[1] = 1;
|
||||
dev->cmdbuf[2] = 'D';
|
||||
dev->cmdbuf[3] = 0;
|
||||
dev->cmdbuf_count = 4;
|
||||
break;
|
||||
case CMD_EJECT:
|
||||
cdrom_stop(cdrom);
|
||||
cdrom_eject(0);
|
||||
dev->readcount = 0;
|
||||
break;
|
||||
case CMD_LOCK:
|
||||
dev->cmdrd_count = 1;
|
||||
break;
|
||||
default:
|
||||
dev->cmdbuf[0] = dev->stat | STAT_CMD_CHECK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
mitsumi_cdrom_reset(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
mitsumi_cdrom_init(const device_t *info)
|
||||
{
|
||||
mcd_t *dev;
|
||||
|
||||
dev = malloc(sizeof(mcd_t));
|
||||
memset(dev, 0x00, sizeof(mcd_t));
|
||||
|
||||
dev->irq = 5;
|
||||
dev->dma = 5;
|
||||
|
||||
io_sethandler(0x310, 2,
|
||||
mitsumi_cdrom_in, NULL, NULL, mitsumi_cdrom_out, NULL, NULL, dev);
|
||||
|
||||
mitsumi_cdrom_reset(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
mitsumi_cdrom_close(void *priv)
|
||||
{
|
||||
mcd_t *dev = (mcd_t *) priv;
|
||||
|
||||
if (dev) {
|
||||
free(dev);
|
||||
dev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const device_t mitsumi_cdrom_device = {
|
||||
"Mitsumi CD-ROM interface",
|
||||
"mcd",
|
||||
DEVICE_ISA | DEVICE_AT,
|
||||
0,
|
||||
mitsumi_cdrom_init,
|
||||
mitsumi_cdrom_close,
|
||||
NULL,
|
||||
{ NULL },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of Chips&Technology's 82C100 chipset.
|
||||
* Implementation of Chips&Technology's 82C100 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
add_library(chipset OBJECT 82c100.c acc2168.c cs8230.c ali1429.c ali1489.c ali1531.c ali1541.c ali1543.c
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ACC 2046/2168 chipset
|
||||
* Implementation of the ACC 2046/2168 chipset
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Tiseno100
|
||||
*
|
||||
* Copyright 2019 Sarah Walker.
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2019 Sarah Walker.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the ALi M1429 chipset.
|
||||
* Implementation of the ALi M1429 chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020,2021 Tiseno100.
|
||||
* Copyright 2021,2021 Miran Grca.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020,2021 Tiseno100.
|
||||
* Copyright 2021,2021 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -72,7 +74,6 @@
|
||||
1 1 0: CLK2IN/12
|
||||
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -323,8 +324,8 @@ ali1429_init(const device_t *info)
|
||||
GREEN = info->local;
|
||||
|
||||
/* M1429 Ports:
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
22h Index Port
|
||||
23h Data Port
|
||||
*/
|
||||
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1489 chipset.
|
||||
* Implementation of the ALi M1489 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020,2021 Tiseno100.
|
||||
* Copyright 2020,2021 Miran Grca.
|
||||
* Copyright 2020,2021 Tiseno100.
|
||||
* Copyright 2020,2021 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1531B CPU-to-PCI Bridge.
|
||||
* Implementation of the ALi M1531B CPU-to-PCI Bridge.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1541/2 CPU-to-PCI Bridge.
|
||||
* Implementation of the ALi M1541/2 CPU-to-PCI Bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1543 Desktop South Bridge.
|
||||
* Implementation of the ALi M1543 Desktop South Bridge.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M1621/2 CPU-to-PCI Bridge.
|
||||
* Implementation of the ALi M1621/2 CPU-to-PCI Bridge.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -57,28 +59,28 @@ ali1621_log(const char *fmt, ...)
|
||||
|
||||
/* Table translated to a more sensible format:
|
||||
Read cycles:
|
||||
SMREN SMM Mode Code Data
|
||||
0 X X PCI PCI
|
||||
1 0 Close PCI PCI
|
||||
1 0 Lock PCI PCI
|
||||
1 0 Protect PCI PCI
|
||||
1 0 Open DRAM DRAM
|
||||
1 1 Open DRAM DRAM
|
||||
1 1 Protect DRAM DRAM
|
||||
1 1 Close DRAM PCI
|
||||
1 1 Lock DRAM PCI
|
||||
SMREN SMM Mode Code Data
|
||||
0 X X PCI PCI
|
||||
1 0 Close PCI PCI
|
||||
1 0 Lock PCI PCI
|
||||
1 0 Protect PCI PCI
|
||||
1 0 Open DRAM DRAM
|
||||
1 1 Open DRAM DRAM
|
||||
1 1 Protect DRAM DRAM
|
||||
1 1 Close DRAM PCI
|
||||
1 1 Lock DRAM PCI
|
||||
|
||||
Write cycles:
|
||||
SMWEN SMM Mode Data
|
||||
0 X X PCI
|
||||
1 0 Close PCI
|
||||
1 0 Lock PCI
|
||||
1 0 Protect PCI
|
||||
1 0 Open DRAM
|
||||
1 1 Open DRAM
|
||||
1 1 Protect DRAM
|
||||
1 1 Close PCI
|
||||
1 1 Lock PCI
|
||||
SMWEN SMM Mode Data
|
||||
0 X X PCI
|
||||
1 0 Close PCI
|
||||
1 0 Lock PCI
|
||||
1 0 Protect PCI
|
||||
1 0 Open DRAM
|
||||
1 1 Open DRAM
|
||||
1 1 Protect DRAM
|
||||
1 1 Close PCI
|
||||
1 1 Lock PCI
|
||||
|
||||
Explanation of the modes based above:
|
||||
If SM*EN = 0, SMRAM is entirely disabled, otherwise:
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M6117 SoC.
|
||||
* Implementation of the ALi M6117 SoC.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2020 RichardG.
|
||||
* Copyright 2020 RichardG.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Contaq/Cypress 82C596(A) and 597 chipsets.
|
||||
* Implementation of the Contaq/Cypress 82C596(A) and 597 chipsets.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Chips & Technologies CS4031 chipset.
|
||||
* Implementation of the Chips & Technologies CS4031 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of C&T CS8230 ("386/AT") chipset.
|
||||
* Emulation of C&T CS8230 ("386/AT") chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
*
|
||||
* Copyright 2020 Sarah Walker.
|
||||
* Copyright 2020 Sarah Walker.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ETEQ Cheetah ET6000 chipset.
|
||||
* Implementation of the ETEQ Cheetah ET6000 chipset.
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the G2 GC100/GC100A chipset.
|
||||
* NOTE: As documentation is currently available only for the
|
||||
* CG100 chipset, the GC100A chipset has been reverese-engineered.
|
||||
* Thus, its behavior may not be fully accurate.
|
||||
* Implementation of the G2 GC100/GC100A chipset.
|
||||
*
|
||||
* Authors: EngiNerd, <webmaster.crrc@yahoo.it>
|
||||
* NOTE: As documentation is currently available only for the
|
||||
* GC100 chipset, the GC100A chipset has been reverese-engineered.
|
||||
* Thus, its behavior may not be fully accurate.
|
||||
*
|
||||
* Copyright 2020-2021 EngiNerd.
|
||||
*
|
||||
*
|
||||
* Authors: EngiNerd, <webmaster.crrc@yahoo.it>
|
||||
*
|
||||
* Copyright 2020-2021 EngiNerd.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the HEADLAND AT286 chipset.
|
||||
* Implementation of the HEADLAND AT286 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Original by GreatPsycho for PCem.
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Original by GreatPsycho for PCem.
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2010-2019 Sarah Walker.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Miran Grca.
|
||||
* Copyright 2017-2019 GreatPsycho.
|
||||
* Copyright 2010-2019 Sarah Walker.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Miran Grca.
|
||||
* Copyright 2017-2019 GreatPsycho.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -255,7 +255,7 @@ memmap_state_update(headland_t *dev)
|
||||
mem_mapping_set_exec(&dev->high_mapping, ram + 0x100000);
|
||||
}
|
||||
} else {
|
||||
/* 1 MB - 1 MB + 384k: RAM pointing to A0000-FFFFF
|
||||
/* 1 MB - 1 MB + 384k: RAM pointing to A0000-FFFFF
|
||||
1 MB + 384k: Any ram pointing 1 MB onwards. */
|
||||
/* First, do the addresses above 1 MB. */
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the IMS 8848/8849 chipset.
|
||||
* Implementation of the IMS 8848/8849 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* Emulation of Intel 82420EX chipset that acts as both the
|
||||
* northbridge and the southbridge.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of Intel 82420EX chipset that acts as both the
|
||||
* northbridge and the southbridge.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Intel PCISet chips from 420TX to 440GX.
|
||||
* Implementation of the Intel PCISet chips from 420TX to 440GX.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019,2020 Miran Grca.
|
||||
* Copyright 2019-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Intel 82335(KU82335) chipset.
|
||||
* Implementation of the Intel 82335(KU82335) chipset.
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Intel 450KX Mars Chipset.
|
||||
* Implementation of the Intel 450KX Mars Chipset.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -19,7 +21,6 @@ Due to 86Box limitations we can't manage them seperately thus it is dev branch t
|
||||
|
||||
i450GX is way more popular of an option but needs more stuff.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC
|
||||
* SLC90E66 (Victory66) Xcelerators.
|
||||
* Emulation of the Intel PIIX, PIIX3, PIIX4, PIIX4E, and SMSC
|
||||
* SLC90E66 (Victory66) Xcelerators.
|
||||
*
|
||||
* PRD format :
|
||||
* word 0 - base address
|
||||
* word 1 - bits 1-15 = byte count, bit 31 = end of transfer
|
||||
* PRD format :
|
||||
* word 0 - base address
|
||||
* word 1 - bits 1-15 = byte count, bit 31 = end of transfer
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -1023,9 +1023,9 @@ piix_write(int func, int addr, uint8_t val, void *priv)
|
||||
fregs[0x07] &= 0xf7;
|
||||
break;
|
||||
#if 0
|
||||
case 0x3c:
|
||||
fregs[0x3c] = val;
|
||||
break;
|
||||
case 0x3c:
|
||||
fregs[0x3c] = val;
|
||||
break;
|
||||
#endif
|
||||
case 0x40:
|
||||
fregs[0x40] = (val & 0xc0) | 1;
|
||||
@@ -1657,9 +1657,9 @@ static void
|
||||
/* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */
|
||||
/* Bit 4: External CPU clock (Switch 8). */
|
||||
/* Bit 3: External CPU clock (Switch 7). */
|
||||
/* 50 MHz: Switch 7 = Off, Switch 8 = Off. */
|
||||
/* 60 MHz: Switch 7 = On, Switch 8 = Off. */
|
||||
/* 66 MHz: Switch 7 = Off, Switch 8 = On. */
|
||||
/* 50 MHz: Switch 7 = Off, Switch 8 = Off. */
|
||||
/* 60 MHz: Switch 7 = On, Switch 8 = Off. */
|
||||
/* 66 MHz: Switch 7 = Off, Switch 8 = On. */
|
||||
/* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */
|
||||
/* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */
|
||||
/* Bit 0: 0 = 1.5x multiplier, 1 = 2x multiplier (Switch 6). */
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* Emulation of Intel System I/O PCI chip.
|
||||
* Emulation of Intel System I/O PCI chip.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Emulation of C&T CS8121 ("NEAT") 82C206/211/212/215 chipset.
|
||||
* Emulation of C&T CS8121 ("NEAT") 82C206/211/212/215 chipset.
|
||||
*
|
||||
* Note: The datasheet mentions that the chipset supports up to 8MB
|
||||
* of DRAM. This is intepreted as 'being able to refresh up to
|
||||
* 8MB of DRAM chips', because it works fine with bus-based
|
||||
* memory expansion.
|
||||
* Note: The datasheet mentions that the chipset supports up to 8MB
|
||||
* of DRAM. This is intepreted as 'being able to refresh up to
|
||||
* 8MB of DRAM chips', because it works fine with bus-based
|
||||
* memory expansion.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the Olivetti EVA (98/86) Gate Array.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Implementation of the Olivetti EVA (98/86) Gate Array.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: EngiNerd <webmaster.crrc@yahoo.it>
|
||||
*
|
||||
* Copyright 2020-2021 EngiNerd
|
||||
* Copyright 2020-2021 EngiNerd
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C283 chipset.
|
||||
* Implementation of the OPTi 82C283 chipset.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C291 chipset.
|
||||
|
||||
* Authors: plant/nerd73, Tiseno100
|
||||
* Implementation of the OPTi 82C291 chipset.
|
||||
*
|
||||
* Copyright 2020 plant/nerd73.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*
|
||||
*
|
||||
* Authors: plant/nerd73, Tiseno100
|
||||
*
|
||||
* Copyright 2020 plant/nerd73.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C391/392 chipset.
|
||||
* Implementation of the OPTi 82C391/392 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C493/82C495 chipset.
|
||||
* Implementation of the OPTi 82C493/82C495 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C493/82C499 chipset.
|
||||
* Implementation of the OPTi 82C493/82C499 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C546/82C547(Python) & 82C596/82C597(Cobra) chipsets.
|
||||
* Implementation of the OPTi 82C546/82C547(Python) & 82C596/82C597(Cobra) chipsets.
|
||||
|
||||
* Authors: plant/nerd73,
|
||||
* Authors: plant/nerd73,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Tiseno100
|
||||
*
|
||||
* Copyright 2020 plant/nerd73.
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2020 plant/nerd73.
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -35,7 +35,7 @@
|
||||
typedef struct
|
||||
{
|
||||
uint8_t idx, is_pci,
|
||||
regs[16];
|
||||
regs[16];
|
||||
} opti5x7_t;
|
||||
|
||||
#ifdef ENABLE_OPTI5X7_LOG
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C822 VESA Local Bus to PCI
|
||||
* Bridge Interface.
|
||||
* Implementation of the OPTi 82C822 VESA Local Bus to PCI
|
||||
* Bridge Interface.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2022 Miran Grca.
|
||||
* Copyright 2022 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
@@ -42,11 +42,11 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t irq_convert,
|
||||
pci_regs[256];
|
||||
uint8_t irq_convert,
|
||||
pci_regs[256];
|
||||
} opti822_t;
|
||||
|
||||
#define ENABLE_OPTI822_LOG 1
|
||||
// #define ENABLE_OPTI822_LOG 1
|
||||
#ifdef ENABLE_OPTI822_LOG
|
||||
int opti822_do_log = ENABLE_OPTI822_LOG;
|
||||
|
||||
@@ -56,13 +56,13 @@ opti822_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (opti822_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define opti822_log(fmt, ...)
|
||||
# define opti822_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* NOTE: We currently cheat and pass all PCI shadow RAM accesses to ISA as well.
|
||||
@@ -71,13 +71,13 @@ opti822_log(const char *fmt, ...)
|
||||
static void
|
||||
opti822_recalc(opti822_t *dev)
|
||||
{
|
||||
int i, reg, bit_r, bit_w;
|
||||
int state;
|
||||
int i, reg, bit_r, bit_w;
|
||||
int state;
|
||||
uint32_t base;
|
||||
|
||||
for (i = 0; i < 12; i++) {
|
||||
base = 0x000c0000 + (i << 14);
|
||||
reg = 0x44 + ((i >> 2) ^ 3);
|
||||
base = 0x000c0000 + (i << 14);
|
||||
reg = 0x44 + ((i >> 2) ^ 3);
|
||||
bit_w = (i & 3);
|
||||
bit_r = bit_w + 4;
|
||||
bit_w = 1 << bit_w;
|
||||
@@ -99,18 +99,19 @@ static void
|
||||
opti822_update_irqs(opti822_t *dev, int set)
|
||||
{
|
||||
uint8_t val;
|
||||
int i, reg;
|
||||
int shift, irq;
|
||||
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
|
||||
pic_t *temp_pic;
|
||||
int i, reg;
|
||||
int shift, irq;
|
||||
int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
|
||||
pic_t *temp_pic;
|
||||
|
||||
dev->irq_convert = (dev->pci_regs[0x53] & 0x08);
|
||||
// dev->irq_convert = (dev->pci_regs[0x53] & 0x08);
|
||||
dev->irq_convert = 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
reg = 0x80 + (i >> 1);
|
||||
for (i = 0; i < 16; i++) {
|
||||
reg = 0x88 + (i >> 1);
|
||||
shift = (i & 1) << 2;
|
||||
val = (dev->pci_regs[reg] >> shift) & 0x0f;
|
||||
irq = irq_map[val & 0x07];
|
||||
val = (dev->pci_regs[reg] >> shift) & 0x0f;
|
||||
irq = irq_map[val & 0x07];
|
||||
if (irq == -1)
|
||||
continue;
|
||||
temp_pic = (irq >= 8) ? &pic2 : &pic;
|
||||
@@ -126,7 +127,8 @@ static void
|
||||
opti822_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
|
||||
int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 };
|
||||
int pin, slot;
|
||||
|
||||
opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val);
|
||||
|
||||
@@ -142,7 +144,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
/* Status Register */
|
||||
case 0x06:
|
||||
if (!(dev->pci_regs[0x52] & 0x04))
|
||||
dev->pci_regs[addr] = (val & 0x80);
|
||||
dev->pci_regs[addr] = (val & 0x80);
|
||||
break;
|
||||
case 0x07:
|
||||
dev->pci_regs[addr] &= ~(val & 0xf9);
|
||||
@@ -291,27 +293,33 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
dev->pci_regs[addr] = val;
|
||||
break;
|
||||
|
||||
case 0x88 ... 0x8f:
|
||||
dev->pci_regs[addr] = val;
|
||||
opti822_update_irqs(dev, 0);
|
||||
irq = irq_map[val & 0x07];
|
||||
if (irq >= 0) {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> %02X\n", 0x41 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1, irq);
|
||||
pci_set_irq_routing(PCI_INTA + ((addr & 0x07) << 1), irq);
|
||||
} else {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> FF\n", 0x41 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1);
|
||||
pci_set_irq_routing(PCI_INTA + ((addr & 0x07) << 1), PCI_IRQ_DISABLED);
|
||||
}
|
||||
irq = irq_map[(val >> 4) & 0x07];
|
||||
if (irq >= 0) {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> %02X\n", 0x42 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1, irq);
|
||||
pci_set_irq_routing(PCI_INTB + ((addr & 0x07) << 1), irq);
|
||||
} else {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> FF\n", 0x42 + ((addr & 0x01) << 1), ((addr & 0x06) >> 1) + 1);
|
||||
pci_set_irq_routing(PCI_INTB + ((addr & 0x07) << 1), PCI_IRQ_DISABLED);
|
||||
}
|
||||
opti822_update_irqs(dev, 1);
|
||||
break;
|
||||
case 0x88 ... 0x8f:
|
||||
dev->pci_regs[addr] = val;
|
||||
opti822_update_irqs(dev, 0);
|
||||
irq = irq_map[val & 0x07];
|
||||
pin = 4 - ((addr & 0x01) << 1);
|
||||
slot = ((addr & 0x06) >> 1);
|
||||
if (irq >= 0) {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq);
|
||||
pci_set_irq_routing(pin + (slot << 2), irq);
|
||||
pci_set_irq_level(pin + (slot << 2), !!(val & 0x07));
|
||||
} else {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31);
|
||||
pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED);
|
||||
}
|
||||
irq = irq_map[(val >> 4) & 0x07];
|
||||
pin = 3 - ((addr & 0x01) << 1);
|
||||
slot = ((addr & 0x06) >> 1);
|
||||
if (irq >= 0) {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq);
|
||||
pci_set_irq_routing(pin + (slot << 2), irq);
|
||||
pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07));
|
||||
} else {
|
||||
opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31);
|
||||
pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED);
|
||||
}
|
||||
opti822_update_irqs(dev, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +327,7 @@ static uint8_t
|
||||
opti822_pci_read(int func, int addr, void *priv)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
uint8_t ret;
|
||||
uint8_t ret;
|
||||
|
||||
ret = 0xff;
|
||||
|
||||
@@ -335,13 +343,14 @@ static void
|
||||
opti822_reset(void *priv)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *) priv;
|
||||
|
||||
pci_set_pmc(0);
|
||||
int i;
|
||||
|
||||
memset(dev->pci_regs, 0, 256);
|
||||
|
||||
dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/
|
||||
dev->pci_regs[0x02] = 0x22; dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/
|
||||
dev->pci_regs[0x00] = 0x45;
|
||||
dev->pci_regs[0x01] = 0x10; /*OPTi*/
|
||||
dev->pci_regs[0x02] = 0x22;
|
||||
dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/
|
||||
dev->pci_regs[0x04] = 0x07;
|
||||
dev->pci_regs[0x06] = 0x80;
|
||||
dev->pci_regs[0x07] = 0x02;
|
||||
@@ -349,23 +358,22 @@ opti822_reset(void *priv)
|
||||
dev->pci_regs[0x0b] = 0x06;
|
||||
dev->pci_regs[0x0d] = 0x20;
|
||||
|
||||
dev->pci_regs[0x40] = 0x01; dev->pci_regs[0x41] = 0x0c;
|
||||
dev->pci_regs[0x40] = 0x01;
|
||||
dev->pci_regs[0x41] = 0x0c;
|
||||
dev->pci_regs[0x43] = 0x02;
|
||||
dev->pci_regs[0x52] = 0x06;
|
||||
dev->pci_regs[0x53] = 0x90;
|
||||
|
||||
dev->irq_convert = 0;
|
||||
dev->irq_convert = 1 /*0*/;
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
for (i = 0; i < 16; i++)
|
||||
pci_set_irq_routing(PCI_INTA + i, PCI_IRQ_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
opti822_close(void *p)
|
||||
{
|
||||
opti822_t *dev = (opti822_t *)p;
|
||||
opti822_t *dev = (opti822_t *) p;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the OPTi 82C802G/82C895 chipset.
|
||||
* Implementation of the OPTi 82C802G/82C895 chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2008-2020 Tiseno100.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Emulation of VLSI 82C311 ("SCAMP") chipset.
|
||||
* Emulation of VLSI 82C311 ("SCAMP") chipset.
|
||||
*
|
||||
* Note: The datasheet mentions that the chipset supports up to 8MB
|
||||
* of DRAM. This is intepreted as 'being able to refresh up to
|
||||
* 8MB of DRAM chips', because it works fine with bus-based
|
||||
* memory expansion.
|
||||
* Note: The datasheet mentions that the chipset supports up to 8MB
|
||||
* of DRAM. This is intepreted as 'being able to refresh up to
|
||||
* 8MB of DRAM chips', because it works fine with bus-based
|
||||
* memory expansion.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
*
|
||||
* Copyright 2020 Sarah Walker.
|
||||
* Copyright 2020 Sarah Walker.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of Chips&Technology's SCAT (82C235) chipset.
|
||||
* Implementation of Chips&Technology's SCAT (82C235) chipset.
|
||||
*
|
||||
* Re-worked version based on the 82C235 datasheet and errata.
|
||||
* Re-worked version based on the 82C235 datasheet and errata.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Original by GreatPsycho for PCem.
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Authors: Original by GreatPsycho for PCem.
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2017-2019 GreatPsycho.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 GreatPsycho.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset.
|
||||
* Implementation of the SiS 5511/5512/5513 Pentium PCI/ISA Chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 5571 Chipset.
|
||||
* Implementation of the SiS 5571 Chipset.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 85c496/85c497 chip.
|
||||
* Implementation of the SiS 85c496/85c497 chip.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019,2020 Miran Grca.
|
||||
* Copyright 2019-2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the SiS 85c401/85c402, 85c460, 85c461, and
|
||||
* 85c407/85c471 chipsets.
|
||||
* Emulation of the SiS 85c401/85c402, 85c460, 85c461, and
|
||||
* 85c407/85c471 chipsets.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019,2020 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019,2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 85C50x Chipset.
|
||||
* Implementation of the SiS 85C50x Chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020,2021 Tiseno100.
|
||||
* Copyright 2020,2021 Miran Grca.
|
||||
* Copyright 2020-2021 Tiseno100.
|
||||
* Copyright 2020-2021 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the STMicroelectronics STPC series of SoCs.
|
||||
* Implementation of the STMicroelectronics STPC series of SoCs.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2020 RichardG.
|
||||
* Copyright 2020 RichardG.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the UMC 8886xx PCI to ISA Bridge .
|
||||
* Implementation of the UMC 8886xx PCI to ISA Bridge .
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -65,7 +67,6 @@
|
||||
Function 1 Register 4: (UMC 8886AF/8886BF Only!)
|
||||
Bit 0: Enable Internal IDE
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the UMC HB4 "Super Energy Star Green" PCI Chipset.
|
||||
* Implementation of the UMC HB4 "Super Energy Star Green" PCI Chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Note 2: Additional information were also used from all
|
||||
* around the web.
|
||||
* Note 2: Additional information were also used from all
|
||||
* around the web.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2021 Tiseno100.
|
||||
* Copyright 2021 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the VIA Apollo series of chips.
|
||||
* Implementation of the VIA Apollo series of chips.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
* Tiseno100,
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
* Tiseno100,
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Melissa Goad.
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Melissa Goad.
|
||||
* Copyright 2020 Tiseno100.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 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.
|
||||
*
|
||||
* Emulation of the VIA PIPC southbridges.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the VIA PIPC southbridges.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Melissa Goad, <mszoopers@protonmail.com>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2020 Melissa Goad.
|
||||
* Copyright 2020-2021 RichardG.
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2020 Melissa Goad.
|
||||
* Copyright 2020-2021 RichardG.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the VIA VT82C49X chipset.
|
||||
* Implementation of the VIA VT82C49X chipset.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the VIA VT82C505 VL/PCI Bridge Controller.
|
||||
* Implementation of the VIA VT82C505 VL/PCI Bridge Controller.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Tiseno100,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
* Copyright 2020 Tiseno100.
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the VLSI VL82c480 chipset.
|
||||
* Implementation of the VLSI VL82c480 chipset.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2020 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Implementation of the Western Digital WD76C10 chipset.
|
||||
* Implementation of the Western Digital WD76C10 chipset.
|
||||
*
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
* Note: This chipset has no datasheet, everything were done via
|
||||
* reverse engineering the BIOS of various machines using it.
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*
|
||||
* Authors: Tiseno100
|
||||
*
|
||||
* Copyright 2021 Tiseno100
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
if(DYNAREC)
|
||||
|
||||
@@ -9,28 +9,30 @@
|
||||
#include "x86_ops.h"
|
||||
#include "codegen.h"
|
||||
|
||||
void (*codegen_timing_start)();
|
||||
void (*codegen_timing_start)(void);
|
||||
void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*codegen_timing_block_start)();
|
||||
void (*codegen_timing_block_end)();
|
||||
int (*codegen_timing_jump_cycles)();
|
||||
void (*codegen_timing_block_start)(void);
|
||||
void (*codegen_timing_block_end)(void);
|
||||
int (*codegen_timing_jump_cycles)(void);
|
||||
|
||||
void codegen_timing_set(codegen_timing_t *timing)
|
||||
void
|
||||
codegen_timing_set(codegen_timing_t *timing)
|
||||
{
|
||||
codegen_timing_start = timing->start;
|
||||
codegen_timing_prefix = timing->prefix;
|
||||
codegen_timing_opcode = timing->opcode;
|
||||
codegen_timing_block_start = timing->block_start;
|
||||
codegen_timing_block_end = timing->block_end;
|
||||
codegen_timing_jump_cycles = timing->jump_cycles;
|
||||
codegen_timing_start = timing->start;
|
||||
codegen_timing_prefix = timing->prefix;
|
||||
codegen_timing_opcode = timing->opcode;
|
||||
codegen_timing_block_start = timing->block_start;
|
||||
codegen_timing_block_end = timing->block_end;
|
||||
codegen_timing_jump_cycles = timing->jump_cycles;
|
||||
}
|
||||
|
||||
int codegen_in_recompile;
|
||||
|
||||
/* This is for compatibility with new x87 code. */
|
||||
void codegen_set_rounding_mode(int mode)
|
||||
void
|
||||
codegen_set_rounding_mode(int mode)
|
||||
{
|
||||
/* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10);
|
||||
/* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10);
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
#include "x86_ops.h"
|
||||
|
||||
#ifdef __amd64__
|
||||
#include "codegen_x86-64.h"
|
||||
# include "codegen_x86-64.h"
|
||||
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64
|
||||
#include "codegen_x86.h"
|
||||
# include "codegen_x86.h"
|
||||
#else
|
||||
#error Dynamic recompiler not implemented on your platform
|
||||
# error Dynamic recompiler not implemented on your platform
|
||||
#endif
|
||||
|
||||
/*Handling self-modifying code (of which there is a lot on x86) :
|
||||
@@ -73,38 +73,37 @@
|
||||
same page).
|
||||
*/
|
||||
|
||||
typedef struct codeblock_t
|
||||
{
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t cmp;
|
||||
typedef struct codeblock_t {
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t cmp;
|
||||
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
struct codeblock_t *prev, *next;
|
||||
struct codeblock_t *prev_2, *next_2;
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
struct codeblock_t *prev, *next;
|
||||
struct codeblock_t *prev_2, *next_2;
|
||||
|
||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
struct codeblock_t *parent, *left, *right;
|
||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
struct codeblock_t *parent, *left, *right;
|
||||
|
||||
int pnt;
|
||||
int ins;
|
||||
int pnt;
|
||||
int ins;
|
||||
|
||||
int valid;
|
||||
|
||||
int was_recompiled;
|
||||
int TOP;
|
||||
int was_recompiled;
|
||||
int TOP;
|
||||
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
|
||||
uint8_t data[2048];
|
||||
uint8_t data[2048];
|
||||
} codeblock_t;
|
||||
|
||||
/*Code block uses FPU*/
|
||||
@@ -112,219 +111,192 @@ typedef struct codeblock_t
|
||||
/*Code block is always entered with the same FPU top-of-stack*/
|
||||
#define CODEBLOCK_STATIC_TOP 2
|
||||
|
||||
static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
static inline codeblock_t *
|
||||
codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
{
|
||||
codeblock_t *block = pages[phys >> 12].head;
|
||||
uint64_t a = _cs | ((uint64_t)phys << 32);
|
||||
codeblock_t *block = pages[phys >> 12].head;
|
||||
uint64_t a = _cs | ((uint64_t) phys << 32);
|
||||
|
||||
while (block)
|
||||
{
|
||||
if (a == block->cmp)
|
||||
{
|
||||
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
||||
break;
|
||||
}
|
||||
if (a < block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
||||
new_block->cmp = a;
|
||||
|
||||
if (!block)
|
||||
{
|
||||
pages[new_block->phys >> 12].head = new_block;
|
||||
new_block->parent = new_block->left = new_block->right = NULL;
|
||||
while (block) {
|
||||
if (a == block->cmp) {
|
||||
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
||||
break;
|
||||
}
|
||||
if (a < block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
{
|
||||
codeblock_t *old_block = NULL;
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
while (block)
|
||||
{
|
||||
old_block = block;
|
||||
if (a < old_block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
if (a < old_block->cmp)
|
||||
old_block->left = new_block;
|
||||
else
|
||||
old_block->right = new_block;
|
||||
|
||||
new_block->parent = old_block;
|
||||
new_block->left = new_block->right = NULL;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void codeblock_tree_delete(codeblock_t *block)
|
||||
static inline void
|
||||
codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
codeblock_t *parent = block->parent;
|
||||
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||
uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32);
|
||||
new_block->cmp = a;
|
||||
|
||||
if (!block->left && !block->right)
|
||||
{
|
||||
/*Easy case - remove from parent*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = NULL;
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
parent->left = NULL;
|
||||
if (parent->right == block)
|
||||
parent->right = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!block->left)
|
||||
{
|
||||
/*Only right node*/
|
||||
if (!parent)
|
||||
{
|
||||
pages[block->phys >> 12].head = block->right;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
{
|
||||
parent->left = block->right;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block)
|
||||
{
|
||||
parent->right = block->right;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!block->right)
|
||||
{
|
||||
/*Only left node*/
|
||||
if (!parent)
|
||||
{
|
||||
pages[block->phys >> 12].head = block->left;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
{
|
||||
parent->left = block->left;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block)
|
||||
{
|
||||
parent->right = block->left;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
if (!block) {
|
||||
pages[new_block->phys >> 12].head = new_block;
|
||||
new_block->parent = new_block->left = new_block->right = NULL;
|
||||
} else {
|
||||
codeblock_t *old_block = NULL;
|
||||
|
||||
while (block) {
|
||||
old_block = block;
|
||||
if (a < old_block->cmp)
|
||||
block = block->left;
|
||||
else
|
||||
block = block->right;
|
||||
}
|
||||
|
||||
if (a < old_block->cmp)
|
||||
old_block->left = new_block;
|
||||
else
|
||||
{
|
||||
/*Difficult case - node has two children. Walk right child to find lowest node*/
|
||||
codeblock_t *lowest = block->right, *highest;
|
||||
codeblock_t *old_parent;
|
||||
old_block->right = new_block;
|
||||
|
||||
while (lowest->left)
|
||||
lowest = lowest->left;
|
||||
|
||||
old_parent = lowest->parent;
|
||||
|
||||
/*Replace deleted node with lowest node*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = lowest;
|
||||
else
|
||||
{
|
||||
if (parent->left == block)
|
||||
parent->left = lowest;
|
||||
if (parent->right == block)
|
||||
parent->right = lowest;
|
||||
}
|
||||
|
||||
lowest->parent = parent;
|
||||
lowest->left = block->left;
|
||||
if (lowest->left)
|
||||
lowest->left->parent = lowest;
|
||||
|
||||
old_parent->left = NULL;
|
||||
|
||||
highest = lowest->right;
|
||||
if (!highest)
|
||||
{
|
||||
if (lowest != block->right)
|
||||
{
|
||||
lowest->right = block->right;
|
||||
block->right->parent = lowest;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (highest->right)
|
||||
highest = highest->right;
|
||||
|
||||
if (block->right && block->right != lowest)
|
||||
{
|
||||
highest->right = block->right;
|
||||
block->right->parent = highest;
|
||||
}
|
||||
}
|
||||
new_block->parent = old_block;
|
||||
new_block->left = new_block->right = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MASK_INDEX_MASK 3
|
||||
static inline void
|
||||
codeblock_tree_delete(codeblock_t *block)
|
||||
{
|
||||
codeblock_t *parent = block->parent;
|
||||
|
||||
if (!block->left && !block->right) {
|
||||
/*Easy case - remove from parent*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = NULL;
|
||||
else {
|
||||
if (parent->left == block)
|
||||
parent->left = NULL;
|
||||
if (parent->right == block)
|
||||
parent->right = NULL;
|
||||
}
|
||||
return;
|
||||
} else if (!block->left) {
|
||||
/*Only right node*/
|
||||
if (!parent) {
|
||||
pages[block->phys >> 12].head = block->right;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
} else {
|
||||
if (parent->left == block) {
|
||||
parent->left = block->right;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block) {
|
||||
parent->right = block->right;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (!block->right) {
|
||||
/*Only left node*/
|
||||
if (!parent) {
|
||||
pages[block->phys >> 12].head = block->left;
|
||||
pages[block->phys >> 12].head->parent = NULL;
|
||||
} else {
|
||||
if (parent->left == block) {
|
||||
parent->left = block->left;
|
||||
parent->left->parent = parent;
|
||||
}
|
||||
if (parent->right == block) {
|
||||
parent->right = block->left;
|
||||
parent->right->parent = parent;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
/*Difficult case - node has two children. Walk right child to find lowest node*/
|
||||
codeblock_t *lowest = block->right, *highest;
|
||||
codeblock_t *old_parent;
|
||||
|
||||
while (lowest->left)
|
||||
lowest = lowest->left;
|
||||
|
||||
old_parent = lowest->parent;
|
||||
|
||||
/*Replace deleted node with lowest node*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = lowest;
|
||||
else {
|
||||
if (parent->left == block)
|
||||
parent->left = lowest;
|
||||
if (parent->right == block)
|
||||
parent->right = lowest;
|
||||
}
|
||||
|
||||
lowest->parent = parent;
|
||||
lowest->left = block->left;
|
||||
if (lowest->left)
|
||||
lowest->left->parent = lowest;
|
||||
|
||||
old_parent->left = NULL;
|
||||
|
||||
highest = lowest->right;
|
||||
if (!highest) {
|
||||
if (lowest != block->right) {
|
||||
lowest->right = block->right;
|
||||
block->right->parent = lowest;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (highest->right)
|
||||
highest = highest->right;
|
||||
|
||||
if (block->right && block->right != lowest) {
|
||||
highest->right = block->right;
|
||||
block->right->parent = highest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MASK_INDEX_MASK 3
|
||||
#define PAGE_MASK_INDEX_SHIFT 10
|
||||
#define PAGE_MASK_MASK 63
|
||||
#define PAGE_MASK_SHIFT 4
|
||||
#define PAGE_MASK_MASK 63
|
||||
#define PAGE_MASK_SHIFT 4
|
||||
|
||||
extern codeblock_t *codeblock;
|
||||
|
||||
extern codeblock_t **codeblock_hash;
|
||||
|
||||
void codegen_init();
|
||||
void codegen_reset();
|
||||
void codegen_block_init(uint32_t phys_addr);
|
||||
void codegen_block_remove();
|
||||
void codegen_block_start_recompile(codeblock_t *block);
|
||||
void codegen_block_end_recompile(codeblock_t *block);
|
||||
void codegen_block_end();
|
||||
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc);
|
||||
void codegen_generate_seg_restore();
|
||||
void codegen_set_op32();
|
||||
void codegen_flush();
|
||||
void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
extern void codegen_init(void);
|
||||
extern void codegen_reset(void);
|
||||
extern void codegen_block_init(uint32_t phys_addr);
|
||||
extern void codegen_block_remove(void);
|
||||
extern void codegen_block_start_recompile(codeblock_t *block);
|
||||
extern void codegen_block_end_recompile(codeblock_t *block);
|
||||
extern void codegen_block_end(void);
|
||||
extern void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc);
|
||||
extern void codegen_generate_seg_restore(void);
|
||||
extern void codegen_set_op32(void);
|
||||
extern void codegen_flush(void);
|
||||
extern void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
|
||||
extern int cpu_block_end;
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
|
||||
extern void (*codegen_timing_start)();
|
||||
extern void (*codegen_timing_start)(void);
|
||||
extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
extern void (*codegen_timing_block_start)();
|
||||
extern void (*codegen_timing_block_end)();
|
||||
extern int (*codegen_timing_jump_cycles)();
|
||||
extern void (*codegen_timing_block_start)(void);
|
||||
extern void (*codegen_timing_block_end)(void);
|
||||
extern int (*codegen_timing_jump_cycles)(void);
|
||||
|
||||
typedef struct codegen_timing_t
|
||||
{
|
||||
void (*start)();
|
||||
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)();
|
||||
void (*block_end)();
|
||||
int (*jump_cycles)();
|
||||
typedef struct codegen_timing_t {
|
||||
void (*start)(void);
|
||||
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)(void);
|
||||
void (*block_end)(void);
|
||||
int (*jump_cycles)(void);
|
||||
} codegen_timing_t;
|
||||
|
||||
extern codegen_timing_t codegen_timing_pentium;
|
||||
@@ -342,53 +314,53 @@ extern int block_pos;
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
static inline void addbyte(uint8_t val)
|
||||
static inline void
|
||||
addbyte(uint8_t val)
|
||||
{
|
||||
codeblock[block_current].data[block_pos++] = val;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
codeblock[block_current].data[block_pos++] = val;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void addword(uint16_t val)
|
||||
static inline void
|
||||
addword(uint16_t val)
|
||||
{
|
||||
uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 2;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
*p = val;
|
||||
block_pos += 2;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void addlong(uint32_t val)
|
||||
static inline void
|
||||
addlong(uint32_t val)
|
||||
{
|
||||
uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 4;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
*p = val;
|
||||
block_pos += 4;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void addquad(uint64_t val)
|
||||
static inline void
|
||||
addquad(uint64_t val)
|
||||
{
|
||||
uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 8;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
*p = val;
|
||||
block_pos += 8;
|
||||
if (block_pos >= BLOCK_MAX) {
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
}
|
||||
|
||||
/*Current physical page of block being recompiled. -1 if no recompilation taking place */
|
||||
extern uint32_t recomp_page;
|
||||
|
||||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern uint32_t op_old_pc;
|
||||
|
||||
/*Set to 1 if flags have been changed in the block being recompiled, and hence
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
enum
|
||||
{
|
||||
ACCREG_cycles = 0,
|
||||
enum {
|
||||
ACCREG_cycles = 0,
|
||||
|
||||
ACCREG_COUNT
|
||||
ACCREG_COUNT
|
||||
};
|
||||
|
||||
struct ir_data_t;
|
||||
|
||||
void codegen_accumulate(int acc_reg, int delta);
|
||||
void codegen_accumulate_flush(void);
|
||||
void codegen_accumulate_reset();
|
||||
void codegen_accumulate_reset(void);
|
||||
|
||||
@@ -9,59 +9,61 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)},
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] = {
|
||||
[ACCREG_cycles] = {0, (uintptr_t) & (cycles)},
|
||||
};
|
||||
|
||||
void codegen_accumulate(int acc_reg, int delta)
|
||||
void
|
||||
codegen_accumulate(int acc_reg, int delta)
|
||||
{
|
||||
acc_regs[acc_reg].count += delta;
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
#ifdef USE_ACYCS
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong(-delta);
|
||||
}
|
||||
}
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0c);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x04);
|
||||
addbyte(0x25);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
addlong(-delta);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
void
|
||||
codegen_accumulate_flush(void)
|
||||
{
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t)cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t) cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
void
|
||||
codegen_accumulate_reset(void)
|
||||
{
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -9,56 +9,58 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_cycles] = {0, (uintptr_t) &(cycles)}
|
||||
int count;
|
||||
uintptr_t dest_reg;
|
||||
} acc_regs[] = {
|
||||
[ACCREG_cycles] = {0, (uintptr_t) & (cycles)}
|
||||
};
|
||||
|
||||
void codegen_accumulate(int acc_reg, int delta)
|
||||
void
|
||||
codegen_accumulate(int acc_reg, int delta)
|
||||
{
|
||||
acc_regs[acc_reg].count += delta;
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
#ifdef USE_ACYCS
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0d);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) &(acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
}
|
||||
}
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
if (delta == -1) {
|
||||
/* -delta = 1 */
|
||||
addbyte(0xff); /*inc dword ptr[&acycs]*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else if (delta == 1) {
|
||||
/* -delta = -1 */
|
||||
addbyte(0xff); /*dec dword ptr[&acycs]*/
|
||||
addbyte(0x0d);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
} else {
|
||||
addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t) (uintptr_t) & (acycs));
|
||||
addlong((uintptr_t) -delta);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(void)
|
||||
void
|
||||
codegen_accumulate_flush(void)
|
||||
{
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t)cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
/* To reduce the size of the generated code, we take advantage of
|
||||
the fact that the target offset points to _cycles within cpu_state,
|
||||
so we can just use our existing infrastracture for variables
|
||||
relative to cpu_state. */
|
||||
addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t) cpu_state_offset(_cycles));
|
||||
addlong(acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
void
|
||||
codegen_accumulate_reset(void)
|
||||
{
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "codegen_ops.h"
|
||||
|
||||
#if defined __amd64__ || defined _M_X64
|
||||
#include "codegen_ops_x86-64.h"
|
||||
# include "codegen_ops_x86-64.h"
|
||||
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86
|
||||
#include "codegen_ops_x86.h"
|
||||
# include "codegen_ops_x86.h"
|
||||
#endif
|
||||
|
||||
#include "codegen_ops_arith.h"
|
||||
@@ -32,8 +32,8 @@
|
||||
#include "codegen_ops_stack.h"
|
||||
#include "codegen_ops_xchg.h"
|
||||
|
||||
RecompOpFn recomp_opcodes[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL,
|
||||
@@ -77,10 +77,11 @@ RecompOpFn recomp_opcodes[512] =
|
||||
/*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_0f[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_0f[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -124,11 +125,11 @@ RecompOpFn recomp_opcodes_0f[512] =
|
||||
/*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
|
||||
/*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
|
||||
/*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
||||
RecompOpFn recomp_opcodes_d8[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_d8[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs,
|
||||
@@ -172,10 +173,11 @@ RecompOpFn recomp_opcodes_d8[512] =
|
||||
/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP,
|
||||
/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR,
|
||||
/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_d9[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_d9[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -219,10 +221,11 @@ RecompOpFn recomp_opcodes_d9[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_da[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_da[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil,
|
||||
@@ -266,10 +269,11 @@ RecompOpFn recomp_opcodes_da[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_db[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_db[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -313,10 +317,11 @@ RecompOpFn recomp_opcodes_db[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_dc[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_dc[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd,
|
||||
@@ -360,10 +365,11 @@ RecompOpFn recomp_opcodes_dc[512] =
|
||||
/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP,
|
||||
/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr,
|
||||
/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_dd[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_dd[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -407,10 +413,11 @@ RecompOpFn recomp_opcodes_dd[512] =
|
||||
/*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_de[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_de[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw,
|
||||
@@ -454,10 +461,11 @@ RecompOpFn recomp_opcodes_de[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP,
|
||||
/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_df[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_df[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -501,10 +509,11 @@ RecompOpFn recomp_opcodes_df[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_REPE[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_REPE[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -548,10 +557,11 @@ RecompOpFn recomp_opcodes_REPE[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_REPNE[512] =
|
||||
{
|
||||
RecompOpFn recomp_opcodes_REPNE[512] = {
|
||||
// clang-format off
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
@@ -595,4 +605,5 @@ RecompOpFn recomp_opcodes_REPNE[512] =
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
@@ -26,21 +26,21 @@ extern RecompOpFn recomp_opcodes_REPNE[512];
|
||||
#define REG_EBP 5
|
||||
#define REG_ESI 6
|
||||
#define REG_EDI 7
|
||||
#define REG_AX 0
|
||||
#define REG_CX 1
|
||||
#define REG_DX 2
|
||||
#define REG_BX 3
|
||||
#define REG_SP 4
|
||||
#define REG_BP 5
|
||||
#define REG_SI 6
|
||||
#define REG_DI 7
|
||||
#define REG_AL 0
|
||||
#define REG_AH 4
|
||||
#define REG_CL 1
|
||||
#define REG_CH 5
|
||||
#define REG_DL 2
|
||||
#define REG_DH 6
|
||||
#define REG_BL 3
|
||||
#define REG_BH 7
|
||||
#define REG_AX 0
|
||||
#define REG_CX 1
|
||||
#define REG_DX 2
|
||||
#define REG_BX 3
|
||||
#define REG_SP 4
|
||||
#define REG_BP 5
|
||||
#define REG_SI 6
|
||||
#define REG_DI 7
|
||||
#define REG_AL 0
|
||||
#define REG_AH 4
|
||||
#define REG_CL 1
|
||||
#define REG_CH 5
|
||||
#define REG_DL 2
|
||||
#define REG_DH 6
|
||||
#define REG_BL 3
|
||||
#define REG_BH 7
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,256 +1,268 @@
|
||||
static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FXCH(opcode & 7);
|
||||
FP_FXCH(opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FLD(opcode & 7);
|
||||
FP_FLD(opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FST(opcode & 7);
|
||||
FP_FST(opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_ENTER();
|
||||
|
||||
FP_FST(opcode & 7);
|
||||
FP_POP();
|
||||
FP_FST(opcode & 7);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
|
||||
FP_LOAD_S();
|
||||
FP_LOAD_S();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
|
||||
FP_LOAD_D();
|
||||
FP_LOAD_D();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
|
||||
FP_LOAD_IW();
|
||||
FP_LOAD_IW();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
|
||||
FP_LOAD_IL();
|
||||
FP_LOAD_IL();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
|
||||
FP_LOAD_IQ();
|
||||
FP_LOAD_IQ();
|
||||
|
||||
codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1;
|
||||
codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1;
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
host_reg = FP_LOAD_REG(0);
|
||||
host_reg = FP_LOAD_REG(0);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2 = 0;
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2 = 0;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
FP_LOAD_REG_D(0, &host_reg1, &host_reg2);
|
||||
FP_LOAD_REG_D(0, &host_reg1, &host_reg2);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
|
||||
#define ropFarith(name, size, load, op) \
|
||||
static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(FPU_ ## name); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
#define ropFarith(name, size, load, op) \
|
||||
static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(FPU_##name); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
|
||||
ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S);
|
||||
ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D);
|
||||
ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW);
|
||||
ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL);
|
||||
|
||||
#define ropFcompare(name, size, load, op) \
|
||||
static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \
|
||||
\
|
||||
FP_POP(); \
|
||||
\
|
||||
return new_pc; \
|
||||
}
|
||||
#define ropFcompare(name, size, load, op) \
|
||||
static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
x86seg *target_seg; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
op_pc--; \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
load(target_seg); \
|
||||
\
|
||||
op(); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t ropF##name##P##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t new_pc = ropF##name##size(opcode, fetchdat, op_32, op_pc, block); \
|
||||
\
|
||||
FP_POP(); \
|
||||
\
|
||||
return new_pc; \
|
||||
}
|
||||
|
||||
ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S);
|
||||
ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D);
|
||||
@@ -326,320 +338,346 @@ static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
return op_pc + 1;
|
||||
}*/
|
||||
|
||||
|
||||
static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, 0, opcode & 7);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, 0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_ADD, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, opcode & 7);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIV, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_DIVR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_MUL, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUB, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
FP_ENTER();
|
||||
FP_OP_REG(FPU_SUBR, opcode & 7, 0);
|
||||
FP_POP();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, 1);
|
||||
FP_POP2();
|
||||
FP_ENTER();
|
||||
FP_COMPARE_REG(0, 1);
|
||||
FP_POP2();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
|
||||
FP_ENTER();
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxs);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
host_reg = FP_LOAD_REG_INT_W(0);
|
||||
host_reg = FP_LOAD_REG_INT_W(0);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
host_reg = FP_LOAD_REG_INT(0);
|
||||
host_reg = FP_LOAD_REG_INT(0);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block);
|
||||
uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return new_pc;
|
||||
return new_pc;
|
||||
}
|
||||
static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2;
|
||||
x86seg *target_seg;
|
||||
int host_reg1, host_reg2;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2);
|
||||
FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
|
||||
FP_POP();
|
||||
FP_POP();
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0);
|
||||
UPDATE_NPXC(0);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.npxc, 0);
|
||||
UPDATE_NPXC(0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
int host_reg;
|
||||
x86seg *target_seg;
|
||||
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
FP_ENTER();
|
||||
op_pc--;
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxc);
|
||||
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_FCHS();
|
||||
FP_ENTER();
|
||||
FP_FCHS();
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
#define opFLDimm(name, v) \
|
||||
static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static double fp_imm = v; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define opFLDimm(name, v) \
|
||||
static uint32_t ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static double fp_imm = v; \
|
||||
\
|
||||
FP_ENTER(); \
|
||||
FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
opFLDimm(1, 1.0)
|
||||
opFLDimm(L2T, 3.3219280948873623)
|
||||
opFLDimm(L2E, 1.4426950408889634);
|
||||
opFLDimm(L2T, 3.3219280948873623)
|
||||
opFLDimm(L2E, 1.4426950408889634);
|
||||
opFLDimm(PI, 3.141592653589793);
|
||||
opFLDimm(EG2, 0.3010299956639812);
|
||||
opFLDimm(Z, 0.0)
|
||||
|
||||
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
FP_ENTER();
|
||||
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
|
||||
FP_ENTER();
|
||||
FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
@@ -1,257 +1,258 @@
|
||||
static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+1+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 1 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
int host_reg = LOAD_REG_L(REG_ECX);
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int host_reg = LOAD_REG_W(REG_CX);
|
||||
TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
if (op_32 & 0x200) {
|
||||
int host_reg = LOAD_REG_L(REG_ECX);
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc + 1 + offset, 0);
|
||||
} else {
|
||||
int host_reg = LOAD_REG_W(REG_CX);
|
||||
TEST_ZERO_JUMP_W(host_reg, op_pc + 1 + offset, 0);
|
||||
}
|
||||
|
||||
return op_pc+1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
int host_reg = LOAD_REG_L(REG_ECX);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int host_reg = LOAD_REG_W(REG_CX);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0);
|
||||
}
|
||||
if (op_32 & 0x200) {
|
||||
int host_reg = LOAD_REG_L(REG_ECX);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc + 1 + offset, 0);
|
||||
} else {
|
||||
int host_reg = LOAD_REG_W(REG_CX);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
TEST_NONZERO_JUMP_W(host_reg, op_pc + 1 + offset, 0);
|
||||
}
|
||||
|
||||
return op_pc+1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
static void
|
||||
BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not )
|
||||
{
|
||||
CALL_FUNC((uintptr_t)CF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
CALL_FUNC((uintptr_t) CF_SET);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
}
|
||||
|
||||
static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
static void
|
||||
BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not )
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
|
||||
if (not)
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) {
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC8:
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res);
|
||||
if (not )
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
CALL_FUNC((uintptr_t)ZF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
}
|
||||
case FLAGS_UNKNOWN:
|
||||
CALL_FUNC((uintptr_t) ZF_SET);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
static void
|
||||
BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not )
|
||||
{
|
||||
CALL_FUNC((uintptr_t)VF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
CALL_FUNC((uintptr_t) VF_SET);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
}
|
||||
|
||||
static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
static void
|
||||
BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not )
|
||||
{
|
||||
CALL_FUNC((uintptr_t)PF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
CALL_FUNC((uintptr_t) PF_SET);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
}
|
||||
|
||||
static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
|
||||
static void
|
||||
BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not )
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN)
|
||||
{
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_DEC8:
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x80);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) {
|
||||
case FLAGS_ZN8:
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_SHL8:
|
||||
case FLAGS_SHR8:
|
||||
case FLAGS_SAR8:
|
||||
case FLAGS_INC8:
|
||||
case FLAGS_DEC8:
|
||||
host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x80);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_DEC16:
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x8000);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
case FLAGS_ZN16:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SHL16:
|
||||
case FLAGS_SHR16:
|
||||
case FLAGS_SAR16:
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_DEC16:
|
||||
host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x8000);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC32:
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x80000000);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
case FLAGS_ZN32:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SHL32:
|
||||
case FLAGS_SHR32:
|
||||
case FLAGS_SAR32:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_DEC32:
|
||||
host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res);
|
||||
AND_HOST_REG_IMM(host_reg, 0x80000000);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt);
|
||||
break;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
CALL_FUNC((uintptr_t)NF_SET);
|
||||
if (not)
|
||||
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
|
||||
break;
|
||||
}
|
||||
case FLAGS_UNKNOWN:
|
||||
CALL_FUNC((uintptr_t) NF_SET);
|
||||
if (not )
|
||||
TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
else
|
||||
TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define ropBRANCH(name, func, not ) \
|
||||
static uint32_t rop##name(uint8_t opcode, uint32_t fetchdat, \
|
||||
uint32_t op_32, uint32_t op_pc, \
|
||||
codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fetchdat & 0xff; \
|
||||
\
|
||||
if (offset & 0x80) \
|
||||
offset |= 0xffffff00; \
|
||||
\
|
||||
func(1, op_pc, offset, not ); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
static uint32_t rop##name##_w(uint8_t opcode, \
|
||||
uint32_t fetchdat, uint32_t op_32, \
|
||||
uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fetchdat & 0xffff; \
|
||||
\
|
||||
if (offset & 0x8000) \
|
||||
offset |= 0xffff0000; \
|
||||
\
|
||||
func(2, op_pc, offset, not ); \
|
||||
\
|
||||
return op_pc + 2; \
|
||||
} \
|
||||
static uint32_t rop##name##_l(uint8_t opcode, \
|
||||
uint32_t fetchdat, uint32_t op_32, \
|
||||
uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fastreadl(cs + op_pc); \
|
||||
\
|
||||
func(4, op_pc, offset, not ); \
|
||||
\
|
||||
return op_pc + 4; \
|
||||
}
|
||||
|
||||
#define ropBRANCH(name, func, not) \
|
||||
static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \
|
||||
uint32_t op_32, uint32_t op_pc, \
|
||||
codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fetchdat & 0xff; \
|
||||
\
|
||||
if (offset & 0x80) \
|
||||
offset |= 0xffffff00; \
|
||||
\
|
||||
func(1, op_pc, offset, not); \
|
||||
\
|
||||
return op_pc+1; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _w(uint8_t opcode, \
|
||||
uint32_t fetchdat, uint32_t op_32, \
|
||||
uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fetchdat & 0xffff; \
|
||||
\
|
||||
if (offset & 0x8000) \
|
||||
offset |= 0xffff0000; \
|
||||
\
|
||||
func(2, op_pc, offset, not); \
|
||||
\
|
||||
return op_pc+2; \
|
||||
} \
|
||||
static uint32_t rop ## name ## _l(uint8_t opcode, \
|
||||
uint32_t fetchdat, uint32_t op_32, \
|
||||
uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
uint32_t offset = fastreadl(cs + op_pc); \
|
||||
\
|
||||
func(4, op_pc, offset, not); \
|
||||
\
|
||||
return op_pc+4; \
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
ropBRANCH(JB, BRANCH_COND_B, 0)
|
||||
ropBRANCH(JNB, BRANCH_COND_B, 1)
|
||||
ropBRANCH(JE, BRANCH_COND_E, 0)
|
||||
@@ -268,3 +269,4 @@ ropBRANCH(JLE, BRANCH_COND_LE, 0)
|
||||
ropBRANCH(JNLE, BRANCH_COND_LE, 1)
|
||||
ropBRANCH(JBE, BRANCH_COND_BE, 0)
|
||||
ropBRANCH(JNBE, BRANCH_COND_BE, 1)
|
||||
// clang-format on
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +1,263 @@
|
||||
static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
CLEAR_BITS((uintptr_t) &cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
SET_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
SET_BITS((uintptr_t) &cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t) &cpu_state.flags, I_FLAG);
|
||||
#ifdef CHECK_INT
|
||||
CLEAR_BITS((uintptr_t)&pic_pending, 0xffffffff);
|
||||
CLEAR_BITS((uintptr_t) &pic_pending, 0xffffffff);
|
||||
#endif
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
SET_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
return op_pc;
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
SET_BITS((uintptr_t) &cpu_state.flags, I_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
return 0;
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
return 0;
|
||||
|
||||
CALL_FUNC((uintptr_t)flags_rebuild_c);
|
||||
CALL_FUNC((uintptr_t) flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
else {
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg);
|
||||
}
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg);
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
}
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_B(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t codegen_temp;
|
||||
static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t)flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
{
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_W(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
return op_pc + 1;
|
||||
}
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t) flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
else {
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00) {
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
host_reg = 0;
|
||||
} else {
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_W(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_W(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &codegen_temp);
|
||||
STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
return op_pc + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int host_reg;
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t)flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
else
|
||||
{
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00)
|
||||
{
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_L(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else
|
||||
{
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
return op_pc + 1;
|
||||
}
|
||||
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0x30) == 0x00)
|
||||
CALL_FUNC((uintptr_t) flags_rebuild_c);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
else {
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
if ((fetchdat & 0x30) != 0x00) {
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
host_reg = 0;
|
||||
} else {
|
||||
SAVE_EA();
|
||||
MEM_CHECK_WRITE_L(target_seg);
|
||||
host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg);
|
||||
}
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x00: /*INC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
ADD_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
case 0x08: /*DEC*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM(host_reg, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg);
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
else {
|
||||
LOAD_EA();
|
||||
MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg);
|
||||
}
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
|
||||
case 0x10: /*CALL*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
host_reg = LOAD_VAR_L((uintptr_t) &codegen_temp);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if (!host_reg)
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
return op_pc + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,277 +1,267 @@
|
||||
static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg1, host_reg2 = 0;
|
||||
int host_reg1, host_reg2 = 0;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2);
|
||||
LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 7);
|
||||
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
}
|
||||
MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg1, host_reg2;
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
int host_reg1, host_reg2;
|
||||
|
||||
LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2);
|
||||
}
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg);
|
||||
STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
host_reg = LOAD_MMX_D((fetchdat >> 3) & 7);
|
||||
host_reg = LOAD_MMX_D((fetchdat >> 3) & 7);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 3);
|
||||
CHECK_SEG_WRITE(target_seg);
|
||||
CHECK_SEG_LIMITS(target_seg, 3);
|
||||
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
}
|
||||
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
MMX_ENTER();
|
||||
MMX_ENTER();
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
if ((fetchdat & 0xc0) == 0xc0) {
|
||||
int host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg);
|
||||
} else {
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
|
||||
CHECK_SEG_READ(target_seg);
|
||||
CHECK_SEG_READ(target_seg);
|
||||
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, 0);
|
||||
}
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
STORE_MMX_LQ((fetchdat >> 3) & 7, 0);
|
||||
}
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
#define MMX_OP(name, func) \
|
||||
static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int src_reg1, src_reg2; \
|
||||
int xmm_src, xmm_dst; \
|
||||
\
|
||||
MMX_ENTER(); \
|
||||
\
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
if ((fetchdat & 0xc0) == 0xc0) { \
|
||||
xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \
|
||||
} else { \
|
||||
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
\
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
CHECK_SEG_READ(target_seg); \
|
||||
\
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg); \
|
||||
src_reg1 = LOAD_Q_REG_1; \
|
||||
src_reg2 = LOAD_Q_REG_2; \
|
||||
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
|
||||
MEM_LOAD_ADDR_EA_Q(target_seg); \
|
||||
src_reg1 = LOAD_Q_REG_1; \
|
||||
src_reg2 = LOAD_Q_REG_2; \
|
||||
xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \
|
||||
} \
|
||||
xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \
|
||||
func(xmm_dst, xmm_src); \
|
||||
func(xmm_dst, xmm_src); \
|
||||
STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
}
|
||||
|
||||
MMX_OP(ropPAND, MMX_AND)
|
||||
MMX_OP(ropPAND, MMX_AND)
|
||||
MMX_OP(ropPANDN, MMX_ANDN)
|
||||
MMX_OP(ropPOR, MMX_OR)
|
||||
MMX_OP(ropPXOR, MMX_XOR)
|
||||
MMX_OP(ropPOR, MMX_OR)
|
||||
MMX_OP(ropPXOR, MMX_XOR)
|
||||
|
||||
MMX_OP(ropPADDB, MMX_ADDB)
|
||||
MMX_OP(ropPADDW, MMX_ADDW)
|
||||
MMX_OP(ropPADDD, MMX_ADDD)
|
||||
MMX_OP(ropPADDSB, MMX_ADDSB)
|
||||
MMX_OP(ropPADDSW, MMX_ADDSW)
|
||||
MMX_OP(ropPADDUSB, MMX_ADDUSB)
|
||||
MMX_OP(ropPADDUSW, MMX_ADDUSW)
|
||||
MMX_OP(ropPADDB, MMX_ADDB)
|
||||
MMX_OP(ropPADDW, MMX_ADDW)
|
||||
MMX_OP(ropPADDD, MMX_ADDD)
|
||||
MMX_OP(ropPADDSB, MMX_ADDSB)
|
||||
MMX_OP(ropPADDSW, MMX_ADDSW)
|
||||
MMX_OP(ropPADDUSB, MMX_ADDUSB)
|
||||
MMX_OP(ropPADDUSW, MMX_ADDUSW)
|
||||
|
||||
MMX_OP(ropPSUBB, MMX_SUBB)
|
||||
MMX_OP(ropPSUBW, MMX_SUBW)
|
||||
MMX_OP(ropPSUBD, MMX_SUBD)
|
||||
MMX_OP(ropPSUBSB, MMX_SUBSB)
|
||||
MMX_OP(ropPSUBSW, MMX_SUBSW)
|
||||
MMX_OP(ropPSUBUSB, MMX_SUBUSB)
|
||||
MMX_OP(ropPSUBUSW, MMX_SUBUSW)
|
||||
MMX_OP(ropPSUBB, MMX_SUBB)
|
||||
MMX_OP(ropPSUBW, MMX_SUBW)
|
||||
MMX_OP(ropPSUBD, MMX_SUBD)
|
||||
MMX_OP(ropPSUBSB, MMX_SUBSB)
|
||||
MMX_OP(ropPSUBSW, MMX_SUBSW)
|
||||
MMX_OP(ropPSUBUSB, MMX_SUBUSB)
|
||||
MMX_OP(ropPSUBUSW, MMX_SUBUSW)
|
||||
|
||||
MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW);
|
||||
MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD);
|
||||
MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ);
|
||||
MMX_OP(ropPACKSSWB, MMX_PACKSSWB);
|
||||
MMX_OP(ropPCMPGTB, MMX_PCMPGTB);
|
||||
MMX_OP(ropPCMPGTW, MMX_PCMPGTW);
|
||||
MMX_OP(ropPCMPGTD, MMX_PCMPGTD);
|
||||
MMX_OP(ropPACKUSWB, MMX_PACKUSWB);
|
||||
MMX_OP(ropPACKSSWB, MMX_PACKSSWB);
|
||||
MMX_OP(ropPCMPGTB, MMX_PCMPGTB);
|
||||
MMX_OP(ropPCMPGTW, MMX_PCMPGTW);
|
||||
MMX_OP(ropPCMPGTD, MMX_PCMPGTD);
|
||||
MMX_OP(ropPACKUSWB, MMX_PACKUSWB);
|
||||
MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW);
|
||||
MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD);
|
||||
MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ);
|
||||
MMX_OP(ropPACKSSDW, MMX_PACKSSDW);
|
||||
MMX_OP(ropPACKSSDW, MMX_PACKSSDW);
|
||||
|
||||
MMX_OP(ropPCMPEQB, MMX_PCMPEQB);
|
||||
MMX_OP(ropPCMPEQW, MMX_PCMPEQW);
|
||||
MMX_OP(ropPCMPEQD, MMX_PCMPEQD);
|
||||
MMX_OP(ropPCMPEQB, MMX_PCMPEQB);
|
||||
MMX_OP(ropPCMPEQW, MMX_PCMPEQW);
|
||||
MMX_OP(ropPCMPEQD, MMX_PCMPEQD);
|
||||
|
||||
MMX_OP(ropPSRLW, MMX_PSRLW)
|
||||
MMX_OP(ropPSRLD, MMX_PSRLD)
|
||||
MMX_OP(ropPSRLQ, MMX_PSRLQ)
|
||||
MMX_OP(ropPSRAW, MMX_PSRAW)
|
||||
MMX_OP(ropPSRAD, MMX_PSRAD)
|
||||
MMX_OP(ropPSLLW, MMX_PSLLW)
|
||||
MMX_OP(ropPSLLD, MMX_PSLLD)
|
||||
MMX_OP(ropPSLLQ, MMX_PSLLQ)
|
||||
MMX_OP(ropPSRLW, MMX_PSRLW)
|
||||
MMX_OP(ropPSRLD, MMX_PSRLD)
|
||||
MMX_OP(ropPSRLQ, MMX_PSRLQ)
|
||||
MMX_OP(ropPSRAW, MMX_PSRAW)
|
||||
MMX_OP(ropPSRAD, MMX_PSRAD)
|
||||
MMX_OP(ropPSLLW, MMX_PSLLW)
|
||||
MMX_OP(ropPSLLD, MMX_PSLLD)
|
||||
MMX_OP(ropPSLLQ, MMX_PSLLQ)
|
||||
|
||||
MMX_OP(ropPMULLW, MMX_PMULLW);
|
||||
MMX_OP(ropPMULHW, MMX_PMULHW);
|
||||
MMX_OP(ropPMADDWD, MMX_PMADDWD);
|
||||
MMX_OP(ropPMULLW, MMX_PMULLW);
|
||||
MMX_OP(ropPMULHW, MMX_PMULHW);
|
||||
MMX_OP(ropPMADDWD, MMX_PMADDWD);
|
||||
|
||||
static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*PSRLW*/
|
||||
MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*PSRLD*/
|
||||
MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*PSRLQ*/
|
||||
MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAQ*/
|
||||
MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLQ*/
|
||||
MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
codegen_mmx_entered = 0;
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x10: /*PSRLW*/
|
||||
MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t
|
||||
ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x10: /*PSRLD*/
|
||||
MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t
|
||||
ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int xmm_dst;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0x08) || !(fetchdat & 0x30))
|
||||
return 0;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7);
|
||||
switch (fetchdat & 0x38) {
|
||||
case 0x10: /*PSRLQ*/
|
||||
MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x20: /*PSRAQ*/
|
||||
MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
case 0x30: /*PSLLQ*/
|
||||
MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff);
|
||||
break;
|
||||
}
|
||||
STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
codegen_mmx_entered = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +1,129 @@
|
||||
#define SHIFT(size, size2, res_store, immediate) \
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
{ \
|
||||
reg = LOAD_REG_ ## size(fetchdat & 7); \
|
||||
if (immediate) count = (fetchdat >> 8) & 0x1f; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
SAVE_EA(); \
|
||||
MEM_CHECK_WRITE_ ## size(target_seg); \
|
||||
reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \
|
||||
if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \
|
||||
} \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \
|
||||
\
|
||||
res_store((uintptr_t)&cpu_state.flags_op1, reg); \
|
||||
\
|
||||
switch (fetchdat & 0x38) \
|
||||
{ \
|
||||
case 0x20: case 0x30: /*SHL*/ \
|
||||
SHL_ ## size ## _IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x28: /*SHR*/ \
|
||||
SHR_ ## size ## _IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x38: /*SAR*/ \
|
||||
SAR_ ## size ## _IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
res_store((uintptr_t)&cpu_state.flags_res, reg); \
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
STORE_REG_ ## size ## _RELEASE(reg); \
|
||||
else \
|
||||
{ \
|
||||
LOAD_EA(); \
|
||||
MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \
|
||||
}
|
||||
#define SHIFT(size, size2, res_store, immediate) \
|
||||
if ((fetchdat & 0xc0) == 0xc0) { \
|
||||
reg = LOAD_REG_##size(fetchdat & 7); \
|
||||
if (immediate) \
|
||||
count = (fetchdat >> 8) & 0x1f; \
|
||||
} else { \
|
||||
target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
SAVE_EA(); \
|
||||
MEM_CHECK_WRITE_##size(target_seg); \
|
||||
reg = MEM_LOAD_ADDR_EA_##size##_NO_ABRT(target_seg); \
|
||||
if (immediate) \
|
||||
count = fastreadb(cs + op_pc + 1) & 0x1f; \
|
||||
} \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, count); \
|
||||
\
|
||||
res_store((uintptr_t) &cpu_state.flags_op1, reg); \
|
||||
\
|
||||
switch (fetchdat & 0x38) { \
|
||||
case 0x20: \
|
||||
case 0x30: /*SHL*/ \
|
||||
SHL_##size##_IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHL##size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x28: /*SHR*/ \
|
||||
SHR_##size##_IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHR##size2); \
|
||||
break; \
|
||||
\
|
||||
case 0x38: /*SAR*/ \
|
||||
SAR_##size##_IMM(reg, count); \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SAR##size2); \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
res_store((uintptr_t) &cpu_state.flags_res, reg); \
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
STORE_REG_##size##_RELEASE(reg); \
|
||||
else { \
|
||||
LOAD_EA(); \
|
||||
MEM_STORE_ADDR_EA_##size##_NO_ABRT(target_seg, reg); \
|
||||
}
|
||||
|
||||
static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1);
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1);
|
||||
|
||||
return op_pc + 2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1);
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1);
|
||||
|
||||
return op_pc + 2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 1);
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 1);
|
||||
|
||||
return op_pc + 2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
||||
static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0);
|
||||
SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0);
|
||||
SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
x86seg *target_seg = NULL;
|
||||
int count = 1;
|
||||
int reg;
|
||||
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 0);
|
||||
SHIFT(L, 32, STORE_HOST_REG_ADDR, 0);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
@@ -1,238 +1,254 @@
|
||||
static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_L(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_L(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t imm = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
uint16_t imm = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+2;
|
||||
return op_pc + 2;
|
||||
}
|
||||
static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t imm = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
uint32_t imm = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+4;
|
||||
return op_pc + 4;
|
||||
}
|
||||
|
||||
static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
uint16_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
|
||||
if (imm & 0x80)
|
||||
imm |= 0xff00;
|
||||
if (imm & 0x80)
|
||||
imm |= 0xff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
uint32_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
|
||||
if (imm & 0x80)
|
||||
imm |= 0xffffff00;
|
||||
if (imm & 0x80)
|
||||
imm |= 0xffffff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
SP_MODIFY(2);
|
||||
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
SP_MODIFY(2);
|
||||
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
SP_MODIFY(4);
|
||||
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
SP_MODIFY(4);
|
||||
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(2);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(4);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(2+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(2 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(4+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0);
|
||||
SP_MODIFY(4 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc+2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 2);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc+4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 4);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
|
||||
ADD_HOST_REG_IMM_W(host_reg, 2);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
|
||||
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
|
||||
ADD_HOST_REG_IMM_W(host_reg, 2);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
|
||||
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
|
||||
ADD_HOST_REG_IMM(host_reg, 4);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
|
||||
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
|
||||
ADD_HOST_REG_IMM(host_reg, 4);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
|
||||
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
|
||||
|
||||
return op_pc;
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
#define ROP_PUSH_SEG(seg) \
|
||||
static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-2); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-4); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define ROP_PUSH_SEG(seg) \
|
||||
static uint32_t ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-2); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int host_reg; \
|
||||
\
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-4); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t) &seg); \
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
ROP_PUSH_SEG(CS)
|
||||
ROP_PUSH_SEG(DS)
|
||||
@@ -241,27 +257,27 @@ ROP_PUSH_SEG(FS)
|
||||
ROP_PUSH_SEG(GS)
|
||||
ROP_PUSH_SEG(SS)
|
||||
|
||||
#define ROP_POP_SEG(seg, rseg) \
|
||||
static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define ROP_POP_SEG(seg, rseg) \
|
||||
static uint32_t ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
static uint32_t ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
ROP_POP_SEG(DS, cpu_state.seg_ds)
|
||||
ROP_POP_SEG(ES, cpu_state.seg_es)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,16 @@
|
||||
#define OP_XCHG_AX_(reg) \
|
||||
static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int ax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
ax_reg = LOAD_REG_W(REG_AX); \
|
||||
host_reg = LOAD_REG_W(REG_ ## reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define OP_XCHG_AX_(reg) \
|
||||
static uint32_t ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int ax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
ax_reg = LOAD_REG_W(REG_AX); \
|
||||
host_reg = LOAD_REG_W(REG_##reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
OP_XCHG_AX_(BX)
|
||||
OP_XCHG_AX_(CX)
|
||||
@@ -20,19 +20,19 @@ OP_XCHG_AX_(DI)
|
||||
OP_XCHG_AX_(SP)
|
||||
OP_XCHG_AX_(BP)
|
||||
|
||||
#define OP_XCHG_EAX_(reg) \
|
||||
static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int eax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
eax_reg = LOAD_REG_L(REG_EAX); \
|
||||
host_reg = LOAD_REG_L(REG_ ## reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
#define OP_XCHG_EAX_(reg) \
|
||||
static uint32_t ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
|
||||
{ \
|
||||
int eax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
eax_reg = LOAD_REG_L(REG_EAX); \
|
||||
host_reg = LOAD_REG_L(REG_##reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
OP_XCHG_EAX_(EBX)
|
||||
OP_XCHG_EAX_(ECX)
|
||||
@@ -42,48 +42,51 @@ OP_XCHG_EAX_(EDI)
|
||||
OP_XCHG_EAX_(ESP)
|
||||
OP_XCHG_EAX_(EBP)
|
||||
|
||||
static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_B(fetchdat & 7);
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7);
|
||||
dst_reg = LOAD_REG_B(fetchdat & 7);
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_W(fetchdat & 7);
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7);
|
||||
dst_reg = LOAD_REG_W(fetchdat & 7);
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
static uint32_t
|
||||
ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_L(fetchdat & 7);
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7);
|
||||
dst_reg = LOAD_REG_L(fetchdat & 7);
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,23 @@
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
#define HASH(l) ((l) &0x1ffff)
|
||||
|
||||
#define BLOCK_EXIT_OFFSET 0x7e0
|
||||
#ifdef OLD_GPF
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
#else
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12)
|
||||
#endif
|
||||
|
||||
#define BLOCK_MAX 1620
|
||||
|
||||
enum
|
||||
{
|
||||
OP_RET = 0xc3
|
||||
enum {
|
||||
OP_RET = 0xc3
|
||||
};
|
||||
|
||||
#define NR_HOST_REGS 4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,23 @@
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
#define BLOCK_SIZE 0x4000
|
||||
#define BLOCK_MASK 0x3fff
|
||||
#define BLOCK_START 0
|
||||
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
#define HASH_SIZE 0x20000
|
||||
#define HASH_MASK 0x1ffff
|
||||
|
||||
#define HASH(l) ((l) & 0x1ffff)
|
||||
#define HASH(l) ((l) &0x1ffff)
|
||||
|
||||
#define BLOCK_EXIT_OFFSET 0x7f0
|
||||
#ifdef OLD_GPF
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
|
||||
#else
|
||||
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14)
|
||||
# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14)
|
||||
#endif
|
||||
|
||||
#define BLOCK_MAX 1720
|
||||
|
||||
enum
|
||||
{
|
||||
OP_RET = 0xc3
|
||||
enum {
|
||||
OP_RET = 0xc3
|
||||
};
|
||||
|
||||
#define NR_HOST_REGS 4
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
# 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
# running old operating systems and software designed for IBM
|
||||
# PC systems and compatibles from 1981 through fairly recent
|
||||
# system designs based on the PCI bus.
|
||||
#
|
||||
# This file is part of the 86Box distribution.
|
||||
# This file is part of the 86Box distribution.
|
||||
#
|
||||
# CMake build script.
|
||||
# CMake build script.
|
||||
#
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
# Authors: David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
#
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
# Copyright 2020,2021 David Hrdlička.
|
||||
#
|
||||
|
||||
if(DYNAREC)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,34 +30,33 @@
|
||||
same page).
|
||||
*/
|
||||
|
||||
typedef struct codeblock_t
|
||||
{
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t phys, phys_2;
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
uint8_t ins;
|
||||
uint8_t TOP;
|
||||
typedef struct codeblock_t {
|
||||
uint32_t pc;
|
||||
uint32_t _cs;
|
||||
uint32_t phys, phys_2;
|
||||
uint16_t status;
|
||||
uint16_t flags;
|
||||
uint8_t ins;
|
||||
uint8_t TOP;
|
||||
|
||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
uint16_t parent, left, right;
|
||||
/*Pointers for codeblock tree, used to search for blocks when hash lookup
|
||||
fails.*/
|
||||
uint16_t parent, left, right;
|
||||
|
||||
uint8_t *data;
|
||||
uint8_t *data;
|
||||
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
uint16_t prev, next;
|
||||
uint16_t prev_2, next_2;
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
uint16_t prev, next;
|
||||
uint16_t prev_2, next_2;
|
||||
|
||||
/*First mem_block_t used by this block. Any subsequent mem_block_ts
|
||||
will be in the list starting at head_mem_block->next.*/
|
||||
struct mem_block_t *head_mem_block;
|
||||
/*First mem_block_t used by this block. Any subsequent mem_block_ts
|
||||
will be in the list starting at head_mem_block->next.*/
|
||||
struct mem_block_t *head_mem_block;
|
||||
} codeblock_t;
|
||||
|
||||
extern codeblock_t *codeblock;
|
||||
@@ -83,262 +82,233 @@ extern uint8_t *block_write_data;
|
||||
/*Code block is not inlining immediate parameters, parameters must be fetched from memory*/
|
||||
#define CODEBLOCK_NO_IMMEDIATES 0x80
|
||||
|
||||
#define BLOCK_PC_INVALID 0xffffffff
|
||||
#define BLOCK_PC_INVALID 0xffffffff
|
||||
|
||||
#define BLOCK_INVALID 0
|
||||
#define BLOCK_INVALID 0
|
||||
|
||||
static inline int get_block_nr(codeblock_t *block)
|
||||
static inline int
|
||||
get_block_nr(codeblock_t *block)
|
||||
{
|
||||
return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t);
|
||||
return ((uintptr_t) block - (uintptr_t) codeblock) / sizeof(codeblock_t);
|
||||
}
|
||||
|
||||
static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
static inline codeblock_t *
|
||||
codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
{
|
||||
codeblock_t *block;
|
||||
uint64_t a = _cs | ((uint64_t)phys << 32);
|
||||
codeblock_t *block;
|
||||
uint64_t a = _cs | ((uint64_t) phys << 32);
|
||||
|
||||
if (!pages[phys >> 12].head)
|
||||
return NULL;
|
||||
if (!pages[phys >> 12].head)
|
||||
return NULL;
|
||||
|
||||
block = &codeblock[pages[phys >> 12].head];
|
||||
while (block)
|
||||
{
|
||||
uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32);
|
||||
if (a == block_cmp)
|
||||
{
|
||||
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
||||
break;
|
||||
}
|
||||
if (a < block_cmp)
|
||||
block = block->left ? &codeblock[block->left] : NULL;
|
||||
else
|
||||
block = block->right ? &codeblock[block->right] : NULL;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head];
|
||||
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
||||
|
||||
if (!pages[new_block->phys >> 12].head)
|
||||
{
|
||||
pages[new_block->phys >> 12].head = get_block_nr(new_block);
|
||||
new_block->parent = new_block->left = new_block->right = BLOCK_INVALID;
|
||||
block = &codeblock[pages[phys >> 12].head];
|
||||
while (block) {
|
||||
uint64_t block_cmp = block->_cs | ((uint64_t) block->phys << 32);
|
||||
if (a == block_cmp) {
|
||||
if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)))
|
||||
break;
|
||||
}
|
||||
if (a < block_cmp)
|
||||
block = block->left ? &codeblock[block->left] : NULL;
|
||||
else
|
||||
{
|
||||
codeblock_t *old_block = NULL;
|
||||
uint64_t old_block_cmp = 0;
|
||||
block = block->right ? &codeblock[block->right] : NULL;
|
||||
}
|
||||
|
||||
while (block)
|
||||
{
|
||||
old_block = block;
|
||||
old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32);
|
||||
|
||||
if (a < old_block_cmp)
|
||||
block = block->left ? &codeblock[block->left] : NULL;
|
||||
else
|
||||
block = block->right ? &codeblock[block->right] : NULL;
|
||||
}
|
||||
|
||||
if (a < old_block_cmp)
|
||||
old_block->left = get_block_nr(new_block);
|
||||
else
|
||||
old_block->right = get_block_nr(new_block);
|
||||
|
||||
new_block->parent = get_block_nr(old_block);
|
||||
new_block->left = new_block->right = BLOCK_INVALID;
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
static inline void codeblock_tree_delete(codeblock_t *block)
|
||||
static inline void
|
||||
codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
uint16_t parent_nr = block->parent;
|
||||
codeblock_t *parent;
|
||||
codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head];
|
||||
uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32);
|
||||
|
||||
if (block->parent)
|
||||
parent = &codeblock[block->parent];
|
||||
if (!pages[new_block->phys >> 12].head) {
|
||||
pages[new_block->phys >> 12].head = get_block_nr(new_block);
|
||||
new_block->parent = new_block->left = new_block->right = BLOCK_INVALID;
|
||||
} else {
|
||||
codeblock_t *old_block = NULL;
|
||||
uint64_t old_block_cmp = 0;
|
||||
|
||||
while (block) {
|
||||
old_block = block;
|
||||
old_block_cmp = old_block->_cs | ((uint64_t) old_block->phys << 32);
|
||||
|
||||
if (a < old_block_cmp)
|
||||
block = block->left ? &codeblock[block->left] : NULL;
|
||||
else
|
||||
block = block->right ? &codeblock[block->right] : NULL;
|
||||
}
|
||||
|
||||
if (a < old_block_cmp)
|
||||
old_block->left = get_block_nr(new_block);
|
||||
else
|
||||
parent = NULL;
|
||||
old_block->right = get_block_nr(new_block);
|
||||
|
||||
if (!block->left && !block->right)
|
||||
{
|
||||
/*Easy case - remove from parent*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = BLOCK_INVALID;
|
||||
else
|
||||
{
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr)
|
||||
parent->left = BLOCK_INVALID;
|
||||
if (parent->right == block_nr)
|
||||
parent->right = BLOCK_INVALID;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!block->left)
|
||||
{
|
||||
/*Only right node*/
|
||||
if (!parent_nr)
|
||||
{
|
||||
pages[block->phys >> 12].head = block->right;
|
||||
codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr)
|
||||
{
|
||||
parent->left = block->right;
|
||||
codeblock[parent->left].parent = parent_nr;
|
||||
}
|
||||
if (parent->right == block_nr)
|
||||
{
|
||||
parent->right = block->right;
|
||||
codeblock[parent->right].parent = parent_nr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (!block->right)
|
||||
{
|
||||
/*Only left node*/
|
||||
if (!parent_nr)
|
||||
{
|
||||
pages[block->phys >> 12].head = block->left;
|
||||
codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr)
|
||||
{
|
||||
parent->left = block->left;
|
||||
codeblock[parent->left].parent = parent_nr;
|
||||
}
|
||||
if (parent->right == block_nr)
|
||||
{
|
||||
parent->right = block->left;
|
||||
codeblock[parent->right].parent = parent_nr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Difficult case - node has two children. Walk right child to find lowest node*/
|
||||
codeblock_t *lowest = &codeblock[block->right], *highest;
|
||||
codeblock_t *old_parent;
|
||||
uint16_t lowest_nr;
|
||||
|
||||
while (lowest->left)
|
||||
lowest = &codeblock[lowest->left];
|
||||
lowest_nr = get_block_nr(lowest);
|
||||
|
||||
old_parent = &codeblock[lowest->parent];
|
||||
|
||||
/*Replace deleted node with lowest node*/
|
||||
if (!parent_nr)
|
||||
pages[block->phys >> 12].head = lowest_nr;
|
||||
else
|
||||
{
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr)
|
||||
parent->left = lowest_nr;
|
||||
if (parent->right == block_nr)
|
||||
parent->right = lowest_nr;
|
||||
}
|
||||
|
||||
lowest->parent = parent_nr;
|
||||
lowest->left = block->left;
|
||||
if (lowest->left)
|
||||
codeblock[lowest->left].parent = lowest_nr;
|
||||
|
||||
old_parent->left = BLOCK_INVALID;
|
||||
|
||||
highest = &codeblock[lowest->right];
|
||||
if (!lowest->right)
|
||||
{
|
||||
if (lowest_nr != block->right)
|
||||
{
|
||||
lowest->right = block->right;
|
||||
codeblock[block->right].parent = lowest_nr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (highest->right)
|
||||
highest = &codeblock[highest->right];
|
||||
|
||||
if (block->right && block->right != lowest_nr)
|
||||
{
|
||||
highest->right = block->right;
|
||||
codeblock[block->right].parent = get_block_nr(highest);
|
||||
}
|
||||
}
|
||||
new_block->parent = get_block_nr(old_block);
|
||||
new_block->left = new_block->right = BLOCK_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MASK_MASK 63
|
||||
static inline void
|
||||
codeblock_tree_delete(codeblock_t *block)
|
||||
{
|
||||
uint16_t parent_nr = block->parent;
|
||||
codeblock_t *parent;
|
||||
|
||||
if (block->parent)
|
||||
parent = &codeblock[block->parent];
|
||||
else
|
||||
parent = NULL;
|
||||
|
||||
if (!block->left && !block->right) {
|
||||
/*Easy case - remove from parent*/
|
||||
if (!parent)
|
||||
pages[block->phys >> 12].head = BLOCK_INVALID;
|
||||
else {
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr)
|
||||
parent->left = BLOCK_INVALID;
|
||||
if (parent->right == block_nr)
|
||||
parent->right = BLOCK_INVALID;
|
||||
}
|
||||
return;
|
||||
} else if (!block->left) {
|
||||
/*Only right node*/
|
||||
if (!parent_nr) {
|
||||
pages[block->phys >> 12].head = block->right;
|
||||
codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID;
|
||||
} else {
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr) {
|
||||
parent->left = block->right;
|
||||
codeblock[parent->left].parent = parent_nr;
|
||||
}
|
||||
if (parent->right == block_nr) {
|
||||
parent->right = block->right;
|
||||
codeblock[parent->right].parent = parent_nr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (!block->right) {
|
||||
/*Only left node*/
|
||||
if (!parent_nr) {
|
||||
pages[block->phys >> 12].head = block->left;
|
||||
codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID;
|
||||
} else {
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr) {
|
||||
parent->left = block->left;
|
||||
codeblock[parent->left].parent = parent_nr;
|
||||
}
|
||||
if (parent->right == block_nr) {
|
||||
parent->right = block->left;
|
||||
codeblock[parent->right].parent = parent_nr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
/*Difficult case - node has two children. Walk right child to find lowest node*/
|
||||
codeblock_t *lowest = &codeblock[block->right], *highest;
|
||||
codeblock_t *old_parent;
|
||||
uint16_t lowest_nr;
|
||||
|
||||
while (lowest->left)
|
||||
lowest = &codeblock[lowest->left];
|
||||
lowest_nr = get_block_nr(lowest);
|
||||
|
||||
old_parent = &codeblock[lowest->parent];
|
||||
|
||||
/*Replace deleted node with lowest node*/
|
||||
if (!parent_nr)
|
||||
pages[block->phys >> 12].head = lowest_nr;
|
||||
else {
|
||||
uint16_t block_nr = get_block_nr(block);
|
||||
|
||||
if (parent->left == block_nr)
|
||||
parent->left = lowest_nr;
|
||||
if (parent->right == block_nr)
|
||||
parent->right = lowest_nr;
|
||||
}
|
||||
|
||||
lowest->parent = parent_nr;
|
||||
lowest->left = block->left;
|
||||
if (lowest->left)
|
||||
codeblock[lowest->left].parent = lowest_nr;
|
||||
|
||||
old_parent->left = BLOCK_INVALID;
|
||||
|
||||
highest = &codeblock[lowest->right];
|
||||
if (!lowest->right) {
|
||||
if (lowest_nr != block->right) {
|
||||
lowest->right = block->right;
|
||||
codeblock[block->right].parent = lowest_nr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
while (highest->right)
|
||||
highest = &codeblock[highest->right];
|
||||
|
||||
if (block->right && block->right != lowest_nr) {
|
||||
highest->right = block->right;
|
||||
codeblock[block->right].parent = get_block_nr(highest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define PAGE_MASK_MASK 63
|
||||
#define PAGE_MASK_SHIFT 6
|
||||
|
||||
void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len);
|
||||
|
||||
static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len)
|
||||
static inline void
|
||||
codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len)
|
||||
{
|
||||
if (len == 1)
|
||||
{
|
||||
if (block->flags & CODEBLOCK_BYTE_MASK)
|
||||
{
|
||||
if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/
|
||||
block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK));
|
||||
else
|
||||
block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/
|
||||
block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK));
|
||||
else
|
||||
block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK));
|
||||
}
|
||||
if (len == 1) {
|
||||
if (block->flags & CODEBLOCK_BYTE_MASK) {
|
||||
if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/
|
||||
block->page_mask |= ((uint64_t) 1 << (start_pc & PAGE_MASK_MASK));
|
||||
else
|
||||
block->page_mask2 |= ((uint64_t) 1 << (start_pc & PAGE_MASK_MASK));
|
||||
} else {
|
||||
if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/
|
||||
block->page_mask |= ((uint64_t) 1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK));
|
||||
else
|
||||
block->page_mask2 |= ((uint64_t) 1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK));
|
||||
}
|
||||
else
|
||||
codegen_mark_code_present_multibyte(block, start_pc, len);
|
||||
} else
|
||||
codegen_mark_code_present_multibyte(block, start_pc, len);
|
||||
}
|
||||
|
||||
void codegen_init();
|
||||
void codegen_close();
|
||||
void codegen_reset();
|
||||
void codegen_block_init(uint32_t phys_addr);
|
||||
void codegen_block_remove();
|
||||
void codegen_block_start_recompile(codeblock_t *block);
|
||||
void codegen_block_end_recompile(codeblock_t *block);
|
||||
void codegen_block_end();
|
||||
void codegen_delete_block(codeblock_t *block);
|
||||
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc);
|
||||
void codegen_generate_seg_restore();
|
||||
void codegen_set_op32();
|
||||
void codegen_flush();
|
||||
void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
extern void codegen_init(void);
|
||||
extern void codegen_close(void);
|
||||
extern void codegen_reset(void);
|
||||
extern void codegen_block_init(uint32_t phys_addr);
|
||||
extern void codegen_block_remove(void);
|
||||
extern void codegen_block_start_recompile(codeblock_t *block);
|
||||
extern void codegen_block_end_recompile(codeblock_t *block);
|
||||
extern void codegen_block_end(void);
|
||||
extern void codegen_delete_block(codeblock_t *block);
|
||||
extern void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc);
|
||||
extern void codegen_generate_seg_restore(void);
|
||||
extern void codegen_set_op32(void);
|
||||
extern void codegen_flush(void);
|
||||
extern void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
struct ir_data_t;
|
||||
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset);
|
||||
void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
|
||||
void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
|
||||
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset);
|
||||
extern void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
|
||||
extern void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
|
||||
|
||||
int codegen_purge_purgable_list();
|
||||
extern int codegen_purge_purgable_list(void);
|
||||
/*Delete a random code block to free memory. This is obviously quite expensive, and
|
||||
will only be called when the allocator is out of memory*/
|
||||
void codegen_delete_random_block(int required_mem_block);
|
||||
extern void codegen_delete_random_block(int required_mem_block);
|
||||
|
||||
extern int cpu_block_end;
|
||||
extern int cpu_block_end;
|
||||
extern uint32_t codegen_endpc;
|
||||
|
||||
extern int cpu_reps;
|
||||
@@ -346,21 +316,20 @@ extern int cpu_notreps;
|
||||
|
||||
extern int codegen_block_cycles;
|
||||
|
||||
extern void (*codegen_timing_start)();
|
||||
extern void (*codegen_timing_start)(void);
|
||||
extern void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
extern void (*codegen_timing_opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
extern void (*codegen_timing_block_start)();
|
||||
extern void (*codegen_timing_block_end)();
|
||||
extern int (*codegen_timing_jump_cycles)();
|
||||
extern void (*codegen_timing_block_start)(void);
|
||||
extern void (*codegen_timing_block_end)(void);
|
||||
extern int (*codegen_timing_jump_cycles)(void);
|
||||
|
||||
typedef struct codegen_timing_t
|
||||
{
|
||||
void (*start)();
|
||||
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)();
|
||||
void (*block_end)();
|
||||
int (*jump_cycles)();
|
||||
typedef struct codegen_timing_t {
|
||||
void (*start)(void);
|
||||
void (*prefix)(uint8_t prefix, uint32_t fetchdat);
|
||||
void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc);
|
||||
void (*block_start)(void);
|
||||
void (*block_end)(void);
|
||||
int (*jump_cycles)(void);
|
||||
} codegen_timing_t;
|
||||
|
||||
extern codegen_timing_t codegen_timing_pentium;
|
||||
@@ -371,7 +340,6 @@ extern codegen_timing_t codegen_timing_winchip2;
|
||||
extern codegen_timing_t codegen_timing_k6;
|
||||
extern codegen_timing_t codegen_timing_p6;
|
||||
|
||||
|
||||
void codegen_timing_set(codegen_timing_t *timing);
|
||||
|
||||
extern int block_current;
|
||||
@@ -382,8 +350,8 @@ extern int block_pos;
|
||||
/*Current physical page of block being recompiled. -1 if no recompilation taking place */
|
||||
extern uint32_t recomp_page;
|
||||
|
||||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern x86seg *op_ea_seg;
|
||||
extern int op_ssegs;
|
||||
extern uint32_t op_old_pc;
|
||||
|
||||
/*Set to 1 if flags have been changed in the block being recompiled, and hence
|
||||
@@ -398,13 +366,13 @@ extern int codegen_reg_loaded[8];
|
||||
|
||||
extern int codegen_in_recompile;
|
||||
|
||||
void codegen_generate_reset();
|
||||
void codegen_generate_reset(void);
|
||||
|
||||
int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP);
|
||||
int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP);
|
||||
void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction);
|
||||
|
||||
#ifdef DEBUG_EXTRA
|
||||
extern uint32_t instr_counts[256*256];
|
||||
extern uint32_t instr_counts[256 * 256];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,34 +9,36 @@
|
||||
|
||||
static struct
|
||||
{
|
||||
int count;
|
||||
int dest_reg;
|
||||
} acc_regs[] =
|
||||
{
|
||||
[ACCREG_cycles] = {0, IREG_cycles}
|
||||
int count;
|
||||
int dest_reg;
|
||||
} acc_regs[] = {
|
||||
[ACCREG_cycles] = {0, IREG_cycles}
|
||||
};
|
||||
|
||||
void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
|
||||
void
|
||||
codegen_accumulate(ir_data_t *ir, int acc_reg, int delta)
|
||||
{
|
||||
acc_regs[acc_reg].count += delta;
|
||||
acc_regs[acc_reg].count += delta;
|
||||
|
||||
#ifdef USE_ACYCS
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
uop_ADD_IMM(ir, IREG_acycs, IREG_acycs, -delta);
|
||||
}
|
||||
if ((acc_reg == ACCREG_cycles) && (delta != 0)) {
|
||||
uop_ADD_IMM(ir, IREG_acycs, IREG_acycs, -delta);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void codegen_accumulate_flush(ir_data_t *ir)
|
||||
void
|
||||
codegen_accumulate_flush(ir_data_t *ir)
|
||||
{
|
||||
if (acc_regs[0].count) {
|
||||
uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count);
|
||||
}
|
||||
if (acc_regs[0].count) {
|
||||
uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count);
|
||||
}
|
||||
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
void codegen_accumulate_reset()
|
||||
void
|
||||
codegen_accumulate_reset(void)
|
||||
{
|
||||
acc_regs[0].count = 0;
|
||||
acc_regs[0].count = 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user