Merge branch 'master' of ssh://github.com/86Box/86Box

This commit is contained in:
RichardG867
2022-11-21 14:29:09 -03:00
710 changed files with 92156 additions and 82149 deletions

View File

@@ -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"

View File

@@ -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
View File

@@ -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

View File

@@ -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)

View File

@@ -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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1 @@
3.0 (quilt)

15
debian/watch vendored Normal file
View 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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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>

View File

@@ -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;

View File

@@ -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
View 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
};

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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:

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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). */

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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.
*/
/*

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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
};

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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