Merge branch 'master' into global-config-screenshot

This commit is contained in:
Cacodemon345
2022-12-03 20:29:26 +06:00
committed by GitHub
687 changed files with 90165 additions and 81964 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

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

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;

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

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

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)
@@ -85,9 +89,9 @@ enum {
};
enum {
VISO_FORMAT_HSF = 0, /* High Sierra */
VISO_FORMAT_ISO, /* ISO 9660 */
VISO_FORMAT_ISO_LFN /* ISO 9660 with Joliet and Rock Ridge */
VISO_FORMAT_ISO = 1, /* ISO 9660 (High Sierra if not set) */
VISO_FORMAT_JOLIET = 2, /* Joliet extensions (Microsoft) */
VISO_FORMAT_RR = 4 /* Rock Ridge extensions (*nix) */
};
typedef struct _viso_entry_ {
@@ -111,7 +115,7 @@ typedef struct _viso_entry_ {
typedef struct {
uint64_t vol_size_offsets[2], pt_meta_offsets[2];
int format;
int format, use_version_suffix : 1;
size_t metadata_sectors, all_sectors, entry_map_size, sector_size, file_fifo_pos;
uint8_t *metadata;
@@ -296,7 +300,7 @@ static int
viso_fill_fn_short(char *data, const viso_entry_t *entry, viso_entry_t **entries)
{
/* Get name and extension length. */
const char *ext_pos = S_ISDIR(entry->stats.st_mode) ? NULL : strrchr(entry->basename, '.');
const char *ext_pos = strrchr(entry->basename, '.');
int name_len, ext_len;
if (ext_pos) {
name_len = ext_pos - entry->basename;
@@ -440,7 +444,7 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
time_s->tm_mday = 1;
} else if (time_s->tm_year > (longform ? 8099 : 255)) {
time_s->tm_year = longform ? 8099 : 255;
time_s->tm_mon = 12;
time_s->tm_mon = 11;
time_s->tm_mday = 31;
time_s->tm_hour = 23;
time_s->tm_min = time_s->tm_sec = 59;
@@ -459,14 +463,14 @@ viso_fill_time(uint8_t *data, time_t time, int format, int longform)
*p++ = time_s->tm_min; /* minute */
*p++ = time_s->tm_sec; /* second */
}
if (format >= VISO_FORMAT_ISO)
if (format & VISO_FORMAT_ISO)
*p++ = tz_offset; /* timezone (ISO only) */
return p - data;
}
static int
viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, viso_t *viso, int type)
{
uint8_t *p = data, *q, *r;
@@ -478,11 +482,11 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
if (entry->stats.st_mtime < 0)
pclog("VISO: Warning: Windows returned st_mtime %lld on file [%s]\n", (long long) entry->stats.st_mtime, entry->path);
#endif
p += viso_fill_time(p, entry->stats.st_mtime, format, 0); /* time */
*p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */
p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* time */
*p++ = S_ISDIR(entry->stats.st_mode) ? 0x02 : 0x00; /* flags */
VISO_SKIP(p, 2 + (format <= VISO_FORMAT_HSF)); /* file unit size (reserved on HSF), interleave gap size (HSF/ISO) and skip factor (HSF only) */
VISO_LBE_16(p, 1); /* volume sequence number */
VISO_SKIP(p, 2 + !(viso->format & VISO_FORMAT_ISO)); /* file unit size (reserved on HSF), interleave gap size (HSF/ISO) and skip factor (HSF only) */
VISO_LBE_16(p, 1); /* volume sequence number */
switch (type) {
case VISO_DIR_CURRENT:
@@ -492,7 +496,7 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
*p++ = (type == VISO_DIR_PARENT) ? 1 : 0; /* magic value corresponding to . or .. */
/* Fill Rock Ridge Extension Record for the root directory's . entry. */
if ((type == VISO_DIR_CURRENT_ROOT) && (format >= VISO_FORMAT_ISO_LFN)) {
if ((type == VISO_DIR_CURRENT_ROOT) && (viso->format & VISO_FORMAT_RR)) {
*p++ = 'E';
*p++ = 'R';
*p++ = 8 + (sizeof(rr_eid) - 1) + (sizeof(rr_edesc) - 1); /* length */
@@ -518,8 +522,8 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
*q = strlen(entry->name_short);
memcpy(p, entry->name_short, *q); /* file ID */
p += *q;
if ((format >= VISO_FORMAT_ISO) && !S_ISDIR(entry->stats.st_mode)) {
*p++ = ';'; /* version suffix for files (ISO only?) */
if (viso->use_version_suffix && !S_ISDIR(entry->stats.st_mode)) {
*p++ = ';'; /* version suffix for files (ISO only, except for Windows NT SETUPLDR.BIN El Torito hack) */
*p++ = '1';
*q += 2;
}
@@ -528,7 +532,7 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
*p++ = 0;
/* Fill Rock Ridge data. */
if (format >= VISO_FORMAT_ISO_LFN) {
if (viso->format & VISO_FORMAT_RR) {
*p++ = 'R'; /* RR = present Rock Ridge entries (only documented by RRIP revision 1.09!) */
*p++ = 'R';
*p++ = 5; /* length */
@@ -584,14 +588,14 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int format, int type)
*p++ = times; /* flags */
#ifdef st_birthtime
if (times & (1 << 0))
p += viso_fill_time(p, entry->stats.st_birthtime, format, 0); /* creation */
p += viso_fill_time(p, entry->stats.st_birthtime, viso->format, 0); /* creation */
#endif
if (times & (1 << 1))
p += viso_fill_time(p, entry->stats.st_mtime, format, 0); /* modify */
p += viso_fill_time(p, entry->stats.st_mtime, viso->format, 0); /* modify */
if (times & (1 << 2))
p += viso_fill_time(p, entry->stats.st_atime, format, 0); /* access */
p += viso_fill_time(p, entry->stats.st_atime, viso->format, 0); /* access */
if (times & (1 << 3))
p += viso_fill_time(p, entry->stats.st_ctime, format, 0); /* attributes */
p += viso_fill_time(p, entry->stats.st_ctime, viso->format, 0); /* attributes */
*r += p - r; /* add to length */
}
@@ -760,8 +764,9 @@ viso_init(const char *dirname, int *error)
*error = 1;
if (viso == NULL)
goto end;
viso->sector_size = VISO_SECTOR_SIZE;
viso->format = VISO_FORMAT_ISO_LFN;
viso->sector_size = VISO_SECTOR_SIZE;
viso->format = VISO_FORMAT_ISO | VISO_FORMAT_JOLIET | VISO_FORMAT_RR;
viso->use_version_suffix = (viso->format & VISO_FORMAT_ISO); /* cleared later if required */
/* Prepare temporary data buffers. */
data = calloc(2, viso->sector_size);
@@ -793,7 +798,6 @@ viso_init(const char *dirname, int *error)
if (!dir)
goto end;
strcpy(dir->path, dirname);
strcpy(dir->name_short, "[root]");
if (stat(dirname, &dir->stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&dir->stats, 0x00, sizeof(struct stat));
@@ -801,7 +805,7 @@ viso_init(const char *dirname, int *error)
if (!S_ISDIR(dir->stats.st_mode)) /* root is not a directory */
goto end;
dir->parent = dir; /* for the root's path table and .. entries */
cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, dir->name_short);
cdrom_image_viso_log("[%08X] %s => [root]\n", dir, dir->path);
/* Traverse directories, starting with the root. */
viso_entry_t **dir_entries = NULL;
@@ -809,16 +813,16 @@ viso_init(const char *dirname, int *error)
while (dir) {
/* Open directory for listing. */
DIR *dirp = opendir(dir->path);
if (!dirp)
goto next_dir;
/* Iterate through this directory's children to determine the entry array size. */
size_t children_count = 3; /* include terminator, . and .. */
while ((readdir_entry = readdir(dirp))) {
/* Ignore . and .. pseudo-directories. */
if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || ((readdir_entry->d_name[1] == '.') && (readdir_entry->d_name[2] == '\0'))))
continue;
children_count++;
if (dirp) { /* create empty directory if opendir failed */
while ((readdir_entry = readdir(dirp))) {
/* Ignore . and .. pseudo-directories. */
if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.')))
continue;
children_count++;
}
}
/* Grow array if needed. */
@@ -855,77 +859,89 @@ viso_init(const char *dirname, int *error)
}
/* Iterate through this directory's children again, making the entries. */
rewinddir(dirp);
while ((readdir_entry = readdir(dirp))) {
/* Ignore . and .. pseudo-directories. */
if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || ((readdir_entry->d_name[1] == '.') && (readdir_entry->d_name[2] == '\0'))))
continue;
if (dirp) {
rewinddir(dirp);
while ((readdir_entry = readdir(dirp))) {
/* Ignore . and .. pseudo-directories. */
if ((readdir_entry->d_name[0] == '.') && ((readdir_entry->d_name[1] == '\0') || (*((uint16_t *) &readdir_entry->d_name[1]) == '.')))
continue;
/* Add and fill entry. */
entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2);
if (!entry)
break;
entry->parent = dir;
strcpy(entry->path, dir->path);
path_slash(&entry->path[dir_path_len]);
entry->basename = &entry->path[dir_path_len + 1];
strcpy(entry->basename, readdir_entry->d_name);
/* Add and fill entry. */
entry = dir_entries[children_count++] = (viso_entry_t *) calloc(1, sizeof(viso_entry_t) + dir_path_len + strlen(readdir_entry->d_name) + 2);
if (!entry)
break;
entry->parent = dir;
strcpy(entry->path, dir->path);
path_slash(&entry->path[dir_path_len]);
entry->basename = &entry->path[dir_path_len + 1];
strcpy(entry->basename, readdir_entry->d_name);
/* Stat this child. */
if (stat(entry->path, &entry->stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&entry->stats, 0x00, sizeof(struct stat));
}
/* Handle file size and El Torito boot code. */
if (!S_ISDIR(entry->stats.st_mode)) {
/* Clamp to 4 GB - 1 byte. */
if (entry->stats.st_size > ((uint32_t) -1))
entry->stats.st_size = (uint32_t) -1;
/* Increase entry map size. */
viso->entry_map_size += entry->stats.st_size / viso->sector_size;
if (entry->stats.st_size % viso->sector_size)
viso->entry_map_size++; /* round up to the next sector */
/* Detect El Torito boot code file and set it accordingly. */
if (dir == eltorito_dir) {
if (!stricmp(readdir_entry->d_name, "Boot-NoEmul.img")) {
eltorito_type = 0x00;
have_eltorito_entry:
if (eltorito_entry)
eltorito_others_present = 1; /* flag that the boot code directory contains other files */
eltorito_entry = entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-1.2M.img")) {
eltorito_type = 0x01;
goto have_eltorito_entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-1.44M.img")) {
eltorito_type = 0x02;
goto have_eltorito_entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-2.88M.img")) {
eltorito_type = 0x03;
goto have_eltorito_entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-HardDisk.img")) {
eltorito_type = 0x04;
goto have_eltorito_entry;
} else {
eltorito_others_present = 1; /* flag that the boot code directory contains other files */
}
/* Stat this child. */
if (stat(entry->path, &entry->stats) != 0) {
/* Use a blank structure if stat failed. */
memset(&entry->stats, 0x00, sizeof(struct stat));
}
} else if ((dir == viso->root_dir) && !stricmp(readdir_entry->d_name, "[BOOT]")) {
/* Set this as the directory containing El Torito boot code. */
eltorito_dir = entry;
eltorito_others_present = 0;
}
/* Set short filename. */
if (viso_fill_fn_short(entry->name_short, entry, dir_entries)) {
free(entry);
children_count--;
continue;
}
/* Handle file size and El Torito boot code. */
if (!S_ISDIR(entry->stats.st_mode)) {
/* Clamp file size to 4 GB - 1 byte. */
if (entry->stats.st_size > ((uint32_t) -1))
entry->stats.st_size = (uint32_t) -1;
cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename);
/* Increase entry map size. */
viso->entry_map_size += entry->stats.st_size / viso->sector_size;
if (entry->stats.st_size % viso->sector_size)
viso->entry_map_size++; /* round up to the next sector */
/* Detect El Torito boot code file and set it accordingly. */
if (dir == eltorito_dir) {
if (!stricmp(readdir_entry->d_name, "Boot-NoEmul.img")) {
eltorito_type = 0x00;
have_eltorito_entry:
if (eltorito_entry)
eltorito_others_present = 1; /* flag that the boot code directory contains other files */
eltorito_entry = entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-1.2M.img")) {
eltorito_type = 0x01;
goto have_eltorito_entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-1.44M.img")) {
eltorito_type = 0x02;
goto have_eltorito_entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-2.88M.img")) {
eltorito_type = 0x03;
goto have_eltorito_entry;
} else if (!stricmp(readdir_entry->d_name, "Boot-HardDisk.img")) {
eltorito_type = 0x04;
goto have_eltorito_entry;
} else {
eltorito_others_present = 1; /* flag that the boot code directory contains other files */
}
} else {
/* Disable version suffixes if this structure appears to contain the Windows NT
El Torito boot code, which is known not to tolerate suffixed file names. */
if (eltorito_dir && /* El Torito directory present? */
(eltorito_type == 0x00) && /* El Torito directory not checked yet, or confirmed to contain non-emulation boot code? */
(dir->parent == viso->root_dir) && /* one subdirectory deep? (I386 for instance) */
!stricmp(readdir_entry->d_name, "SETUPLDR.BIN")) /* SETUPLDR.BIN present? */
viso->use_version_suffix = 0;
}
} else if ((dir == viso->root_dir) && !stricmp(readdir_entry->d_name, "[BOOT]")) {
/* Set this as the directory containing El Torito boot code. */
eltorito_dir = entry;
eltorito_others_present = 0;
}
/* Set short filename. */
if (viso_fill_fn_short(entry->name_short, entry, dir_entries)) {
free(entry);
children_count--;
continue;
}
cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", entry, dir->path, entry->name_short, entry->basename);
}
} else {
cdrom_image_viso_log("VISO: Failed to enumerate [%s], will be empty\n", dir->path);
}
/* Add terminator. */
@@ -947,6 +963,8 @@ have_eltorito_entry:
next_dir:
/* Move on to the next directory. */
if (dirp)
closedir(dirp);
dir = dir->next_dir;
}
if (dir_entries)
@@ -960,21 +978,26 @@ next_dir:
the timezone offset for descriptors and file times to use. */
tzset();
time_t now = time(NULL);
tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4);
if (viso->format & VISO_FORMAT_ISO) /* timezones are ISO only */
tz_offset = (now - mktime(gmtime(&now))) / (3600 / 4);
/* Get root directory basename for the volume ID. */
char *basename = path_get_filename(viso->root_dir->path);
if (!basename || (basename[0] == '\0'))
basename = EMU_NAME;
/* Determine whether or not we're working with 2 volume descriptors
(as well as 2 directory trees and 4 path tables) for Joliet. */
int max_vd = (viso->format & VISO_FORMAT_JOLIET) ? 1 : 0;
/* Write volume descriptors. */
for (int i = 0; i <= (viso->format >= VISO_FORMAT_ISO_LFN); i++) {
for (int i = 0; i <= max_vd; i++) {
/* Fill volume descriptor. */
p = data;
if (viso->format <= VISO_FORMAT_HSF)
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 1 + i; /* type */
memcpy(p, (viso->format <= VISO_FORMAT_HSF) ? "CDROM" : "CD001", 5); /* standard ID */
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 1 + i; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
p += 5;
*p++ = 1; /* version */
*p++ = 0; /* unused */
@@ -1013,11 +1036,12 @@ next_dir:
/* Path table metadata is filled in later. */
viso->pt_meta_offsets[i] = ftello64(viso->tf.file) + (p - data);
VISO_SKIP(p, 24 + (16 * (viso->format <= VISO_FORMAT_HSF))); /* PT size, LE PT offset, optional LE PT offset (three on HSF), BE PT offset, optional BE PT offset (three on HSF) */
VISO_SKIP(p, 24 + (16 * !(viso->format & VISO_FORMAT_ISO))); /* PT size, LE PT offset, optional LE PT offset (three on HSF), BE PT offset, optional BE PT offset (three on HSF) */
viso->root_dir->dr_offsets[i] = ftello64(viso->tf.file) + (p - data);
p += viso_fill_dir_record(p, viso->root_dir, viso->format, VISO_DIR_CURRENT); /* root directory */
p += viso_fill_dir_record(p, viso->root_dir, viso, VISO_DIR_CURRENT); /* root directory */
int copyright_abstract_len = (viso->format & VISO_FORMAT_ISO) ? 37 : 32;
if (i) {
viso_write_wstring((uint16_t *) p, L"", 64, VISO_CHARSET_D); /* volume set ID */
p += 128;
@@ -1027,11 +1051,11 @@ next_dir:
p += 128;
viso_write_wstring((uint16_t *) p, EMU_NAME_W L" " EMU_VERSION_W L" VIRTUAL ISO", 64, VISO_CHARSET_A); /* application ID */
p += 128;
viso_write_wstring((uint16_t *) p, L"", (viso->format <= VISO_FORMAT_HSF) ? 16 : 18, VISO_CHARSET_D); /* copyright file ID */
p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37;
viso_write_wstring((uint16_t *) p, L"", (viso->format <= VISO_FORMAT_HSF) ? 16 : 18, VISO_CHARSET_D); /* abstract file ID */
p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37;
if (viso->format >= VISO_FORMAT_ISO) {
viso_write_wstring((uint16_t *) p, L"", copyright_abstract_len >> 1, VISO_CHARSET_D); /* copyright file ID */
p += copyright_abstract_len;
viso_write_wstring((uint16_t *) p, L"", copyright_abstract_len >> 1, VISO_CHARSET_D); /* abstract file ID */
p += copyright_abstract_len;
if (viso->format & VISO_FORMAT_ISO) {
viso_write_wstring((uint16_t *) p, L"", 18, VISO_CHARSET_D); /* bibliography file ID (ISO only) */
p += 37;
}
@@ -1044,11 +1068,11 @@ next_dir:
p += 128;
viso_write_string(p, EMU_NAME " " EMU_VERSION " VIRTUAL ISO", 128, VISO_CHARSET_A); /* application ID */
p += 128;
viso_write_string(p, "", (viso->format <= VISO_FORMAT_HSF) ? 32 : 37, VISO_CHARSET_D); /* copyright file ID */
p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37;
viso_write_string(p, "", (viso->format <= VISO_FORMAT_HSF) ? 32 : 37, VISO_CHARSET_D); /* abstract file ID */
p += (viso->format <= VISO_FORMAT_HSF) ? 32 : 37;
if (viso->format >= VISO_FORMAT_ISO) {
viso_write_string(p, "", copyright_abstract_len, VISO_CHARSET_D); /* copyright file ID */
p += copyright_abstract_len;
viso_write_string(p, "", copyright_abstract_len, VISO_CHARSET_D); /* abstract file ID */
p += copyright_abstract_len;
if (viso->format & VISO_FORMAT_ISO) {
viso_write_string(p, "", 37, VISO_CHARSET_D); /* bibliography file ID (ISO only) */
p += 37;
}
@@ -1074,10 +1098,10 @@ next_dir:
cdrom_image_viso_log("VISO: Writing El Torito boot descriptor for entry [%08X]\n", eltorito_entry);
p = data;
if (viso->format <= VISO_FORMAT_HSF)
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0; /* type */
memcpy(p, (viso->format <= VISO_FORMAT_HSF) ? "CDROM" : "CD001", 5); /* standard ID */
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
p += 5;
*p++ = 1; /* version */
@@ -1098,10 +1122,10 @@ next_dir:
/* Fill terminator. */
p = data;
if (viso->format <= VISO_FORMAT_HSF)
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0xff; /* type */
memcpy(p, (viso->format <= VISO_FORMAT_HSF) ? "CDROM" : "CD001", 5); /* standard ID */
if (!(viso->format & VISO_FORMAT_ISO))
VISO_LBE_32(p, ftello64(viso->tf.file) / viso->sector_size); /* sector offset (HSF only) */
*p++ = 0xff; /* type */
memcpy(p, (viso->format & VISO_FORMAT_ISO) ? "CD001" : "CDROM", 5); /* standard ID */
p += 5;
*p++ = 1; /* version */
@@ -1177,7 +1201,7 @@ next_dir:
}
/* Write each path table. */
for (int i = 0; i <= ((viso->format >= VISO_FORMAT_ISO_LFN) ? 3 : 1); i++) {
for (int i = 0; i <= ((max_vd << 1) | 1); i++) {
cdrom_image_viso_log("VISO: Generating path table #%d:\n", i);
/* Save this path table's start offset. */
@@ -1207,7 +1231,7 @@ next_dir:
/* Fill path table entry. */
p = data;
if (viso->format <= VISO_FORMAT_HSF) {
if (!(viso->format & VISO_FORMAT_ISO)) {
*((uint32_t *) p) = 0; /* extent location (filled in later) */
p += 4;
*p++ = 0; /* extended attribute length */
@@ -1223,16 +1247,17 @@ next_dir:
*((uint16_t *) p) = (i & 1) ? cpu_to_be16(dir->parent->pt_idx) : cpu_to_le16(dir->parent->pt_idx); /* parent directory number */
p += 2;
if (dir == viso->root_dir) { /* directory ID and length */
data[5 * (viso->format <= VISO_FORMAT_HSF)] = 1;
*p = 0x00;
} else if (i & 2) {
data[5 * (viso->format <= VISO_FORMAT_HSF)] = viso_fill_fn_joliet(p, dir, 255);
} else {
data[5 * (viso->format <= VISO_FORMAT_HSF)] = strlen(dir->name_short);
memcpy(p, dir->name_short, data[5 * (viso->format <= VISO_FORMAT_HSF)]);
pt_temp = 5 * !(viso->format & VISO_FORMAT_ISO); /* directory ID length at offset 0 for ISO, 5 for HSF */
if (dir == viso->root_dir) { /* directory ID length then ID for root... */
data[pt_temp] = 1;
*p = 0x00;
} else if (i & 2) { /* ...or Joliet... */
data[pt_temp] = viso_fill_fn_joliet(p, dir, 255);
} else { /* ...or short name */
data[pt_temp] = strlen(dir->name_short);
memcpy(p, dir->name_short, data[pt_temp]);
}
p += data[5 * (viso->format <= VISO_FORMAT_HSF)];
p += data[pt_temp];
if ((p - data) & 1) /* padding for odd directory ID lengths */
*p++ = 0x00;
@@ -1265,7 +1290,7 @@ next_dir:
/* Write directory records for each type. */
int dir_type = VISO_DIR_CURRENT_ROOT;
for (int i = 0; i <= (viso->format >= VISO_FORMAT_ISO_LFN); i++) {
for (int i = 0; i <= max_vd; i++) {
cdrom_image_viso_log("VISO: Generating directory record set #%d:\n", i);
/* Go through directories. */
@@ -1298,7 +1323,7 @@ next_dir:
viso_pwrite(data, dir->pt_offsets[i << 1], 4, 1, viso->tf.file); /* little endian */
viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1], 4, 1, viso->tf.file); /* big endian */
if (i == (viso->format >= VISO_FORMAT_ISO_LFN)) /* overwrite pt_offsets in the union if we no longer need them */
if (i == max_vd) /* overwrite pt_offsets in the union if we no longer need them */
dir->file = NULL;
/* Go through entries in this directory. */
@@ -1313,7 +1338,7 @@ next_dir:
((dir_type == VISO_DIR_PARENT) ? ".." : ((dir_type < VISO_DIR_PARENT) ? "." : (i ? entry->basename : entry->name_short))));
/* Fill directory record. */
viso_fill_dir_record(data, entry, viso->format, dir_type);
viso_fill_dir_record(data, entry, viso, dir_type);
/* Entries cannot cross sector boundaries, so pad to the next sector if needed. */
write = viso->sector_size - (ftello64(viso->tf.file) % viso->sector_size);
@@ -1452,7 +1477,7 @@ next_entry:
} else {
p = data;
VISO_LBE_32(p, viso->all_sectors * base_factor);
for (int i = 0; i <= (viso->format >= VISO_FORMAT_ISO_LFN); i++)
for (int i = 0; i <= max_vd; i++)
viso_pwrite(data, entry->dr_offsets[i] + 2, 8, 1, viso->tf.file);
}

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.
*
* Mitsumi CD-ROM emulation for the ISA bus.
* Mitsumi CD-ROM emulation for the ISA bus.
*
*
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2022 Miran Grca.
* Copyright 2022 Miran Grca.
*/
#include <inttypes.h>
#include <stdarg.h>
@@ -183,7 +183,7 @@ mitsumi_cdrom_read_sector(mcd_t *dev, int first)
return 0;
}
cdrom_stop(cdrom);
ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, &dev->readcount);
ret = cdrom_readsector_raw(cdrom, dev->buf, cdrom->seek_pos, 0, 2, 0x10, (int *) &dev->readcount);
if (!ret)
return 0;
if (dev->mode & 0x40) {

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,8 +42,8 @@
typedef struct
{
uint8_t irq_convert,
pci_regs[256];
uint8_t irq_convert,
pci_regs[256];
} opti822_t;
// #define ENABLE_OPTI822_LOG 1
@@ -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,19 +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 = 1;
for (i = 0; i < 16; i++) {
reg = 0x88 + (i >> 1);
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;
@@ -127,8 +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 pin, slot;
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);
@@ -144,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);
@@ -293,33 +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];
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;
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;
}
}
@@ -327,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;
@@ -343,12 +343,14 @@ static void
opti822_reset(void *priv)
{
opti822_t *dev = (opti822_t *) priv;
int i;
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;
@@ -356,7 +358,8 @@ 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;
@@ -370,7 +373,7 @@ opti822_reset(void *priv)
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